From 6d16337c9faed12716697a3b3af2a2be259b21b0 Mon Sep 17 00:00:00 2001 From: Clare Liguori Date: Wed, 20 Mar 2024 17:02:08 -0700 Subject: [PATCH] feat(codepipeline-actions): show status reason in the pipeline for failed change set executions (#29534) ### Reason for this change The CodePipeline ExecuteChangeSet action can now show a summary of why the change set execution failed. But, it needs an additional IAM permission: `cloudformation:DescribeStackEvents`. With the current action policy generated by CDK, I get the following message in the pipeline when a change set execution fails: ``` Additional Information: Failed to execute change set. Current stack status: UPDATE_ROLLBACK_COMPLETE. Status reason is not available because IAM role associated with the action does not have CloudFormation DescribeStackEvents permission ``` ### Description of changes Added `cloudformation:DescribeStackEvents` permission to the policy generated for the ChangeSetExecute pipeline action. ### Description of how you validated changes Updated unit tests and integ test with the new permission. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- ...dk-codepipeline-cloudformation.assets.json | 6 +++--- ...-codepipeline-cloudformation.template.json | 1 + .../cdk.out | 2 +- .../integ.json | 2 +- .../manifest.json | 10 ++++++++-- .../tree.json | 19 ++++++++++--------- .../private/singleton-policy.ts | 1 + .../cloudformation/pipeline-actions.test.ts | 1 + 8 files changed, 26 insertions(+), 16 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/aws-cdk-codepipeline-cloudformation.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/aws-cdk-codepipeline-cloudformation.assets.json index cd7f3f314fdb6..56d0bc756dae2 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/aws-cdk-codepipeline-cloudformation.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/aws-cdk-codepipeline-cloudformation.assets.json @@ -1,7 +1,7 @@ { - "version": "34.0.0", + "version": "36.0.0", "files": { - "084ca20cbe926238233c0a6584e19f8ce8057e3e7b7adcb4f21c6b6828acd256": { + "9a14027f70a5347df91e17dca191f41087c869425efe6897fa2d61199cf4de5f": { "source": { "path": "aws-cdk-codepipeline-cloudformation.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "084ca20cbe926238233c0a6584e19f8ce8057e3e7b7adcb4f21c6b6828acd256.json", + "objectKey": "9a14027f70a5347df91e17dca191f41087c869425efe6897fa2d61199cf4de5f.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/aws-cdk-codepipeline-cloudformation.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/aws-cdk-codepipeline-cloudformation.template.json index 1a40cea03c640..4459f6e926720 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/aws-cdk-codepipeline-cloudformation.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/aws-cdk-codepipeline-cloudformation.template.json @@ -795,6 +795,7 @@ { "Action": [ "cloudformation:DescribeChangeSet", + "cloudformation:DescribeStackEvents", "cloudformation:DescribeStacks", "cloudformation:ExecuteChangeSet" ], diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/cdk.out index 2313ab5436501..1f0068d32659a 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"34.0.0"} \ No newline at end of file +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/integ.json index 19c9f44bcac42..0f37e6eb95c71 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "34.0.0", + "version": "36.0.0", "testCases": { "integ.cfn-template-from-repo.lit": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/manifest.json index b7b1f0d0bb29e..74bf61c224298 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "34.0.0", + "version": "36.0.0", "artifacts": { "aws-cdk-codepipeline-cloudformation.assets": { "type": "cdk:asset-manifest", @@ -18,7 +18,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/084ca20cbe926238233c0a6584e19f8ce8057e3e7b7adcb4f21c6b6828acd256.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/9a14027f70a5347df91e17dca191f41087c869425efe6897fa2d61199cf4de5f.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -40,6 +40,12 @@ "data": "TemplateRepo2326F199" } ], + "/aws-cdk-codepipeline-cloudformation/Pipeline": [ + { + "type": "aws:cdk:warning", + "data": "V1 pipeline type is implicitly selected when `pipelineType` is not set. If you want to use V2 type, set `PipelineType.V2`. [ack: @aws-cdk/aws-codepipeline:unspecifiedPipelineType]" + } + ], "/aws-cdk-codepipeline-cloudformation/Pipeline/ArtifactsBucketEncryptionKey/Resource": [ { "type": "aws:cdk:logicalId", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/tree.json index 5ecb19c0bb7c9..9d86e4fe09e2a 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.js.snapshot/tree.json @@ -706,13 +706,13 @@ }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.70" + "version": "10.3.0" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.70" + "version": "10.3.0" } }, "Deploy": { @@ -780,7 +780,7 @@ "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Deploy/PrepareChanges/CodePipelineActionRole/8389e75f-0810-4838-bf64-d6f85a95cf83", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.70" + "version": "10.3.0" } }, "DefaultPolicy": { @@ -1038,7 +1038,7 @@ }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.70" + "version": "10.3.0" } }, "ApproveChanges": { @@ -1106,7 +1106,7 @@ }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.70" + "version": "10.3.0" } }, "ExecuteChanges": { @@ -1170,7 +1170,7 @@ "path": "aws-cdk-codepipeline-cloudformation/Pipeline/Deploy/ExecuteChanges/CodePipelineActionRole/8389e75f-0810-4838-bf64-d6f85a95cf83", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.70" + "version": "10.3.0" } }, "DefaultPolicy": { @@ -1188,6 +1188,7 @@ { "Action": [ "cloudformation:DescribeChangeSet", + "cloudformation:DescribeStackEvents", "cloudformation:DescribeStacks", "cloudformation:ExecuteChangeSet" ], @@ -1249,13 +1250,13 @@ }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.70" + "version": "10.3.0" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.70" + "version": "10.3.0" } } }, @@ -1291,7 +1292,7 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.70" + "version": "10.3.0" } } }, diff --git a/packages/aws-cdk-lib/aws-codepipeline-actions/lib/cloudformation/private/singleton-policy.ts b/packages/aws-cdk-lib/aws-codepipeline-actions/lib/cloudformation/private/singleton-policy.ts index be2c0052671b2..a20e89da62b8d 100644 --- a/packages/aws-cdk-lib/aws-codepipeline-actions/lib/cloudformation/private/singleton-policy.ts +++ b/packages/aws-cdk-lib/aws-codepipeline-actions/lib/cloudformation/private/singleton-policy.ts @@ -37,6 +37,7 @@ export class SingletonPolicy extends Construct implements iam.IGrantable { this.statementFor({ actions: [ 'cloudformation:DescribeStacks', + 'cloudformation:DescribeStackEvents', 'cloudformation:DescribeChangeSet', 'cloudformation:ExecuteChangeSet', ], diff --git a/packages/aws-cdk-lib/aws-codepipeline-actions/test/cloudformation/pipeline-actions.test.ts b/packages/aws-cdk-lib/aws-codepipeline-actions/test/cloudformation/pipeline-actions.test.ts index 9d916ad9a0c47..b0380a457a154 100644 --- a/packages/aws-cdk-lib/aws-codepipeline-actions/test/cloudformation/pipeline-actions.test.ts +++ b/packages/aws-cdk-lib/aws-codepipeline-actions/test/cloudformation/pipeline-actions.test.ts @@ -163,6 +163,7 @@ describe('Pipeline Actions', () => { { Action: [ 'cloudformation:DescribeChangeSet', + 'cloudformation:DescribeStackEvents', 'cloudformation:DescribeStacks', 'cloudformation:ExecuteChangeSet', ],