コード例 #1
0
        private async Task <string> CreateChangeSet(DeployContext context, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var parameters = context.Parameters
                             .Select((entry) => new Parameter {
                ParameterKey = entry.Key, ParameterValue = entry.Value
            })
                             .ToList();

            var tags = context.Tags
                       .Select((entry) => new Tag {
                Key = entry.Key, Value = entry.Value
            })
                       .ToList();

            var request = new CreateChangeSetRequest
            {
                StackName     = context.StackName,
                ChangeSetName = context.ChangeSetName,
                ChangeSetType = await GetChangeSetType(context, cancellationToken),
                Capabilities  = context.Capabilities,
                TemplateURL   = context.TemplateURL,
                Parameters    = parameters,
                Tags          = tags,
            };

            var response = await cloudformation.CreateChangeSetAsync(request, cancellationToken);

            return(response.StackId);
        }
コード例 #2
0
 private Amazon.CloudFormation.Model.CreateChangeSetResponse CallAWSServiceOperation(IAmazonCloudFormation client, Amazon.CloudFormation.Model.CreateChangeSetRequest request)
 {
     Utils.Common.WriteVerboseEndpointMessage(this, client.Config, "AWS CloudFormation", "CreateChangeSet");
     try
     {
         #if DESKTOP
         return(client.CreateChangeSet(request));
         #elif CORECLR
         return(client.CreateChangeSetAsync(request).GetAwaiter().GetResult());
         #else
                 #error "Unknown build edition"
         #endif
     }
     catch (AmazonServiceException exc)
     {
         var webException = exc.InnerException as System.Net.WebException;
         if (webException != null)
         {
             throw new Exception(Utils.Common.FormatNameResolutionFailureMessage(client.Config, webException.Message), webException);
         }
         throw;
     }
 }
コード例 #3
0
ファイル: Cloudformation.cs プロジェクト: ziphrax/Humidifier
        public static async Task <DeployStackResult> DeployStackAsync(ILogger log, IAmazonCloudFormation cloudformation, long ticks, string stackName, List <Tag> tags, Dictionary <string, string> parameters, string templateBody = null, Uri templateUrl = null, string roleArn = null)
        {
            log.Information("Checking stack: {stackName}", stackName);

            Stack existingStack = await GetExistingStackAsync(cloudformation, stackName).ConfigureAwait(false);

            log.Information("Found existing stack: " + (existingStack != null));

            var changeSetName = stackName + "-" + ticks;
            var param         = parameters.Select(x => new Parameter {
                ParameterKey = x.Key, ParameterValue = x.Value
            }).ToList();

            // Determine if the stack is in a good state to be updated.
            ChangeSetType changeSetType;

            if (existingStack == null || existingStack.StackStatus == StackStatus.REVIEW_IN_PROGRESS || existingStack.StackStatus == StackStatus.DELETE_COMPLETE)
            {
                changeSetType = ChangeSetType.CREATE;
            }
            // If the state was ROLLBACK_COMPLETE that means the stack failed on initial creation and the resources where cleaned up.
            // It is safe to delete the stack so we can recreate it.
            else if (existingStack.StackStatus == StackStatus.ROLLBACK_COMPLETE)
            {
                await DeleteRollbackCompleteStackAsync(log, cloudformation, existingStack).ConfigureAwait(false);

                changeSetType = ChangeSetType.CREATE;
            }
            // If the status was ROLLBACK_IN_PROGRESS that means the initial creation is failing.
            // Wait to see if it goes into ROLLBACK_COMPLETE status meaning everything got cleaned up and then delete it.
            else if (existingStack.StackStatus == StackStatus.ROLLBACK_IN_PROGRESS)
            {
                existingStack = await WaitForNoLongerInProgress(log, cloudformation, existingStack.StackName).ConfigureAwait(false);

                if (existingStack != null && existingStack.StackStatus == StackStatus.ROLLBACK_COMPLETE)
                {
                    await DeleteRollbackCompleteStackAsync(log, cloudformation, existingStack).ConfigureAwait(false);
                }

                changeSetType = ChangeSetType.CREATE;
            }
            // If the status was DELETE_IN_PROGRESS then just wait for delete to complete
            else if (existingStack.StackStatus == StackStatus.DELETE_IN_PROGRESS)
            {
                await WaitForNoLongerInProgress(log, cloudformation, existingStack.StackName).ConfigureAwait(false);

                changeSetType = ChangeSetType.CREATE;
            }
            // The Stack state is in a normal state and ready to be updated.
            else if (existingStack.StackStatus == StackStatus.CREATE_COMPLETE ||
                     existingStack.StackStatus == StackStatus.UPDATE_COMPLETE ||
                     existingStack.StackStatus == StackStatus.UPDATE_ROLLBACK_COMPLETE)
            {
                changeSetType = ChangeSetType.UPDATE;
            }
            // All other states means the Stack is in an inconsistent state.
            else
            {
                log.Error($"The stack's current state of {existingStack.StackStatus} is invalid for updating");
                return(DeployStackResult.Failed);
            }

            CreateChangeSetResponse changeSetResponse;

            try
            {
                var changeSetRequest = new CreateChangeSetRequest
                {
                    StackName     = stackName,
                    ChangeSetName = changeSetName,
                    ChangeSetType = changeSetType,
                    Capabilities  = new List <string> {
                        CAPABILITY_NAMED_IAM
                    },
                    Tags       = tags,
                    Parameters = param,
                    RoleARN    = roleArn
                };

                if (templateUrl != null)
                {
                    changeSetRequest.TemplateURL = templateUrl.ToString();
                }
                else
                {
                    changeSetRequest.TemplateBody = templateBody;
                }

                // Create the change set which performs the transformation on the Serverless resources in the template.
                changeSetResponse = await cloudformation.CreateChangeSetAsync(changeSetRequest).ConfigureAwait(false);

                log.Information("CloudFormation change set created. StackName: {stackName}, ChangeSetName: {changeSetName}", stackName, changeSetName);
            }
            catch (Exception e)
            {
                log.Error(e, "Error creating cloudformation change set");
                throw;
            }

            // The change set can take a few seconds to be reviewed and be ready to be executed.
            DeployStackResult waitResult = await WaitForChangeSetBeingAvailableAsync(log, cloudformation, changeSetResponse.Id).ConfigureAwait(false);

            if (waitResult == DeployStackResult.NoChanges || waitResult == DeployStackResult.Failed)
            {
                return(waitResult);
            }

            var executeChangeSetRequest = new ExecuteChangeSetRequest
            {
                StackName     = stackName,
                ChangeSetName = changeSetResponse.Id
            };

            // Execute the change set.
            var timeChangeSetExecuted = DateTime.Now;

            try
            {
                await cloudformation.ExecuteChangeSetAsync(executeChangeSetRequest).ConfigureAwait(false);

                if (changeSetType == ChangeSetType.CREATE)
                {
                    log.Information($"Created CloudFormation stack {stackName}");
                }
                else
                {
                    log.Information($"Initiated CloudFormation stack update on {stackName}");
                }
            }
            catch (Exception e)
            {
                log.Error(e, "Error executing cloudformation change set");
                throw;
            }

            // Wait for the stack to finish
            var updatedStack = await WaitStackToCompleteAsync(log, cloudformation, stackName, timeChangeSetExecuted).ConfigureAwait(false);

            if (updatedStack.StackStatus == StackStatus.CREATE_COMPLETE || updatedStack.StackStatus == StackStatus.UPDATE_COMPLETE)
            {
                log.Information($"Stack finished updating with status: {updatedStack.StackStatus}");

                // Display the output parameters.
                DisplayOutputs(log, updatedStack);
            }
            else
            {
                log.Error($"Stack update failed with status: {updatedStack.StackStatus} ({updatedStack.StackStatusReason})");
                return(DeployStackResult.Failed);
            }

            return(DeployStackResult.Ok);
        }