diff --git a/packages/@aws-cdk/aws-redshift/README.md b/packages/@aws-cdk/aws-redshift/README.md index 9ed449b063c4f..fcd48b57af0a6 100644 --- a/packages/@aws-cdk/aws-redshift/README.md +++ b/packages/@aws-cdk/aws-redshift/README.md @@ -454,3 +454,39 @@ const redshiftCluster = new Cluster(stack, 'Redshift', { redshiftCluster.addDefaultIamRole(defaultRole); ``` + +## IAM roles + +Attaching IAM roles to a Redshift Cluster grants permissions to the Redshift service to perform actions on your behalf. + +```ts +declare const vpc: ec2.Vpc + +const role = new iam.Role(this, 'Role', { + assumedBy: new iam.ServicePrincipal('redshift.amazonaws.com'), +}); +const cluster = new Cluster(this, 'Redshift', { + masterUser: { + masterUsername: 'admin', + }, + vpc, + roles: [role], +}); +``` + +Additional IAM roles can be attached to a cluster using the `addIamRole` method. + +```ts +declare const vpc: ec2.Vpc + +const role = new iam.Role(this, 'Role', { + assumedBy: new iam.ServicePrincipal('redshift.amazonaws.com'), +}); +const cluster = new Cluster(this, 'Redshift', { + masterUser: { + masterUsername: 'admin', + }, + vpc, +}); +cluster.addIamRole(role); +``` diff --git a/packages/@aws-cdk/aws-redshift/lib/cluster.ts b/packages/@aws-cdk/aws-redshift/lib/cluster.ts index b0ab7c19e729f..50e3e5e1265a7 100644 --- a/packages/@aws-cdk/aws-redshift/lib/cluster.ts +++ b/packages/@aws-cdk/aws-redshift/lib/cluster.ts @@ -3,8 +3,8 @@ import * as iam from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; import * as s3 from '@aws-cdk/aws-s3'; import * as secretsmanager from '@aws-cdk/aws-secretsmanager'; -import { Duration, IResource, RemovalPolicy, Resource, SecretValue, Token } from '@aws-cdk/core'; -import { AwsCustomResource, PhysicalResourceId, AwsCustomResourcePolicy } from '@aws-cdk/custom-resources'; +import { Duration, IResource, Lazy, RemovalPolicy, Resource, SecretValue, Token } from '@aws-cdk/core'; +import { AwsCustomResource, AwsCustomResourcePolicy, PhysicalResourceId } from '@aws-cdk/custom-resources'; import { Construct } from 'constructs'; import { DatabaseSecret } from './database-secret'; import { Endpoint } from './endpoint'; @@ -299,7 +299,7 @@ export interface ClusterProps { /** * A list of AWS Identity and Access Management (IAM) role that can be used by the cluster to access other AWS services. - * Specify a maximum of 10 roles. + * The maximum number of roles to attach to a cluster is subject to a quota. * * @default - No role is attached to the cluster. */ @@ -470,6 +470,13 @@ export class Cluster extends ClusterBase { */ protected parameterGroup?: IClusterParameterGroup; + /** + * The ARNs of the roles that will be attached to the cluster. + * + * **NOTE** Please do not access this directly, use the `addIamRole` method instead. + */ + private readonly roles: iam.IRole[]; + constructor(scope: Construct, id: string, props: ClusterProps) { super(scope, id); @@ -478,6 +485,7 @@ export class Cluster extends ClusterBase { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS, }; this.parameterGroup = props.parameterGroup; + this.roles = props?.roles ? [...props.roles] : []; const removalPolicy = props.removalPolicy ?? RemovalPolicy.RETAIN; @@ -557,7 +565,7 @@ export class Cluster extends ClusterBase { nodeType: props.nodeType || NodeType.DC2_LARGE, numberOfNodes: nodeCount, loggingProperties, - iamRoles: props?.roles?.map(role => role.roleArn), + iamRoles: Lazy.list({ produce: () => this.roles.map(role => role.roleArn) }, { omitEmpty: true }), dbName: props.defaultDatabaseName || 'default_db', publiclyAccessible: props.publiclyAccessible || false, // Encryption @@ -688,12 +696,12 @@ export class Cluster extends ClusterBase { */ public addDefaultIamRole(defaultIamRole: iam.IRole): void { // Get list of IAM roles attached to cluster - const clusterRoleList = this.cluster.iamRoles ?? []; + const clusterRoleList = this.roles ?? []; // Check to see if default role is included in list of cluster IAM roles var roleAlreadyOnCluster = false; for (var i = 0; i < clusterRoleList.length; i++) { - if (clusterRoleList[i] == defaultIamRole.roleArn) { + if (clusterRoleList[i] === defaultIamRole) { roleAlreadyOnCluster = true; break; } @@ -729,8 +737,24 @@ export class Cluster extends ClusterBase { policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE, }), + installLatestAwsSdk: false, }); defaultIamRole.grantPassRole(defaultRoleCustomResource.grantPrincipal); } + + /** + * Adds a role to the cluster + * + * @param role the role to add + */ + public addIamRole(role: iam.IRole): void { + const clusterRoleList = this.roles; + + if (clusterRoleList.includes(role)) { + throw new Error(`Role '${role.roleArn}' is already attached to the cluster`); + } + + clusterRoleList.push(role); + } } diff --git a/packages/@aws-cdk/aws-redshift/lib/private/database-query-provider/privileges.ts b/packages/@aws-cdk/aws-redshift/lib/private/database-query-provider/privileges.ts index d95a9f9d97395..f1533bb9cb326 100644 --- a/packages/@aws-cdk/aws-redshift/lib/private/database-query-provider/privileges.ts +++ b/packages/@aws-cdk/aws-redshift/lib/private/database-query-provider/privileges.ts @@ -1,9 +1,9 @@ /* eslint-disable-next-line import/no-unresolved */ import * as AWSLambda from 'aws-lambda'; -import { TablePrivilege, UserTablePrivilegesHandlerProps } from '../handler-props'; import { executeStatement } from './redshift-data'; import { ClusterProps } from './types'; import { makePhysicalId } from './util'; +import { TablePrivilege, UserTablePrivilegesHandlerProps } from '../handler-props'; export async function handler(props: UserTablePrivilegesHandlerProps & ClusterProps, event: AWSLambda.CloudFormationCustomResourceEvent) { const username = props.username; diff --git a/packages/@aws-cdk/aws-redshift/lib/private/database-query-provider/table.ts b/packages/@aws-cdk/aws-redshift/lib/private/database-query-provider/table.ts index 4a11f2a61d706..15b206c12c654 100644 --- a/packages/@aws-cdk/aws-redshift/lib/private/database-query-provider/table.ts +++ b/packages/@aws-cdk/aws-redshift/lib/private/database-query-provider/table.ts @@ -1,9 +1,9 @@ /* eslint-disable-next-line import/no-unresolved */ import * as AWSLambda from 'aws-lambda'; -import { Column } from '../../table'; import { executeStatement } from './redshift-data'; import { ClusterProps, TableAndClusterProps, TableSortStyle } from './types'; import { areColumnsEqual, getDistKeyColumn, getSortKeyColumns } from './util'; +import { Column } from '../../table'; export async function handler(props: TableAndClusterProps, event: AWSLambda.CloudFormationCustomResourceEvent) { const tableNamePrefix = props.tableName.prefix; diff --git a/packages/@aws-cdk/aws-redshift/lib/private/database-query-provider/user.ts b/packages/@aws-cdk/aws-redshift/lib/private/database-query-provider/user.ts index ae19440230ae9..50e79800980d7 100644 --- a/packages/@aws-cdk/aws-redshift/lib/private/database-query-provider/user.ts +++ b/packages/@aws-cdk/aws-redshift/lib/private/database-query-provider/user.ts @@ -2,10 +2,10 @@ import * as AWSLambda from 'aws-lambda'; /* eslint-disable-next-line import/no-extraneous-dependencies */ import * as SecretsManager from 'aws-sdk/clients/secretsmanager'; -import { UserHandlerProps } from '../handler-props'; import { executeStatement } from './redshift-data'; import { ClusterProps } from './types'; import { makePhysicalId } from './util'; +import { UserHandlerProps } from '../handler-props'; const secretsManager = new SecretsManager(); diff --git a/packages/@aws-cdk/aws-redshift/lib/private/database-query-provider/util.ts b/packages/@aws-cdk/aws-redshift/lib/private/database-query-provider/util.ts index c6fe3709bd136..872ce9df500bf 100644 --- a/packages/@aws-cdk/aws-redshift/lib/private/database-query-provider/util.ts +++ b/packages/@aws-cdk/aws-redshift/lib/private/database-query-provider/util.ts @@ -1,5 +1,5 @@ -import { Column } from '../../table'; import { ClusterProps } from './types'; +import { Column } from '../../table'; export function makePhysicalId(resourceName: string, clusterProps: ClusterProps, requestId: string): string { return `${clusterProps.clusterName}:${clusterProps.databaseName}:${resourceName}:${requestId}`; diff --git a/packages/@aws-cdk/aws-redshift/lib/private/database-query.ts b/packages/@aws-cdk/aws-redshift/lib/private/database-query.ts index d87c72ffdcf8f..8e2f793724d8a 100644 --- a/packages/@aws-cdk/aws-redshift/lib/private/database-query.ts +++ b/packages/@aws-cdk/aws-redshift/lib/private/database-query.ts @@ -5,9 +5,9 @@ import * as secretsmanager from '@aws-cdk/aws-secretsmanager'; import * as cdk from '@aws-cdk/core'; import * as customresources from '@aws-cdk/custom-resources'; import { Construct } from 'constructs'; +import { DatabaseQueryHandlerProps } from './handler-props'; import { Cluster } from '../cluster'; import { DatabaseOptions } from '../database-options'; -import { DatabaseQueryHandlerProps } from './handler-props'; export interface DatabaseQueryProps extends DatabaseOptions { readonly handler: string; diff --git a/packages/@aws-cdk/aws-redshift/lib/private/privileges.ts b/packages/@aws-cdk/aws-redshift/lib/private/privileges.ts index 01b2d5f34ae0d..b9975d7fdec7c 100644 --- a/packages/@aws-cdk/aws-redshift/lib/private/privileges.ts +++ b/packages/@aws-cdk/aws-redshift/lib/private/privileges.ts @@ -1,11 +1,11 @@ import * as cdk from '@aws-cdk/core'; import { Construct } from 'constructs'; -import { DatabaseOptions } from '../database-options'; -import { ITable, TableAction } from '../table'; -import { IUser } from '../user'; import { DatabaseQuery } from './database-query'; import { HandlerName } from './database-query-provider/handler-name'; import { TablePrivilege as SerializedTablePrivilege, UserTablePrivilegesHandlerProps } from './handler-props'; +import { DatabaseOptions } from '../database-options'; +import { ITable, TableAction } from '../table'; +import { IUser } from '../user'; /** * The Redshift table and action that make up a privilege that can be granted to a Redshift user. diff --git a/packages/@aws-cdk/aws-redshift/test/cluster.test.ts b/packages/@aws-cdk/aws-redshift/test/cluster.test.ts index 11d005d6ae2ca..b05188bc300d9 100644 --- a/packages/@aws-cdk/aws-redshift/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-redshift/test/cluster.test.ts @@ -648,6 +648,103 @@ describe('default IAM role', () => { }); }); +describe('IAM role', () => { + test('roles can be directly attached to cluster during declaration', () => { + // GIVEN + const role = new iam.Role(stack, 'Role', { + assumedBy: new iam.ServicePrincipal('redshift.amazonaws.com'), + }); + new Cluster(stack, 'Redshift', { + masterUser: { + masterUsername: 'admin', + }, + vpc, + roles: [role], + }); + + // THEN + Template.fromStack(stack).hasResource('AWS::Redshift::Cluster', { + Properties: { + IamRoles: Match.arrayEquals([ + { 'Fn::GetAtt': [Match.stringLikeRegexp('Role*'), 'Arn'] }, + ]), + }, + }); + }); + + test('roles can be attached to cluster after declaration', () => { + // GIVEN + const role = new iam.Role(stack, 'Role', { + assumedBy: new iam.ServicePrincipal('redshift.amazonaws.com'), + }); + const cluster = new Cluster(stack, 'Redshift', { + masterUser: { + masterUsername: 'admin', + }, + vpc, + }); + + // WHEN + cluster.addIamRole(role); + + // THEN + Template.fromStack(stack).hasResource('AWS::Redshift::Cluster', { + Properties: { + IamRoles: Match.arrayEquals([ + { 'Fn::GetAtt': [Match.stringLikeRegexp('Role*'), 'Arn'] }, + ]), + }, + }); + }); + + test('roles can be attached to cluster in another stack', () => { + // GIVEN + const cluster = new Cluster(stack, 'Redshift', { + masterUser: { + masterUsername: 'admin', + }, + vpc, + }); + + const newTestStack = new cdk.Stack(stack, 'NewTestStack', { env: { account: stack.account, region: stack.region } }); + const role = new iam.Role(newTestStack, 'Role', { + assumedBy: new iam.ServicePrincipal('redshift.amazonaws.com'), + }); + + // WHEN + cluster.addIamRole(role); + + // THEN + Template.fromStack(stack).hasResource('AWS::Redshift::Cluster', { + Properties: { + IamRoles: Match.arrayEquals([ + { 'Fn::ImportValue': Match.stringLikeRegexp('NewTestStack:ExportsOutputFnGetAttRole*') }, + ]), + }, + }); + }); + + test('throws when adding role that is already in cluster', () => { + // GIVEN + const role = new iam.Role(stack, 'Role', { + assumedBy: new iam.ServicePrincipal('redshift.amazonaws.com'), + }); + const cluster = new Cluster(stack, 'Redshift', { + masterUser: { + masterUsername: 'admin', + }, + vpc, + roles: [role], + }); + + expect(() => + // WHEN + cluster.addIamRole(role), + // THEN + ).toThrow(`Role '${role.roleArn}' is already attached to the cluster`); + }); +}); + function testStack() { const newTestStack = new cdk.Stack(undefined, undefined, { env: { account: '12345', region: 'us-test-1' } }); newTestStack.node.setContext('availability-zones:12345:us-test-1', ['us-test-1a', 'us-test-1b']); diff --git a/packages/@aws-cdk/aws-redshift/test/integ.cluster-defaultiamrole.js.snapshot/manifest.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-defaultiamrole.js.snapshot/manifest.json index 572dd5a8f51eb..8591dc9c53c77 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.cluster-defaultiamrole.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-defaultiamrole.js.snapshot/manifest.json @@ -17,7 +17,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/fa991089a30fe26fab8225c5ca4145a65cd9c6f1c7ebebae477f130972053ca5.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/2a0f381c4c3f8c34bfd6f8afdccd71f2d437e9a354e3383b625429e833e7a53f.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -207,12 +207,6 @@ "data": "Cluster192CD0375" } ], - "/redshift-defaultiamrole-integ/Cluster1/default-role": [ - { - "type": "aws:cdk:warning", - "data": "installLatestAwsSdk was not specified, and defaults to true. You probably do not want this. Set the global context flag '@aws-cdk/customresources:installLatestAwsSdkDefault' to false to switch this behavior off project-wide, or set the property explicitly to true if you know you need to call APIs that are not in Lambda's built-in SDK version." - } - ], "/redshift-defaultiamrole-integ/Cluster1/default-role/Resource/Default": [ { "type": "aws:cdk:logicalId", @@ -273,12 +267,6 @@ "data": "Cluster2720FF351" } ], - "/redshift-defaultiamrole-integ/Cluster2/default-role": [ - { - "type": "aws:cdk:warning", - "data": "installLatestAwsSdk was not specified, and defaults to true. You probably do not want this. Set the global context flag '@aws-cdk/customresources:installLatestAwsSdkDefault' to false to switch this behavior off project-wide, or set the property explicitly to true if you know you need to call APIs that are not in Lambda's built-in SDK version." - } - ], "/redshift-defaultiamrole-integ/Cluster2/default-role/Resource/Default": [ { "type": "aws:cdk:logicalId", diff --git a/packages/@aws-cdk/aws-redshift/test/integ.cluster-defaultiamrole.js.snapshot/redshift-defaultiamrole-integ.assets.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-defaultiamrole.js.snapshot/redshift-defaultiamrole-integ.assets.json index 0470e75b0fae0..37fe0c765ea75 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.cluster-defaultiamrole.js.snapshot/redshift-defaultiamrole-integ.assets.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-defaultiamrole.js.snapshot/redshift-defaultiamrole-integ.assets.json @@ -14,7 +14,7 @@ } } }, - "fa991089a30fe26fab8225c5ca4145a65cd9c6f1c7ebebae477f130972053ca5": { + "2a0f381c4c3f8c34bfd6f8afdccd71f2d437e9a354e3383b625429e833e7a53f": { "source": { "path": "redshift-defaultiamrole-integ.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "fa991089a30fe26fab8225c5ca4145a65cd9c6f1c7ebebae477f130972053ca5.json", + "objectKey": "2a0f381c4c3f8c34bfd6f8afdccd71f2d437e9a354e3383b625429e833e7a53f.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-redshift/test/integ.cluster-defaultiamrole.js.snapshot/redshift-defaultiamrole-integ.template.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-defaultiamrole.js.snapshot/redshift-defaultiamrole-integ.template.json index 12ab1f22a9a01..6f0e3413e69bc 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.cluster-defaultiamrole.js.snapshot/redshift-defaultiamrole-integ.template.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-defaultiamrole.js.snapshot/redshift-defaultiamrole-integ.template.json @@ -615,7 +615,7 @@ ] ] }, - "InstallLatestAwsSdk": "false" + "InstallLatestAwsSdk": false }, "DependsOn": [ "Cluster1defaultroleCustomResourcePolicy6ECBAB35" @@ -932,7 +932,7 @@ ] ] }, - "InstallLatestAwsSdk": "false" + "InstallLatestAwsSdk": false }, "DependsOn": [ "Cluster2defaultroleCustomResourcePolicy042F9AF5" diff --git a/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.js.snapshot/IamRoleIntegDefaultTestDeployAssertBEF20992.assets.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.js.snapshot/IamRoleIntegDefaultTestDeployAssertBEF20992.assets.json new file mode 100644 index 0000000000000..903f4ed2bae4c --- /dev/null +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.js.snapshot/IamRoleIntegDefaultTestDeployAssertBEF20992.assets.json @@ -0,0 +1,19 @@ +{ + "version": "29.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "IamRoleIntegDefaultTestDeployAssertBEF20992.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/aws-redshift/test/integ.cluster-iamrole.js.snapshot/IamRoleIntegDefaultTestDeployAssertBEF20992.template.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.js.snapshot/IamRoleIntegDefaultTestDeployAssertBEF20992.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.js.snapshot/IamRoleIntegDefaultTestDeployAssertBEF20992.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/aws-redshift/test/integ.cluster-iamrole.js.snapshot/cdk.out b/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.js.snapshot/cdk.out new file mode 100644 index 0000000000000..d8b441d447f8a --- /dev/null +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"29.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.js.snapshot/integ.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.js.snapshot/integ.json new file mode 100644 index 0000000000000..754546fb1b7e4 --- /dev/null +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "29.0.0", + "testCases": { + "IamRoleInteg/DefaultTest": { + "stacks": [ + "redshift-iamrole-integ" + ], + "assertionStack": "IamRoleInteg/DefaultTest/DeployAssert", + "assertionStackName": "IamRoleIntegDefaultTestDeployAssertBEF20992" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.js.snapshot/manifest.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.js.snapshot/manifest.json new file mode 100644 index 0000000000000..91316c878a02a --- /dev/null +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.js.snapshot/manifest.json @@ -0,0 +1,330 @@ +{ + "version": "29.0.0", + "artifacts": { + "redshift-iamrole-integ.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "redshift-iamrole-integ.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "redshift-iamrole-integ": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "redshift-iamrole-integ.template.json", + "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}/85e1ecadf2c1e47c7bf3425bf186e3d1e0b6fe7a4c4d5b8956acb337d4fd9c22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "redshift-iamrole-integ.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": [ + "redshift-iamrole-integ.assets" + ], + "metadata": { + "/redshift-iamrole-integ/VPC/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCB9E5F0B4" + } + ], + "/redshift-iamrole-integ/VPC/PublicSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1SubnetB4246D30" + } + ], + "/redshift-iamrole-integ/VPC/PublicSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1RouteTableFEE4B781" + } + ], + "/redshift-iamrole-integ/VPC/PublicSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1RouteTableAssociation0B0896DC" + } + ], + "/redshift-iamrole-integ/VPC/PublicSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1DefaultRoute91CEF279" + } + ], + "/redshift-iamrole-integ/VPC/PublicSubnet1/EIP": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1EIP6AD938E8" + } + ], + "/redshift-iamrole-integ/VPC/PublicSubnet1/NATGateway": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1NATGatewayE0556630" + } + ], + "/redshift-iamrole-integ/VPC/PublicSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2Subnet74179F39" + } + ], + "/redshift-iamrole-integ/VPC/PublicSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2RouteTable6F1A15F1" + } + ], + "/redshift-iamrole-integ/VPC/PublicSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2RouteTableAssociation5A808732" + } + ], + "/redshift-iamrole-integ/VPC/PublicSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2DefaultRouteB7481BBA" + } + ], + "/redshift-iamrole-integ/VPC/PublicSubnet2/EIP": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2EIP4947BC00" + } + ], + "/redshift-iamrole-integ/VPC/PublicSubnet2/NATGateway": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2NATGateway3C070193" + } + ], + "/redshift-iamrole-integ/VPC/PrivateSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1Subnet8BCA10E0" + } + ], + "/redshift-iamrole-integ/VPC/PrivateSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1RouteTableBE8A6027" + } + ], + "/redshift-iamrole-integ/VPC/PrivateSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1RouteTableAssociation347902D1" + } + ], + "/redshift-iamrole-integ/VPC/PrivateSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1DefaultRouteAE1D6490" + } + ], + "/redshift-iamrole-integ/VPC/PrivateSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ], + "/redshift-iamrole-integ/VPC/PrivateSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2RouteTable0A19E10E" + } + ], + "/redshift-iamrole-integ/VPC/PrivateSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2RouteTableAssociation0C73D413" + } + ], + "/redshift-iamrole-integ/VPC/PrivateSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2DefaultRouteF4F5CFD2" + } + ], + "/redshift-iamrole-integ/VPC/IGW": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCIGWB7E252D3" + } + ], + "/redshift-iamrole-integ/VPC/VPCGW": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCVPCGW99B986DC" + } + ], + "/redshift-iamrole-integ/RoleA/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "RoleA3119C8FE" + } + ], + "/redshift-iamrole-integ/RoleB/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "RoleB318292C8" + } + ], + "/redshift-iamrole-integ/Cluster/Subnets/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "ClusterSubnetsDCFA5CB7" + } + ], + "/redshift-iamrole-integ/Cluster/SecurityGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ClusterSecurityGroup0921994B" + } + ], + "/redshift-iamrole-integ/Cluster/Secret/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ClusterSecret6368BD0F" + } + ], + "/redshift-iamrole-integ/Cluster/Secret/Attachment/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ClusterSecretAttachment769E6258" + } + ], + "/redshift-iamrole-integ/Cluster/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ClusterEB0386A7" + } + ], + "/redshift-iamrole-integ/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/redshift-iamrole-integ/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ], + "ClusteraddroleRoleAA2FB3227": [ + { + "type": "aws:cdk:logicalId", + "data": "ClusteraddroleRoleAA2FB3227", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" + ] + } + ], + "ClusteraddroleRoleACustomResourcePolicyB2DE8E3F": [ + { + "type": "aws:cdk:logicalId", + "data": "ClusteraddroleRoleACustomResourcePolicyB2DE8E3F", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" + ] + } + ], + "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2": [ + { + "type": "aws:cdk:logicalId", + "data": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" + ] + } + ], + "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleDefaultPolicyD28E1A5E": [ + { + "type": "aws:cdk:logicalId", + "data": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleDefaultPolicyD28E1A5E", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" + ] + } + ], + "AWS679f53fac002430cb0da5b7982bd22872D164C4C": [ + { + "type": "aws:cdk:logicalId", + "data": "AWS679f53fac002430cb0da5b7982bd22872D164C4C", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" + ] + } + ] + }, + "displayName": "redshift-iamrole-integ" + }, + "IamRoleIntegDefaultTestDeployAssertBEF20992.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "IamRoleIntegDefaultTestDeployAssertBEF20992.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "IamRoleIntegDefaultTestDeployAssertBEF20992": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "IamRoleIntegDefaultTestDeployAssertBEF20992.template.json", + "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": [ + "IamRoleIntegDefaultTestDeployAssertBEF20992.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": [ + "IamRoleIntegDefaultTestDeployAssertBEF20992.assets" + ], + "metadata": { + "/IamRoleInteg/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/IamRoleInteg/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "IamRoleInteg/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.js.snapshot/redshift-iamrole-integ.assets.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.js.snapshot/redshift-iamrole-integ.assets.json new file mode 100644 index 0000000000000..fb7c5c6cd1f9f --- /dev/null +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.js.snapshot/redshift-iamrole-integ.assets.json @@ -0,0 +1,19 @@ +{ + "version": "29.0.0", + "files": { + "85e1ecadf2c1e47c7bf3425bf186e3d1e0b6fe7a4c4d5b8956acb337d4fd9c22": { + "source": { + "path": "redshift-iamrole-integ.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "85e1ecadf2c1e47c7bf3425bf186e3d1e0b6fe7a4c4d5b8956acb337d4fd9c22.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/aws-redshift/test/integ.cluster-iamrole.js.snapshot/redshift-iamrole-integ.template.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.js.snapshot/redshift-iamrole-integ.template.json new file mode 100644 index 0000000000000..e1d24bdabd1dc --- /dev/null +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.js.snapshot/redshift-iamrole-integ.template.json @@ -0,0 +1,584 @@ +{ + "Resources": { + "VPCB9E5F0B4": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "redshift-iamrole-integ/VPC" + } + ] + } + }, + "VPCPublicSubnet1SubnetB4246D30": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.0.0/18", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "redshift-iamrole-integ/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1RouteTableFEE4B781": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "redshift-iamrole-integ/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1RouteTableAssociation0B0896DC": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + } + } + }, + "VPCPublicSubnet1DefaultRoute91CEF279": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VPCIGWB7E252D3" + } + }, + "DependsOn": [ + "VPCVPCGW99B986DC" + ] + }, + "VPCPublicSubnet1EIP6AD938E8": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "redshift-iamrole-integ/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1NATGatewayE0556630": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet1EIP6AD938E8", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "redshift-iamrole-integ/VPC/PublicSubnet1" + } + ] + }, + "DependsOn": [ + "VPCPublicSubnet1DefaultRoute91CEF279", + "VPCPublicSubnet1RouteTableAssociation0B0896DC" + ] + }, + "VPCPublicSubnet2Subnet74179F39": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.64.0/18", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "redshift-iamrole-integ/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet2RouteTable6F1A15F1": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "redshift-iamrole-integ/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet2RouteTableAssociation5A808732": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + } + }, + "VPCPublicSubnet2DefaultRouteB7481BBA": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VPCIGWB7E252D3" + } + }, + "DependsOn": [ + "VPCVPCGW99B986DC" + ] + }, + "VPCPublicSubnet2EIP4947BC00": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "redshift-iamrole-integ/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet2NATGateway3C070193": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + }, + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet2EIP4947BC00", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "redshift-iamrole-integ/VPC/PublicSubnet2" + } + ] + }, + "DependsOn": [ + "VPCPublicSubnet2DefaultRouteB7481BBA", + "VPCPublicSubnet2RouteTableAssociation5A808732" + ] + }, + "VPCPrivateSubnet1Subnet8BCA10E0": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.128.0/18", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "redshift-iamrole-integ/VPC/PrivateSubnet1" + } + ] + } + }, + "VPCPrivateSubnet1RouteTableBE8A6027": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "redshift-iamrole-integ/VPC/PrivateSubnet1" + } + ] + } + }, + "VPCPrivateSubnet1RouteTableAssociation347902D1": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "SubnetId": { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + } + } + }, + "VPCPrivateSubnet1DefaultRouteAE1D6490": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VPCPublicSubnet1NATGatewayE0556630" + } + } + }, + "VPCPrivateSubnet2SubnetCFCDAA7A": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.192.0/18", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "redshift-iamrole-integ/VPC/PrivateSubnet2" + } + ] + } + }, + "VPCPrivateSubnet2RouteTable0A19E10E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "redshift-iamrole-integ/VPC/PrivateSubnet2" + } + ] + } + }, + "VPCPrivateSubnet2RouteTableAssociation0C73D413": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "SubnetId": { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + } + }, + "VPCPrivateSubnet2DefaultRouteF4F5CFD2": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VPCPublicSubnet2NATGateway3C070193" + } + } + }, + "VPCIGWB7E252D3": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "redshift-iamrole-integ/VPC" + } + ] + } + }, + "VPCVPCGW99B986DC": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "InternetGatewayId": { + "Ref": "VPCIGWB7E252D3" + } + } + }, + "RoleA3119C8FE": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "redshift.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "RoleB318292C8": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "redshift.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "ClusterSubnetsDCFA5CB7": { + "Type": "AWS::Redshift::ClusterSubnetGroup", + "Properties": { + "Description": "Subnets for Cluster Redshift cluster", + "SubnetIds": [ + { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "ClusterSecurityGroup0921994B": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "Redshift security group", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "ClusterSecret6368BD0F": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "GenerateSecretString": { + "ExcludeCharacters": "\"@/\\ '", + "GenerateStringKey": "password", + "PasswordLength": 30, + "SecretStringTemplate": "{\"username\":\"admin\"}" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "ClusterSecretAttachment769E6258": { + "Type": "AWS::SecretsManager::SecretTargetAttachment", + "Properties": { + "SecretId": { + "Ref": "ClusterSecret6368BD0F" + }, + "TargetId": { + "Ref": "ClusterEB0386A7" + }, + "TargetType": "AWS::Redshift::Cluster" + } + }, + "ClusterEB0386A7": { + "Type": "AWS::Redshift::Cluster", + "Properties": { + "ClusterType": "multi-node", + "DBName": "default_db", + "MasterUsername": { + "Fn::Join": [ + "", + [ + "{{resolve:secretsmanager:", + { + "Ref": "ClusterSecret6368BD0F" + }, + ":SecretString:username::}}" + ] + ] + }, + "MasterUserPassword": { + "Fn::Join": [ + "", + [ + "{{resolve:secretsmanager:", + { + "Ref": "ClusterSecret6368BD0F" + }, + ":SecretString:password::}}" + ] + ] + }, + "NodeType": "dc2.large", + "AllowVersionUpgrade": true, + "AutomatedSnapshotRetentionPeriod": 1, + "ClusterSubnetGroupName": { + "Ref": "ClusterSubnetsDCFA5CB7" + }, + "Encrypted": true, + "IamRoles": [ + { + "Fn::GetAtt": [ + "RoleB318292C8", + "Arn" + ] + }, + { + "Fn::GetAtt": [ + "RoleA3119C8FE", + "Arn" + ] + } + ], + "NumberOfNodes": 2, + "PubliclyAccessible": false, + "VpcSecurityGroupIds": [ + { + "Fn::GetAtt": [ + "ClusterSecurityGroup0921994B", + "GroupId" + ] + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "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/aws-redshift/test/integ.cluster-iamrole.js.snapshot/tree.json b/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.js.snapshot/tree.json new file mode 100644 index 0000000000000..4044a5ca3f0c4 --- /dev/null +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.js.snapshot/tree.json @@ -0,0 +1,1035 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "redshift-iamrole-integ": { + "id": "redshift-iamrole-integ", + "path": "redshift-iamrole-integ", + "children": { + "VPC": { + "id": "VPC", + "path": "redshift-iamrole-integ/VPC", + "children": { + "Resource": { + "id": "Resource", + "path": "redshift-iamrole-integ/VPC/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPC", + "aws:cdk:cloudformation:props": { + "cidrBlock": "10.0.0.0/16", + "enableDnsHostnames": true, + "enableDnsSupport": true, + "instanceTenancy": "default", + "tags": [ + { + "key": "Name", + "value": "redshift-iamrole-integ/VPC" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnVPC", + "version": "0.0.0" + } + }, + "PublicSubnet1": { + "id": "PublicSubnet1", + "path": "redshift-iamrole-integ/VPC/PublicSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "redshift-iamrole-integ/VPC/PublicSubnet1/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "VPCB9E5F0B4" + }, + "availabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.0.0/18", + "mapPublicIpOnLaunch": true, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Public" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Public" + }, + { + "key": "Name", + "value": "redshift-iamrole-integ/VPC/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "redshift-iamrole-integ/VPC/PublicSubnet1/Acl", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "redshift-iamrole-integ/VPC/PublicSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "VPCB9E5F0B4" + }, + "tags": [ + { + "key": "Name", + "value": "redshift-iamrole-integ/VPC/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "redshift-iamrole-integ/VPC/PublicSubnet1/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "subnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "redshift-iamrole-integ/VPC/PublicSubnet1/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "destinationCidrBlock": "0.0.0.0/0", + "gatewayId": { + "Ref": "VPCIGWB7E252D3" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRoute", + "version": "0.0.0" + } + }, + "EIP": { + "id": "EIP", + "path": "redshift-iamrole-integ/VPC/PublicSubnet1/EIP", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::EIP", + "aws:cdk:cloudformation:props": { + "domain": "vpc", + "tags": [ + { + "key": "Name", + "value": "redshift-iamrole-integ/VPC/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnEIP", + "version": "0.0.0" + } + }, + "NATGateway": { + "id": "NATGateway", + "path": "redshift-iamrole-integ/VPC/PublicSubnet1/NATGateway", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", + "aws:cdk:cloudformation:props": { + "subnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + "allocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet1EIP6AD938E8", + "AllocationId" + ] + }, + "tags": [ + { + "key": "Name", + "value": "redshift-iamrole-integ/VPC/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnNatGateway", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.PublicSubnet", + "version": "0.0.0" + } + }, + "PublicSubnet2": { + "id": "PublicSubnet2", + "path": "redshift-iamrole-integ/VPC/PublicSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "redshift-iamrole-integ/VPC/PublicSubnet2/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "VPCB9E5F0B4" + }, + "availabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.64.0/18", + "mapPublicIpOnLaunch": true, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Public" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Public" + }, + { + "key": "Name", + "value": "redshift-iamrole-integ/VPC/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "redshift-iamrole-integ/VPC/PublicSubnet2/Acl", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "redshift-iamrole-integ/VPC/PublicSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "VPCB9E5F0B4" + }, + "tags": [ + { + "key": "Name", + "value": "redshift-iamrole-integ/VPC/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "redshift-iamrole-integ/VPC/PublicSubnet2/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "subnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "redshift-iamrole-integ/VPC/PublicSubnet2/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "destinationCidrBlock": "0.0.0.0/0", + "gatewayId": { + "Ref": "VPCIGWB7E252D3" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRoute", + "version": "0.0.0" + } + }, + "EIP": { + "id": "EIP", + "path": "redshift-iamrole-integ/VPC/PublicSubnet2/EIP", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::EIP", + "aws:cdk:cloudformation:props": { + "domain": "vpc", + "tags": [ + { + "key": "Name", + "value": "redshift-iamrole-integ/VPC/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnEIP", + "version": "0.0.0" + } + }, + "NATGateway": { + "id": "NATGateway", + "path": "redshift-iamrole-integ/VPC/PublicSubnet2/NATGateway", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", + "aws:cdk:cloudformation:props": { + "subnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + }, + "allocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet2EIP4947BC00", + "AllocationId" + ] + }, + "tags": [ + { + "key": "Name", + "value": "redshift-iamrole-integ/VPC/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnNatGateway", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.PublicSubnet", + "version": "0.0.0" + } + }, + "PrivateSubnet1": { + "id": "PrivateSubnet1", + "path": "redshift-iamrole-integ/VPC/PrivateSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "redshift-iamrole-integ/VPC/PrivateSubnet1/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "VPCB9E5F0B4" + }, + "availabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.128.0/18", + "mapPublicIpOnLaunch": false, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Private" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Private" + }, + { + "key": "Name", + "value": "redshift-iamrole-integ/VPC/PrivateSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "redshift-iamrole-integ/VPC/PrivateSubnet1/Acl", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "redshift-iamrole-integ/VPC/PrivateSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "VPCB9E5F0B4" + }, + "tags": [ + { + "key": "Name", + "value": "redshift-iamrole-integ/VPC/PrivateSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "redshift-iamrole-integ/VPC/PrivateSubnet1/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "subnetId": { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "redshift-iamrole-integ/VPC/PrivateSubnet1/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "destinationCidrBlock": "0.0.0.0/0", + "natGatewayId": { + "Ref": "VPCPublicSubnet1NATGatewayE0556630" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.PrivateSubnet", + "version": "0.0.0" + } + }, + "PrivateSubnet2": { + "id": "PrivateSubnet2", + "path": "redshift-iamrole-integ/VPC/PrivateSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "redshift-iamrole-integ/VPC/PrivateSubnet2/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "VPCB9E5F0B4" + }, + "availabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.192.0/18", + "mapPublicIpOnLaunch": false, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Private" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Private" + }, + { + "key": "Name", + "value": "redshift-iamrole-integ/VPC/PrivateSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "redshift-iamrole-integ/VPC/PrivateSubnet2/Acl", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "redshift-iamrole-integ/VPC/PrivateSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "VPCB9E5F0B4" + }, + "tags": [ + { + "key": "Name", + "value": "redshift-iamrole-integ/VPC/PrivateSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "redshift-iamrole-integ/VPC/PrivateSubnet2/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "subnetId": { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "redshift-iamrole-integ/VPC/PrivateSubnet2/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "destinationCidrBlock": "0.0.0.0/0", + "natGatewayId": { + "Ref": "VPCPublicSubnet2NATGateway3C070193" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.PrivateSubnet", + "version": "0.0.0" + } + }, + "IGW": { + "id": "IGW", + "path": "redshift-iamrole-integ/VPC/IGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::InternetGateway", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "redshift-iamrole-integ/VPC" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnInternetGateway", + "version": "0.0.0" + } + }, + "VPCGW": { + "id": "VPCGW", + "path": "redshift-iamrole-integ/VPC/VPCGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "VPCB9E5F0B4" + }, + "internetGatewayId": { + "Ref": "VPCIGWB7E252D3" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnVPCGatewayAttachment", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.Vpc", + "version": "0.0.0" + } + }, + "RoleA": { + "id": "RoleA", + "path": "redshift-iamrole-integ/RoleA", + "children": { + "ImportRoleA": { + "id": "ImportRoleA", + "path": "redshift-iamrole-integ/RoleA/ImportRoleA", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "redshift-iamrole-integ/RoleA/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "redshift.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "RoleB": { + "id": "RoleB", + "path": "redshift-iamrole-integ/RoleB", + "children": { + "ImportRoleB": { + "id": "ImportRoleB", + "path": "redshift-iamrole-integ/RoleB/ImportRoleB", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "redshift-iamrole-integ/RoleB/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "redshift.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Cluster": { + "id": "Cluster", + "path": "redshift-iamrole-integ/Cluster", + "children": { + "Subnets": { + "id": "Subnets", + "path": "redshift-iamrole-integ/Cluster/Subnets", + "children": { + "Default": { + "id": "Default", + "path": "redshift-iamrole-integ/Cluster/Subnets/Default", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Redshift::ClusterSubnetGroup", + "aws:cdk:cloudformation:props": { + "description": "Subnets for Cluster Redshift cluster", + "subnetIds": [ + { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-redshift.CfnClusterSubnetGroup", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-redshift.ClusterSubnetGroup", + "version": "0.0.0" + } + }, + "SecurityGroup": { + "id": "SecurityGroup", + "path": "redshift-iamrole-integ/Cluster/SecurityGroup", + "children": { + "Resource": { + "id": "Resource", + "path": "redshift-iamrole-integ/Cluster/SecurityGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "Redshift security group", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSecurityGroup", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.SecurityGroup", + "version": "0.0.0" + } + }, + "Secret": { + "id": "Secret", + "path": "redshift-iamrole-integ/Cluster/Secret", + "children": { + "Resource": { + "id": "Resource", + "path": "redshift-iamrole-integ/Cluster/Secret/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::SecretsManager::Secret", + "aws:cdk:cloudformation:props": { + "generateSecretString": { + "passwordLength": 30, + "secretStringTemplate": "{\"username\":\"admin\"}", + "generateStringKey": "password", + "excludeCharacters": "\"@/\\ '" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-secretsmanager.CfnSecret", + "version": "0.0.0" + } + }, + "Attachment": { + "id": "Attachment", + "path": "redshift-iamrole-integ/Cluster/Secret/Attachment", + "children": { + "Resource": { + "id": "Resource", + "path": "redshift-iamrole-integ/Cluster/Secret/Attachment/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::SecretsManager::SecretTargetAttachment", + "aws:cdk:cloudformation:props": { + "secretId": { + "Ref": "ClusterSecret6368BD0F" + }, + "targetId": { + "Ref": "ClusterEB0386A7" + }, + "targetType": "AWS::Redshift::Cluster" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-secretsmanager.CfnSecretTargetAttachment", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-secretsmanager.SecretTargetAttachment", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-redshift.DatabaseSecret", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "redshift-iamrole-integ/Cluster/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Redshift::Cluster", + "aws:cdk:cloudformation:props": { + "clusterType": "multi-node", + "dbName": "default_db", + "masterUsername": { + "Fn::Join": [ + "", + [ + "{{resolve:secretsmanager:", + { + "Ref": "ClusterSecret6368BD0F" + }, + ":SecretString:username::}}" + ] + ] + }, + "masterUserPassword": { + "Fn::Join": [ + "", + [ + "{{resolve:secretsmanager:", + { + "Ref": "ClusterSecret6368BD0F" + }, + ":SecretString:password::}}" + ] + ] + }, + "nodeType": "dc2.large", + "allowVersionUpgrade": true, + "automatedSnapshotRetentionPeriod": 1, + "clusterSubnetGroupName": { + "Ref": "ClusterSubnetsDCFA5CB7" + }, + "encrypted": true, + "iamRoles": [ + { + "Fn::GetAtt": [ + "RoleB318292C8", + "Arn" + ] + }, + { + "Fn::GetAtt": [ + "RoleA3119C8FE", + "Arn" + ] + } + ], + "numberOfNodes": 2, + "publiclyAccessible": false, + "vpcSecurityGroupIds": [ + { + "Fn::GetAtt": [ + "ClusterSecurityGroup0921994B", + "GroupId" + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-redshift.CfnCluster", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-redshift.Cluster", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "redshift-iamrole-integ/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "redshift-iamrole-integ/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "IamRoleInteg": { + "id": "IamRoleInteg", + "path": "IamRoleInteg", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "IamRoleInteg/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "IamRoleInteg/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.209" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "IamRoleInteg/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "IamRoleInteg/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "IamRoleInteg/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.209" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.ts b/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.ts new file mode 100644 index 0000000000000..cb664b04c87fa --- /dev/null +++ b/packages/@aws-cdk/aws-redshift/test/integ.cluster-iamrole.ts @@ -0,0 +1,42 @@ +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as iam from '@aws-cdk/aws-iam'; +import { App, RemovalPolicy, Stack, StackProps } from '@aws-cdk/core'; +import * as integ from '@aws-cdk/integ-tests'; +import { Construct } from 'constructs'; +import * as redshift from '../lib'; + +class RedshiftEnv extends Stack { + constructor(scope: Construct, id: string, props?: StackProps) { + super(scope, id, props); + + const vpc = new ec2.Vpc(this, 'VPC'); + const role = new iam.Role(this, 'RoleA', { + assumedBy: new iam.ServicePrincipal('redshift.amazonaws.com'), + }); + + // Adding iam role after cluster creation + const redshiftCluster = new redshift.Cluster(this, 'Cluster', { + vpc: vpc, + vpcSubnets: { + subnetType: ec2.SubnetType.PUBLIC, + }, + masterUser: { + masterUsername: 'admin', + }, + roles: [new iam.Role(this, 'RoleB', { + assumedBy: new iam.ServicePrincipal('redshift.amazonaws.com'), + })], + removalPolicy: RemovalPolicy.DESTROY, + }); + + redshiftCluster.addIamRole(role); + } +} + +const app = new App(); + +new integ.IntegTest(app, 'IamRoleInteg', { + testCases: [new RedshiftEnv(app, 'redshift-iamrole-integ')], +}); + +app.synth();