/// <summary>
        /// Used to modify recordset with value from api gateway code deploy in another account.
        /// </summary>
        /// <param name="jobEvent">CodePipeline event.</param>
        /// <param name="context">Lambda Context</param>
        /// <returns>Job success of the Lambda</returns>
        public async Task <AmazonWebServiceResponse> UpdateApiGatewayAliasRecordSet(CodePipelineJobEvent jobEvent, ILambdaContext context)
        {
            var jobId = jobEvent.CodePipelineJob.Id;

            context.Logger.LogLine($"JobId: {jobId}");

            using (var codePipelineClient = new AmazonCodePipelineClient())
                using (var s3Client = new AmazonS3Client())
                    using (var dnsClient = new AmazonRoute53Client())
                    {
                        // Prep the user parameters
                        var userParameters = jobEvent.CodePipelineJob.Data.ActionConfiguration.Configuration["UserParameters"];
                        context.Logger.LogLine("UserParameters:");
                        context.Logger.LogLine(userParameters);
                        var paramDict = JsonConvert.DeserializeObject <Dictionary <string, string> >(userParameters);

                        try
                        {
                            DnsSettings dnsSettings = null;

                            // Get the first (only) input artifact
                            var artifact           = jobEvent.CodePipelineJob.Data.InputArtifacts.First();
                            var artifactBucketName = artifact.Location.S3Location.BucketName;
                            var artifactBucketKey  = artifact.Location.S3Location.ObjectKey;

                            // Unzip and get json
                            using (var getResponse = await s3Client.GetObjectAsync(artifactBucketName, artifactBucketKey))
                            {
                                var memoryStream = new MemoryStream();
                                using (var objectStream = getResponse.ResponseStream)
                                {
                                    objectStream.CopyTo(memoryStream);
                                }


                                var searchFile = paramDict["DnsJson"];
                                context.Logger.LogLine("Unziping artifact");
                                context.Logger.LogLine($"Searching for {searchFile}");
                                using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Read))
                                {
                                    foreach (var entry in archive.Entries)
                                    {
                                        var fileName = entry.Name;
                                        context.Logger.LogLine("Checking File: " + entry.Name);

                                        if (searchFile == fileName)
                                        {
                                            using (var fileStream = entry.Open())
                                                using (var streamReader = new StreamReader(fileStream))
                                                {
                                                    var dnsJson = await streamReader.ReadToEndAsync();

                                                    dnsSettings = JsonConvert.DeserializeObject <DnsSettings>(dnsJson);
                                                }

                                            break;
                                        }
                                    }
                                }
                            }

                            // Get the hosted zones in the tools region
                            context.Logger.LogLine($"Searching for {dnsSettings.HostedZoneLookupDomainName}");
                            var hostedZones = await dnsClient.ListHostedZonesAsync();

                            var myHostedZone = hostedZones.HostedZones.FirstOrDefault(z => z.Name == dnsSettings.HostedZoneLookupDomainName);
                            if (myHostedZone == null)
                            {
                                var noZoneMessage = $"Hosted Zone {dnsSettings.HostedZoneLookupDomainName} could not be found";
                                context.Logger.LogLine(noZoneMessage);
                                var failureDetails = new FailureDetails
                                {
                                    Message = noZoneMessage,
                                    Type    = FailureType.ConfigurationError
                                };
                                return(await codePipelineClient.PutJobFailureResultAsync(jobId, failureDetails));
                            }

                            // The record set we need to create
                            var recordSet = new ResourceRecordSet
                            {
                                Name            = dnsSettings.WebApiDnsDomain,
                                Type            = RRType.A,
                                ResourceRecords = new List <ResourceRecord> {
                                    new ResourceRecord {
                                        Value = $"ALIAS {dnsSettings.RegionalDomainName}"
                                    }
                                }
                            };
                            var rsChange = new Change
                            {
                                Action            = ChangeAction.UPSERT,
                                ResourceRecordSet = recordSet
                            };
                            var rsChangeBatch = new ChangeBatch
                            {
                                Changes = new List <Change> {
                                    rsChange
                                }
                            };


                            // Create/Update the recordset
                            var changeDnsRequest = new ChangeResourceRecordSetsRequest
                            {
                                ChangeBatch  = rsChangeBatch,
                                HostedZoneId = myHostedZone.Id
                            };
                            var changeResponse = await dnsClient.ChangeResourceRecordSetsAsync(changeDnsRequest);

                            // Log and send the success response
                            context.Logger.LogLine($"Request Id {changeResponse.ChangeInfo.Id} submitted");
                            context.Logger.LogLine($"{dnsSettings.WebApiDnsDomain} => A ALIAS {dnsSettings.RegionalDomainName}");
                            var successResultRequest = new PutJobSuccessResultRequest
                            {
                                JobId = jobId
                            };
                            return(await codePipelineClient.PutJobSuccessResultAsync(successResultRequest));
                        }
                        catch (Exception ex)
                        {
                            // Send the failure response and log
                            return(await DoException(codePipelineClient, ex, jobId, context));
                        }
                    }
        }
        /// <summary>
        /// A Lambda function to respond to HTTP Get methods from API Gateway
        /// </summary>
        /// <param name="request"></param>
        /// <returns>The list of blogs</returns>
        public async Task <AmazonWebServiceResponse> FixCloudFormationOutput(CodePipelineJobEvent jobEvent, ILambdaContext context)
        {
            var jobId = jobEvent.CodePipelineJob.Id;

            context.Logger.LogLine($"JobId: {jobId}");

            // Setup Clients
            var codePipelineClient = new AmazonCodePipelineClient();
            var stsClient          = new AmazonSecurityTokenServiceClient();

            try
            {
                var jobData = jobEvent.CodePipelineJob.Data;

                // Assume the role in the cloudformation account that screwed up the bucket permissions
                // for the output object
                var userParameters = jobData.ActionConfiguration.Configuration["UserParameters"];
                var paramDict      = JsonConvert.DeserializeObject <Dictionary <string, string> >(userParameters);
                var roleArn        = paramDict["RoleArn"];

                var assumeRoleRequest = new AssumeRoleRequest {
                    RoleArn         = roleArn,
                    RoleSessionName = "codepipeline",
                    DurationSeconds = 900
                };
                var assumeRoleResponse = await stsClient.AssumeRoleAsync(assumeRoleRequest);

                // Setup an S3 Client with the sts creds
                var s3Client = new AmazonS3Client(assumeRoleResponse.Credentials);

                // Update the ACLs of the input artifacts
                foreach (var inputArtifact in jobData.InputArtifacts)
                {
                    var bucketName = inputArtifact.Location.S3Location.BucketName;
                    var bucketKey  = inputArtifact.Location.S3Location.ObjectKey;
                    context.Logger.LogLine($"Fixing {bucketName}/{bucketKey}");

                    var putObjectAclRequest = new PutACLRequest
                    {
                        BucketName = bucketName,
                        CannedACL  = S3CannedACL.BucketOwnerFullControl,
                        Key        = bucketKey
                    };
                    await s3Client.PutACLAsync(putObjectAclRequest);
                }

                // Send the success response
                var successResultRequest = new PutJobSuccessResultRequest
                {
                    JobId = jobId
                };
                return(await codePipelineClient.PutJobSuccessResultAsync(successResultRequest));
            }
            catch (Exception ex)
            {
                // Send the failure response and log
                context.Logger.LogLine("FixCloudFormationOutput Exception");
                context.Logger.LogLine(ex.Message);
                var failureDetails = new FailureDetails {
                    Message = ex.Message,
                    Type    = FailureType.JobFailed
                };
                return(await codePipelineClient.PutJobFailureResultAsync(jobId, failureDetails));
            }
        }