func updateStackViaChangeSet(serviceName string, cfTemplateURL string, capabilities []*string, awsTags []*cloudformation.Tag, awsCloudFormation *cloudformation.CloudFormation, logger *logrus.Logger) error { // Create a change set name... changeSetRequestName := CloudFormationResourceName(fmt.Sprintf("%sChangeSet", serviceName)) changeSetInput := &cloudformation.CreateChangeSetInput{ Capabilities: capabilities, ChangeSetName: aws.String(changeSetRequestName), ClientToken: aws.String(changeSetRequestName), Description: aws.String(fmt.Sprintf("Change set for service: %s", serviceName)), StackName: aws.String(serviceName), TemplateURL: aws.String(cfTemplateURL), } if len(awsTags) != 0 { changeSetInput.Tags = awsTags } _, changeSetError := awsCloudFormation.CreateChangeSet(changeSetInput) if nil != changeSetError { return changeSetError } logger.WithFields(logrus.Fields{ "StackName": serviceName, }).Info("Issued CreateChangeSet request") describeChangeSetInput := cloudformation.DescribeChangeSetInput{ ChangeSetName: aws.String(changeSetRequestName), StackName: aws.String(serviceName), } var describeChangeSetOutput *cloudformation.DescribeChangeSetOutput for waitComplete := false; !waitComplete; { sleepDuration := time.Duration(11+rand.Int31n(13)) * time.Second time.Sleep(sleepDuration) changeSetOutput, describeChangeSetError := awsCloudFormation.DescribeChangeSet(&describeChangeSetInput) if nil != describeChangeSetError { return describeChangeSetError } describeChangeSetOutput = changeSetOutput waitComplete = (nil != describeChangeSetOutput) } logger.WithFields(logrus.Fields{ "DescribeChangeSetOutput": describeChangeSetOutput, }).Debug("DescribeChangeSet result") ////////////////////////////////////////////////////////////////////////////// // If there aren't any changes, then skip it... if len(describeChangeSetOutput.Changes) <= 0 { logger.WithFields(logrus.Fields{ "StackName": serviceName, }).Info("No changes detected for service") // Delete it... deleteChangeSetInput := cloudformation.DeleteChangeSetInput{ ChangeSetName: aws.String(changeSetRequestName), StackName: aws.String(serviceName), } _, deleteChangeSetResultErr := awsCloudFormation.DeleteChangeSet(&deleteChangeSetInput) return deleteChangeSetResultErr } ////////////////////////////////////////////////////////////////////////////// // Apply the change executeChangeSetInput := cloudformation.ExecuteChangeSetInput{ ChangeSetName: aws.String(changeSetRequestName), StackName: aws.String(serviceName), } executeChangeSetOutput, executeChangeSetError := awsCloudFormation.ExecuteChangeSet(&executeChangeSetInput) logger.WithFields(logrus.Fields{ "ExecuteChangeSetOutput": executeChangeSetOutput, }).Debug("ExecuteChangeSet result") if nil == executeChangeSetError { logger.WithFields(logrus.Fields{ "StackName": serviceName, }).Info("Issued ExecuteChangeSet request") } return executeChangeSetError }