in src/tasks/CloudFormationCreateOrUpdateStack/TaskOperations.ts [244:337]
private async createOrUpdateWithChangeSet(changesetType: string): Promise<string> {
const changeSetExists = await testChangeSetExists(
this.cloudFormationClient,
this.taskParameters.changeSetName,
this.taskParameters.stackName
)
if (changeSetExists) {
await this.deleteExistingChangeSet(this.taskParameters.changeSetName, this.taskParameters.stackName)
}
const request: CloudFormation.CreateChangeSetInput = {
ChangeSetName: this.taskParameters.changeSetName,
ChangeSetType: changesetType,
StackName: this.taskParameters.stackName,
RoleARN: this.taskParameters.roleARN
}
if (this.taskParameters.description) {
request.Description = this.taskParameters.description
}
switch (this.taskParameters.templateSource) {
case fileSource:
if (this.taskParameters.s3BucketName) {
request.TemplateURL = await this.uploadTemplateFile(
this.taskParameters.templateFile,
this.taskParameters.s3BucketName
)
} else {
request.TemplateBody = await this.loadTemplateFile(this.taskParameters.templateFile)
}
break
case urlSource:
request.TemplateURL = this.taskParameters.templateUrl
break
case s3Source:
// sync call
request.TemplateURL = await SdkUtils.getPresignedUrl(
this.s3Client,
'getObject',
this.taskParameters.s3BucketName,
this.taskParameters.s3ObjectKey
)
break
// already validated that stack exists and so this mode is acceptable
case usePreviousTemplate:
request.UsePreviousTemplate = true
break
}
request.Parameters = this.loadTemplateParameters()
request.NotificationARNs = this.getNotificationArns(this.taskParameters.notificationARNs)
request.ResourceTypes = this.getResourceTypes(this.taskParameters.resourceTypes)
request.Capabilities = this.getCapabilities(
this.taskParameters.capabilityIAM,
this.taskParameters.capabilityNamedIAM,
this.taskParameters.capabilityAutoExpand
)
request.Tags = SdkUtils.getTags<CloudFormation.Tag[]>(this.taskParameters.tags)
request.IncludeNestedStacks = this.taskParameters.includeNestedStacks
if (this.taskParameters.monitorRollbackTriggers) {
request.RollbackConfiguration = {
MonitoringTimeInMinutes: this.taskParameters.monitoringTimeInMinutes,
RollbackTriggers: this.constructRollbackTriggerCollection(this.taskParameters.rollbackTriggerARNs)
}
}
try {
// note that we can create a change set with no changes, but when we wait for completion it's then
// that we get a validation failure, which we check for inside waitForChangeSetCreation
console.log(tl.loc('CreatingChangeSet', changesetType, this.taskParameters.changeSetName))
const response: CloudFormation.CreateChangeSetOutput = await this.cloudFormationClient
.createChangeSet(request)
.promise()
tl.debug(`Change set id ${response.Id}, stack id ${response.StackId}`)
const changesToApply = await this.waitForChangeSetCreation(request.ChangeSetName, request.StackName)
if (changesToApply && this.taskParameters.autoExecuteChangeSet) {
await this.executeChangeSet(this.taskParameters.changeSetName, this.taskParameters.stackName)
}
if (!response.StackId) {
return ''
}
return response.StackId
} catch (err) {
console.error(tl.loc('ChangeSetCreationFailed', (err as Error).message), err)
throw err
}
}