diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/aws-cdk-codepipeline-stepfunctions.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/aws-cdk-codepipeline-stepfunctions.assets.json index 132232d28ad09..b810b1588c7d0 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/aws-cdk-codepipeline-stepfunctions.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/aws-cdk-codepipeline-stepfunctions.assets.json @@ -1,7 +1,7 @@ { - "version": "30.0.0", + "version": "32.0.0", "files": { - "9c2191cf64f5d0c7288c4daeb90518584cb5076983557a2d930df85cbf8b1e4d": { + "367d7f35f59c5f8e0a4ffcbe34f936dffd0eb167b6d1261e138577db0e7da631": { "source": { "path": "aws-cdk-codepipeline-stepfunctions.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "9c2191cf64f5d0c7288c4daeb90518584cb5076983557a2d930df85cbf8b1e4d.json", + "objectKey": "367d7f35f59c5f8e0a4ffcbe34f936dffd0eb167b6d1261e138577db0e7da631.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.pipeline-stepfunctions.js.snapshot/aws-cdk-codepipeline-stepfunctions.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/aws-cdk-codepipeline-stepfunctions.template.json index 7e3e23f4f9c16..567555af9ce77 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/aws-cdk-codepipeline-stepfunctions.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/aws-cdk-codepipeline-stepfunctions.template.json @@ -538,15 +538,45 @@ [ "arn:", { - "Ref": "AWS::Partition" + "Fn::Select": [ + 1, + { + "Fn::Split": [ + ":", + { + "Ref": "SimpleStateMachineE8E2CF40" + } + ] + } + ] }, ":states:", { - "Ref": "AWS::Region" + "Fn::Select": [ + 3, + { + "Fn::Split": [ + ":", + { + "Ref": "SimpleStateMachineE8E2CF40" + } + ] + } + ] }, ":", { - "Ref": "AWS::AccountId" + "Fn::Select": [ + 4, + { + "Fn::Split": [ + ":", + { + "Ref": "SimpleStateMachineE8E2CF40" + } + ] + } + ] }, ":execution:", { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/cdk.out index ae4b03c54e770..f0b901e7c06e5 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"30.0.0"} \ No newline at end of file +{"version":"32.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/integ.json index dd4483a86ac5f..75a69c2b9251e 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "30.0.0", + "version": "32.0.0", "testCases": { "integ.pipeline-stepfunctions": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/manifest.json index 04dcf319e6137..338fe767f998c 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "30.0.0", + "version": "32.0.0", "artifacts": { "aws-cdk-codepipeline-stepfunctions.assets": { "type": "cdk:asset-manifest", @@ -17,7 +17,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}/9c2191cf64f5d0c7288c4daeb90518584cb5076983557a2d930df85cbf8b1e4d.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/367d7f35f59c5f8e0a4ffcbe34f936dffd0eb167b6d1261e138577db0e7da631.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/tree.json index bccc846a27687..497b3079eb000 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-stepfunctions.js.snapshot/tree.json @@ -12,7 +12,7 @@ "id": "StartState", "path": "aws-cdk-codepipeline-stepfunctions/StartState", "constructInfo": { - "fqn": "@aws-cdk/aws-stepfunctions.Pass", + "fqn": "aws-cdk-lib.aws_stepfunctions.Pass", "version": "0.0.0" } }, @@ -28,7 +28,7 @@ "id": "ImportRole", "path": "aws-cdk-codepipeline-stepfunctions/SimpleStateMachine/Role/ImportRole", "constructInfo": { - "fqn": "@aws-cdk/core.Resource", + "fqn": "aws-cdk-lib.Resource", "version": "0.0.0" } }, @@ -53,13 +53,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } }, @@ -79,13 +79,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-stepfunctions.CfnStateMachine", + "fqn": "aws-cdk-lib.aws_stepfunctions.CfnStateMachine", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-stepfunctions.StateMachine", + "fqn": "aws-cdk-lib.aws_stepfunctions.StateMachine", "version": "0.0.0" } }, @@ -134,13 +134,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.CfnKey", + "fqn": "aws-cdk-lib.aws_kms.CfnKey", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.Key", + "fqn": "aws-cdk-lib.aws_kms.Key", "version": "0.0.0" } }, @@ -164,13 +164,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.CfnAlias", + "fqn": "aws-cdk-lib.aws_kms.CfnAlias", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-kms.Alias", + "fqn": "aws-cdk-lib.aws_kms.Alias", "version": "0.0.0" } }, @@ -208,7 +208,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucket", + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", "version": "0.0.0" } }, @@ -267,19 +267,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucketPolicy", + "fqn": "aws-cdk-lib.aws_s3.CfnBucketPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.BucketPolicy", + "fqn": "aws-cdk-lib.aws_s3.BucketPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.Bucket", + "fqn": "aws-cdk-lib.aws_s3.Bucket", "version": "0.0.0" } }, @@ -291,7 +291,7 @@ "id": "ImportRole", "path": "aws-cdk-codepipeline-stepfunctions/MyPipeline/Role/ImportRole", "constructInfo": { - "fqn": "@aws-cdk/core.Resource", + "fqn": "aws-cdk-lib.Resource", "version": "0.0.0" } }, @@ -316,7 +316,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -415,19 +415,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } }, @@ -524,7 +524,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codepipeline.CfnPipeline", + "fqn": "aws-cdk-lib.aws_codepipeline.CfnPipeline", "version": "0.0.0" } }, @@ -544,7 +544,7 @@ "id": "ImportCodePipelineActionRole", "path": "aws-cdk-codepipeline-stepfunctions/MyPipeline/Source/Source/CodePipelineActionRole/ImportCodePipelineActionRole", "constructInfo": { - "fqn": "@aws-cdk/core.Resource", + "fqn": "aws-cdk-lib.Resource", "version": "0.0.0" } }, @@ -584,7 +584,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -691,32 +691,32 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.237" + "version": "10.2.26" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.237" + "version": "10.2.26" } }, "Invoke": { @@ -735,7 +735,7 @@ "id": "ImportCodePipelineActionRole", "path": "aws-cdk-codepipeline-stepfunctions/MyPipeline/Invoke/Invoke/CodePipelineActionRole/ImportCodePipelineActionRole", "constructInfo": { - "fqn": "@aws-cdk/core.Resource", + "fqn": "aws-cdk-lib.Resource", "version": "0.0.0" } }, @@ -775,7 +775,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -810,15 +810,45 @@ [ "arn:", { - "Ref": "AWS::Partition" + "Fn::Select": [ + 1, + { + "Fn::Split": [ + ":", + { + "Ref": "SimpleStateMachineE8E2CF40" + } + ] + } + ] }, ":states:", { - "Ref": "AWS::Region" + "Fn::Select": [ + 3, + { + "Fn::Split": [ + ":", + { + "Ref": "SimpleStateMachineE8E2CF40" + } + ] + } + ] }, ":", { - "Ref": "AWS::AccountId" + "Fn::Select": [ + 4, + { + "Fn::Split": [ + ":", + { + "Ref": "SimpleStateMachineE8E2CF40" + } + ] + } + ] }, ":execution:", { @@ -851,37 +881,37 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.237" + "version": "10.2.26" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.237" + "version": "10.2.26" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-codepipeline.Pipeline", + "fqn": "aws-cdk-lib.aws_codepipeline.Pipeline", "version": "0.0.0" } }, @@ -897,13 +927,13 @@ "aws:cdk:cloudformation:props": {} }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucket", + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.Bucket", + "fqn": "aws-cdk-lib.aws_s3.Bucket", "version": "0.0.0" } }, @@ -911,7 +941,7 @@ "id": "BootstrapVersion", "path": "aws-cdk-codepipeline-stepfunctions/BootstrapVersion", "constructInfo": { - "fqn": "@aws-cdk/core.CfnParameter", + "fqn": "aws-cdk-lib.CfnParameter", "version": "0.0.0" } }, @@ -919,13 +949,13 @@ "id": "CheckBootstrapVersion", "path": "aws-cdk-codepipeline-stepfunctions/CheckBootstrapVersion", "constructInfo": { - "fqn": "@aws-cdk/core.CfnRule", + "fqn": "aws-cdk-lib.CfnRule", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/core.Stack", + "fqn": "aws-cdk-lib.Stack", "version": "0.0.0" } }, @@ -934,12 +964,12 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.237" + "version": "10.2.26" } } }, "constructInfo": { - "fqn": "@aws-cdk/core.App", + "fqn": "aws-cdk-lib.App", "version": "0.0.0" } } diff --git a/packages/aws-cdk-lib/aws-codepipeline-actions/lib/stepfunctions/invoke-action.ts b/packages/aws-cdk-lib/aws-codepipeline-actions/lib/stepfunctions/invoke-action.ts index 4e30e28e0e70f..30128a7b9ec3c 100644 --- a/packages/aws-cdk-lib/aws-codepipeline-actions/lib/stepfunctions/invoke-action.ts +++ b/packages/aws-cdk-lib/aws-codepipeline-actions/lib/stepfunctions/invoke-action.ts @@ -131,12 +131,19 @@ export class StepFunctionInvokeAction extends Action { })); // allow state machine executions to be inspected + const { account, region, partition, resourceName } = cdk.Stack.of(this.props.stateMachine) + .splitArn(this.props.stateMachine.stateMachineArn, cdk.ArnFormat.COLON_RESOURCE_NAME); options.role.addToPrincipalPolicy(new iam.PolicyStatement({ actions: ['states:DescribeExecution'], resources: [cdk.Stack.of(this.props.stateMachine).formatArn({ + // Make sure we use the same account, region & partition as the state machine's ARN + account, + region, + partition, + // And now the real deal... service: 'states', resource: 'execution', - resourceName: `${cdk.Stack.of(this.props.stateMachine).splitArn(this.props.stateMachine.stateMachineArn, cdk.ArnFormat.COLON_RESOURCE_NAME).resourceName}:${this.props.executionNamePrefix ?? ''}*`, + resourceName: `${resourceName}:${this.props.executionNamePrefix ?? ''}*`, arnFormat: cdk.ArnFormat.COLON_RESOURCE_NAME, })], })); diff --git a/packages/aws-cdk-lib/aws-codepipeline-actions/test/stepfunctions/stepfunctions-invoke-actions.test.ts b/packages/aws-cdk-lib/aws-codepipeline-actions/test/stepfunctions/stepfunctions-invoke-actions.test.ts index 636e6472a8779..a0fe537159597 100644 --- a/packages/aws-cdk-lib/aws-codepipeline-actions/test/stepfunctions/stepfunctions-invoke-actions.test.ts +++ b/packages/aws-cdk-lib/aws-codepipeline-actions/test/stepfunctions/stepfunctions-invoke-actions.test.ts @@ -2,153 +2,160 @@ import { Template, Match } from '../../../assertions'; import * as codepipeline from '../../../aws-codepipeline'; import * as s3 from '../../../aws-s3'; import * as stepfunction from '../../../aws-stepfunctions'; -import { Stack } from '../../../core'; +import { Stack, Stage } from '../../../core'; import * as cpactions from '../../lib'; describe('StepFunctions Invoke Action', () => { - describe('StepFunctions Invoke Action', () => { - test('Verify stepfunction configuration properties are set to specific values', () => { - const stack = new Stack(); - - // when - minimalPipeline(stack); - - // then - Template.fromStack(stack).hasResourceProperties('AWS::CodePipeline::Pipeline', Match.objectLike({ - Stages: [ - // Must have a source stage - { - Actions: [ - { - ActionTypeId: { - Category: 'Source', - Owner: 'AWS', - Provider: 'S3', - Version: '1', - }, - Configuration: { - S3Bucket: { - Ref: 'MyBucketF68F3FF0', - }, - S3ObjectKey: 'some/path/to', - }, + test('Verify stepfunction configuration properties are set to specific values', () => { + const stack = new Stack(); + + // when + minimalPipeline(stack); + + // then + Template.fromStack(stack).hasResourceProperties('AWS::CodePipeline::Pipeline', Match.objectLike({ + Stages: [ + // Must have a source stage + { + Actions: [ + { + ActionTypeId: { + Category: 'Source', + Owner: 'AWS', + Provider: 'S3', + Version: '1', }, - ], - }, - // Must have stepfunction invoke action configuration - { - Actions: [ - { - ActionTypeId: { - Category: 'Invoke', - Owner: 'AWS', - Provider: 'StepFunctions', - Version: '1', + Configuration: { + S3Bucket: { + Ref: 'MyBucketF68F3FF0', }, - Configuration: { - StateMachineArn: { - Ref: 'SimpleStateMachineE8E2CF40', - }, - InputType: 'Literal', - // JSON Stringified input when the input type is Literal - Input: '{\"IsHelloWorldExample\":true}', + S3ObjectKey: 'some/path/to', + }, + }, + ], + }, + // Must have stepfunction invoke action configuration + { + Actions: [ + { + ActionTypeId: { + Category: 'Invoke', + Owner: 'AWS', + Provider: 'StepFunctions', + Version: '1', + }, + Configuration: { + StateMachineArn: { + Ref: 'SimpleStateMachineE8E2CF40', }, + InputType: 'Literal', + // JSON Stringified input when the input type is Literal + Input: '{\"IsHelloWorldExample\":true}', }, - ], - }, - ], - })); + }, + ], + }, + ], + })); - }); + }); - test('Allows the pipeline to invoke this stepfunction', () => { - const stack = new Stack(); + test('Allows the pipeline to invoke this stepfunction', () => { + const stack = new Stack(); - minimalPipeline(stack); + minimalPipeline(stack); - Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { - PolicyName: 'MyPipelineInvokeCodePipelineActionRoleDefaultPolicy07A602B1', - PolicyDocument: { - Statement: Match.arrayWith([ - { - Action: ['states:StartExecution', 'states:DescribeStateMachine'], - Resource: { - Ref: 'SimpleStateMachineE8E2CF40', - }, - Effect: 'Allow', + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyName: 'MyPipelineInvokeCodePipelineActionRoleDefaultPolicy07A602B1', + PolicyDocument: { + Statement: Match.arrayWith([ + { + Action: ['states:StartExecution', 'states:DescribeStateMachine'], + Resource: { + Ref: 'SimpleStateMachineE8E2CF40', }, - ]), - }, - }); + Effect: 'Allow', + }, + ]), + }, + }); - Template.fromStack(stack).resourceCountIs('AWS::IAM::Role', 4); + Template.fromStack(stack).resourceCountIs('AWS::IAM::Role', 4); - }); + }); - test('Allows the pipeline to describe this stepfunction execution', () => { - const stack = new Stack(); + test('Allows the pipeline to describe this stepfunction execution', () => { + const stack = new Stack(); - minimalPipeline(stack); + minimalPipeline(stack); - Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { - PolicyDocument: { - Statement: [ - {}, - { - Action: 'states:DescribeExecution', - Resource: { - 'Fn::Join': [ - '', - [ - 'arn:', - { - Ref: 'AWS::Partition', - }, - ':states:', - { - Ref: 'AWS::Region', - }, - ':', - { - Ref: 'AWS::AccountId', - }, - ':execution:', - { - 'Fn::Select': [ - 6, - { - 'Fn::Split': [ - ':', - { - Ref: 'SimpleStateMachineE8E2CF40', - }, - ], - }, - ], - }, - ':*', - ], + const arnParts = { + 'Fn::Split': [':', { Ref: 'SimpleStateMachineE8E2CF40' }], + }; + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + {}, + { + Action: 'states:DescribeExecution', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { 'Fn::Select': [1, arnParts] }, + ':states:', + { 'Fn::Select': [3, arnParts] }, + ':', + { 'Fn::Select': [4, arnParts] }, + ':execution:', + { 'Fn::Select': [6, arnParts] }, + ':*', ], - }, - Effect: 'Allow', + ], }, - ], - }, - }); + Effect: 'Allow', + }, + ], + }, + }); - Template.fromStack(stack).resourceCountIs('AWS::IAM::Role', 4); + Template.fromStack(stack).resourceCountIs('AWS::IAM::Role', 4); - }); + }); + + test('Allows the pipeline to describe this stepfunction execution (across accounts & regions)', () => { + const stack = new Stack(undefined, undefined, { env: { account: '11111111111', region: 'us-east-1' } }); + minimalPipeline(stack, '999999999999', 'bermuda-triangle-1337'); + + // The permissions are defined by the cross-account stack here... + const cfnStack = Stage.of(stack)?.synth().stacks.find(({ stackName }) => stackName === 'Default-support-999999999999'); + expect(cfnStack).toBeDefined(); + + Template.fromJSON(cfnStack!.template).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + {}, + { + Action: 'states:DescribeExecution', + Resource: 'arn:aws:states:bermuda-triangle-1337:999999999999:execution:SimpleStateMachine:*', + Effect: 'Allow', + }, + ], + }, + }); }); + }); -function minimalPipeline(stack: Stack): codepipeline.IStage { +function minimalPipeline(stack: Stack, account?: string, region?: string): codepipeline.IStage { const sourceOutput = new codepipeline.Artifact(); - const startState = new stepfunction.Pass(stack, 'StartState'); - const simpleStateMachine = new stepfunction.StateMachine(stack, 'SimpleStateMachine', { - definition: startState, - }); + const simpleStateMachine = account || region + ? stepfunction.StateMachine.fromStateMachineArn(stack, 'SimpleStateMachine', `arn:aws:states:${region}:${account}:stateMachine:SimpleStateMachine`) + : new stepfunction.StateMachine(stack, 'SimpleStateMachine', { + definition: new stepfunction.Pass(stack, 'StartState'), + }); const pipeline = new codepipeline.Pipeline(stack, 'MyPipeline'); const sourceStage = pipeline.addStage({ stageName: 'Source',