diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdk-table-with-customized-role.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdk-table-with-customized-role.assets.json new file mode 100644 index 0000000000000..23b584c2e6591 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdk-table-with-customized-role.assets.json @@ -0,0 +1,19 @@ +{ + "version": "38.0.1", + "files": { + "70267cb4d71000f9402304c37f8f7f27be51a2639cc15153bf93abab53fc60cd": { + "source": { + "path": "cdk-table-with-customized-role.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "70267cb4d71000f9402304c37f8f7f27be51a2639cc15153bf93abab53fc60cd.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-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdk-table-with-customized-role.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdk-table-with-customized-role.template.json new file mode 100644 index 0000000000000..4a512f0150bc8 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdk-table-with-customized-role.template.json @@ -0,0 +1,83 @@ +{ + "Resources": { + "TableCD117FA1": { + "Type": "AWS::DynamoDB::Table", + "Properties": { + "AttributeDefinitions": [ + { + "AttributeName": "pk", + "AttributeType": "S" + }, + { + "AttributeName": "gsi-pk", + "AttributeType": "S" + } + ], + "GlobalSecondaryIndexes": [ + { + "IndexName": "gsi", + "KeySchema": [ + { + "AttributeName": "gsi-pk", + "KeyType": "HASH" + } + ], + "Projection": { + "ProjectionType": "ALL" + }, + "ProvisionedThroughput": { + "ReadCapacityUnits": 5, + "WriteCapacityUnits": 5 + } + } + ], + "KeySchema": [ + { + "AttributeName": "pk", + "KeyType": "HASH" + } + ], + "ProvisionedThroughput": { + "ReadCapacityUnits": 5, + "WriteCapacityUnits": 5 + } + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + } + }, + "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-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdk-table-with-customized-role2.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdk-table-with-customized-role2.assets.json new file mode 100644 index 0000000000000..05d955ca02cea --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdk-table-with-customized-role2.assets.json @@ -0,0 +1,19 @@ +{ + "version": "38.0.1", + "files": { + "75d2a3c3208960a28b88f27cd9f94f89a8126de261c69dc422537395c5c29fbe": { + "source": { + "path": "cdk-table-with-customized-role2.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "75d2a3c3208960a28b88f27cd9f94f89a8126de261c69dc422537395c5c29fbe.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-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdk-table-with-customized-role2.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdk-table-with-customized-role2.template.json new file mode 100644 index 0000000000000..9b673891b73cb --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdk-table-with-customized-role2.template.json @@ -0,0 +1,61 @@ +{ + "Resources": { + "TableCD117FA1": { + "Type": "AWS::DynamoDB::Table", + "Properties": { + "AttributeDefinitions": [ + { + "AttributeName": "pk", + "AttributeType": "S" + } + ], + "KeySchema": [ + { + "AttributeName": "pk", + "KeyType": "HASH" + } + ], + "ProvisionedThroughput": { + "ReadCapacityUnits": 5, + "WriteCapacityUnits": 5 + } + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + } + }, + "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-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdk.out new file mode 100644 index 0000000000000..c6e612584e352 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"38.0.1"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdkdynamodbcustomizedroleintegDefaultTestDeployAssertD6C925FC.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdkdynamodbcustomizedroleintegDefaultTestDeployAssertD6C925FC.assets.json new file mode 100644 index 0000000000000..374f439045d06 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdkdynamodbcustomizedroleintegDefaultTestDeployAssertD6C925FC.assets.json @@ -0,0 +1,19 @@ +{ + "version": "38.0.1", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "cdkdynamodbcustomizedroleintegDefaultTestDeployAssertD6C925FC.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-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdkdynamodbcustomizedroleintegDefaultTestDeployAssertD6C925FC.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdkdynamodbcustomizedroleintegDefaultTestDeployAssertD6C925FC.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/cdkdynamodbcustomizedroleintegDefaultTestDeployAssertD6C925FC.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-dynamodb/test/integ.table-with-customized-role.js.snapshot/iam-policy-report.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/iam-policy-report.json new file mode 100644 index 0000000000000..aadc926f1bee0 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/iam-policy-report.json @@ -0,0 +1,90 @@ +{ + "roles": [ + { + "roleConstructPath": "cdk-table-with-customized-role/Table/ScalingRole", + "roleName": "AWSServiceRoleForApplicationAutoScaling_DynamoDBTable", + "assumeRolePolicy": [], + "managedPolicyArns": [], + "managedPolicyStatements": [], + "identityPolicyStatements": [] + }, + { + "roleConstructPath": "cdk-table-with-customized-role/Role", + "roleName": "my-precreated-role-name", + "missing": false, + "assumeRolePolicy": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "dynamodb.amazonaws.com" + } + } + ], + "managedPolicyArns": [], + "managedPolicyStatements": [], + "identityPolicyStatements": [ + { + "Action": [ + "dynamodb:BatchGetItem", + "dynamodb:GetRecords", + "dynamodb:GetShardIterator", + "dynamodb:Query", + "dynamodb:GetItem", + "dynamodb:Scan", + "dynamodb:ConditionCheckItem", + "dynamodb:DescribeTable" + ], + "Effect": "Allow", + "Resource": [ + "(cdk-table-with-customized-role/Table/Resource.Arn)", + "(cdk-table-with-customized-role/Table/Resource.Arn)/index/*" + ] + } + ] + }, + { + "roleConstructPath": "cdk-table-with-customized-role2/Table/ScalingRole", + "roleName": "AWSServiceRoleForApplicationAutoScaling_DynamoDBTable", + "assumeRolePolicy": [], + "managedPolicyArns": [], + "managedPolicyStatements": [], + "identityPolicyStatements": [] + }, + { + "roleConstructPath": "cdk-table-with-customized-role2/Role", + "roleName": "my-precreated-role-name", + "missing": false, + "assumeRolePolicy": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "dynamodb.amazonaws.com" + } + } + ], + "managedPolicyArns": [], + "managedPolicyStatements": [], + "identityPolicyStatements": [ + { + "Action": [ + "dynamodb:BatchGetItem", + "dynamodb:GetRecords", + "dynamodb:GetShardIterator", + "dynamodb:Query", + "dynamodb:GetItem", + "dynamodb:Scan", + "dynamodb:ConditionCheckItem", + "dynamodb:DescribeTable" + ], + "Effect": "Allow", + "Resource": [ + "(cdk-table-with-customized-role2/Table/Resource.Arn)", + "(NOVALUE)" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/iam-policy-report.txt b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/iam-policy-report.txt new file mode 100644 index 0000000000000..25b1ead7ae780 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/iam-policy-report.txt @@ -0,0 +1,107 @@ + (cdk-table-with-customized-role/Table/ScalingRole) + +AssumeRole Policy: +NONE + +Managed Policy ARNs: +NONE + +Managed Policies Statements: +NONE + +Identity Policy Statements: +NONE + + (cdk-table-with-customized-role/Role) + +AssumeRole Policy: +[ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "dynamodb.amazonaws.com" + } + } +] + +Managed Policy ARNs: +NONE + +Managed Policies Statements: +NONE + +Identity Policy Statements: +[ + { + "Action": [ + "dynamodb:BatchGetItem", + "dynamodb:GetRecords", + "dynamodb:GetShardIterator", + "dynamodb:Query", + "dynamodb:GetItem", + "dynamodb:Scan", + "dynamodb:ConditionCheckItem", + "dynamodb:DescribeTable" + ], + "Effect": "Allow", + "Resource": [ + "(cdk-table-with-customized-role/Table/Resource.Arn)", + "(cdk-table-with-customized-role/Table/Resource.Arn)/index/*" + ] + } +] + + (cdk-table-with-customized-role2/Table/ScalingRole) + +AssumeRole Policy: +NONE + +Managed Policy ARNs: +NONE + +Managed Policies Statements: +NONE + +Identity Policy Statements: +NONE + + (cdk-table-with-customized-role2/Role) + +AssumeRole Policy: +[ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "dynamodb.amazonaws.com" + } + } +] + +Managed Policy ARNs: +NONE + +Managed Policies Statements: +NONE + +Identity Policy Statements: +[ + { + "Action": [ + "dynamodb:BatchGetItem", + "dynamodb:GetRecords", + "dynamodb:GetShardIterator", + "dynamodb:Query", + "dynamodb:GetItem", + "dynamodb:Scan", + "dynamodb:ConditionCheckItem", + "dynamodb:DescribeTable" + ], + "Effect": "Allow", + "Resource": [ + "(cdk-table-with-customized-role2/Table/Resource.Arn)", + "(NOVALUE)" + ] + } +] \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/integ.json new file mode 100644 index 0000000000000..05d41e8b269ff --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/integ.json @@ -0,0 +1,14 @@ +{ + "version": "38.0.1", + "testCases": { + "cdk-dynamodb-customized-role-integ/DefaultTest": { + "stacks": [ + "cdk-table-with-customized-role", + "cdk-table-with-customized-role2" + ], + "diffAssets": true, + "assertionStack": "cdk-dynamodb-customized-role-integ/DefaultTest/DeployAssert", + "assertionStackName": "cdkdynamodbcustomizedroleintegDefaultTestDeployAssertD6C925FC" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/manifest.json new file mode 100644 index 0000000000000..66aa906b31622 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/manifest.json @@ -0,0 +1,170 @@ +{ + "version": "38.0.1", + "artifacts": { + "cdk-table-with-customized-role.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "cdk-table-with-customized-role.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "cdk-table-with-customized-role": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "cdk-table-with-customized-role.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "notificationArns": [], + "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}/70267cb4d71000f9402304c37f8f7f27be51a2639cc15153bf93abab53fc60cd.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "cdk-table-with-customized-role.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": [ + "cdk-table-with-customized-role.assets" + ], + "metadata": { + "/cdk-table-with-customized-role/Table/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "TableCD117FA1" + } + ], + "/cdk-table-with-customized-role/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/cdk-table-with-customized-role/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "cdk-table-with-customized-role" + }, + "cdk-table-with-customized-role2.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "cdk-table-with-customized-role2.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "cdk-table-with-customized-role2": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "cdk-table-with-customized-role2.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "notificationArns": [], + "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}/75d2a3c3208960a28b88f27cd9f94f89a8126de261c69dc422537395c5c29fbe.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "cdk-table-with-customized-role2.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": [ + "cdk-table-with-customized-role2.assets" + ], + "metadata": { + "/cdk-table-with-customized-role2/Table/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "TableCD117FA1" + } + ], + "/cdk-table-with-customized-role2/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/cdk-table-with-customized-role2/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "cdk-table-with-customized-role2" + }, + "cdkdynamodbcustomizedroleintegDefaultTestDeployAssertD6C925FC.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "cdkdynamodbcustomizedroleintegDefaultTestDeployAssertD6C925FC.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "cdkdynamodbcustomizedroleintegDefaultTestDeployAssertD6C925FC": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "cdkdynamodbcustomizedroleintegDefaultTestDeployAssertD6C925FC.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "notificationArns": [], + "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": [ + "cdkdynamodbcustomizedroleintegDefaultTestDeployAssertD6C925FC.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": [ + "cdkdynamodbcustomizedroleintegDefaultTestDeployAssertD6C925FC.assets" + ], + "metadata": { + "/cdk-dynamodb-customized-role-integ/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/cdk-dynamodb-customized-role-integ/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "cdk-dynamodb-customized-role-integ/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-dynamodb/test/integ.table-with-customized-role.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/tree.json new file mode 100644 index 0000000000000..8cb209f416f3b --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.js.snapshot/tree.json @@ -0,0 +1,319 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "cdk-table-with-customized-role": { + "id": "cdk-table-with-customized-role", + "path": "cdk-table-with-customized-role", + "children": { + "Table": { + "id": "Table", + "path": "cdk-table-with-customized-role/Table", + "children": { + "Resource": { + "id": "Resource", + "path": "cdk-table-with-customized-role/Table/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::DynamoDB::Table", + "aws:cdk:cloudformation:props": { + "attributeDefinitions": [ + { + "attributeName": "pk", + "attributeType": "S" + }, + { + "attributeName": "gsi-pk", + "attributeType": "S" + } + ], + "globalSecondaryIndexes": [ + { + "indexName": "gsi", + "keySchema": [ + { + "attributeName": "gsi-pk", + "keyType": "HASH" + } + ], + "projection": { + "projectionType": "ALL" + }, + "provisionedThroughput": { + "readCapacityUnits": 5, + "writeCapacityUnits": 5 + } + } + ], + "keySchema": [ + { + "attributeName": "pk", + "keyType": "HASH" + } + ], + "provisionedThroughput": { + "readCapacityUnits": 5, + "writeCapacityUnits": 5 + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_dynamodb.CfnTable", + "version": "0.0.0" + } + }, + "ImportScalingRole": { + "id": "ImportScalingRole", + "path": "cdk-table-with-customized-role/Table/ImportScalingRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "ScalingRole": { + "id": "ScalingRole", + "path": "cdk-table-with-customized-role/Table/ScalingRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_dynamodb.Table", + "version": "0.0.0" + } + }, + "Role": { + "id": "Role", + "path": "cdk-table-with-customized-role/Role", + "children": { + "ImportRole": { + "id": "ImportRole", + "path": "cdk-table-with-customized-role/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "PrecreatedRoleRole": { + "id": "PrecreatedRoleRole", + "path": "cdk-table-with-customized-role/Role/PrecreatedRoleRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "cdk-table-with-customized-role/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "cdk-table-with-customized-role/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "PolicySynthesizer": { + "id": "PolicySynthesizer", + "path": "PolicySynthesizer", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "cdk-table-with-customized-role2": { + "id": "cdk-table-with-customized-role2", + "path": "cdk-table-with-customized-role2", + "children": { + "Table": { + "id": "Table", + "path": "cdk-table-with-customized-role2/Table", + "children": { + "Resource": { + "id": "Resource", + "path": "cdk-table-with-customized-role2/Table/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::DynamoDB::Table", + "aws:cdk:cloudformation:props": { + "attributeDefinitions": [ + { + "attributeName": "pk", + "attributeType": "S" + } + ], + "keySchema": [ + { + "attributeName": "pk", + "keyType": "HASH" + } + ], + "provisionedThroughput": { + "readCapacityUnits": 5, + "writeCapacityUnits": 5 + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_dynamodb.CfnTable", + "version": "0.0.0" + } + }, + "ImportScalingRole": { + "id": "ImportScalingRole", + "path": "cdk-table-with-customized-role2/Table/ImportScalingRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "ScalingRole": { + "id": "ScalingRole", + "path": "cdk-table-with-customized-role2/Table/ScalingRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_dynamodb.Table", + "version": "0.0.0" + } + }, + "Role": { + "id": "Role", + "path": "cdk-table-with-customized-role2/Role", + "children": { + "ImportRole": { + "id": "ImportRole", + "path": "cdk-table-with-customized-role2/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "PrecreatedRoleRole": { + "id": "PrecreatedRoleRole", + "path": "cdk-table-with-customized-role2/Role/PrecreatedRoleRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "cdk-table-with-customized-role2/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "cdk-table-with-customized-role2/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "cdk-dynamodb-customized-role-integ": { + "id": "cdk-dynamodb-customized-role-integ", + "path": "cdk-dynamodb-customized-role-integ", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "cdk-dynamodb-customized-role-integ/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "cdk-dynamodb-customized-role-integ/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "cdk-dynamodb-customized-role-integ/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "cdk-dynamodb-customized-role-integ/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "cdk-dynamodb-customized-role-integ/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-dynamodb/test/integ.table-with-customized-role.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.ts new file mode 100644 index 0000000000000..f57a789aac8af --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.table-with-customized-role.ts @@ -0,0 +1,70 @@ +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import { App, Stack, StackProps } from 'aws-cdk-lib'; +import { AttributeType, Table } from 'aws-cdk-lib/aws-dynamodb'; +import { Construct } from 'constructs'; +import { Role, ServicePrincipal } from 'aws-cdk-lib/aws-iam'; + +class TestStack extends Stack { + public constructor(scope: Construct, id: string, props: StackProps) { + super(scope, id, props); + + Role.customizeRoles(this, { + usePrecreatedRoles: { + 'cdk-table-with-customized-role/Role': 'my-precreated-role-name', + }, + }); + + const table = new Table(this, 'Table', { + partitionKey: { + name: 'pk', + type: AttributeType.STRING, + }, + }); + + // Add GSI will add a new Resource under IAM Policy + // i.e. `${this.tableArn}/index/*`. Test the Policy + // Synthesizer generation with concatenated value. + table.addGlobalSecondaryIndex({ + indexName: 'gsi', + partitionKey: { + name: 'gsi-pk', + type: AttributeType.STRING, + }, + }); + const role = new Role(this, 'Role', { + assumedBy: new ServicePrincipal('dynamodb.amazonaws.com'), + }); + table.grantReadData(role); + } +} + +class TestStack2 extends Stack { + public constructor(scope: Construct, id: string, props: StackProps) { + super(scope, id, props); + + Role.customizeRoles(this, { + usePrecreatedRoles: { + 'cdk-table-with-customized-role2/Role': 'my-precreated-role-name', + }, + }); + + const table = new Table(this, 'Table', { + partitionKey: { + name: 'pk', + type: AttributeType.STRING, + }, + }); + const role = new Role(this, 'Role', { + assumedBy: new ServicePrincipal('dynamodb.amazonaws.com'), + }); + table.grantReadData(role); + } +} + +const app = new App(); +const stack = new TestStack(app, 'cdk-table-with-customized-role', {}); +const stack2 = new TestStack2(app, 'cdk-table-with-customized-role2', {}); +new IntegTest(app, 'cdk-dynamodb-customized-role-integ', { + testCases: [stack, stack2], + diffAssets: true, +}); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/cdk.out new file mode 100644 index 0000000000000..c6e612584e352 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"38.0.1"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/iam-policy-report.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/iam-policy-report.json new file mode 100644 index 0000000000000..5158764076512 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/iam-policy-report.json @@ -0,0 +1,33 @@ +{ + "roles": [ + { + "roleConstructPath": "integ-customize-role/TestRole", + "roleName": "my-precreated-role", + "missing": false, + "assumeRolePolicy": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "sqs.amazonaws.com" + } + } + ], + "managedPolicyArns": [], + "managedPolicyStatements": [], + "identityPolicyStatements": [ + { + "Action": "sqs:SendMessage", + "Effect": "Allow", + "Resource": [ + "arn:aws:s3:::abc/xyz/123.txt", + "(NOVALUE)", + "arn:(PARTITION):iam:(REGION):(ACCOUNT)/role/FakeRole'", + "(integ-customize-role/MyGroup/Resource.Arn)/*", + "(integ-customize-role/MyGroup/Resource.Arn)" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/iam-policy-report.txt b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/iam-policy-report.txt new file mode 100644 index 0000000000000..411574c3f4a84 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/iam-policy-report.txt @@ -0,0 +1,33 @@ + (integ-customize-role/TestRole) + +AssumeRole Policy: +[ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "sqs.amazonaws.com" + } + } +] + +Managed Policy ARNs: +NONE + +Managed Policies Statements: +NONE + +Identity Policy Statements: +[ + { + "Action": "sqs:SendMessage", + "Effect": "Allow", + "Resource": [ + "arn:aws:s3:::abc/xyz/123.txt", + "(NOVALUE)", + "arn:(PARTITION):iam:(REGION):(ACCOUNT)/role/FakeRole'", + "(integ-customize-role/MyGroup/Resource.Arn)/*", + "(integ-customize-role/MyGroup/Resource.Arn)" + ] + } +] \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/integ-customize-role.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/integ-customize-role.assets.json new file mode 100644 index 0000000000000..ced77f405ca79 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/integ-customize-role.assets.json @@ -0,0 +1,19 @@ +{ + "version": "38.0.1", + "files": { + "99b010bd74243a5c7fc3fe4f0861127e62239193f1706349d5e1cc8bede9b752": { + "source": { + "path": "integ-customize-role.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "99b010bd74243a5c7fc3fe4f0861127e62239193f1706349d5e1cc8bede9b752.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-iam/test/integ.customize-role.js.snapshot/integ-customize-role.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/integ-customize-role.template.json new file mode 100644 index 0000000000000..19256abf8289c --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/integ-customize-role.template.json @@ -0,0 +1,41 @@ +{ + "Resources": { + "MyGroupCBA54B1B": { + "Type": "AWS::IAM::Group" + } + }, + "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-iam/test/integ.customize-role.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/integ.json new file mode 100644 index 0000000000000..9268abe090edd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "38.0.1", + "testCases": { + "integ-iam-customize-role/DefaultTest": { + "stacks": [ + "integ-customize-role" + ], + "assertionStack": "integ-iam-customize-role/DefaultTest/DeployAssert", + "assertionStackName": "integiamcustomizeroleDefaultTestDeployAssert811D838D" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/integiamcustomizeroleDefaultTestDeployAssert811D838D.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/integiamcustomizeroleDefaultTestDeployAssert811D838D.assets.json new file mode 100644 index 0000000000000..f200334e177fb --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/integiamcustomizeroleDefaultTestDeployAssert811D838D.assets.json @@ -0,0 +1,19 @@ +{ + "version": "38.0.1", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "integiamcustomizeroleDefaultTestDeployAssert811D838D.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-iam/test/integ.customize-role.js.snapshot/integiamcustomizeroleDefaultTestDeployAssert811D838D.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/integiamcustomizeroleDefaultTestDeployAssert811D838D.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/integiamcustomizeroleDefaultTestDeployAssert811D838D.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-iam/test/integ.customize-role.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/manifest.json new file mode 100644 index 0000000000000..c68843a263202 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/manifest.json @@ -0,0 +1,115 @@ +{ + "version": "38.0.1", + "artifacts": { + "integ-customize-role.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "integ-customize-role.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "integ-customize-role": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "integ-customize-role.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "notificationArns": [], + "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}/99b010bd74243a5c7fc3fe4f0861127e62239193f1706349d5e1cc8bede9b752.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "integ-customize-role.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": [ + "integ-customize-role.assets" + ], + "metadata": { + "/integ-customize-role/MyGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyGroupCBA54B1B" + } + ], + "/integ-customize-role/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/integ-customize-role/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "integ-customize-role" + }, + "integiamcustomizeroleDefaultTestDeployAssert811D838D.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "integiamcustomizeroleDefaultTestDeployAssert811D838D.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "integiamcustomizeroleDefaultTestDeployAssert811D838D": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "integiamcustomizeroleDefaultTestDeployAssert811D838D.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "notificationArns": [], + "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": [ + "integiamcustomizeroleDefaultTestDeployAssert811D838D.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": [ + "integiamcustomizeroleDefaultTestDeployAssert811D838D.assets" + ], + "metadata": { + "/integ-iam-customize-role/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/integ-iam-customize-role/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "integ-iam-customize-role/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-iam/test/integ.customize-role.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/tree.json new file mode 100644 index 0000000000000..8ea986612ca8b --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.js.snapshot/tree.json @@ -0,0 +1,157 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "integ-customize-role": { + "id": "integ-customize-role", + "path": "integ-customize-role", + "children": { + "MyGroup": { + "id": "MyGroup", + "path": "integ-customize-role/MyGroup", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-customize-role/MyGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Group", + "aws:cdk:cloudformation:props": {} + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnGroup", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Group", + "version": "0.0.0" + } + }, + "TestRole": { + "id": "TestRole", + "path": "integ-customize-role/TestRole", + "children": { + "ImportTestRole": { + "id": "ImportTestRole", + "path": "integ-customize-role/TestRole/ImportTestRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "PrecreatedRoleTestRole": { + "id": "PrecreatedRoleTestRole", + "path": "integ-customize-role/TestRole/PrecreatedRoleTestRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "integ-customize-role/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "integ-customize-role/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "PolicySynthesizer": { + "id": "PolicySynthesizer", + "path": "PolicySynthesizer", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "integ-iam-customize-role": { + "id": "integ-iam-customize-role", + "path": "integ-iam-customize-role", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "integ-iam-customize-role/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "integ-iam-customize-role/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "integ-iam-customize-role/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "integ-iam-customize-role/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "integ-iam-customize-role/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-iam/test/integ.customize-role.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.ts new file mode 100644 index 0000000000000..13f36822fdb6f --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.customize-role.ts @@ -0,0 +1,36 @@ +import { App, Fn, Stack } from 'aws-cdk-lib'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import { Group, PolicyStatement, Role, ServicePrincipal } from 'aws-cdk-lib/aws-iam'; + +const app = new App(); + +const stack = new Stack(app, 'integ-customize-role'); + +Role.customizeRoles(stack, { + usePrecreatedRoles: { + 'integ-customize-role/TestRole': 'my-precreated-role', + }, +}); + +const group = new Group(stack, 'MyGroup'); + +const role = new Role(stack, 'TestRole', { + assumedBy: new ServicePrincipal('sqs.amazonaws.com'), +}); + +role.addToPolicy(new PolicyStatement({ + resources: [ + 'arn:aws:s3:::abc/xyz/123.txt', + Fn.ref('AWS::NoValue'), + `arn:${Fn.ref('AWS::Partition')}:iam:${Fn.ref('AWS::Region')}:${Fn.ref('AWS::AccountId')}/role/FakeRole'`, + `${group.groupArn}/*`, + group.groupArn, + ], + actions: ['sqs:SendMessage'], +})); + +new IntegTest(app, 'integ-iam-customize-role', { + testCases: [stack], +}); + +app.synth(); diff --git a/packages/aws-cdk-lib/aws-iam/README.md b/packages/aws-cdk-lib/aws-iam/README.md index 8d4ad61d3243b..686c0b443172f 100644 --- a/packages/aws-cdk-lib/aws-iam/README.md +++ b/packages/aws-cdk-lib/aws-iam/README.md @@ -238,6 +238,72 @@ iam.Role.customizeRoles(this, { For more information on configuring permissions see the [Security And Safety Dev Guide](https://github.com/aws/aws-cdk/wiki/Security-And-Safety-Dev-Guide) +#### Policy report generation + +When `customizeRoles` is used, the `iam-policy-report.txt` report will contain a list +of IAM roles and associated permissions that would have been created. This report is +generated in an attempt to resolve and replace any references with a more user-friendly +value. + +The following are some examples of the value that will appear in the report: + +```json +"Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":role/Role" + ] + ] +} +``` + +The policy report will instead get: + +```json +"Resource": "arn:(PARTITION):iam::(ACCOUNT):role/Role" +``` + +If IAM policy is referencing a resource attribute: + +```json +"Resource": [ + { + "Fn::GetAtt": [ + "SomeResource", + "Arn" + ] + }, + { + "Ref": "AWS::NoValue", + } +] +``` + +The policy report will instead get: + +```json +"Resource": [ + "(Path/To/SomeResource.Arn)" + "(NOVALUE)" +] +``` + +The following pseudo parameters will be converted: + +1. `{ 'Ref': 'AWS::AccountId' }` -> `(ACCOUNT) +2. `{ 'Ref': 'AWS::Partition' }` -> `(PARTITION) +3. `{ 'Ref': 'AWS::Region' }` -> `(REGION) +4. `{ 'Ref': 'AWS::NoValue' }` -> `(NOVALUE) + #### Generating a permissions report It is also possible to generate the report _without_ preventing the role/policy creation. diff --git a/packages/aws-cdk-lib/core/lib/helpers-internal/customize-roles.ts b/packages/aws-cdk-lib/core/lib/helpers-internal/customize-roles.ts index 67d81b5d85727..c456cfb2665db 100644 --- a/packages/aws-cdk-lib/core/lib/helpers-internal/customize-roles.ts +++ b/packages/aws-cdk-lib/core/lib/helpers-internal/customize-roles.ts @@ -4,7 +4,7 @@ import { Construct } from 'constructs'; import { Annotations } from '../annotations'; import { attachCustomSynthesis } from '../app'; import { Reference } from '../reference'; -import { IResolvable, DefaultTokenResolver, StringConcat } from '../resolvable'; +import { IResolvable, StringConcat, DefaultTokenResolver, IFragmentConcatenator } from '../resolvable'; import { ISynthesisSession } from '../stack-synthesizers'; import { Token, Tokenization } from '../token'; @@ -122,6 +122,48 @@ interface PolicyReportRole { readonly identityPolicyStatements?: string[]; } +/** + * PolicySynthesizer token resolver implementation + * + */ +export class PolicySynthesizerTokenResolver extends DefaultTokenResolver { + constructor(concat: IFragmentConcatenator) { + super(concat); + } + + /** + * PolicySynthesizer Token resolution + * + * Resolve the Token until the token can be resolved into + * "(Path/To/SomeResource.Arn)" format. Otherwise, recurse + * into whatever it returns, + */ + public resolveToken(t: IResolvable, context: any, postProcessor: any) { + try { + let resolved = t.resolve(context); + + // If the token value is resolvable into the format "(Path/To/SomeResource.Arn)", return it + // as this is the format expected by the Policy Synthesizer. + const resolvable = Tokenization.reverseString(resolved); + if (resolvable.length === 1 && Reference.isReference(resolvable.firstToken)) { + return `(${resolvable.firstToken.target.node.path}.${resolvable.firstToken.displayName})`; + } + // The token might have returned more values that need resolving, recurse + resolved = context.resolve(resolved); + resolved = postProcessor.postProcess(resolved, context); + return resolved; + } catch (e: any) { + let message = `Resolution error: ${e.message}.`; + if (t.creationStack && t.creationStack.length > 0) { + message += `\nObject creation stack:\n at ${t.creationStack.join('\n at ')}`; + } + + e.message = message; + throw e; + } + } +} + /** * A construct that is responsible for generating an IAM policy Report * for all IAM roles that are created as part of the CDK application. @@ -139,14 +181,17 @@ export class PolicySynthesizer extends Construct { if (synthesizer) { return synthesizer as PolicySynthesizer; } - return new PolicySynthesizer(scope.node.root); + return new PolicySynthesizer(scope); } + private readonly _scope: Construct; private readonly roleReport: { [rolePath: string]: RoleReportOptions } = {}; private readonly managedPolicyReport: { [policyPath: string]: ManagedPolicyReportOptions } = {}; constructor(scope: Construct) { - super(scope, POLICY_SYNTHESIZER_ID); + // PolicySynthesizer should be created under the `App` scope + super(scope.node.root, POLICY_SYNTHESIZER_ID); + this._scope = scope; attachCustomSynthesis(this, { onSynthesize: (session: ISynthesisSession) => { const report = this.createJsonReport(); @@ -195,7 +240,7 @@ export class PolicySynthesizer extends Construct { '', 'Identity Policy Statements:', this.toJsonString(role.identityPolicyStatements), - ].join('\n')).join(''); + ].join('\n')).join('\n\n'); } /** @@ -316,9 +361,11 @@ export class PolicySynthesizer extends Construct { if (Reference.isReference(r)) { return `(${r.target.node.path}.${r.displayName})`; } + // Token resolution requires a stack scope. We can't directly use 'this' scope + // because PolicySynthesizer is always created under 'App' scope. const resolved = Tokenization.resolve(r, { - scope: this, - resolver: new DefaultTokenResolver(new StringConcat()), + scope: this._scope, + resolver: new PolicySynthesizerTokenResolver(new StringConcat()), }); if (typeof resolved === 'object' && resolved.hasOwnProperty('Ref')) { switch (resolved.Ref) { @@ -328,10 +375,18 @@ export class PolicySynthesizer extends Construct { return '(PARTITION)'; case 'AWS::Region': return '(REGION)'; + case 'AWS::NoValue': + return '(NOVALUE)'; default: return r; } } + // If the original value is an unresolved Token and we have successfully + // resolve it through the above Token resolution process, we should + // return the resolved token instead. + if (Token.isUnresolved(r) && typeof resolved === 'string' && resolved) { + return resolved; + } return r; }, });