diff --git a/packages/@aws-cdk/aws-servicecatalog/README.md b/packages/@aws-cdk/aws-servicecatalog/README.md index daeacd42d93ef..105dd795667e1 100644 --- a/packages/@aws-cdk/aws-servicecatalog/README.md +++ b/packages/@aws-cdk/aws-servicecatalog/README.md @@ -209,7 +209,7 @@ class LambdaProduct extends servicecatalog.ProductStack { } const userDefinedBucket = new Bucket(this, `UserDefinedBucket`, { - assetBucketName: 'user-defined-bucket-for-product-stack-assets', + bucketName: 'user-defined-bucket-for-product-stack-assets', }); const product = new servicecatalog.CloudFormationProduct(this, 'Product', { @@ -231,6 +231,39 @@ will automatically grant read permissions to the spoke account. Note, it is not recommended using a referenced bucket as permissions cannot be added from CDK. In this case, it will be your responsibility to grant read permissions for the asset bucket to the spoke account. +If you want to provide your own bucket policy or scope down your bucket policy further to only allow +reads from a specific launch role, refer to the following example policy: + +```ts +new iam.PolicyStatement({ + actions: [ + 's3:GetObject*', + 's3:GetBucket*', + 's3:List*', ], + effect: iam.Effect.ALLOW, + resources: [ + bucket.bucketArn, + bucket.arnForObjects('*'), + ], + principals: [ + new iam.ArnPrincipal(cdk.Stack.of(this).formatArn({ + service: 'iam', + region: '', + sharedAccount, + resource: 'role', + resourceName: launchRoleName, + })) + ], + conditions: { + 'ForAnyValue:StringEquals': { + 'aws:CalledVia': ['cloudformation.amazonaws.com'], + }, + 'Bool': { + 'aws:ViaAWSService': true, + }, + }, +}); +``` Furthermore, in order for a spoke account to provision a product with an asset, the role launching the product needs permissions to read from the asset bucket. diff --git a/packages/@aws-cdk/aws-servicecatalog/lib/private/product-stack-synthesizer.ts b/packages/@aws-cdk/aws-servicecatalog/lib/private/product-stack-synthesizer.ts index 2419a01bfc2d8..cfe242858f629 100644 --- a/packages/@aws-cdk/aws-servicecatalog/lib/private/product-stack-synthesizer.ts +++ b/packages/@aws-cdk/aws-servicecatalog/lib/private/product-stack-synthesizer.ts @@ -1,4 +1,5 @@ import { CfnBucket, IBucket } from '@aws-cdk/aws-s3'; +import { BucketDeployment, ISource, Source } from '@aws-cdk/aws-s3-deployment'; import * as cdk from '@aws-cdk/core'; import { ProductStack } from '../product-stack'; @@ -9,10 +10,12 @@ import { ProductStack } from '../product-stack'; */ export class ProductStackSynthesizer extends cdk.StackSynthesizer { private readonly assetBucket?: IBucket; + private readonly assets: ISource[]; constructor(assetBucket?: IBucket) { super(); this.assetBucket = assetBucket; + this.assets = []; } public addFileAsset(asset: cdk.FileAssetSource): cdk.FileAssetLocation { @@ -22,7 +25,7 @@ export class ProductStackSynthesizer extends cdk.StackSynthesizer { const physicalName = this.physicalNameOfBucket(this.assetBucket); - (this.boundStack as ProductStack)._addAsset(asset); + this._addAsset(asset); const bucketName = physicalName; const s3Filename = asset.fileName?.split('.')[1] + '.zip'; @@ -34,7 +37,12 @@ export class ProductStackSynthesizer extends cdk.StackSynthesizer { } private physicalNameOfBucket(bucket: IBucket) { - const resolvedName = cdk.Stack.of(bucket).resolve((bucket.node.defaultChild as CfnBucket).bucketName); + let resolvedName; + if (cdk.Resource.isOwnedResource(bucket)) { + resolvedName = cdk.Stack.of(bucket).resolve((bucket.node.defaultChild as CfnBucket).bucketName); + } else { + resolvedName = bucket.bucketName; + } if (resolvedName === undefined) { throw new Error('A bucketName must be provided to use Assets'); } @@ -45,9 +53,40 @@ export class ProductStackSynthesizer extends cdk.StackSynthesizer { throw new Error('Service Catalog Product Stacks cannot use Assets'); } + /** + * Asset are prepared for bulk deployment to S3. + * @internal + */ + public _addAsset(asset: cdk.FileAssetSource): void { + const outdir = cdk.App.of(this.boundStack)?.outdir ?? 'cdk.out'; + const assetPath = `./${outdir}/${asset.fileName}`; + this.assets.push(Source.asset(assetPath)); + } + + /** + * Deploy all assets to S3. + * @internal + */ + public _deployAssets() { + const parentStack = (this.boundStack as ProductStack)._getParentStack(); + if (this.assetBucket && this.assets.length > 0) { + if (!cdk.Resource.isOwnedResource(this.assetBucket)) { + cdk.Annotations.of(parentStack).addWarning('[WARNING] Bucket Policy Permissions cannot be added to' + + ' referenced Bucket. Please make sure your bucket has the correct permissions'); + } + new BucketDeployment(parentStack, 'AssetsBucketDeployment', { + sources: this.assets, + destinationBucket: this.assetBucket, + extract: false, + prune: false, + }); + } + } + public synthesize(session: cdk.ISynthesisSession): void { // Synthesize the template, but don't emit as a cloud assembly artifact. // It will be registered as an S3 asset of its parent instead. + this._deployAssets(); this.synthesizeTemplate(session); } } diff --git a/packages/@aws-cdk/aws-servicecatalog/lib/product-stack.ts b/packages/@aws-cdk/aws-servicecatalog/lib/product-stack.ts index 06dafe8216d95..4de5fa6e02ac1 100644 --- a/packages/@aws-cdk/aws-servicecatalog/lib/product-stack.ts +++ b/packages/@aws-cdk/aws-servicecatalog/lib/product-stack.ts @@ -2,7 +2,6 @@ import * as crypto from 'crypto'; import * as fs from 'fs'; import * as path from 'path'; import { IBucket } from '@aws-cdk/aws-s3'; -import { BucketDeployment, ISource, Source } from '@aws-cdk/aws-s3-deployment'; import * as cdk from '@aws-cdk/core'; import { Construct } from 'constructs'; import { ProductStackSynthesizer } from './private/product-stack-synthesizer'; @@ -34,7 +33,6 @@ export class ProductStack extends cdk.Stack { private _templateUrl?: string; private _parentStack: cdk.Stack; - private readonly assets: ISource[]; private assetBucket?: IBucket; constructor(scope: Construct, id: string, props: ProductStackProps = {}) { @@ -47,7 +45,6 @@ export class ProductStack extends cdk.Stack { // this is the file name of the synthesized template file within the cloud assembly this.templateFile = `${cdk.Names.uniqueId(this)}.product.template.json`; - this.assets = []; this.assetBucket = props.assetBucket; } @@ -79,32 +76,12 @@ export class ProductStack extends cdk.Stack { } /** - * Asset are prepared for bulk deployment to S3. - * @internal - */ - public _addAsset(asset: cdk.FileAssetSource): void { - const assetPath = './cdk.out/' + asset.fileName; - this.assets.push(Source.asset(assetPath)); - } - - /** - * Deploy all assets to S3. + * Fetch the parent Stack. + * * @internal */ - private _deployAssets() { - if (this.assetBucket && this.assets.length > 0) { - if (!cdk.Resource.isOwnedResource(this.assetBucket)) { - // eslint-disable-next-line no-console - console.warn('[WARNING]', 'Bucket Policy Permissions cannot be added to' + - ' referenced Bucket. Please make sure your bucket has the correct permissions'); - } - new BucketDeployment(this._parentStack, 'AssetsBucketDeployment', { - sources: this.assets, - destinationBucket: this.assetBucket, - extract: false, - prune: false, - }); - } + public _getParentStack(): cdk.Stack { + return this._parentStack; } /** @@ -129,8 +106,6 @@ export class ProductStack extends cdk.Stack { this._parentProductStackHistory._writeTemplateToSnapshot(cfn); } - this._deployAssets(); - fs.writeFileSync(path.join(session.assembly.outdir, this.templateFile), cfn); } } diff --git a/packages/@aws-cdk/aws-servicecatalog/package.json b/packages/@aws-cdk/aws-servicecatalog/package.json index 3e3d4f19dfbd0..6e0163bcaae62 100644 --- a/packages/@aws-cdk/aws-servicecatalog/package.json +++ b/packages/@aws-cdk/aws-servicecatalog/package.json @@ -85,10 +85,12 @@ "@aws-cdk/integ-runner": "0.0.0", "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", + "@aws-cdk/integ-tests": "0.0.0", "@types/jest": "^27.5.2" }, "dependencies": { "@aws-cdk/aws-iam": "0.0.0", + "@aws-cdk/aws-lambda": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@aws-cdk/aws-s3-assets": "0.0.0", "@aws-cdk/aws-s3-deployment": "0.0.0", @@ -99,6 +101,7 @@ "homepage": "https://github.com/aws/aws-cdk", "peerDependencies": { "@aws-cdk/aws-iam": "0.0.0", + "@aws-cdk/aws-lambda": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@aws-cdk/aws-s3-assets": "0.0.0", "@aws-cdk/aws-s3-deployment": "0.0.0", diff --git a/packages/@aws-cdk/aws-servicecatalog/test/assets/index.py b/packages/@aws-cdk/aws-servicecatalog/test/assets/index.py new file mode 100644 index 0000000000000..105bdadc3c1a8 --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalog/test/assets/index.py @@ -0,0 +1,7 @@ +import json + +def handler(event, context): + return { + 'statusCode': 200, + 'body': json.dumps('Hello from Lambda!') + } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/asset.5d8d1d0aacea23824c62f362e1e3c14b7dd14a31c71b53bfae4d14a6373c5510.zip b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/asset.5d8d1d0aacea23824c62f362e1e3c14b7dd14a31c71b53bfae4d14a6373c5510.zip new file mode 100644 index 0000000000000..cdc4c4515e7d9 Binary files /dev/null and b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/asset.5d8d1d0aacea23824c62f362e1e3c14b7dd14a31c71b53bfae4d14a6373c5510.zip differ diff --git a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/asset.6412a5f4524c6b41d26fbeee226c68c2dad735393940a51008d77e6f8b1038f5.json b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/asset.6412a5f4524c6b41d26fbeee226c68c2dad735393940a51008d77e6f8b1038f5.json new file mode 100644 index 0000000000000..9785ab36f253f --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/asset.6412a5f4524c6b41d26fbeee226c68c2dad735393940a51008d77e6f8b1038f5.json @@ -0,0 +1,98 @@ +{ + "AWSTemplateFormatVersion" : "2010-09-09", + + "Description" : "AWS Service Catalog sample template. Creates an Amazon EC2 instance running the Amazon Linux AMI. The AMI is chosen based on the region in which the stack is run. This example creates an EC2 security group for the instance to give you SSH access. **WARNING** This template creates an Amazon EC2 instance. You will be billed for the AWS resources used if you create a stack from this template.", + + "Parameters" : { + "KeyName": { + "Description" : "Name of an existing EC2 key pair for SSH access to the EC2 instance.", + "Type": "AWS::EC2::KeyPair::KeyName" + }, + + "InstanceType" : { + "Description" : "EC2 instance type.", + "Type" : "String", + "Default" : "t2.micro", + "AllowedValues" : [ "t2.micro", "t2.small", "t2.medium"] + }, + + "SSHLocation" : { + "Description" : "The IP address range that can SSH to the EC2 instance.", + "Type": "String", + "MinLength": "9", + "MaxLength": "18", + "Default": "0.0.0.0/0", + "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", + "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x." + } + }, + + "Metadata" : { + "AWS::CloudFormation::Interface" : { + "ParameterGroups" : [{ + "Label" : {"default": "Instance configuration"}, + "Parameters" : ["InstanceType"] + },{ + "Label" : {"default": "Security configuration"}, + "Parameters" : ["KeyName", "SSHLocation"] + }], + "ParameterLabels" : { + "InstanceType": {"default": "Server size:"}, + "KeyName": {"default": "Key pair:"}, + "SSHLocation": {"default": "CIDR range:"} + } + } + }, + + "Mappings" : { + "AWSRegionArch2AMI" : { + "us-east-1" : { "HVM64" : "ami-08842d60" }, + "us-west-2" : { "HVM64" : "ami-8786c6b7" }, + "us-west-1" : { "HVM64" : "ami-cfa8a18a" }, + "eu-west-1" : { "HVM64" : "ami-748e2903" }, + "ap-southeast-1" : { "HVM64" : "ami-d6e1c584" }, + "ap-northeast-1" : { "HVM64" : "ami-35072834" }, + "ap-southeast-2" : { "HVM64" : "ami-fd4724c7" }, + "sa-east-1" : { "HVM64" : "ami-956cc688" }, + "cn-north-1" : { "HVM64" : "ami-ac57c595" }, + "eu-central-1" : { "HVM64" : "ami-b43503a9" } + } + + }, + + "Resources" : { + "EC2Instance" : { + "Type" : "AWS::EC2::Instance", + "Properties" : { + "InstanceType" : { "Ref" : "InstanceType" }, + "SecurityGroups" : [ { "Ref" : "InstanceSecurityGroup" } ], + "KeyName" : { "Ref" : "KeyName" }, + "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, "HVM64" ] } + } + }, + + "InstanceSecurityGroup" : { + "Type" : "AWS::EC2::SecurityGroup", + "Properties" : { + "GroupDescription" : "Enable SSH access via port 22", + "SecurityGroupIngress" : [ { + "IpProtocol" : "tcp", + "FromPort" : "22", + "ToPort" : "22", + "CidrIp" : { "Ref" : "SSHLocation"} + } ] + } + } + }, + + "Outputs" : { + "PublicDNSName" : { + "Description" : "Public DNS name of the new EC2 instance", + "Value" : { "Fn::GetAtt" : [ "EC2Instance", "PublicDnsName" ] } + }, + "PublicIPAddress" : { + "Description" : "Public IP address of the new EC2 instance", + "Value" : { "Fn::GetAtt" : [ "EC2Instance", "PublicIp" ] } + } + } +} diff --git a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/asset.b59f768286e16b69628bb23b9c1a1f07300a24101b8979d8e2a94ff1ab03d09e.json b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/asset.b59f768286e16b69628bb23b9c1a1f07300a24101b8979d8e2a94ff1ab03d09e.json new file mode 100644 index 0000000000000..69c3138be93f4 --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/asset.b59f768286e16b69628bb23b9c1a1f07300a24101b8979d8e2a94ff1ab03d09e.json @@ -0,0 +1,98 @@ +{ + "AWSTemplateFormatVersion" : "2010-09-09", + + "Description" : "AWS Service Catalog sample template. Creates an Amazon EC2 instance running the Amazon Linux AMI. The AMI is chosen based on the region in which the stack is run. This example creates an EC2 security group for the instance to give you SSH access. **WARNING** This template creates an Amazon EC2 instance. You will be billed for the AWS resources used if you create a stack from this template.", + + "Parameters" : { + "KeyName": { + "Description" : "Name of an existing EC2 key pair for SSH access to the EC2 instance.", + "Type": "AWS::EC2::KeyPair::KeyName" + }, + + "InstanceType" : { + "Description" : "EC2 instance type.", + "Type" : "String", + "Default" : "t2.micro", + "AllowedValues" : [ "t2.micro", "t2.small", "t2.medium", "m3.medium", "m3.large", "m3.xlarge", "m3.2xlarge" ] + }, + + "SSHLocation" : { + "Description" : "The IP address range that can SSH to the EC2 instance.", + "Type": "String", + "MinLength": "9", + "MaxLength": "18", + "Default": "0.0.0.0/0", + "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", + "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x." + } + }, + + "Metadata" : { + "AWS::CloudFormation::Interface" : { + "ParameterGroups" : [{ + "Label" : {"default": "Instance configuration"}, + "Parameters" : ["InstanceType"] + },{ + "Label" : {"default": "Security configuration"}, + "Parameters" : ["KeyName", "SSHLocation"] + }], + "ParameterLabels" : { + "InstanceType": {"default": "Server size:"}, + "KeyName": {"default": "Key pair:"}, + "SSHLocation": {"default": "CIDR range:"} + } + } + }, + + "Mappings" : { + "AWSRegionArch2AMI" : { + "us-east-1" : { "HVM64" : "ami-08842d60" }, + "us-west-2" : { "HVM64" : "ami-8786c6b7" }, + "us-west-1" : { "HVM64" : "ami-cfa8a18a" }, + "eu-west-1" : { "HVM64" : "ami-748e2903" }, + "ap-southeast-1" : { "HVM64" : "ami-d6e1c584" }, + "ap-northeast-1" : { "HVM64" : "ami-35072834" }, + "ap-southeast-2" : { "HVM64" : "ami-fd4724c7" }, + "sa-east-1" : { "HVM64" : "ami-956cc688" }, + "cn-north-1" : { "HVM64" : "ami-ac57c595" }, + "eu-central-1" : { "HVM64" : "ami-b43503a9" } + } + + }, + + "Resources" : { + "EC2Instance" : { + "Type" : "AWS::EC2::Instance", + "Properties" : { + "InstanceType" : { "Ref" : "InstanceType" }, + "SecurityGroups" : [ { "Ref" : "InstanceSecurityGroup" } ], + "KeyName" : { "Ref" : "KeyName" }, + "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, "HVM64" ] } + } + }, + + "InstanceSecurityGroup" : { + "Type" : "AWS::EC2::SecurityGroup", + "Properties" : { + "GroupDescription" : "Enable SSH access via port 22", + "SecurityGroupIngress" : [ { + "IpProtocol" : "tcp", + "FromPort" : "22", + "ToPort" : "22", + "CidrIp" : { "Ref" : "SSHLocation"} + } ] + } + } + }, + + "Outputs" : { + "PublicDNSName" : { + "Description" : "Public DNS name of the new EC2 instance", + "Value" : { "Fn::GetAtt" : [ "EC2Instance", "PublicDnsName" ] } + }, + "PublicIPAddress" : { + "Description" : "Public IP address of the new EC2 instance", + "Value" : { "Fn::GetAtt" : [ "EC2Instance", "PublicIp" ] } + } + } +} diff --git a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/asset.d3833f63e813b3a96ea04c8c50ca98209330867f5f6ac358efca11f85a3476c2.d3833f63e813b3a96ea04c8c50ca98209330867f5f6ac358efca11f85a3476c2/index.py b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/asset.d3833f63e813b3a96ea04c8c50ca98209330867f5f6ac358efca11f85a3476c2.d3833f63e813b3a96ea04c8c50ca98209330867f5f6ac358efca11f85a3476c2/index.py new file mode 100644 index 0000000000000..105bdadc3c1a8 --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/asset.d3833f63e813b3a96ea04c8c50ca98209330867f5f6ac358efca11f85a3476c2.d3833f63e813b3a96ea04c8c50ca98209330867f5f6ac358efca11f85a3476c2/index.py @@ -0,0 +1,7 @@ +import json + +def handler(event, context): + return { + 'statusCode': 200, + 'body': json.dumps('Hello from Lambda!') + } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/asset.d3833f63e813b3a96ea04c8c50ca98209330867f5f6ac358efca11f85a3476c2/index.py b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/asset.d3833f63e813b3a96ea04c8c50ca98209330867f5f6ac358efca11f85a3476c2/index.py new file mode 100644 index 0000000000000..105bdadc3c1a8 --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/asset.d3833f63e813b3a96ea04c8c50ca98209330867f5f6ac358efca11f85a3476c2/index.py @@ -0,0 +1,7 @@ +import json + +def handler(event, context): + return { + 'statusCode': 200, + 'body': json.dumps('Hello from Lambda!') + } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/integ-servicecatalog-product.assets.json b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/integ-servicecatalog-product.assets.json index 5d79ca9c9aedd..bacdff0a872d2 100644 --- a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/integ-servicecatalog-product.assets.json +++ b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/integ-servicecatalog-product.assets.json @@ -7,10 +7,11 @@ "packaging": "zip" }, "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "12345678-test-region": { + "bucketName": "cdk-hnb659fds-assets-12345678-test-region", "objectKey": "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c.zip", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + "region": "test-region", + "assumeRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-file-publishing-role-12345678-test-region" } } }, @@ -20,10 +21,11 @@ "packaging": "file" }, "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "12345678-test-region": { + "bucketName": "cdk-hnb659fds-assets-12345678-test-region", "objectKey": "b59f768286e16b69628bb23b9c1a1f07300a24101b8979d8e2a94ff1ab03d09e.json", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + "region": "test-region", + "assumeRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-file-publishing-role-12345678-test-region" } } }, @@ -33,10 +35,11 @@ "packaging": "file" }, "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "12345678-test-region": { + "bucketName": "cdk-hnb659fds-assets-12345678-test-region", "objectKey": "6412a5f4524c6b41d26fbeee226c68c2dad735393940a51008d77e6f8b1038f5.json", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + "region": "test-region", + "assumeRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-file-publishing-role-12345678-test-region" } } }, @@ -46,23 +49,11 @@ "packaging": "file" }, "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "12345678-test-region": { + "bucketName": "cdk-hnb659fds-assets-12345678-test-region", "objectKey": "dd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1f.json", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" - } - } - }, - "44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a": { - "source": { - "path": "integservicecatalogproductS3AssetProductCED6E119.product.template.json", - "packaging": "file" - }, - "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a.json", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + "region": "test-region", + "assumeRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-file-publishing-role-12345678-test-region" } } }, @@ -72,10 +63,11 @@ "packaging": "file" }, "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "12345678-test-region": { + "bucketName": "cdk-hnb659fds-assets-12345678-test-region", "objectKey": "5d8d1d0aacea23824c62f362e1e3c14b7dd14a31c71b53bfae4d14a6373c5510.zip", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + "region": "test-region", + "assumeRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-file-publishing-role-12345678-test-region" } } }, @@ -85,36 +77,53 @@ "packaging": "zip" }, "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "12345678-test-region": { + "bucketName": "cdk-hnb659fds-assets-12345678-test-region", "objectKey": "6ddcf10002539818a9256eff3fb2b22aa09298d8f946e26ba121c175a600c44e.zip", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + "region": "test-region", + "assumeRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-file-publishing-role-12345678-test-region" } } }, - "4083400addc1de83cd1be06b8d7b1a4f52b08ce4cbcaf1247516d9c1d7668d47": { + "d3833f63e813b3a96ea04c8c50ca98209330867f5f6ac358efca11f85a3476c2": { "source": { - "path": "asset.4083400addc1de83cd1be06b8d7b1a4f52b08ce4cbcaf1247516d9c1d7668d47.zip", + "path": "asset.d3833f63e813b3a96ea04c8c50ca98209330867f5f6ac358efca11f85a3476c2.d3833f63e813b3a96ea04c8c50ca98209330867f5f6ac358efca11f85a3476c2", + "packaging": "zip" + }, + "destinations": { + "12345678-test-region": { + "bucketName": "cdk-hnb659fds-assets-12345678-test-region", + "objectKey": "d3833f63e813b3a96ea04c8c50ca98209330867f5f6ac358efca11f85a3476c2.zip", + "region": "test-region", + "assumeRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-file-publishing-role-12345678-test-region" + } + } + }, + "e67e4a20283cee8bcc0e52733149d8f8ce3cb0065d28786f548d8fb382aaea36": { + "source": { + "path": "integservicecatalogproductS3AssetProductCED6E119.product.template.json", "packaging": "file" }, "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "4083400addc1de83cd1be06b8d7b1a4f52b08ce4cbcaf1247516d9c1d7668d47.zip", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + "12345678-test-region": { + "bucketName": "cdk-hnb659fds-assets-12345678-test-region", + "objectKey": "e67e4a20283cee8bcc0e52733149d8f8ce3cb0065d28786f548d8fb382aaea36.json", + "region": "test-region", + "assumeRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-file-publishing-role-12345678-test-region" } } }, - "64975905aca20e342092cbeafd7b7c6f276ab76ba29d79a88c8ace664f6f91b4": { + "13ee75438bb5ffa930a5b8c2727ee72937bb2e5fd2d829305c3ac792d4ada57d": { "source": { "path": "integ-servicecatalog-product.template.json", "packaging": "file" }, "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "64975905aca20e342092cbeafd7b7c6f276ab76ba29d79a88c8ace664f6f91b4.json", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + "12345678-test-region": { + "bucketName": "cdk-hnb659fds-assets-12345678-test-region", + "objectKey": "13ee75438bb5ffa930a5b8c2727ee72937bb2e5fd2d829305c3ac792d4ada57d.json", + "region": "test-region", + "assumeRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-file-publishing-role-12345678-test-region" } } } diff --git a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/integ-servicecatalog-product.template.json b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/integ-servicecatalog-product.template.json index 2ca302f8a0a7b..0bdbe219d6e6c 100644 --- a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/integ-servicecatalog-product.template.json +++ b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/integ-servicecatalog-product.template.json @@ -130,9 +130,7 @@ "Type": "AWS::Lambda::Function", "Properties": { "Code": { - "S3Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, + "S3Bucket": "cdk-hnb659fds-assets-12345678-test-region", "S3Key": "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c.zip" }, "Timeout": 900, @@ -178,7 +176,7 @@ "DisableTemplateValidation": false, "Info": { "LoadTemplateFromURL": { - "Fn::Sub": "https://s3.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/b59f768286e16b69628bb23b9c1a1f07300a24101b8979d8e2a94ff1ab03d09e.json" + "Fn::Sub": "https://s3.test-region.${AWS::URLSuffix}/cdk-hnb659fds-assets-12345678-test-region/b59f768286e16b69628bb23b9c1a1f07300a24101b8979d8e2a94ff1ab03d09e.json" } } }, @@ -186,7 +184,7 @@ "DisableTemplateValidation": false, "Info": { "LoadTemplateFromURL": { - "Fn::Sub": "https://s3.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/6412a5f4524c6b41d26fbeee226c68c2dad735393940a51008d77e6f8b1038f5.json" + "Fn::Sub": "https://s3.test-region.${AWS::URLSuffix}/cdk-hnb659fds-assets-12345678-test-region/6412a5f4524c6b41d26fbeee226c68c2dad735393940a51008d77e6f8b1038f5.json" } } }, @@ -194,7 +192,7 @@ "DisableTemplateValidation": false, "Info": { "LoadTemplateFromURL": { - "Fn::Sub": "https://s3.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/dd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1f.json" + "Fn::Sub": "https://s3.test-region.${AWS::URLSuffix}/cdk-hnb659fds-assets-12345678-test-region/dd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1f.json" } } }, @@ -202,7 +200,7 @@ "DisableTemplateValidation": false, "Info": { "LoadTemplateFromURL": { - "Fn::Sub": "https://s3.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/dd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1f.json" + "Fn::Sub": "https://s3.test-region.${AWS::URLSuffix}/cdk-hnb659fds-assets-12345678-test-region/dd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1f.json" } } }, @@ -210,7 +208,7 @@ "DisableTemplateValidation": true, "Info": { "LoadTemplateFromURL": { - "Fn::Sub": "https://s3.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a.json" + "Fn::Sub": "https://s3.test-region.${AWS::URLSuffix}/cdk-hnb659fds-assets-12345678-test-region/e67e4a20283cee8bcc0e52733149d8f8ce3cb0065d28786f548d8fb382aaea36.json" } }, "Name": "testAssetProduct" @@ -219,7 +217,7 @@ "DisableTemplateValidation": false, "Info": { "LoadTemplateFromURL": { - "Fn::Sub": "https://s3.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/dd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1f.json" + "Fn::Sub": "https://s3.test-region.${AWS::URLSuffix}/cdk-hnb659fds-assets-12345678-test-region/dd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1f.json" } }, "Name": "v1" @@ -231,9 +229,7 @@ "Type": "AWS::Lambda::LayerVersion", "Properties": { "Content": { - "S3Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, + "S3Bucket": "cdk-hnb659fds-assets-12345678-test-region", "S3Key": "5d8d1d0aacea23824c62f362e1e3c14b7dd14a31c71b53bfae4d14a6373c5510.zip" }, "Description": "/opt/awscli/aws" @@ -249,12 +245,10 @@ ] }, "SourceBucketNames": [ - { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - } + "cdk-hnb659fds-assets-12345678-test-region" ], "SourceObjectKeys": [ - "4083400addc1de83cd1be06b8d7b1a4f52b08ce4cbcaf1247516d9c1d7668d47.zip" + "d3833f63e813b3a96ea04c8c50ca98209330867f5f6ac358efca11f85a3476c2.zip" ], "DestinationBucketName": { "Ref": "TestAssetBucket9434EFAE" @@ -317,11 +311,7 @@ { "Ref": "AWS::Partition" }, - ":s3:::", - { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "/*" + ":s3:::cdk-hnb659fds-assets-12345678-test-region" ] ] }, @@ -333,10 +323,7 @@ { "Ref": "AWS::Partition" }, - ":s3:::", - { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - } + ":s3:::cdk-hnb659fds-assets-12345678-test-region/*" ] ] } @@ -394,9 +381,7 @@ "Type": "AWS::Lambda::Function", "Properties": { "Code": { - "S3Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, + "S3Bucket": "cdk-hnb659fds-assets-12345678-test-region", "S3Key": "6ddcf10002539818a9256eff3fb2b22aa09298d8f946e26ba121c175a600c44e.zip" }, "Role": { diff --git a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/integ.json b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/integ.json index e30acfbd344f4..d687fd5162992 100644 --- a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/integ.json @@ -1,14 +1,13 @@ { + "enableLookups": true, "version": "21.0.0", "testCases": { - "integ.product": { + "integ-product/DefaultTest": { "stacks": [ "integ-servicecatalog-product" ], - "diffAssets": false, - "stackUpdateWorkflow": true + "assertionStack": "integ-product/DefaultTest/DeployAssert", + "assertionStackName": "integproductDefaultTestDeployAssertEB23E2A9" } - }, - "synthContext": {}, - "enableLookups": false + } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/integproductDefaultTestDeployAssertEB23E2A9.assets.json b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/integproductDefaultTestDeployAssertEB23E2A9.assets.json new file mode 100644 index 0000000000000..6a611300fa6d0 --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/integproductDefaultTestDeployAssertEB23E2A9.assets.json @@ -0,0 +1,19 @@ +{ + "version": "21.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "integproductDefaultTestDeployAssertEB23E2A9.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-servicecatalog/test/integ.product.js.snapshot/integproductDefaultTestDeployAssertEB23E2A9.template.json b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/integproductDefaultTestDeployAssertEB23E2A9.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/integproductDefaultTestDeployAssertEB23E2A9.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-servicecatalog/test/integ.product.js.snapshot/integservicecatalogproductS3AssetProductCED6E119.product.template.json b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/integservicecatalogproductS3AssetProductCED6E119.product.template.json index 9e26dfeeb6e64..ab05aca608d14 100644 --- a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/integservicecatalogproductS3AssetProductCED6E119.product.template.json +++ b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/integservicecatalogproductS3AssetProductCED6E119.product.template.json @@ -1 +1,55 @@ -{} \ No newline at end of file +{ + "Resources": { + "HelloHandlerServiceRole11EF7C63": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "HelloHandler2E4FBA4D": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "product-stack-asset-bucket-12345678-test-region", + "S3Key": "d3833f63e813b3a96ea04c8c50ca98209330867f5f6ac358efca11f85a3476c2.zip" + }, + "Role": { + "Fn::GetAtt": [ + "HelloHandlerServiceRole11EF7C63", + "Arn" + ] + }, + "Handler": "index.handler", + "Runtime": "python3.9" + }, + "DependsOn": [ + "HelloHandlerServiceRole11EF7C63" + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/manifest.json b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/manifest.json index b9a1b09b515ca..f758bde05cf3f 100644 --- a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/manifest.json @@ -11,20 +11,20 @@ }, "integ-servicecatalog-product": { "type": "aws:cloudformation:stack", - "environment": "aws://unknown-account/unknown-region", + "environment": "aws://12345678/test-region", "properties": { "templateFile": "integ-servicecatalog-product.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}/64975905aca20e342092cbeafd7b7c6f276ab76ba29d79a88c8ace664f6f91b4.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-deploy-role-12345678-test-region", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-cfn-exec-role-12345678-test-region", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-12345678-test-region/13ee75438bb5ffa930a5b8c2727ee72937bb2e5fd2d829305c3ac792d4ada57d.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ "integ-servicecatalog-product.assets" ], "lookupRole": { - "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "arn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-lookup-role-12345678-test-region", "requiresBootstrapStackVersion": 8, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" } @@ -132,6 +132,53 @@ }, "displayName": "integ-servicecatalog-product" }, + "integproductDefaultTestDeployAssertEB23E2A9.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "integproductDefaultTestDeployAssertEB23E2A9.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "integproductDefaultTestDeployAssertEB23E2A9": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "integproductDefaultTestDeployAssertEB23E2A9.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": [ + "integproductDefaultTestDeployAssertEB23E2A9.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": [ + "integproductDefaultTestDeployAssertEB23E2A9.assets" + ], + "metadata": { + "/integ-product/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/integ-product/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "integ-product/DefaultTest/DeployAssert" + }, "Tree": { "type": "cdk:tree", "properties": { diff --git a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/tree.json b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/tree.json index 4529efcbae898..353283d4d72a2 100644 --- a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.js.snapshot/tree.json @@ -313,29 +313,121 @@ "id": "S3AssetProduct", "path": "integ-servicecatalog-product/S3AssetProduct", "children": { - "testAsset": { - "id": "testAsset", - "path": "integ-servicecatalog-product/S3AssetProduct/testAsset", + "HelloHandler": { + "id": "HelloHandler", + "path": "integ-servicecatalog-product/S3AssetProduct/HelloHandler", "children": { - "Stage": { - "id": "Stage", - "path": "integ-servicecatalog-product/S3AssetProduct/testAsset/Stage", + "ServiceRole": { + "id": "ServiceRole", + "path": "integ-servicecatalog-product/S3AssetProduct/HelloHandler/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "integ-servicecatalog-product/S3AssetProduct/HelloHandler/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "integ-servicecatalog-product/S3AssetProduct/HelloHandler/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, "constructInfo": { - "fqn": "@aws-cdk/core.AssetStaging", + "fqn": "@aws-cdk/aws-iam.Role", "version": "0.0.0" } }, - "AssetBucket": { - "id": "AssetBucket", - "path": "integ-servicecatalog-product/S3AssetProduct/testAsset/AssetBucket", + "Code": { + "id": "Code", + "path": "integ-servicecatalog-product/S3AssetProduct/HelloHandler/Code", + "children": { + "Stage": { + "id": "Stage", + "path": "integ-servicecatalog-product/S3AssetProduct/HelloHandler/Code/Stage", + "constructInfo": { + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" + } + }, + "AssetBucket": { + "id": "AssetBucket", + "path": "integ-servicecatalog-product/S3AssetProduct/HelloHandler/Code/AssetBucket", + "constructInfo": { + "fqn": "@aws-cdk/aws-s3.BucketBase", + "version": "0.0.0" + } + } + }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.BucketBase", + "fqn": "@aws-cdk/aws-s3-assets.Asset", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "integ-servicecatalog-product/S3AssetProduct/HelloHandler/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "s3Bucket": "product-stack-asset-bucket-12345678-test-region", + "s3Key": "d3833f63e813b3a96ea04c8c50ca98209330867f5f6ac358efca11f85a3476c2.zip" + }, + "role": { + "Fn::GetAtt": [ + "HelloHandlerServiceRole11EF7C63", + "Arn" + ] + }, + "handler": "index.handler", + "runtime": "python3.9" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3-assets.Asset", + "fqn": "@aws-cdk/aws-lambda.Function", "version": "0.0.0" } } @@ -420,7 +512,7 @@ "disableTemplateValidation": false, "info": { "LoadTemplateFromURL": { - "Fn::Sub": "https://s3.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/b59f768286e16b69628bb23b9c1a1f07300a24101b8979d8e2a94ff1ab03d09e.json" + "Fn::Sub": "https://s3.test-region.${AWS::URLSuffix}/cdk-hnb659fds-assets-12345678-test-region/b59f768286e16b69628bb23b9c1a1f07300a24101b8979d8e2a94ff1ab03d09e.json" } } }, @@ -428,7 +520,7 @@ "disableTemplateValidation": false, "info": { "LoadTemplateFromURL": { - "Fn::Sub": "https://s3.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/6412a5f4524c6b41d26fbeee226c68c2dad735393940a51008d77e6f8b1038f5.json" + "Fn::Sub": "https://s3.test-region.${AWS::URLSuffix}/cdk-hnb659fds-assets-12345678-test-region/6412a5f4524c6b41d26fbeee226c68c2dad735393940a51008d77e6f8b1038f5.json" } } }, @@ -436,7 +528,7 @@ "disableTemplateValidation": false, "info": { "LoadTemplateFromURL": { - "Fn::Sub": "https://s3.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/dd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1f.json" + "Fn::Sub": "https://s3.test-region.${AWS::URLSuffix}/cdk-hnb659fds-assets-12345678-test-region/dd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1f.json" } } }, @@ -444,7 +536,7 @@ "disableTemplateValidation": false, "info": { "LoadTemplateFromURL": { - "Fn::Sub": "https://s3.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/dd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1f.json" + "Fn::Sub": "https://s3.test-region.${AWS::URLSuffix}/cdk-hnb659fds-assets-12345678-test-region/dd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1f.json" } } }, @@ -453,7 +545,7 @@ "disableTemplateValidation": true, "info": { "LoadTemplateFromURL": { - "Fn::Sub": "https://s3.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a.json" + "Fn::Sub": "https://s3.test-region.${AWS::URLSuffix}/cdk-hnb659fds-assets-12345678-test-region/e67e4a20283cee8bcc0e52733149d8f8ce3cb0065d28786f548d8fb382aaea36.json" } } }, @@ -462,7 +554,7 @@ "disableTemplateValidation": false, "info": { "LoadTemplateFromURL": { - "Fn::Sub": "https://s3.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/dd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1f.json" + "Fn::Sub": "https://s3.test-region.${AWS::URLSuffix}/cdk-hnb659fds-assets-12345678-test-region/dd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1f.json" } } } @@ -529,9 +621,7 @@ "aws:cdk:cloudformation:type": "AWS::Lambda::LayerVersion", "aws:cdk:cloudformation:props": { "content": { - "s3Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, + "s3Bucket": "cdk-hnb659fds-assets-12345678-test-region", "s3Key": "5d8d1d0aacea23824c62f362e1e3c14b7dd14a31c71b53bfae4d14a6373c5510.zip" }, "description": "/opt/awscli/aws" @@ -689,11 +779,7 @@ { "Ref": "AWS::Partition" }, - ":s3:::", - { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "/*" + ":s3:::cdk-hnb659fds-assets-12345678-test-region" ] ] }, @@ -705,10 +791,7 @@ { "Ref": "AWS::Partition" }, - ":s3:::", - { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - } + ":s3:::cdk-hnb659fds-assets-12345678-test-region/*" ] ] } @@ -812,9 +895,7 @@ "aws:cdk:cloudformation:type": "AWS::Lambda::Function", "aws:cdk:cloudformation:props": { "code": { - "s3Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, + "s3Bucket": "cdk-hnb659fds-assets-12345678-test-region", "s3Key": "6ddcf10002539818a9256eff3fb2b22aa09298d8f946e26ba121c175a600c44e.zip" }, "role": { @@ -866,6 +947,60 @@ "version": "0.0.0" } }, + "integ-product": { + "id": "integ-product", + "path": "integ-product", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "integ-product/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "integ-product/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.154" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "integ-product/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "integ-product/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "integ-product/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", diff --git a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.ts b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.ts index 7362b8885e53c..34e88eea023ad 100644 --- a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.ts +++ b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.ts @@ -1,8 +1,9 @@ import * as path from 'path'; +import * as lambda from '@aws-cdk/aws-lambda'; import * as s3 from '@aws-cdk/aws-s3'; -import * as s3_assets from '@aws-cdk/aws-s3-assets'; import * as sns from '@aws-cdk/aws-sns'; import * as cdk from '@aws-cdk/core'; +import { IntegTest } from '@aws-cdk/integ-tests'; import * as servicecatalog from '../lib'; import { ProductStackHistory, ProductStackProps } from '../lib'; @@ -48,7 +49,7 @@ import { ProductStackHistory, ProductStackProps } from '../lib'; * * 7. Disassociate your principal from your portfolio. ``` - $ aws servicecatalog disassociate-principal-with-portfolio \ + $ aws servicecatalog disassociate-principal-from-portfolio \ --portfolio-id= \ --principal-arn= \ ``` @@ -60,7 +61,12 @@ import { ProductStackHistory, ProductStackProps } from '../lib'; */ const app = new cdk.App(); -const stack = new cdk.Stack(app, 'integ-servicecatalog-product'); +const stack = new cdk.Stack(app, 'integ-servicecatalog-product', { + env: { + account: process.env.CDK_INTEG_ACCOUNT ?? process.env.CDK_DEFAULT_ACCOUNT, + region: process.env.CDK_INTEG_REGION ?? process.env.CDK_DEFAULT_REGION, + }, +}); class TestProductStack extends servicecatalog.ProductStack { constructor(scope: any, id: string) { @@ -81,8 +87,10 @@ class TestAssetProductStack extends servicecatalog.ProductStack { constructor(scope: any, id: string, props?: ProductStackProps) { super(scope, id, props); - new s3_assets.Asset(this, 'testAsset', { - path: path.join(__dirname, 'products.template.zip'), + new lambda.Function(this, 'HelloHandler', { + runtime: lambda.Runtime.PYTHON_3_9, + code: lambda.Code.fromAsset('./assets'), + handler: 'index.handler', }); } } @@ -94,7 +102,7 @@ const productStackHistory = new ProductStackHistory(stack, 'ProductStackHistory' }); const testAssetBucket = new s3.Bucket(stack, 'TestAssetBucket', { - bucketName: 'product-stack-asset-bucket-12345678-test-region', + bucketName: `product-stack-asset-bucket-${stack.account}-${stack.region}`, removalPolicy: cdk.RemovalPolicy.DESTROY, autoDeleteObjects: true, }); @@ -131,6 +139,11 @@ const product = new servicecatalog.CloudFormationProduct(stack, 'TestProduct', { ], }); +new IntegTest(app, 'integ-product', { + testCases: [stack], + enableLookups: true, +}); + portfolio.addProduct(product); new cdk.CfnOutput(stack, 'PortfolioId', { value: portfolio.portfolioId }); diff --git a/packages/@aws-cdk/aws-servicecatalog/test/products.template.zip b/packages/@aws-cdk/aws-servicecatalog/test/products.template.zip deleted file mode 100644 index e69de29bb2d1d..0000000000000