From 3e3bf6c46d2e9738c85320b95900df9be71fd6c5 Mon Sep 17 00:00:00 2001 From: Vaid Saraswat Date: Wed, 31 Jul 2024 18:36:07 -0700 Subject: [PATCH] Adding support for KMS in StateMachine and Activity resources --- ...efaultTestDeployAssert7B5CA61B.assets.json | 19 + ...aultTestDeployAssert7B5CA61B.template.json | 36 ++ ...vity-with-aok-encryptionconfig.assets.json | 19 + ...ty-with-aok-encryptionconfig.template.json | 86 ++++ .../integ.json | 12 + .../manifest.json | 125 +++++ .../tree.json | 214 +++++++++ ...efaultTestDeployAssert11207853.assets.json | 19 + ...aultTestDeployAssert11207853.template.json | 36 ++ ...vity-with-cmk-encryptionconfig.assets.json | 19 + ...ty-with-cmk-encryptionconfig.template.json | 194 ++++++++ .../cdk.out | 1 + .../integ.json | 12 + .../manifest.json | 131 +++++ .../tree.json | 338 +++++++++++++ .../integ.state-machine-and-activity-cmk.ts | 39 ++ .../aws-cdk-lib/aws-stepfunctions/README.md | 48 ++ .../aws-stepfunctions/lib/activity.ts | 34 +- .../lib/encryption-configuration.ts | 34 -- .../aws-stepfunctions/lib/state-machine.ts | 87 ++-- .../aws-cdk-lib/aws-stepfunctions/lib/util.ts | 6 + .../aws-stepfunctions/test/activity.test.ts | 35 +- .../test/state-machine.test.ts | 451 +++++++++--------- 23 files changed, 1673 insertions(+), 322 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/StateMachineAndActivityWithAOKEncryptionConfigurationDefaultTestDeployAssert7B5CA61B.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/StateMachineAndActivityWithAOKEncryptionConfigurationDefaultTestDeployAssert7B5CA61B.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/StateMachineAndActivityWithCMKEncryptionConfigurationDefaultTestDeployAssert11207853.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/StateMachineAndActivityWithCMKEncryptionConfigurationDefaultTestDeployAssert11207853.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.ts delete mode 100644 packages/aws-cdk-lib/aws-stepfunctions/lib/encryption-configuration.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/StateMachineAndActivityWithAOKEncryptionConfigurationDefaultTestDeployAssert7B5CA61B.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/StateMachineAndActivityWithAOKEncryptionConfigurationDefaultTestDeployAssert7B5CA61B.assets.json new file mode 100644 index 0000000000000..dcafebe134c60 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/StateMachineAndActivityWithAOKEncryptionConfigurationDefaultTestDeployAssert7B5CA61B.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "StateMachineAndActivityWithAOKEncryptionConfigurationDefaultTestDeployAssert7B5CA61B.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/StateMachineAndActivityWithAOKEncryptionConfigurationDefaultTestDeployAssert7B5CA61B.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/StateMachineAndActivityWithAOKEncryptionConfigurationDefaultTestDeployAssert7B5CA61B.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/StateMachineAndActivityWithAOKEncryptionConfigurationDefaultTestDeployAssert7B5CA61B.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig.assets.json new file mode 100644 index 0000000000000..30f1c69c7db82 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "dbd160a66af556b3144ce323cac08e1968f13bca36b0095a44025d93c413e6c2": { + "source": { + "path": "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "dbd160a66af556b3144ce323cac08e1968f13bca36b0095a44025d93c413e6c2.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig.template.json new file mode 100644 index 0000000000000..ab7eb8fe953da --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig.template.json @@ -0,0 +1,86 @@ +{ + "Resources": { + "StateMachineWithAOKEncryptionConfigurationRoleA5E4221F": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "StateMachineWithAOKEncryptionConfiguration934313C7": { + "Type": "AWS::StepFunctions::StateMachine", + "Properties": { + "DefinitionString": "{\"StartAt\":\"Pass\",\"States\":{\"Pass\":{\"Type\":\"Pass\",\"End\":true}}}", + "EncryptionConfiguration": { + "Type": "AWS_OWNED_KEY" + }, + "RoleArn": { + "Fn::GetAtt": [ + "StateMachineWithAOKEncryptionConfigurationRoleA5E4221F", + "Arn" + ] + }, + "StateMachineName": "StateMachineWithCMKEncryptionConfiguration", + "StateMachineType": "STANDARD" + }, + "DependsOn": [ + "StateMachineWithAOKEncryptionConfigurationRoleA5E4221F" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "ActivityWithAOKEncryptionConfiguration065A6DC5": { + "Type": "AWS::StepFunctions::Activity", + "Properties": { + "EncryptionConfiguration": { + "Type": "AWS_OWNED_KEY" + }, + "Name": "ActivityWithCMKEncryptionConfiguration" + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/integ.json new file mode 100644 index 0000000000000..a8d03f1655843 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "36.0.0", + "testCases": { + "StateMachineAndActivityWithAOKEncryptionConfiguration/DefaultTest": { + "stacks": [ + "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig" + ], + "assertionStack": "StateMachineAndActivityWithAOKEncryptionConfiguration/DefaultTest/DeployAssert", + "assertionStackName": "StateMachineAndActivityWithAOKEncryptionConfigurationDefaultTestDeployAssert7B5CA61B" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/manifest.json new file mode 100644 index 0000000000000..e2631356db888 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/manifest.json @@ -0,0 +1,125 @@ +{ + "version": "36.0.0", + "artifacts": { + "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig.template.json", + "terminationProtection": false, + "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}/dbd160a66af556b3144ce323cac08e1968f13bca36b0095a44025d93c413e6c2.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig.assets" + ], + "metadata": { + "/aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig/StateMachineWithAOKEncryptionConfiguration/Role/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "StateMachineWithAOKEncryptionConfigurationRoleA5E4221F" + } + ], + "/aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig/StateMachineWithAOKEncryptionConfiguration/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "StateMachineWithAOKEncryptionConfiguration934313C7" + } + ], + "/aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig/ActivityWithAOKEncryptionConfiguration/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ActivityWithAOKEncryptionConfiguration065A6DC5" + } + ], + "/aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig" + }, + "StateMachineAndActivityWithAOKEncryptionConfigurationDefaultTestDeployAssert7B5CA61B.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "StateMachineAndActivityWithAOKEncryptionConfigurationDefaultTestDeployAssert7B5CA61B.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "StateMachineAndActivityWithAOKEncryptionConfigurationDefaultTestDeployAssert7B5CA61B": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "StateMachineAndActivityWithAOKEncryptionConfigurationDefaultTestDeployAssert7B5CA61B.template.json", + "terminationProtection": false, + "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}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "StateMachineAndActivityWithAOKEncryptionConfigurationDefaultTestDeployAssert7B5CA61B.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "StateMachineAndActivityWithAOKEncryptionConfigurationDefaultTestDeployAssert7B5CA61B.assets" + ], + "metadata": { + "/StateMachineAndActivityWithAOKEncryptionConfiguration/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/StateMachineAndActivityWithAOKEncryptionConfiguration/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "StateMachineAndActivityWithAOKEncryptionConfiguration/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/tree.json new file mode 100644 index 0000000000000..e4259df6bcf29 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-aok.js.snapshot/tree.json @@ -0,0 +1,214 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig": { + "id": "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig", + "path": "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig", + "children": { + "Pass": { + "id": "Pass", + "path": "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig/Pass", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.Pass", + "version": "0.0.0" + } + }, + "StateMachineWithAOKEncryptionConfiguration": { + "id": "StateMachineWithAOKEncryptionConfiguration", + "path": "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig/StateMachineWithAOKEncryptionConfiguration", + "children": { + "Role": { + "id": "Role", + "path": "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig/StateMachineWithAOKEncryptionConfiguration/Role", + "children": { + "ImportRole": { + "id": "ImportRole", + "path": "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig/StateMachineWithAOKEncryptionConfiguration/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig/StateMachineWithAOKEncryptionConfiguration/Role/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig/StateMachineWithAOKEncryptionConfiguration/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::StepFunctions::StateMachine", + "aws:cdk:cloudformation:props": { + "definitionString": "{\"StartAt\":\"Pass\",\"States\":{\"Pass\":{\"Type\":\"Pass\",\"End\":true}}}", + "encryptionConfiguration": { + "type": "AWS_OWNED_KEY" + }, + "roleArn": { + "Fn::GetAtt": [ + "StateMachineWithAOKEncryptionConfigurationRoleA5E4221F", + "Arn" + ] + }, + "stateMachineName": "StateMachineWithCMKEncryptionConfiguration", + "stateMachineType": "STANDARD" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.CfnStateMachine", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.StateMachine", + "version": "0.0.0" + } + }, + "ActivityWithAOKEncryptionConfiguration": { + "id": "ActivityWithAOKEncryptionConfiguration", + "path": "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig/ActivityWithAOKEncryptionConfiguration", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig/ActivityWithAOKEncryptionConfiguration/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::StepFunctions::Activity", + "aws:cdk:cloudformation:props": { + "encryptionConfiguration": { + "type": "AWS_OWNED_KEY" + }, + "name": "ActivityWithCMKEncryptionConfiguration" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.CfnActivity", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.Activity", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-stepfunctions-statemachine-and-activity-with-aok-encryptionconfig/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "StateMachineAndActivityWithAOKEncryptionConfiguration": { + "id": "StateMachineAndActivityWithAOKEncryptionConfiguration", + "path": "StateMachineAndActivityWithAOKEncryptionConfiguration", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "StateMachineAndActivityWithAOKEncryptionConfiguration/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "StateMachineAndActivityWithAOKEncryptionConfiguration/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "StateMachineAndActivityWithAOKEncryptionConfiguration/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "StateMachineAndActivityWithAOKEncryptionConfiguration/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "StateMachineAndActivityWithAOKEncryptionConfiguration/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/StateMachineAndActivityWithCMKEncryptionConfigurationDefaultTestDeployAssert11207853.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/StateMachineAndActivityWithCMKEncryptionConfigurationDefaultTestDeployAssert11207853.assets.json new file mode 100644 index 0000000000000..23cf5cd9b8e0e --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/StateMachineAndActivityWithCMKEncryptionConfigurationDefaultTestDeployAssert11207853.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "StateMachineAndActivityWithCMKEncryptionConfigurationDefaultTestDeployAssert11207853.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/StateMachineAndActivityWithCMKEncryptionConfigurationDefaultTestDeployAssert11207853.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/StateMachineAndActivityWithCMKEncryptionConfigurationDefaultTestDeployAssert11207853.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/StateMachineAndActivityWithCMKEncryptionConfigurationDefaultTestDeployAssert11207853.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig.assets.json new file mode 100644 index 0000000000000..45165fd878cb5 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "73e6ad59415a12f1fd7cee5139e3d29802d28177e6c2582c66f0c11a2403bb48": { + "source": { + "path": "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "73e6ad59415a12f1fd7cee5139e3d29802d28177e6c2582c66f0c11a2403bb48.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig.template.json new file mode 100644 index 0000000000000..ac0acc701476b --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig.template.json @@ -0,0 +1,194 @@ +{ + "Resources": { + "Key961B73FD": { + "Type": "AWS::KMS::Key", + "Properties": { + "KeyPolicy": { + "Statement": [ + { + "Action": "kms:*", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": "*" + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey", + "kms:GenerateDataKey" + ], + "Condition": { + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + }, + "aws:SourceArn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":states:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":stateMachine/StateMachineWithCMKEncryptionConfiguration" + ] + ] + }, + "kms:EncryptionContext:aws:states:stateMachineArn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":states:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":stateMachine/StateMachineWithCMKEncryptionConfiguration" + ] + ] + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + }, + "Resource": "*" + } + ], + "Version": "2012-10-17" + } + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "StateMachineWithCMKEncryptionConfigurationRoleA49EBB18": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "StateMachineWithCMKEncryptionConfiguration10773462": { + "Type": "AWS::StepFunctions::StateMachine", + "Properties": { + "DefinitionString": "{\"StartAt\":\"Pass\",\"States\":{\"Pass\":{\"Type\":\"Pass\",\"End\":true}}}", + "EncryptionConfiguration": { + "KmsDataKeyReusePeriodSeconds": 75, + "KmsKeyId": { + "Fn::GetAtt": [ + "Key961B73FD", + "Arn" + ] + }, + "Type": "CUSTOMER_MANAGED_KMS_KEY" + }, + "RoleArn": { + "Fn::GetAtt": [ + "StateMachineWithCMKEncryptionConfigurationRoleA49EBB18", + "Arn" + ] + }, + "StateMachineName": "StateMachineWithCMKEncryptionConfiguration", + "StateMachineType": "STANDARD" + }, + "DependsOn": [ + "StateMachineWithCMKEncryptionConfigurationRoleA49EBB18" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "ActivityWithCMKEncryptionConfiguration3D01813A": { + "Type": "AWS::StepFunctions::Activity", + "Properties": { + "EncryptionConfiguration": { + "KmsDataKeyReusePeriodSeconds": 75, + "KmsKeyId": { + "Fn::GetAtt": [ + "Key961B73FD", + "Arn" + ] + }, + "Type": "CUSTOMER_MANAGED_KMS_KEY" + }, + "Name": "ActivityWithCMKEncryptionConfiguration" + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/cdk.out new file mode 100644 index 0000000000000..1f0068d32659a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/integ.json new file mode 100644 index 0000000000000..1f47999fadeab --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "36.0.0", + "testCases": { + "StateMachineAndActivityWithCMKEncryptionConfiguration/DefaultTest": { + "stacks": [ + "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig" + ], + "assertionStack": "StateMachineAndActivityWithCMKEncryptionConfiguration/DefaultTest/DeployAssert", + "assertionStackName": "StateMachineAndActivityWithCMKEncryptionConfigurationDefaultTestDeployAssert11207853" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/manifest.json new file mode 100644 index 0000000000000..4e79f92129ea6 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/manifest.json @@ -0,0 +1,131 @@ +{ + "version": "36.0.0", + "artifacts": { + "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig.template.json", + "terminationProtection": false, + "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}/73e6ad59415a12f1fd7cee5139e3d29802d28177e6c2582c66f0c11a2403bb48.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig.assets" + ], + "metadata": { + "/aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig/Key/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Key961B73FD" + } + ], + "/aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig/StateMachineWithCMKEncryptionConfiguration/Role/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "StateMachineWithCMKEncryptionConfigurationRoleA49EBB18" + } + ], + "/aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig/StateMachineWithCMKEncryptionConfiguration/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "StateMachineWithCMKEncryptionConfiguration10773462" + } + ], + "/aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig/ActivityWithCMKEncryptionConfiguration/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ActivityWithCMKEncryptionConfiguration3D01813A" + } + ], + "/aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig" + }, + "StateMachineAndActivityWithCMKEncryptionConfigurationDefaultTestDeployAssert11207853.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "StateMachineAndActivityWithCMKEncryptionConfigurationDefaultTestDeployAssert11207853.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "StateMachineAndActivityWithCMKEncryptionConfigurationDefaultTestDeployAssert11207853": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "StateMachineAndActivityWithCMKEncryptionConfigurationDefaultTestDeployAssert11207853.template.json", + "terminationProtection": false, + "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}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "StateMachineAndActivityWithCMKEncryptionConfigurationDefaultTestDeployAssert11207853.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "StateMachineAndActivityWithCMKEncryptionConfigurationDefaultTestDeployAssert11207853.assets" + ], + "metadata": { + "/StateMachineAndActivityWithCMKEncryptionConfiguration/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/StateMachineAndActivityWithCMKEncryptionConfiguration/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "StateMachineAndActivityWithCMKEncryptionConfiguration/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/tree.json new file mode 100644 index 0000000000000..054094d85691d --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.js.snapshot/tree.json @@ -0,0 +1,338 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig": { + "id": "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig", + "path": "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig", + "children": { + "Key": { + "id": "Key", + "path": "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig/Key", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig/Key/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::KMS::Key", + "aws:cdk:cloudformation:props": { + "keyPolicy": { + "Statement": [ + { + "Action": "kms:*", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": "*" + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey", + "kms:GenerateDataKey" + ], + "Condition": { + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + }, + "aws:SourceArn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":states:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":stateMachine/StateMachineWithCMKEncryptionConfiguration" + ] + ] + }, + "kms:EncryptionContext:aws:states:stateMachineArn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":states:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":stateMachine/StateMachineWithCMKEncryptionConfiguration" + ] + ] + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + }, + "Resource": "*" + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_kms.CfnKey", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_kms.Key", + "version": "0.0.0" + } + }, + "Pass": { + "id": "Pass", + "path": "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig/Pass", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.Pass", + "version": "0.0.0" + } + }, + "StateMachineWithCMKEncryptionConfiguration": { + "id": "StateMachineWithCMKEncryptionConfiguration", + "path": "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig/StateMachineWithCMKEncryptionConfiguration", + "children": { + "Role": { + "id": "Role", + "path": "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig/StateMachineWithCMKEncryptionConfiguration/Role", + "children": { + "ImportRole": { + "id": "ImportRole", + "path": "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig/StateMachineWithCMKEncryptionConfiguration/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig/StateMachineWithCMKEncryptionConfiguration/Role/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig/StateMachineWithCMKEncryptionConfiguration/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::StepFunctions::StateMachine", + "aws:cdk:cloudformation:props": { + "definitionString": "{\"StartAt\":\"Pass\",\"States\":{\"Pass\":{\"Type\":\"Pass\",\"End\":true}}}", + "encryptionConfiguration": { + "kmsKeyId": { + "Fn::GetAtt": [ + "Key961B73FD", + "Arn" + ] + }, + "kmsDataKeyReusePeriodSeconds": 75, + "type": "CUSTOMER_MANAGED_KMS_KEY" + }, + "roleArn": { + "Fn::GetAtt": [ + "StateMachineWithCMKEncryptionConfigurationRoleA49EBB18", + "Arn" + ] + }, + "stateMachineName": "StateMachineWithCMKEncryptionConfiguration", + "stateMachineType": "STANDARD" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.CfnStateMachine", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.StateMachine", + "version": "0.0.0" + } + }, + "ActivityWithCMKEncryptionConfiguration": { + "id": "ActivityWithCMKEncryptionConfiguration", + "path": "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig/ActivityWithCMKEncryptionConfiguration", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig/ActivityWithCMKEncryptionConfiguration/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::StepFunctions::Activity", + "aws:cdk:cloudformation:props": { + "encryptionConfiguration": { + "kmsKeyId": { + "Fn::GetAtt": [ + "Key961B73FD", + "Arn" + ] + }, + "kmsDataKeyReusePeriodSeconds": 75, + "type": "CUSTOMER_MANAGED_KMS_KEY" + }, + "name": "ActivityWithCMKEncryptionConfiguration" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.CfnActivity", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.Activity", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "StateMachineAndActivityWithCMKEncryptionConfiguration": { + "id": "StateMachineAndActivityWithCMKEncryptionConfiguration", + "path": "StateMachineAndActivityWithCMKEncryptionConfiguration", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "StateMachineAndActivityWithCMKEncryptionConfiguration/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "StateMachineAndActivityWithCMKEncryptionConfiguration/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "StateMachineAndActivityWithCMKEncryptionConfiguration/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "StateMachineAndActivityWithCMKEncryptionConfiguration/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "StateMachineAndActivityWithCMKEncryptionConfiguration/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.ts new file mode 100644 index 0000000000000..25860024829cb --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.state-machine-and-activity-cmk.ts @@ -0,0 +1,39 @@ +import * as cdk from 'aws-cdk-lib'; +import * as sfn from 'aws-cdk-lib/aws-stepfunctions'; +import * as kms from 'aws-cdk-lib/aws-kms'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; + +class KMSStateMachine extends cdk.Stack { + readonly stateMachine: sfn.StateMachine; + readonly activity: sfn.Activity; + readonly kmsKey: kms.Key; + + constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { + super(scope, id, props); + + this.kmsKey = new kms.Key(this, 'Key'); + + this.stateMachine = new sfn.StateMachine(this, 'StateMachineWithCMKEncryptionConfiguration', { + stateMachineName: 'StateMachineWithCMKEncryptionConfiguration', + definitionBody: sfn.DefinitionBody.fromChainable(sfn.Chain.start(new sfn.Pass(this, 'Pass'))), + stateMachineType: sfn.StateMachineType.STANDARD, + kmsKey: this.kmsKey, + kmsDataKeyReusePeriodSeconds: cdk.Duration.seconds(75), + }); + + this.activity = new sfn.Activity(this, 'ActivityWithCMKEncryptionConfiguration', { + activityName: 'ActivityWithCMKEncryptionConfiguration', + kmsKey: this.kmsKey, + kmsDataKeyReusePeriodSeconds: cdk.Duration.seconds(75), + }); + + } +} +const app = new cdk.App(); +const stack = new KMSStateMachine(app, 'aws-stepfunctions-statemachine-and-activity-with-cmk-encryptionconfig'); + +new IntegTest(app, 'StateMachineAndActivityWithCMKEncryptionConfiguration', { + testCases: [stack], +}); + +app.synth(); diff --git a/packages/aws-cdk-lib/aws-stepfunctions/README.md b/packages/aws-cdk-lib/aws-stepfunctions/README.md index 92ca936868184..509368ef33c44 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/README.md +++ b/packages/aws-cdk-lib/aws-stepfunctions/README.md @@ -108,6 +108,32 @@ new sfn.StateMachine(this, 'StateMachineFromFile', { }); ``` +### Creating a StateMachine with Encryption using a Customer Managed Key +``` +const stateMachine = new sfn.StateMachine(this, 'StateMachineWithCMKEncryptionConfiguration', { + stateMachineName: 'StateMachineWithCMKEncryptionConfiguration', + definitionBody: sfn.DefinitionBody.fromChainable(sfn.Chain.start(new sfn.Pass(this, 'Pass'))), + stateMachineType: sfn.StateMachineType.STANDARD, + encryptionConfiguration: { + kmsKeyId: this.kmsKey.keyId, + kmsDataKeyReusePeriodSeconds: 75, + type: sfn.EncryptionType.CUSTOMER_MANAGED_KMS_KEY, + }, + }); +``` + +### Creating a StateMachine with Encryption using an AWS Owned Key +``` +const stateMachinne = new sfn.StateMachine(this, 'StateMachineWithAOKEncryptionConfiguration', { + stateMachineName: 'StateMachineWithAOKEncryptionConfiguration', + definitionBody: sfn.DefinitionBody.fromChainable(sfn.Chain.start(new sfn.Pass(this, 'Pass'))), + stateMachineType: sfn.StateMachineType.STANDARD, + encryptionConfiguration: { + type: sfn.EncryptionType.AWS_OWNED_KEY, + }, + }); +``` + ## State Machine Data An Execution represents each time the State Machine is run. Every Execution has [State Machine @@ -887,6 +913,28 @@ const activity = new sfn.Activity(this, 'Activity'); new CfnOutput(this, 'ActivityArn', { value: activity.activityArn }); ``` +### Creating an Activity with Encryption using a Customer Managed Key +``` +const activity = new sfn.Activity(this, 'ActivityWithCMKEncryptionConfiguration', { + activityName: 'ActivityWithCMKEncryptionConfiguration', + encryptionConfiguration: { + kmsKeyId: this.kmsKey.keyId, + kmsDataKeyReusePeriodSeconds: 75, + type: sfn.EncryptionType.CUSTOMER_MANAGED_KMS_KEY, + }, + }); +``` + +### Creating an Activity with Encryption using an AWS Owned Key +``` +const activity = new sfn.Activity(this, 'ActivityWithAOKEncryptionConfiguration', { + activityName: 'ActivityWithAOKEncryptionConfiguration', + encryptionConfiguration: { + type: sfn.EncryptionType.AWS_OWNED_KEY, + }, + }); +``` + ### Activity-Level Permissions Granting IAM permissions to an activity can be achieved by calling the `grant(principal, actions)` API: diff --git a/packages/aws-cdk-lib/aws-stepfunctions/lib/activity.ts b/packages/aws-cdk-lib/aws-stepfunctions/lib/activity.ts index c72f279f67440..69a6b28a690c3 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/lib/activity.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/lib/activity.ts @@ -1,11 +1,11 @@ import { Construct } from 'constructs'; -import { EncryptionConfiguration } from './encryption-configuration'; import { StatesMetrics } from './stepfunctions-canned-metrics.generated'; import { CfnActivity } from './stepfunctions.generated'; +import { isValidKmsDataKeyReusePeriodSeconds } from './util'; import * as cloudwatch from '../../aws-cloudwatch'; import * as iam from '../../aws-iam'; -import { ArnFormat, IResource, Lazy, Names, Resource, Stack } from '../../core'; -export * from './encryption-configuration'; +import * as kms from '../../aws-kms'; +import { ArnFormat, Duration, IResource, Lazy, Names, Resource, Stack } from '../../core'; /** * Properties for defining a new Step Functions Activity @@ -22,7 +22,19 @@ export interface ActivityProps { * * @default - no EncryptionConfiguration */ - readonly encryptionConfiguration?: EncryptionConfiguration; + + /** + * Identifier for KMS key, which can be in the format of key ARN, key ID, alias ARN or alias name + * @default - no kmsKeyId is associated + */ + readonly kmsKey?: kms.IKey; + + /** + * Maximum duration for which SFN will reuse data keys. When the period expires, + * SFN will call GenerateDataKey. This setting only applies to a customer managed key and does not apply to an AWS owned KMS key. + * @default - 300s + */ + readonly kmsDataKeyReusePeriodSeconds?: Duration; } /** @@ -68,7 +80,6 @@ export class Activity extends Resource implements IActivity { /** * @attribute */ - public readonly encryptionConfiguration?: EncryptionConfiguration; constructor(scope: Construct, id: string, props: ActivityProps = {}) { super(scope, id, { @@ -76,9 +87,19 @@ export class Activity extends Resource implements IActivity { Lazy.string({ produce: () => this.generateName() }), }); + if (props?.kmsDataKeyReusePeriodSeconds && !isValidKmsDataKeyReusePeriodSeconds(props.kmsDataKeyReusePeriodSeconds)) { + throw new Error('kmsDataKeyReusePeriodSeconds needs to be a value between 60 and 900'); + } + const resource = new CfnActivity(this, 'Resource', { name: this.physicalName!, // not null because of above call to `super` - encryptionConfiguration: props.encryptionConfiguration ?? undefined, + encryptionConfiguration: props.kmsKey? { + kmsKeyId: props.kmsKey.keyArn, + kmsDataKeyReusePeriodSeconds: props.kmsDataKeyReusePeriodSeconds?.toSeconds(), + type: 'CUSTOMER_MANAGED_KMS_KEY', + }: { + type: 'AWS_OWNED_KEY', + }, }); this.activityArn = this.getResourceArnAttribute(resource.ref, { @@ -242,5 +263,4 @@ export interface IActivity extends IResource { * * @attribute */ - readonly encryptionConfiguration?: EncryptionConfiguration; } diff --git a/packages/aws-cdk-lib/aws-stepfunctions/lib/encryption-configuration.ts b/packages/aws-cdk-lib/aws-stepfunctions/lib/encryption-configuration.ts deleted file mode 100644 index d1bf328608d9f..0000000000000 --- a/packages/aws-cdk-lib/aws-stepfunctions/lib/encryption-configuration.ts +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Define an EncryptionConfiguration - */ -export interface EncryptionConfiguration { - /** - * Identifier for KMS key, which can in the format of key ARN, key ID, alias ARN or alias name - * @default - no kmsKeyId is associated - */ - readonly kmsKeyId?: string; - /** - * Maximum duration for which SFN will reuse data keys. When the period expires, - * SFN will call GenerateDataKey. This setting only applies to customer managed KMS key and does not apply to AWS owned KMS key. - * @default - 300s - */ - readonly kmsDataKeyReusePeriodSeconds?: number; - /** - * The encryption option specified for the state machine - * @default - AWS_OWNED_KEY - */ - readonly type: EncryptionType; -} -/** - * Define an EncryptionType - */ -export enum EncryptionType { -/** - * SFN owned key - */ - AWS_OWNED_KEY = 'AWS_OWNED_KEY', - /** - * Customer managed key - */ - CUSTOMER_MANAGED_KMS_KEY = 'CUSTOMER_MANAGED_KMS_KEY', -} \ No newline at end of file diff --git a/packages/aws-cdk-lib/aws-stepfunctions/lib/state-machine.ts b/packages/aws-cdk-lib/aws-stepfunctions/lib/state-machine.ts index f1284b5af957c..2f4aa3f6f9e45 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/lib/state-machine.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/lib/state-machine.ts @@ -1,15 +1,16 @@ import { Construct } from 'constructs'; -import { EncryptionConfiguration } from './encryption-configuration'; import { StateGraph } from './state-graph'; import { StatesMetrics } from './stepfunctions-canned-metrics.generated'; import { CfnStateMachine } from './stepfunctions.generated'; import { IChainable } from './types'; +import { isValidKmsDataKeyReusePeriodSeconds } from './util'; import * as cloudwatch from '../../aws-cloudwatch'; import * as iam from '../../aws-iam'; +import * as kms from '../../aws-kms'; import * as logs from '../../aws-logs'; import * as s3_assets from '../../aws-s3-assets'; + import { Arn, ArnFormat, Duration, IResource, RemovalPolicy, Resource, Stack, Token } from '../../core'; -export * from './encryption-configuration'; /** * Two types of state machines are available in AWS Step Functions: EXPRESS AND STANDARD. @@ -157,10 +158,17 @@ export interface StateMachineProps { readonly removalPolicy?: RemovalPolicy; /** - * EncryptionConfiguration for this state machine - * @default No EncryptionConfiguration + * Identifier for KMS key, which can be in the format of key ARN, key ID, alias ARN or alias name + * @default - no kmsKeyId is associated */ - readonly encryptionConfiguration?: EncryptionConfiguration; + readonly kmsKey?: kms.IKey; + + /** + * Maximum duration for which SFN will reuse data keys. When the period expires, + * SFN will call GenerateDataKey. This setting only applies to a customer managed key and does not apply to an AWS owned KMS key. + * @default - 300s + */ + readonly kmsDataKeyReusePeriodSeconds?: Duration; } /** @@ -172,7 +180,6 @@ abstract class StateMachineBase extends Resource implements IStateMachine { */ public static fromStateMachineArn(scope: Construct, id: string, stateMachineArn: string): IStateMachine { class Import extends StateMachineBase { - public encryptionConfiguration?: EncryptionConfiguration | undefined; public readonly stateMachineArn = stateMachineArn; public readonly grantPrincipal = new iam.UnknownPrincipal({ resource: this }); } @@ -196,33 +203,10 @@ abstract class StateMachineBase extends Resource implements IStateMachine { public abstract readonly stateMachineArn: string; - public abstract readonly encryptionConfiguration?: EncryptionConfiguration; - /** * The principal this state machine is running as */ public abstract readonly grantPrincipal: iam.IPrincipal; - - private isEncryptionConfigurationSet() { - return this.encryptionConfiguration !== undefined; - } - - private getKmsGenerateDataKeyAndDecryptActions() { - if (this.isEncryptionConfigurationSet()) { - return ['kms:GenerateDataKey', 'kms:Decrypt']; - } else { - return []; - } - } - - private getKmsDecryptAction() { - if (this.isEncryptionConfigurationSet()) { - return ['kms:Decrypt']; - } else { - return []; - } - } - /** * Grant the given identity permissions to start an execution of this state * machine. @@ -230,7 +214,7 @@ abstract class StateMachineBase extends Resource implements IStateMachine { public grantStartExecution(identity: iam.IGrantable): iam.Grant { return iam.Grant.addToPrincipal({ grantee: identity, - actions: ['states:StartExecution', ... this.getKmsGenerateDataKeyAndDecryptActions()], + actions: ['states:StartExecution'], resourceArns: [this.stateMachineArn], }); } @@ -242,7 +226,7 @@ abstract class StateMachineBase extends Resource implements IStateMachine { public grantStartSyncExecution(identity: iam.IGrantable): iam.Grant { return iam.Grant.addToPrincipal({ grantee: identity, - actions: ['states:StartSyncExecution', ...this.getKmsDecryptAction()], + actions: ['states:StartSyncExecution'], resourceArns: [this.stateMachineArn], }); } @@ -266,7 +250,6 @@ abstract class StateMachineBase extends Resource implements IStateMachine { 'states:DescribeExecution', 'states:DescribeStateMachineForExecution', 'states:GetExecutionHistory', - ...this.getKmsDecryptAction(), ], resourceArns: [`${this.executionArn()}:*`], }); @@ -276,7 +259,6 @@ abstract class StateMachineBase extends Resource implements IStateMachine { 'states:ListActivities', 'states:DescribeStateMachine', 'states:DescribeActivity', - ...this.getKmsDecryptAction(), ], resourceArns: ['*'], }); @@ -292,7 +274,6 @@ abstract class StateMachineBase extends Resource implements IStateMachine { 'states:SendTaskSuccess', 'states:SendTaskFailure', 'states:SendTaskHeartbeat', - ...this.getKmsDecryptAction(), ], resourceArns: [this.stateMachineArn], }); @@ -451,7 +432,6 @@ export class StateMachine extends StateMachineBase { * Type of the EncryptionConfiguration * @attribute */ - public readonly encryptionConfiguration?: EncryptionConfiguration; /** * Identifier for the state machine revision, which is an immutable, read-only snapshot of a state machine’s definition and configuration. @@ -492,6 +472,33 @@ export class StateMachine extends StateMachineBase { } } + if (props?.kmsDataKeyReusePeriodSeconds && !isValidKmsDataKeyReusePeriodSeconds(props.kmsDataKeyReusePeriodSeconds)) { + throw new Error('kmsDataKeyReusePeriodSeconds needs to be a value between 60 and 900'); + } + + if (props?.kmsKey) { + props?.kmsKey.addToResourcePolicy(new iam.PolicyStatement({ + resources: ['*'], + actions: ['kms:Decrypt', 'kms:GenerateDataKey', 'kms:DescribeKey'], + principals: [new iam.ServicePrincipal('states.amazonaws.com')], + conditions: { + StringEquals: { + 'aws:SourceAccount': this.stack.account, + 'aws:SourceArn': Stack.of(this).formatArn({ + service: 'states', + resource: 'stateMachine', + resourceName: this.physicalName, + }), + 'kms:EncryptionContext:aws:states:stateMachineArn': Stack.of(this).formatArn({ + service: 'states', + resource: 'stateMachine', + resourceName: this.physicalName, + }), + }, + }, + })); + } + const resource = new CfnStateMachine(this, 'Resource', { stateMachineName: this.physicalName, stateMachineType: props.stateMachineType ?? undefined, @@ -500,12 +507,17 @@ export class StateMachine extends StateMachineBase { tracingConfiguration: props.tracingEnabled ? this.buildTracingConfiguration() : undefined, ...definitionBody.bind(this, this.role, props, graph), definitionSubstitutions: props.definitionSubstitutions, - encryptionConfiguration: props.encryptionConfiguration, + encryptionConfiguration: props.kmsKey? { + kmsKeyId: props.kmsKey.keyArn, + kmsDataKeyReusePeriodSeconds: props.kmsDataKeyReusePeriodSeconds? props.kmsDataKeyReusePeriodSeconds.toSeconds() : 300, + type: 'CUSTOMER_MANAGED_KMS_KEY', + }: { + type: 'AWS_OWNED_KEY', + }, }); resource.applyRemovalPolicy(props.removalPolicy, { default: RemovalPolicy.DESTROY }); resource.node.addDependency(this.role); - this.encryptionConfiguration = props.encryptionConfiguration; this.stateMachineName = this.getResourceNameAttribute(resource.attrName); this.stateMachineArn = this.getResourceArnAttribute(resource.ref, { service: 'states', @@ -607,7 +619,6 @@ export interface IStateMachine extends IResource, iam.IGrantable { * * @attribute */ - readonly encryptionConfiguration?: EncryptionConfiguration; /** * Grant the given identity permissions to start an execution of this state diff --git a/packages/aws-cdk-lib/aws-stepfunctions/lib/util.ts b/packages/aws-cdk-lib/aws-stepfunctions/lib/util.ts index 234bbcc0c4144..45dd334791ee2 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/lib/util.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/lib/util.ts @@ -1,4 +1,10 @@ +import { Duration } from '../../core'; + export function noEmptyObject(o: Record): Record | undefined { if (Object.keys(o).length === 0) { return undefined; } return o; +} + +export function isValidKmsDataKeyReusePeriodSeconds(kmsDataKeyReusePeriodSeconds: Duration) { + return kmsDataKeyReusePeriodSeconds >= Duration.seconds(60) && kmsDataKeyReusePeriodSeconds <= Duration.seconds(900); } \ No newline at end of file diff --git a/packages/aws-cdk-lib/aws-stepfunctions/test/activity.test.ts b/packages/aws-cdk-lib/aws-stepfunctions/test/activity.test.ts index 78e3c4d09ed98..15fe7440b622f 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/test/activity.test.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/test/activity.test.ts @@ -3,7 +3,6 @@ import * as iam from '../../aws-iam'; import * as kms from '../../aws-kms'; import * as cdk from '../../core'; import * as stepfunctions from '../lib'; -import { EncryptionType } from '../lib/encryption-configuration'; describe('Activity', () => { test('instantiate Activity', () => { @@ -80,42 +79,50 @@ describe('Activity', () => { // WHEN new stepfunctions.Activity(stack, 'Activity', { - encryptionConfiguration: { - kmsKeyId: kmsKey.keyId, - kmsDataKeyReusePeriodSeconds: 75, - type: EncryptionType.CUSTOMER_MANAGED_KMS_KEY, - }, + kmsKey: kmsKey, + kmsDataKeyReusePeriodSeconds: cdk.Duration.seconds(75), }); // THEN Template.fromStack(stack).hasResourceProperties('AWS::StepFunctions::Activity', { Name: 'Activity', EncryptionConfiguration: Match.objectLike({ - KmsKeyId: { - Ref: 'Key961B73FD', - }, + KmsKeyId: { 'Fn::GetAtt': ['Key961B73FD', 'Arn'] }, KmsDataKeyReusePeriodSeconds: 75, - Type: EncryptionType.CUSTOMER_MANAGED_KMS_KEY, + Type: 'CUSTOMER_MANAGED_KMS_KEY', }), }); }); + test('instantiate Activity with invalid KmsDataKeyReusePeriodSeconds throws error', () => { + // GIVEN + const stack = new cdk.Stack(); + const kmsKey = new kms.Key(stack, 'Key'); + + // FAIL + expect(() => { + // WHEN + new stepfunctions.Activity(stack, 'Activity', { + kmsKey: kmsKey, + kmsDataKeyReusePeriodSeconds: cdk.Duration.seconds(5), + }); + }).toThrow('kmsDataKeyReusePeriodSeconds needs to be a value between 60 and 900'); + + }), + test('instantiate Activity with EncryptionConfiguration using AWS Owned Key', () => { // GIVEN const stack = new cdk.Stack(); // WHEN new stepfunctions.Activity(stack, 'Activity', { - encryptionConfiguration: { - type: EncryptionType.AWS_OWNED_KEY, - }, }); // THEN Template.fromStack(stack).hasResourceProperties('AWS::StepFunctions::Activity', { Name: 'Activity', EncryptionConfiguration: Match.objectLike({ - Type: EncryptionType.AWS_OWNED_KEY, + Type: 'AWS_OWNED_KEY', }), }); }); diff --git a/packages/aws-cdk-lib/aws-stepfunctions/test/state-machine.test.ts b/packages/aws-cdk-lib/aws-stepfunctions/test/state-machine.test.ts index 3d345341ae0a5..82f025610ae51 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/test/state-machine.test.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/test/state-machine.test.ts @@ -6,7 +6,6 @@ import * as logs from '../../aws-logs'; import * as s3 from '../../aws-s3'; import * as cdk from '../../core'; import * as sfn from '../lib'; -import { EncryptionType } from '../lib/encryption-configuration'; describe('State Machine', () => { test('Instantiate Default State Machine with deprecated definition', () => { @@ -709,11 +708,8 @@ describe('State Machine', () => { stateMachineName: 'MyStateMachine', definitionBody: sfn.DefinitionBody.fromChainable(sfn.Chain.start(new sfn.Pass(stack, 'Pass'))), stateMachineType: sfn.StateMachineType.STANDARD, - encryptionConfiguration: { - kmsKeyId: kmsKey.keyId, - kmsDataKeyReusePeriodSeconds: 75, - type: EncryptionType.CUSTOMER_MANAGED_KMS_KEY, - }, + kmsKey: kmsKey, + kmsDataKeyReusePeriodSeconds: cdk.Duration.seconds(75), }); // THEN @@ -722,27 +718,114 @@ describe('State Machine', () => { StateMachineType: 'STANDARD', DefinitionString: '{"StartAt":"Pass","States":{"Pass":{"Type":"Pass","End":true}}}', EncryptionConfiguration: Match.objectLike({ - KmsKeyId: { - Ref: 'Key961B73FD', - }, + KmsKeyId: { 'Fn::GetAtt': ['Key961B73FD', 'Arn'] }, KmsDataKeyReusePeriodSeconds: 75, - Type: EncryptionType.CUSTOMER_MANAGED_KMS_KEY, + Type: 'CUSTOMER_MANAGED_KMS_KEY', }), }); + + Template.fromStack(stack).hasResourceProperties('AWS::KMS::Key', { + KeyPolicy: { + Statement: [ + { + Action: 'kms:*', + Effect: 'Allow', + Principal: { + AWS: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':iam::', + { + Ref: 'AWS::AccountId', + }, + ':root', + ], + ], + }, + }, + Resource: '*', + }, + { + Action: [ + 'kms:Decrypt', + 'kms:GenerateDataKey', + 'kms:DescribeKey', + ], + Condition: { + StringEquals: { + 'aws:SourceAccount': { + Ref: 'AWS::AccountId', + }, + 'aws:SourceArn': { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':states:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':stateMachine/MyStateMachine', + ], + ], + }, + 'kms:EncryptionContext:aws:states:stateMachineArn': { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':states:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':stateMachine/MyStateMachine', + ], + ], + }, + }, + }, + Effect: 'Allow', + Principal: { + Service: 'states.amazonaws.com', + }, + Resource: '*', + }, + ], + Version: '2012-10-17', + }, + }); }), - test('instantiate StateMachine with EncryptionConfiguration using AWS Owned Key', () => { + test('instantiate StateMachine with EncryptionConfiguration using Customer Managed Key - defaults to 300 secs for KmsDataKeyReusePeriodSeconds', () => { // GIVEN const stack = new cdk.Stack(); + const kmsKey = new kms.Key(stack, 'Key'); // WHEN new sfn.StateMachine(stack, 'MyStateMachine', { stateMachineName: 'MyStateMachine', definitionBody: sfn.DefinitionBody.fromChainable(sfn.Chain.start(new sfn.Pass(stack, 'Pass'))), stateMachineType: sfn.StateMachineType.STANDARD, - encryptionConfiguration: { - type: EncryptionType.AWS_OWNED_KEY, - }, + kmsKey: kmsKey, }); // THEN @@ -751,231 +834,141 @@ describe('State Machine', () => { StateMachineType: 'STANDARD', DefinitionString: '{"StartAt":"Pass","States":{"Pass":{"Type":"Pass","End":true}}}', EncryptionConfiguration: Match.objectLike({ - Type: EncryptionType.AWS_OWNED_KEY, + KmsKeyId: { 'Fn::GetAtt': ['Key961B73FD', 'Arn'] }, + KmsDataKeyReusePeriodSeconds: 300, + Type: 'CUSTOMER_MANAGED_KMS_KEY', }), }); - }); -}); - -test('Standard StateMachine can grant kms permissions needed to StartExecution', () => { - // GIVEN - const stack = new cdk.Stack(); - const kmsKey = new kms.Key(stack, 'Key'); - - const role = new iam.Role(stack, 'Role', { - assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), - }); - - const stateMachine = new sfn.StateMachine(stack, 'MyStateMachine', { - stateMachineName: 'MyStateMachine', - definitionBody: sfn.DefinitionBody.fromChainable(sfn.Chain.start(new sfn.Pass(stack, 'Pass'))), - stateMachineType: sfn.StateMachineType.STANDARD, - encryptionConfiguration: { - kmsKeyId: kmsKey.keyId, - kmsDataKeyReusePeriodSeconds: 75, - type: EncryptionType.CUSTOMER_MANAGED_KMS_KEY, - }, - }); - - // WHEN - stateMachine.grantStartExecution(role); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { - PolicyDocument: { - Statement: Match.arrayWith([Match.objectLike({ - Action: [ - 'states:StartExecution', - 'kms:GenerateDataKey', - 'kms:Decrypt', - ], - Effect: 'Allow', - Resource: { - Ref: 'MyStateMachine6C968CA5', - }, - })]), - }, - }); -}); - -test('Express StateMachine can grant kms permissions needed to StartSyncExecution', () => { - // GIVEN - const stack = new cdk.Stack(); - const kmsKey = new kms.Key(stack, 'Key'); - - const role = new iam.Role(stack, 'Role', { - assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), - }); - - const stateMachine = new sfn.StateMachine(stack, 'MyStateMachine', { - stateMachineName: 'MyStateMachine', - definitionBody: sfn.DefinitionBody.fromChainable(sfn.Chain.start(new sfn.Pass(stack, 'Pass'))), - stateMachineType: sfn.StateMachineType.EXPRESS, - encryptionConfiguration: { - kmsKeyId: kmsKey.keyId, - kmsDataKeyReusePeriodSeconds: 75, - type: EncryptionType.CUSTOMER_MANAGED_KMS_KEY, - }, - }); - - // WHEN - stateMachine.grantStartSyncExecution(role); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { - PolicyDocument: { - Statement: [ - { - Action: [ - 'states:StartSyncExecution', - 'kms:Decrypt', - ], - Effect: 'Allow', - Resource: { - Ref: 'MyStateMachine6C968CA5', - }, - }, - ], - }, - }, - ); -}); - -test('Standard StateMachine with EncryptionConfiguration can give read permissions', () => { - // GIVEN - const stack = new cdk.Stack(); - const kmsKey = new kms.Key(stack, 'Key'); - - const role = new iam.Role(stack, 'Role', { - assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), - }); - const stateMachine = new sfn.StateMachine(stack, 'MyStateMachine', { - stateMachineName: 'MyStateMachine', - definitionBody: sfn.DefinitionBody.fromChainable(sfn.Chain.start(new sfn.Pass(stack, 'Pass'))), - stateMachineType: sfn.StateMachineType.STANDARD, - encryptionConfiguration: { - kmsKeyId: kmsKey.keyId, - kmsDataKeyReusePeriodSeconds: 75, - type: EncryptionType.CUSTOMER_MANAGED_KMS_KEY, - }, - }); - - // WHEN - stateMachine.grantRead(role); - - Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { - PolicyDocument: { - Statement: [ - { - Action: [ - 'states:ListExecutions', - 'states:ListStateMachines', - ], - Effect: 'Allow', - Resource: { - Ref: 'MyStateMachine6C968CA5', + Template.fromStack(stack).hasResourceProperties('AWS::KMS::Key', { + KeyPolicy: { + Statement: [ + { + Action: 'kms:*', + Effect: 'Allow', + Principal: { + AWS: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':iam::', + { + Ref: 'AWS::AccountId', + }, + ':root', + ], + ], + }, + }, + Resource: '*', }, - }, - { - Action: [ - 'states:DescribeExecution', - 'states:DescribeStateMachineForExecution', - 'states:GetExecutionHistory', - 'kms:Decrypt', - ], - Effect: 'Allow', - Resource: { - 'Fn::Join': [ - '', - [ - 'arn:', - { - Ref: 'AWS::Partition', - }, - ':states:', - { - Ref: 'AWS::Region', - }, - ':', - { + { + Action: [ + 'kms:Decrypt', + 'kms:GenerateDataKey', + 'kms:DescribeKey', + ], + Condition: { + StringEquals: { + 'aws:SourceAccount': { Ref: 'AWS::AccountId', }, - ':execution:', - { - 'Fn::Select': [ - 6, - { - 'Fn::Split': [ - ':', - { - Ref: 'MyStateMachine6C968CA5', - }, - ], - }, + 'aws:SourceArn': { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':states:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':stateMachine/MyStateMachine', + ], ], }, - ':*', - ], - ], + 'kms:EncryptionContext:aws:states:stateMachineArn': { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':states:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':stateMachine/MyStateMachine', + ], + ], + }, + }, + }, + Effect: 'Allow', + Principal: { + Service: 'states.amazonaws.com', + }, + Resource: '*', }, - }, - { - Action: [ - 'states:ListActivities', - 'states:DescribeStateMachine', - 'states:DescribeActivity', - 'kms:Decrypt', - ], - Effect: 'Allow', - Resource: '*', - }, - ], - }, - }, - ); -}); - -test('Created state machine can grant task response actions to the state machine', () => { - // GIVEN - const stack = new cdk.Stack(); - const kmsKey = new kms.Key(stack, 'Key'); - - const role = new iam.Role(stack, 'Role', { - assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), - }); + ], + Version: '2012-10-17', + }, + }); + }), - const stateMachine = new sfn.StateMachine(stack, 'MyStateMachine', { - stateMachineName: 'MyStateMachine', - definitionBody: sfn.DefinitionBody.fromChainable(sfn.Chain.start(new sfn.Pass(stack, 'Pass'))), - stateMachineType: sfn.StateMachineType.STANDARD, - encryptionConfiguration: { - kmsKeyId: kmsKey.keyId, - kmsDataKeyReusePeriodSeconds: 75, - type: EncryptionType.CUSTOMER_MANAGED_KMS_KEY, - }, - }); + test('instantiate StateMachine with invalid KmsDataKeyReusePeriodSeconds throws error', () => { + // GIVEN + const stack = new cdk.Stack(); + const kmsKey = new kms.Key(stack, 'Key'); - // WHEN - stateMachine.grantTaskResponse(role); + // FAIL + expect(() => { + // WHEN + new sfn.StateMachine(stack, 'MyStateMachine', { + stateMachineName: 'MyStateMachine', + definitionBody: sfn.DefinitionBody.fromChainable(sfn.Chain.start(new sfn.Pass(stack, 'Pass'))), + stateMachineType: sfn.StateMachineType.STANDARD, + kmsKey: kmsKey, + kmsDataKeyReusePeriodSeconds: cdk.Duration.seconds(20), + }); + }).toThrow('kmsDataKeyReusePeriodSeconds needs to be a value between 60 and 900'); - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { - PolicyDocument: { - Statement: [ - { - Action: [ - 'states:SendTaskSuccess', - 'states:SendTaskFailure', - 'states:SendTaskHeartbeat', - 'kms:Decrypt', - ], - Effect: 'Allow', - Resource: { - Ref: 'MyStateMachine6C968CA5', - }, - }, - ], - }, + }), + + test('instantiate StateMachine with EncryptionConfiguration using AWS Owned Key', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new sfn.StateMachine(stack, 'MyStateMachine', { + stateMachineName: 'MyStateMachine', + definitionBody: sfn.DefinitionBody.fromChainable(sfn.Chain.start(new sfn.Pass(stack, 'Pass'))), + stateMachineType: sfn.StateMachineType.STANDARD, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::StepFunctions::StateMachine', { + StateMachineName: 'MyStateMachine', + StateMachineType: 'STANDARD', + DefinitionString: '{"StartAt":"Pass","States":{"Pass":{"Type":"Pass","End":true}}}', + EncryptionConfiguration: Match.objectLike({ + Type: 'AWS_OWNED_KEY', + }), + }); }); -}); +}); \ No newline at end of file