-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Description
Describe the bug
Since #28336 was merged, cdk diff now creates a ChangeSet to provide more accurate diffs, rather than simply comparing templates.
However, cdk diff is unable to create a ChangeSet if the IAM Role is not permitted to create a ChangeSet without tags.
Example
cdk diff stack-foo -v
[17:41:12] Attempting to create ChangeSet with name cdk-diff-change-set for stack stack-foo
[17:41:13] User: arn:aws:sts::AWS_ACCOUNT_ID:assumed-role/DeployRole is not authorized to perform: cloudformation:CreateChangeSet on resource: arn:aws:cloudformation:us-east-1:AWS_ACCOUNT_ID:stack/stack-foo/xxxx with an explicit deny in an identity-based policy
Could not create a change set, will base the diff on template differences (run again with -v to see the reason)
Regression Issue
- Select this option if this issue appears to be a regression.
Last Known Working CDK Version
No response
Expected Behavior
cdk diff can create a ChangeSet and show diff.
Current Behavior
cdk diff cannot create a ChangeSet and it show diffs on template differences.
Reproduction Steps
- Add a deny statement to the DeployRole.
{
Sid: `DenyCfnActionsWithoutFooTag`,
Effect: 'Deny',
Action: [
'cloudformation:CreateChangeSet',
'cloudformation:CreateStack',
'cloudformation:UpdateStack'
],
Resource: '*',
Condition: {
'ForAllValues:StringNotEquals': {
'aws:TagKeys': 'Foo'
}
}
}
- Add a tag to a stack
const stack = new Stack(app, 'MyStack', {
tags: {
'Foo': 'tag-value',
},
});
- Run cdk diff
cdk diff stack-foo -v
Possible Solution
Add Tags options here.
aws-cdk/packages/aws-cdk/lib/api/deployments/cloudformation.ts
Lines 470 to 482 in 20176e6
| const changeSet = await options.cfn.createChangeSet({ | |
| StackName: options.stack.stackName, | |
| ChangeSetName: options.changeSetName, | |
| ChangeSetType: options.resourcesToImport ? 'IMPORT' : options.exists ? 'UPDATE' : 'CREATE', | |
| Description: `CDK Changeset for diff ${options.uuid}`, | |
| ClientToken: `diff${options.uuid}`, | |
| TemplateURL: options.bodyParameter.TemplateURL, | |
| TemplateBody: options.bodyParameter.TemplateBody, | |
| Parameters: stackParams.apiParameters, | |
| ResourcesToImport: options.resourcesToImport, | |
| RoleARN: options.role, | |
| Capabilities: ['CAPABILITY_IAM', 'CAPABILITY_NAMED_IAM', 'CAPABILITY_AUTO_EXPAND'], | |
| }); |
Additional Information/Context
cdk deploy stack-foo --no-execute can create a ChangeSet because it uses Tags option.
aws-cdk/packages/aws-cdk/lib/api/deployments/deploy-stack.ts
Lines 483 to 492 in 20176e6
| const changeSet = await this.cfn.createChangeSet({ | |
| StackName: this.stackName, | |
| ChangeSetName: changeSetName, | |
| ChangeSetType: this.options.resourcesToImport ? 'IMPORT' : this.update ? 'UPDATE' : 'CREATE', | |
| ResourcesToImport: this.options.resourcesToImport, | |
| Description: `CDK Changeset for execution ${this.uuid}`, | |
| ClientToken: `create${this.uuid}`, | |
| ImportExistingResources: importExistingResources, | |
| ...this.commonPrepareOptions(), | |
| }); |
aws-cdk/packages/aws-cdk/lib/api/deployments/deploy-stack.ts
Lines 633 to 643 in 20176e6
| private commonPrepareOptions(): Partial<Pick<UpdateStackCommandInput, CommonPrepareOptions>> { | |
| return { | |
| Capabilities: ['CAPABILITY_IAM', 'CAPABILITY_NAMED_IAM', 'CAPABILITY_AUTO_EXPAND'], | |
| NotificationARNs: this.options.notificationArns, | |
| Parameters: this.stackParams.apiParameters, | |
| RoleARN: this.options.roleArn, | |
| TemplateBody: this.bodyParameter.TemplateBody, | |
| TemplateURL: this.bodyParameter.TemplateURL, | |
| Tags: this.options.tags, | |
| }; | |
| } |
CDK CLI Version
cdk version 2.177.0 (build b396961)
Framework Version
No response
Node.js Version
v22.3.0
OS
MacOS
Language
TypeScript
Language Version
TypeScript(~5.6.3)
Other information
No response