diff --git a/packages/@aws-cdk/aws-route53-patterns/README.md b/packages/@aws-cdk/aws-route53-patterns/README.md index a8c9c6b3874e0..cf34a9c6e1276 100644 --- a/packages/@aws-cdk/aws-route53-patterns/README.md +++ b/packages/@aws-cdk/aws-route53-patterns/README.md @@ -51,3 +51,32 @@ new patterns.HttpsRedirect(this, 'Redirect', { }), }); ``` + +To have `HttpsRedirect` use the `Certificate` construct as the default +created certificate instead of the deprecated `DnsValidatedCertificate` +construct, enable the `@aws-cdk/aws-route53-patters:useCertificate` +feature flag. If you are creating the stack in a region other than `us-east-1` +you must also enable `crossRegionReferences` on the stack. + +```ts +declare const app: App; +const stack = new Stack(app, 'Stack', { + crossRegionReferences: true, + env: { + region: 'us-east-2', + }, +}); + +new patterns.HttpsRedirect(this, 'Redirect', { + recordNames: ['foo.example.com'], + targetDomain: 'bar.example.com', + zone: route53.HostedZone.fromHostedZoneAttributes(this, 'HostedZone', { + hostedZoneId: 'ID', + zoneName: 'example.com', + }), +}); +``` + +It is safe to upgrade to `@aws-cdk/aws-route53-patterns:useCertificate` since +the new certificate will be created and updated on the CloudFront distribution +before the old certificate is deleted. diff --git a/packages/@aws-cdk/aws-route53-patterns/lib/website-redirect.ts b/packages/@aws-cdk/aws-route53-patterns/lib/website-redirect.ts index 20f0eacd8ec2e..dfb2e44be5c7b 100644 --- a/packages/@aws-cdk/aws-route53-patterns/lib/website-redirect.ts +++ b/packages/@aws-cdk/aws-route53-patterns/lib/website-redirect.ts @@ -1,10 +1,11 @@ -import { md5hash } from '@aws-cdk/core/lib/helpers-internal'; -import { DnsValidatedCertificate, ICertificate } from '@aws-cdk/aws-certificatemanager'; +import { DnsValidatedCertificate, ICertificate, Certificate, CertificateValidation } from '@aws-cdk/aws-certificatemanager'; import { CloudFrontWebDistribution, OriginProtocolPolicy, PriceClass, ViewerCertificate, ViewerProtocolPolicy } from '@aws-cdk/aws-cloudfront'; import { ARecord, AaaaRecord, IHostedZone, RecordTarget } from '@aws-cdk/aws-route53'; import { CloudFrontTarget } from '@aws-cdk/aws-route53-targets'; import { BlockPublicAccess, Bucket, RedirectProtocol } from '@aws-cdk/aws-s3'; -import { ArnFormat, RemovalPolicy, Stack, Token } from '@aws-cdk/core'; +import { ArnFormat, RemovalPolicy, Stack, Token, FeatureFlags } from '@aws-cdk/core'; +import { md5hash } from '@aws-cdk/core/lib/helpers-internal'; +import { ROUTE53_PATTERNS_USE_CERTIFICATE } from '@aws-cdk/cx-api'; import { Construct } from 'constructs'; /** @@ -63,13 +64,7 @@ export class HttpsRedirect extends Construct { throw new Error(`The certificate must be in the us-east-1 region and the certificate you provided is in ${certificateRegion}.`); } } - - const redirectCert = props.certificate ?? new DnsValidatedCertificate(this, 'RedirectCertificate', { - domainName: domainNames[0], - subjectAlternativeNames: domainNames, - hostedZone: props.zone, - region: 'us-east-1', - }); + const redirectCert = props.certificate ?? this.createCertificate(domainNames, props.zone); const redirectBucket = new Bucket(this, 'RedirectBucket', { websiteRedirect: { @@ -107,4 +102,70 @@ export class HttpsRedirect extends Construct { new AaaaRecord(this, `RedirectAliasRecordSix${hash}`, aliasProps); }); } + + /** + * Gets the stack to use for creating the Certificate + * If the current stack is not in `us-east-1` then this + * will create a new `us-east-1` stack. + * + * CloudFront is a global resource which you can create (via CloudFormation) from + * _any_ region. So I could create a CloudFront distribution in `us-east-2` if I wanted + * to (maybe the rest of my application lives there). The problem is that some supporting resources + * that CloudFront uses (i.e. ACM Certificates) are required to exist in `us-east-1`. This means + * that if I want to create a CloudFront distribution in `us-east-2` I still need to create a ACM certificate in + * `us-east-1`. + * + * In order to do this correctly we need to know which region the CloudFront distribution is being created in. + * We have two options, either require the user to specify the region or make an assumption if they do not. + * This implementation requires the user specify the region. + */ + private certificateScope(): Construct { + const stack = Stack.of(this); + const parent = stack.node.scope; + if (!parent) { + throw new Error(`Stack ${stack.stackId} must be created in the scope of an App or Stage`); + } + if (Token.isUnresolved(stack.region)) { + throw new Error(`When ${ROUTE53_PATTERNS_USE_CERTIFICATE} is enabled, a region must be defined on the Stack`); + } + if (stack.region !== 'us-east-1') { + const stackId = `certificate-redirect-stack-${stack.node.addr}`; + const certStack = parent.node.tryFindChild(stackId) as Stack; + return certStack ?? new Stack(parent, stackId, { + env: { region: 'us-east-1', account: stack.account }, + }); + } + return this; + } + + /** + * Creates a certificate. + * + * If the `ROUTE53_PATTERNS_USE_CERTIFICATE` feature flag is set then + * this will use the `Certificate` class otherwise it will use the + * `DnsValidatedCertificate` class + * + * This is also safe to upgrade since the new certificate will be created and updated + * on the CloudFront distribution before the old one is deleted. + */ + private createCertificate(domainNames: string[], zone: IHostedZone): ICertificate { + const useCertificate = FeatureFlags.of(this).isEnabled(ROUTE53_PATTERNS_USE_CERTIFICATE); + if (useCertificate) { + // this preserves backwards compatibility. Previously the certificate was always created in `this` scope + // so we need to keep the name the same + const id = (this.certificateScope() === this) ? 'RedirectCertificate' : 'RedirectCertificate'+this.node.addr; + return new Certificate(this.certificateScope(), id, { + domainName: domainNames[0], + subjectAlternativeNames: domainNames, + validation: CertificateValidation.fromDns(zone), + }); + } else { + return new DnsValidatedCertificate(this, 'RedirectCertificate', { + domainName: domainNames[0], + subjectAlternativeNames: domainNames, + hostedZone: zone, + region: 'us-east-1', + }); + } + } } diff --git a/packages/@aws-cdk/aws-route53-patterns/package.json b/packages/@aws-cdk/aws-route53-patterns/package.json index 21f2fd6d4dd6e..8b2d298daf4ed 100644 --- a/packages/@aws-cdk/aws-route53-patterns/package.json +++ b/packages/@aws-cdk/aws-route53-patterns/package.json @@ -76,6 +76,7 @@ "@aws-cdk/assertions": "0.0.0", "@aws-cdk/cdk-build-tools": "0.0.0", "@aws-cdk/integ-runner": "0.0.0", + "@aws-cdk/integ-tests": "0.0.0", "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^27.5.2", @@ -89,6 +90,7 @@ "@aws-cdk/aws-route53-targets": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@aws-cdk/core": "0.0.0", + "@aws-cdk/cx-api": "0.0.0", "@aws-cdk/region-info": "0.0.0", "constructs": "^10.0.0" }, @@ -101,6 +103,7 @@ "@aws-cdk/aws-route53-targets": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@aws-cdk/core": "0.0.0", + "@aws-cdk/cx-api": "0.0.0", "@aws-cdk/region-info": "0.0.0", "constructs": "^10.0.0" }, diff --git a/packages/@aws-cdk/aws-route53-patterns/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-route53-patterns/rosetta/default.ts-fixture index 1ec9038bfff0b..e3c0d143d05a6 100644 --- a/packages/@aws-cdk/aws-route53-patterns/rosetta/default.ts-fixture +++ b/packages/@aws-cdk/aws-route53-patterns/rosetta/default.ts-fixture @@ -1,6 +1,6 @@ // Fixture with packages imported, but nothing else import { Construct } from 'constructs'; -import { Stack } from '@aws-cdk/core'; +import { Stack, App } from '@aws-cdk/core'; import * as route53 from '@aws-cdk/aws-route53'; import * as patterns from '@aws-cdk/aws-route53-patterns'; diff --git a/packages/@aws-cdk/aws-route53-patterns/test/bucket-website-target.test.ts b/packages/@aws-cdk/aws-route53-patterns/test/bucket-website-target.test.ts index 91f81a467a43f..972129fa02f79 100644 --- a/packages/@aws-cdk/aws-route53-patterns/test/bucket-website-target.test.ts +++ b/packages/@aws-cdk/aws-route53-patterns/test/bucket-website-target.test.ts @@ -2,6 +2,7 @@ import { Template } from '@aws-cdk/assertions'; import { Certificate } from '@aws-cdk/aws-certificatemanager'; import { HostedZone } from '@aws-cdk/aws-route53'; import { App, Stack } from '@aws-cdk/core'; +import { ROUTE53_PATTERNS_USE_CERTIFICATE } from '@aws-cdk/cx-api'; import { HttpsRedirect } from '../lib'; test('create HTTPS redirect', () => { @@ -152,3 +153,144 @@ test('throws when certificate in region other than us-east-1 is supplied', () => }); }).toThrow(/The certificate must be in the us-east-1 region and the certificate you provided is in us-east-2./); }); + +describe('Uses Certificate when @aws-cdk/aws-route53-patters:useCertificate=true', () => { + test('explicit different region', () => { + // GIVEN + const app = new App({ + context: { + [ROUTE53_PATTERNS_USE_CERTIFICATE]: true, + }, + }); + + // WHEN + const stack = new Stack(app, 'test', { env: { region: 'us-east-2' }, crossRegionReferences: true }); + new HttpsRedirect(stack, 'Redirect', { + recordNames: ['foo.example.com'], + targetDomain: 'bar.example.com', + zone: HostedZone.fromHostedZoneAttributes(stack, 'HostedZone', { + hostedZoneId: 'ID', + zoneName: 'example.com', + }), + }); + + // THEN + const certStack = app.node.findChild(`certificate-redirect-stack-${stack.node.addr}`) as Stack; + Template.fromStack(certStack).hasResourceProperties('AWS::CertificateManager::Certificate', { + DomainName: 'foo.example.com', + }); + + Template.fromStack(stack).hasResourceProperties('AWS::CloudFront::Distribution', { + DistributionConfig: { + ViewerCertificate: { + AcmCertificateArn: { + 'Fn::GetAtt': [ + 'ExportsReader8B249524', + '/cdk/exports/test/certificateredirectstackc8e2763df63c0f7e0c9afe0394e299bb731e281e8euseast1RefRedirectCertificatec8693e36481e135aa76e35c2db892ec6a33a94c7461E1B6E15A36EB7DA', + ], + }, + }, + }, + }); + }); + + test('explicit same region', () => { + // GIVEN + const app = new App({ + context: { + [ROUTE53_PATTERNS_USE_CERTIFICATE]: true, + }, + }); + + // WHEN + const stack = new Stack(app, 'test', { env: { region: 'us-east-1' }, crossRegionReferences: true }); + new HttpsRedirect(stack, 'Redirect', { + recordNames: ['foo.example.com'], + targetDomain: 'bar.example.com', + zone: HostedZone.fromHostedZoneAttributes(stack, 'HostedZone', { + hostedZoneId: 'ID', + zoneName: 'example.com', + }), + }); + + // THEN + const certStack = app.node.tryFindChild(`certificate-redirect-stack-${stack.node.addr}`); + expect(certStack).toBeUndefined(); + Template.fromStack(stack).hasResourceProperties('AWS::CertificateManager::Certificate', { + DomainName: 'foo.example.com', + }); + + Template.fromStack(stack).hasResourceProperties('AWS::CloudFront::Distribution', { + DistributionConfig: { + ViewerCertificate: { + AcmCertificateArn: { + Ref: 'RedirectRedirectCertificateB4F2F130', + }, + }, + }, + }); + }); + + test('same support stack used for multiple certificates', () => { + // GIVEN + const app = new App({ + context: { + [ROUTE53_PATTERNS_USE_CERTIFICATE]: true, + }, + }); + + // WHEN + const stack = new Stack(app, 'test', { env: { region: 'us-east-2' }, crossRegionReferences: true }); + new HttpsRedirect(stack, 'Redirect', { + recordNames: ['foo.example.com'], + targetDomain: 'bar.example.com', + zone: HostedZone.fromHostedZoneAttributes(stack, 'HostedZone', { + hostedZoneId: 'ID', + zoneName: 'example.com', + }), + }); + + new HttpsRedirect(stack, 'Redirect2', { + recordNames: ['foo2.example.com'], + targetDomain: 'bar2.example.com', + zone: HostedZone.fromHostedZoneAttributes(stack, 'HostedZone2', { + hostedZoneId: 'ID', + zoneName: 'example.com', + }), + }); + + // THEN + const certStack = app.node.tryFindChild(`certificate-redirect-stack-${stack.node.addr}`) as Stack; + Template.fromStack(certStack).hasResourceProperties('AWS::CertificateManager::Certificate', { + DomainName: 'foo.example.com', + }); + Template.fromStack(certStack).hasResourceProperties('AWS::CertificateManager::Certificate', { + DomainName: 'foo2.example.com', + }); + }); + + test('unresolved region throws', () => { + // GIVEN + const app = new App({ + context: { + [ROUTE53_PATTERNS_USE_CERTIFICATE]: true, + }, + }); + + // WHEN + const stack = new Stack(app, 'test'); + + // THEN + expect(() => { + new HttpsRedirect(stack, 'Redirect', { + recordNames: ['foo.example.com'], + targetDomain: 'bar.example.com', + zone: HostedZone.fromHostedZoneAttributes(stack, 'HostedZone', { + hostedZoneId: 'ID', + zoneName: 'example.com', + }), + }); + + }).toThrow(/When @aws-cdk\/aws-route53-patters:useCertificate is enabled, a region must be defined on the Stack/); + }); +}); diff --git a/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/cdk.out b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/cdk.out new file mode 100644 index 0000000000000..145739f539580 --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"22.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/integ-https-redirect-same-region.assets.json b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/integ-https-redirect-same-region.assets.json new file mode 100644 index 0000000000000..a829f07fccabf --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/integ-https-redirect-same-region.assets.json @@ -0,0 +1,20 @@ +{ + "version": "22.0.0", + "files": { + "cfd1c229f1b6f82ba7c98886bbb9cce3f98c3d07fc1cee4b2525494d7cd8d4bf": { + "source": { + "path": "integ-https-redirect-same-region.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-us-east-1": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1", + "objectKey": "cfd1c229f1b6f82ba7c98886bbb9cce3f98c3d07fc1cee4b2525494d7cd8d4bf.json", + "region": "us-east-1", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-us-east-1" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/integ-https-redirect-same-region.template.json b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/integ-https-redirect-same-region.template.json new file mode 100644 index 0000000000000..c36c3fe38ac1c --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/integ-https-redirect-same-region.template.json @@ -0,0 +1,217 @@ +{ + "Resources": { + "redirectRedirectCertificateD6C59F7F": { + "Type": "AWS::CertificateManager::Certificate", + "Properties": { + "DomainName": "integ-same-region.example.com", + "DomainValidationOptions": [ + { + "DomainName": "integ-same-region.example.com", + "HostedZoneId": "Z23ABC4XYZL05B" + }, + { + "DomainName": "integ-same-region.example.com", + "HostedZoneId": "Z23ABC4XYZL05B" + } + ], + "SubjectAlternativeNames": [ + "integ-same-region.example.com" + ], + "Tags": [ + { + "Key": "Name", + "Value": "integ-https-redirect-same-region/redirect/RedirectCertificate" + } + ], + "ValidationMethod": "DNS" + } + }, + "redirectRedirectBucketAA44E2FE": { + "Type": "AWS::S3::Bucket", + "Properties": { + "PublicAccessBlockConfiguration": { + "BlockPublicAcls": true, + "BlockPublicPolicy": true, + "IgnorePublicAcls": true, + "RestrictPublicBuckets": true + }, + "WebsiteConfiguration": { + "RedirectAllRequestsTo": { + "HostName": "aws.amazon.com", + "Protocol": "https" + } + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "redirectRedirectDistributionCFDistribution1A4C48E3": { + "Type": "AWS::CloudFront::Distribution", + "Properties": { + "DistributionConfig": { + "Aliases": [ + "integ-same-region.example.com" + ], + "Comment": "Redirect to aws.amazon.com from integ-same-region.example.com", + "DefaultCacheBehavior": { + "AllowedMethods": [ + "GET", + "HEAD" + ], + "CachedMethods": [ + "GET", + "HEAD" + ], + "Compress": true, + "ForwardedValues": { + "Cookies": { + "Forward": "none" + }, + "QueryString": false + }, + "TargetOriginId": "origin1", + "ViewerProtocolPolicy": "redirect-to-https" + }, + "DefaultRootObject": "", + "Enabled": true, + "HttpVersion": "http2", + "IPV6Enabled": true, + "Origins": [ + { + "ConnectionAttempts": 3, + "ConnectionTimeout": 10, + "CustomOriginConfig": { + "HTTPPort": 80, + "HTTPSPort": 443, + "OriginKeepaliveTimeout": 5, + "OriginProtocolPolicy": "http-only", + "OriginReadTimeout": 30, + "OriginSSLProtocols": [ + "TLSv1.2" + ] + }, + "DomainName": { + "Fn::Select": [ + 2, + { + "Fn::Split": [ + "/", + { + "Fn::GetAtt": [ + "redirectRedirectBucketAA44E2FE", + "WebsiteURL" + ] + } + ] + } + ] + }, + "Id": "origin1" + } + ], + "PriceClass": "PriceClass_All", + "ViewerCertificate": { + "AcmCertificateArn": { + "Ref": "redirectRedirectCertificateD6C59F7F" + }, + "SslSupportMethod": "sni-only" + } + } + } + }, + "redirectRedirectAliasRecorde7728a9F2A656C": { + "Type": "AWS::Route53::RecordSet", + "Properties": { + "Name": "integ-same-region.example.com.", + "Type": "A", + "AliasTarget": { + "DNSName": { + "Fn::GetAtt": [ + "redirectRedirectDistributionCFDistribution1A4C48E3", + "DomainName" + ] + }, + "HostedZoneId": { + "Fn::FindInMap": [ + "AWSCloudFrontPartitionHostedZoneIdMap", + { + "Ref": "AWS::Partition" + }, + "zoneId" + ] + } + }, + "HostedZoneId": "Z23ABC4XYZL05B" + } + }, + "redirectRedirectAliasRecordSixe7728a9391F03E": { + "Type": "AWS::Route53::RecordSet", + "Properties": { + "Name": "integ-same-region.example.com.", + "Type": "AAAA", + "AliasTarget": { + "DNSName": { + "Fn::GetAtt": [ + "redirectRedirectDistributionCFDistribution1A4C48E3", + "DomainName" + ] + }, + "HostedZoneId": { + "Fn::FindInMap": [ + "AWSCloudFrontPartitionHostedZoneIdMap", + { + "Ref": "AWS::Partition" + }, + "zoneId" + ] + } + }, + "HostedZoneId": "Z23ABC4XYZL05B" + } + } + }, + "Mappings": { + "AWSCloudFrontPartitionHostedZoneIdMap": { + "aws": { + "zoneId": "Z2FDTNDATAQYW2" + }, + "aws-cn": { + "zoneId": "Z3RFFRIM2A3IF5" + } + } + }, + "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-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/integ.json b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/integ.json new file mode 100644 index 0000000000000..5fa00cc3de2a0 --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/integ.json @@ -0,0 +1,14 @@ +{ + "enableLookups": true, + "version": "22.0.0", + "testCases": { + "integ-test/DefaultTest": { + "stacks": [ + "integ-https-redirect-same-region" + ], + "stackUpdateWorkflow": false, + "assertionStack": "integ-test/DefaultTest/DeployAssert", + "assertionStackName": "integtestDefaultTestDeployAssert24D5C536" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/integtestDefaultTestDeployAssert24D5C536.assets.json b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/integtestDefaultTestDeployAssert24D5C536.assets.json new file mode 100644 index 0000000000000..6aa47f90e9d7f --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/integtestDefaultTestDeployAssert24D5C536.assets.json @@ -0,0 +1,19 @@ +{ + "version": "22.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "integtestDefaultTestDeployAssert24D5C536.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-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/integtestDefaultTestDeployAssert24D5C536.template.json b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/integtestDefaultTestDeployAssert24D5C536.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/integtestDefaultTestDeployAssert24D5C536.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-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/manifest.json b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/manifest.json new file mode 100644 index 0000000000000..ee2d553282578 --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/manifest.json @@ -0,0 +1,177 @@ +{ + "version": "22.0.0", + "artifacts": { + "integ-https-redirect-same-region.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "integ-https-redirect-same-region.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "integ-https-redirect-same-region": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/us-east-1", + "properties": { + "templateFile": "integ-https-redirect-same-region.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-us-east-1", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-us-east-1", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1/cfd1c229f1b6f82ba7c98886bbb9cce3f98c3d07fc1cee4b2525494d7cd8d4bf.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "integ-https-redirect-same-region.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-us-east-1", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "integ-https-redirect-same-region.assets" + ], + "metadata": { + "/integ-https-redirect-same-region/redirect/RedirectCertificate/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "redirectRedirectCertificateD6C59F7F" + } + ], + "/integ-https-redirect-same-region/redirect/RedirectBucket/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "redirectRedirectBucketAA44E2FE" + } + ], + "/integ-https-redirect-same-region/redirect/RedirectDistribution/CFDistribution": [ + { + "type": "aws:cdk:logicalId", + "data": "redirectRedirectDistributionCFDistribution1A4C48E3" + } + ], + "/integ-https-redirect-same-region/redirect/RedirectAliasRecorde7728a/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "redirectRedirectAliasRecorde7728a9F2A656C" + } + ], + "/integ-https-redirect-same-region/redirect/RedirectAliasRecordSixe7728a/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "redirectRedirectAliasRecordSixe7728a9391F03E" + } + ], + "/integ-https-redirect-same-region/AWSCloudFrontPartitionHostedZoneIdMap": [ + { + "type": "aws:cdk:logicalId", + "data": "AWSCloudFrontPartitionHostedZoneIdMap" + } + ], + "/integ-https-redirect-same-region/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/integ-https-redirect-same-region/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ], + "redirectRedirectCertificateCertificateRequestorFunctionServiceRole9E01E94F": [ + { + "type": "aws:cdk:logicalId", + "data": "redirectRedirectCertificateCertificateRequestorFunctionServiceRole9E01E94F", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" + ] + } + ], + "redirectRedirectCertificateCertificateRequestorFunctionServiceRoleDefaultPolicy7AC24A96": [ + { + "type": "aws:cdk:logicalId", + "data": "redirectRedirectCertificateCertificateRequestorFunctionServiceRoleDefaultPolicy7AC24A96", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" + ] + } + ], + "redirectRedirectCertificateCertificateRequestorFunctionBBD1548C": [ + { + "type": "aws:cdk:logicalId", + "data": "redirectRedirectCertificateCertificateRequestorFunctionBBD1548C", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" + ] + } + ], + "redirectRedirectCertificateCertificateRequestorResourceBB4D62C1": [ + { + "type": "aws:cdk:logicalId", + "data": "redirectRedirectCertificateCertificateRequestorResourceBB4D62C1", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" + ] + } + ] + }, + "displayName": "integ-https-redirect-same-region" + }, + "integtestDefaultTestDeployAssert24D5C536.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "integtestDefaultTestDeployAssert24D5C536.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "integtestDefaultTestDeployAssert24D5C536": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "integtestDefaultTestDeployAssert24D5C536.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": [ + "integtestDefaultTestDeployAssert24D5C536.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": [ + "integtestDefaultTestDeployAssert24D5C536.assets" + ], + "metadata": { + "/integ-test/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/integ-test/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "integ-test/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/tree.json b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/tree.json new file mode 100644 index 0000000000000..93f7bbb68dd62 --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.js.snapshot/tree.json @@ -0,0 +1,384 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "integ-https-redirect-same-region": { + "id": "integ-https-redirect-same-region", + "path": "integ-https-redirect-same-region", + "children": { + "HostedZone": { + "id": "HostedZone", + "path": "integ-https-redirect-same-region/HostedZone", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "redirect": { + "id": "redirect", + "path": "integ-https-redirect-same-region/redirect", + "children": { + "RedirectCertificate": { + "id": "RedirectCertificate", + "path": "integ-https-redirect-same-region/redirect/RedirectCertificate", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-https-redirect-same-region/redirect/RedirectCertificate/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CertificateManager::Certificate", + "aws:cdk:cloudformation:props": { + "domainName": "integ-same-region.example.com", + "domainValidationOptions": [ + { + "domainName": "integ-same-region.example.com", + "hostedZoneId": "Z23ABC4XYZL05B" + }, + { + "domainName": "integ-same-region.example.com", + "hostedZoneId": "Z23ABC4XYZL05B" + } + ], + "subjectAlternativeNames": [ + "integ-same-region.example.com" + ], + "tags": [ + { + "key": "Name", + "value": "integ-https-redirect-same-region/redirect/RedirectCertificate" + } + ], + "validationMethod": "DNS" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-certificatemanager.CfnCertificate", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-certificatemanager.Certificate", + "version": "0.0.0" + } + }, + "RedirectBucket": { + "id": "RedirectBucket", + "path": "integ-https-redirect-same-region/redirect/RedirectBucket", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-https-redirect-same-region/redirect/RedirectBucket/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::Bucket", + "aws:cdk:cloudformation:props": { + "publicAccessBlockConfiguration": { + "blockPublicAcls": true, + "blockPublicPolicy": true, + "ignorePublicAcls": true, + "restrictPublicBuckets": true + }, + "websiteConfiguration": { + "redirectAllRequestsTo": { + "hostName": "aws.amazon.com", + "protocol": "https" + } + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-s3.CfnBucket", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-s3.Bucket", + "version": "0.0.0" + } + }, + "RedirectDistribution": { + "id": "RedirectDistribution", + "path": "integ-https-redirect-same-region/redirect/RedirectDistribution", + "children": { + "CFDistribution": { + "id": "CFDistribution", + "path": "integ-https-redirect-same-region/redirect/RedirectDistribution/CFDistribution", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CloudFront::Distribution", + "aws:cdk:cloudformation:props": { + "distributionConfig": { + "comment": "Redirect to aws.amazon.com from integ-same-region.example.com", + "enabled": true, + "defaultRootObject": "", + "httpVersion": "http2", + "priceClass": "PriceClass_All", + "ipv6Enabled": true, + "origins": [ + { + "id": "origin1", + "domainName": { + "Fn::Select": [ + 2, + { + "Fn::Split": [ + "/", + { + "Fn::GetAtt": [ + "redirectRedirectBucketAA44E2FE", + "WebsiteURL" + ] + } + ] + } + ] + }, + "customOriginConfig": { + "httpPort": 80, + "httpsPort": 443, + "originKeepaliveTimeout": 5, + "originReadTimeout": 30, + "originProtocolPolicy": "http-only", + "originSslProtocols": [ + "TLSv1.2" + ] + }, + "connectionAttempts": 3, + "connectionTimeout": 10 + } + ], + "defaultCacheBehavior": { + "allowedMethods": [ + "GET", + "HEAD" + ], + "cachedMethods": [ + "GET", + "HEAD" + ], + "compress": true, + "forwardedValues": { + "queryString": false, + "cookies": { + "forward": "none" + } + }, + "targetOriginId": "origin1", + "viewerProtocolPolicy": "redirect-to-https" + }, + "aliases": [ + "integ-same-region.example.com" + ], + "viewerCertificate": { + "acmCertificateArn": { + "Ref": "redirectRedirectCertificateD6C59F7F" + }, + "sslSupportMethod": "sni-only" + } + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-cloudfront.CfnDistribution", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-cloudfront.CloudFrontWebDistribution", + "version": "0.0.0" + } + }, + "RedirectAliasRecorde7728a": { + "id": "RedirectAliasRecorde7728a", + "path": "integ-https-redirect-same-region/redirect/RedirectAliasRecorde7728a", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-https-redirect-same-region/redirect/RedirectAliasRecorde7728a/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Route53::RecordSet", + "aws:cdk:cloudformation:props": { + "name": "integ-same-region.example.com.", + "type": "A", + "aliasTarget": { + "hostedZoneId": { + "Fn::FindInMap": [ + "AWSCloudFrontPartitionHostedZoneIdMap", + { + "Ref": "AWS::Partition" + }, + "zoneId" + ] + }, + "dnsName": { + "Fn::GetAtt": [ + "redirectRedirectDistributionCFDistribution1A4C48E3", + "DomainName" + ] + } + }, + "hostedZoneId": "Z23ABC4XYZL05B" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-route53.CfnRecordSet", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-route53.ARecord", + "version": "0.0.0" + } + }, + "RedirectAliasRecordSixe7728a": { + "id": "RedirectAliasRecordSixe7728a", + "path": "integ-https-redirect-same-region/redirect/RedirectAliasRecordSixe7728a", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-https-redirect-same-region/redirect/RedirectAliasRecordSixe7728a/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Route53::RecordSet", + "aws:cdk:cloudformation:props": { + "name": "integ-same-region.example.com.", + "type": "AAAA", + "aliasTarget": { + "hostedZoneId": { + "Fn::FindInMap": [ + "AWSCloudFrontPartitionHostedZoneIdMap", + { + "Ref": "AWS::Partition" + }, + "zoneId" + ] + }, + "dnsName": { + "Fn::GetAtt": [ + "redirectRedirectDistributionCFDistribution1A4C48E3", + "DomainName" + ] + } + }, + "hostedZoneId": "Z23ABC4XYZL05B" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-route53.CfnRecordSet", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-route53.AaaaRecord", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-route53-patterns.HttpsRedirect", + "version": "0.0.0" + } + }, + "AWSCloudFrontPartitionHostedZoneIdMap": { + "id": "AWSCloudFrontPartitionHostedZoneIdMap", + "path": "integ-https-redirect-same-region/AWSCloudFrontPartitionHostedZoneIdMap", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnMapping", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "integ-https-redirect-same-region/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "integ-https-redirect-same-region/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "integ-test": { + "id": "integ-test", + "path": "integ-test", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "integ-test/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "integ-test/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.168" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "integ-test/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "integ-test/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "integ-test/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.168" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.ts b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.ts new file mode 100644 index 0000000000000..d5f79d88d0697 --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.ts @@ -0,0 +1,38 @@ +import { PublicHostedZone } from '@aws-cdk/aws-route53'; +import { Stack, App } from '@aws-cdk/core'; +// import { ROUTE53_PATTERNS_USE_CERTIFICATE } from '@aws-cdk/cx-api'; +import { IntegTest } from '@aws-cdk/integ-tests'; +import { HttpsRedirect } from '../lib'; +const hostedZoneId = process.env.CDK_INTEG_HOSTED_ZONE_ID ?? process.env.HOSTED_ZONE_ID; +if (!hostedZoneId) throw new Error('For this test you must provide your own HostedZoneId as an env var "HOSTED_ZONE_ID"'); +const hostedZoneName = process.env.CDK_INTEG_HOSTED_ZONE_NAME ?? process.env.HOSTED_ZONE_NAME; +if (!hostedZoneName) throw new Error('For this test you must provide your own HostedZoneName as an env var "HOSTED_ZONE_NAME"'); +const domainName = process.env.CDK_INTEG_DOMAIN_NAME ?? process.env.DOMAIN_NAME; +if (!domainName) throw new Error('For this test you must provide your own Domain Name as an env var "DOMAIN_NAME"'); + +const app = new App({ + // uncomment this to test the old behavior + // postCliContext: { + // [ROUTE53_PATTERNS_USE_CERTIFICATE]: false, + // }, +}); +const testCase = new Stack(app, 'integ-https-redirect-same-region', { + env: { region: 'us-east-1' }, +}); + +const hostedZone = PublicHostedZone.fromHostedZoneAttributes(testCase, 'HostedZone', { + hostedZoneId, + zoneName: hostedZoneName, +}); +new HttpsRedirect(testCase, 'redirect', { + zone: hostedZone, + recordNames: [`integ-same-region.${hostedZoneName}`], + targetDomain: 'aws.amazon.com', +}); + +new IntegTest(app, 'integ-test', { + testCases: [testCase], + enableLookups: true, + stackUpdateWorkflow: false, +}); + diff --git a/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/asset.f86f86755c3b2013542fc4f9405bfe145a86c0bec508dd0b37baabe2055d33f3/__entrypoint__.js b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/asset.f86f86755c3b2013542fc4f9405bfe145a86c0bec508dd0b37baabe2055d33f3/__entrypoint__.js new file mode 100644 index 0000000000000..1e3a3093c1706 --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/asset.f86f86755c3b2013542fc4f9405bfe145a86c0bec508dd0b37baabe2055d33f3/__entrypoint__.js @@ -0,0 +1,144 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.withRetries = exports.handler = exports.external = void 0; +const https = require("https"); +const url = require("url"); +// for unit tests +exports.external = { + sendHttpRequest: defaultSendHttpRequest, + log: defaultLog, + includeStackTraces: true, + userHandlerIndex: './index', +}; +const CREATE_FAILED_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::CREATE_FAILED'; +const MISSING_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::MISSING_PHYSICAL_ID'; +async function handler(event, context) { + const sanitizedEvent = { ...event, ResponseURL: '...' }; + exports.external.log(JSON.stringify(sanitizedEvent, undefined, 2)); + // ignore DELETE event when the physical resource ID is the marker that + // indicates that this DELETE is a subsequent DELETE to a failed CREATE + // operation. + if (event.RequestType === 'Delete' && event.PhysicalResourceId === CREATE_FAILED_PHYSICAL_ID_MARKER) { + exports.external.log('ignoring DELETE event caused by a failed CREATE event'); + await submitResponse('SUCCESS', event); + return; + } + try { + // invoke the user handler. this is intentionally inside the try-catch to + // ensure that if there is an error it's reported as a failure to + // cloudformation (otherwise cfn waits). + // eslint-disable-next-line @typescript-eslint/no-require-imports + const userHandler = require(exports.external.userHandlerIndex).handler; + const result = await userHandler(sanitizedEvent, context); + // validate user response and create the combined event + const responseEvent = renderResponse(event, result); + // submit to cfn as success + await submitResponse('SUCCESS', responseEvent); + } + catch (e) { + const resp = { + ...event, + Reason: exports.external.includeStackTraces ? e.stack : e.message, + }; + if (!resp.PhysicalResourceId) { + // special case: if CREATE fails, which usually implies, we usually don't + // have a physical resource id. in this case, the subsequent DELETE + // operation does not have any meaning, and will likely fail as well. to + // address this, we use a marker so the provider framework can simply + // ignore the subsequent DELETE. + if (event.RequestType === 'Create') { + exports.external.log('CREATE failed, responding with a marker physical resource id so that the subsequent DELETE will be ignored'); + resp.PhysicalResourceId = CREATE_FAILED_PHYSICAL_ID_MARKER; + } + else { + // otherwise, if PhysicalResourceId is not specified, something is + // terribly wrong because all other events should have an ID. + exports.external.log(`ERROR: Malformed event. "PhysicalResourceId" is required: ${JSON.stringify(event)}`); + } + } + // this is an actual error, fail the activity altogether and exist. + await submitResponse('FAILED', resp); + } +} +exports.handler = handler; +function renderResponse(cfnRequest, handlerResponse = {}) { + // if physical ID is not returned, we have some defaults for you based + // on the request type. + const physicalResourceId = handlerResponse.PhysicalResourceId ?? cfnRequest.PhysicalResourceId ?? cfnRequest.RequestId; + // if we are in DELETE and physical ID was changed, it's an error. + if (cfnRequest.RequestType === 'Delete' && physicalResourceId !== cfnRequest.PhysicalResourceId) { + throw new Error(`DELETE: cannot change the physical resource ID from "${cfnRequest.PhysicalResourceId}" to "${handlerResponse.PhysicalResourceId}" during deletion`); + } + // merge request event and result event (result prevails). + return { + ...cfnRequest, + ...handlerResponse, + PhysicalResourceId: physicalResourceId, + }; +} +async function submitResponse(status, event) { + const json = { + Status: status, + Reason: event.Reason ?? status, + StackId: event.StackId, + RequestId: event.RequestId, + PhysicalResourceId: event.PhysicalResourceId || MISSING_PHYSICAL_ID_MARKER, + LogicalResourceId: event.LogicalResourceId, + NoEcho: event.NoEcho, + Data: event.Data, + }; + exports.external.log('submit response to cloudformation', json); + const responseBody = JSON.stringify(json); + const parsedUrl = url.parse(event.ResponseURL); + const req = { + hostname: parsedUrl.hostname, + path: parsedUrl.path, + method: 'PUT', + headers: { 'content-type': '', 'content-length': responseBody.length }, + }; + const retryOptions = { + attempts: 5, + sleep: 1000, + }; + await withRetries(retryOptions, exports.external.sendHttpRequest)(req, responseBody); +} +async function defaultSendHttpRequest(options, responseBody) { + return new Promise((resolve, reject) => { + try { + const request = https.request(options, _ => resolve()); + request.on('error', reject); + request.write(responseBody); + request.end(); + } + catch (e) { + reject(e); + } + }); +} +function defaultLog(fmt, ...params) { + // eslint-disable-next-line no-console + console.log(fmt, ...params); +} +function withRetries(options, fn) { + return async (...xs) => { + let attempts = options.attempts; + let ms = options.sleep; + while (true) { + try { + return await fn(...xs); + } + catch (e) { + if (attempts-- <= 0) { + throw e; + } + await sleep(Math.floor(Math.random() * ms)); + ms *= 2; + } + } + }; +} +exports.withRetries = withRetries; +async function sleep(ms) { + return new Promise((ok) => setTimeout(ok, ms)); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZWpzLWVudHJ5cG9pbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJub2RlanMtZW50cnlwb2ludC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsMkJBQTJCO0FBRTNCLGlCQUFpQjtBQUNKLFFBQUEsUUFBUSxHQUFHO0lBQ3RCLGVBQWUsRUFBRSxzQkFBc0I7SUFDdkMsR0FBRyxFQUFFLFVBQVU7SUFDZixrQkFBa0IsRUFBRSxJQUFJO0lBQ3hCLGdCQUFnQixFQUFFLFNBQVM7Q0FDNUIsQ0FBQztBQUVGLE1BQU0sZ0NBQWdDLEdBQUcsd0RBQXdELENBQUM7QUFDbEcsTUFBTSwwQkFBMEIsR0FBRyw4REFBOEQsQ0FBQztBQVczRixLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQWtELEVBQUUsT0FBMEI7SUFDMUcsTUFBTSxjQUFjLEdBQUcsRUFBRSxHQUFHLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDeEQsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFM0QsdUVBQXVFO0lBQ3ZFLHVFQUF1RTtJQUN2RSxhQUFhO0lBQ2IsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsa0JBQWtCLEtBQUssZ0NBQWdDLEVBQUU7UUFDbkcsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsdURBQXVELENBQUMsQ0FBQztRQUN0RSxNQUFNLGNBQWMsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdkMsT0FBTztLQUNSO0lBRUQsSUFBSTtRQUNGLHlFQUF5RTtRQUN6RSxpRUFBaUU7UUFDakUsd0NBQXdDO1FBQ3hDLGlFQUFpRTtRQUNqRSxNQUFNLFdBQVcsR0FBWSxPQUFPLENBQUMsZ0JBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUN4RSxNQUFN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RUFBRSxFQUFFO1FBQ3hCLElBQUksUUFBUSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7UUFDaEMsSUFBSSxFQUFFLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQztRQUN2QixPQUFPLElBQUksRUFBRTtZQUNYLElBQUk7Z0JBQ0YsT0FBTyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO2FBQ3hCO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1YsSUFBSSxRQUFRLEVBQUUsSUFBSSxDQUFDLEVBQUU7b0JBQ25CLE1BQU0sQ0FBQyxDQUFDO2lCQUNUO2dCQUNELE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQzVDLEVBQUUsSUFBSSxDQUFDLENBQUM7YUFDVDtTQUNGO0lBQ0gsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQWhCRCxrQ0FnQkM7QUFFRCxLQUFLLFVBQVUsS0FBSyxDQUFDLEVBQVU7SUFDN0IsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2pELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBodHRwcyBmcm9tICdodHRwcyc7XG5pbXBvcnQgKiBhcyB1cmwgZnJvbSAndXJsJztcblxuLy8gZm9yIHVuaXQgdGVzdHNcbmV4cG9ydCBjb25zdCBleHRlcm5hbCA9IHtcbiAgc2VuZEh0dHBSZXF1ZXN0OiBkZWZhdWx0U2VuZEh0dHBSZXF1ZXN0LFxuICBsb2c6IGRlZmF1bHRMb2csXG4gIGluY2x1ZGVTdGFja1RyYWNlczogdHJ1ZSxcbiAgdXNlckhhbmRsZXJJbmRleDogJy4vaW5kZXgnLFxufTtcblxuY29uc3QgQ1JFQVRFX0ZBSUxFRF9QSFlTSUNBTF9JRF9NQVJLRVIgPSAnQVdTQ0RLOjpDdXN0b21SZXNvdXJjZVByb3ZpZGVyRnJhbWV3b3JrOjpDUkVBVEVfRkFJTEVEJztcbmNvbnN0IE1JU1NJTkdfUEhZU0lDQUxfSURfTUFSS0VSID0gJ0FXU0NESzo6Q3VzdG9tUmVzb3VyY2VQcm92aWRlckZyYW1ld29yazo6TUlTU0lOR19QSFlTSUNBTF9JRCc7XG5cbmV4cG9ydCB0eXBlIFJlc3BvbnNlID0gQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCAmIEhhbmRsZXJSZXNwb25zZTtcbmV4cG9ydCB0eXBlIEhhbmRsZXIgPSAoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSA9PiBQcm9taXNlPEhhbmRsZXJSZXNwb25zZSB8IHZvaWQ+O1xuZXhwb3J0IHR5cGUgSGFuZGxlclJlc3BvbnNlID0gdW5kZWZpbmVkIHwge1xuICBEYXRhPzogYW55O1xuICBQaHlzaWNhbFJlc291cmNlSWQ/OiBzdHJpbmc7XG4gIFJlYXNvbj86IHN0cmluZztcbiAgTm9FY2hvPzogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50LCBjb250ZXh0OiBBV1NMYW1iZGEuQ29udGV4dCkge1xuICBjb25zdCBzYW5pdGl6ZWRFdmVudCA9IHsgLi4uZXZlbnQsIFJlc3BvbnNlVVJMOiAnLi4uJyB9O1xuICBleHRlcm5hbC5sb2coSlNPTi5zdHJpbmdpZnkoc2FuaXRpemVkRXZlbnQsIHVuZGVmaW5lZCwgMikpO1xuXG4gIC8vIGlnbm9yZSBERUxFVEUgZXZlbnQgd2hlbiB0aGUgcGh5c2ljYWwgcmVzb3VyY2UgSUQgaXMgdGhlIG1hcmtlciB0aGF0XG4gIC8vIGluZGljYXRlcyB0aGF0IHRoaXMgREVMRVRFIGlzIGEgc3Vic2VxdWVudCBERUxFVEUgdG8gYSBmYWlsZWQgQ1JFQVRFXG4gIC8vIG9wZXJhdGlvbi5cbiAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnRGVsZXRlJyAmJiBldmVudC5QaHlzaWNhbFJlc291cmNlSWQgPT09IENSRUFURV9GQUlMRURfUEhZU0lDQUxfSURfTUFSS0VSKSB7XG4gICAgZXh0ZXJuYWwubG9nKCdpZ25vcmluZyBERUxFVEUgZXZlbnQgY2F1c2VkIGJ5IGEgZmFpbGVkIENSRUFURSBldmVudCcpO1xuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdTVUNDRVNTJywgZXZlbnQpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRyeSB7XG4gICAgLy8gaW52b2tlIHRoZSB1c2VyIGhhbmRsZXIuIHRoaXMgaXMgaW50ZW50aW9uYWxseSBpbnNpZGUgdGhlIHRyeS1jYXRjaCB0b1xuICAgIC8vIGVuc3VyZSB0aGF0IGlmIHRoZXJlIGlzIGFuIGVycm9yIGl0J3MgcmVwb3J0ZWQgYXMgYSBmYWlsdXJlIHRvXG4gICAgLy8gY2xvdWRmb3JtYXRpb24gKG90aGVyd2lzZSBjZm4gd2FpdHMpLlxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gICAgY29uc3QgdXNlckhhbmRsZXI6IEhhbmRsZXIgPSByZXF1aXJlKGV4dGVybmFsLnVzZXJIYW5kbGVySW5kZXgpLmhhbmRsZXI7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdXNlckhhbmRsZXIoc2FuaXRpemVkRXZlbnQsIGNvbnRleHQpO1xuXG4gICAgLy8gdmFsaWRhdGUgdXNlciByZXNwb25zZSBhbmQgY3JlYXRlIHRoZSBjb21iaW5lZCBldmVudFxuICAgIGNvbnN0IHJlc3BvbnNlRXZlbnQgPSByZW5kZXJSZXNwb25zZShldmVudCwgcmVzdWx0KTtcblxuICAgIC8vIHN1Ym1pdCB0byBjZm4gYXMgc3VjY2Vzc1xuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdTVUNDRVNTJywgcmVzcG9uc2VFdmVudCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zdCByZXNwOiBSZXNwb25zZSA9IHtcbiAgICAgIC4uLmV2ZW50LFxuICAgICAgUmVhc29uOiBleHRlcm5hbC5pbmNsdWRlU3RhY2tUcmFjZXMgPyBlLnN0YWNrIDogZS5tZXNzYWdlLFxuICAgIH07XG5cbiAgICBpZiAoIXJlc3AuUGh5c2ljYWxSZXNvdXJjZUlkKSB7XG4gICAgICAvLyBzcGVjaWFsIGNhc2U6IGlmIENSRUFURSBmYWlscywgd2hpY2ggdXN1YWxseSBpbXBsaWVzLCB3ZSB1c3VhbGx5IGRvbid0XG4gICAgICAvLyBoYXZlIGEgcGh5c2ljYWwgcmVzb3VyY2UgaWQuIGluIHRoaXMgY2FzZSwgdGhlIHN1YnNlcXVlbnQgREVMRVRFXG4gICAgICAvLyBvcGVyYXRpb24gZG9lcyBub3QgaGF2ZSBhbnkgbWVhbmluZywgYW5kIHdpbGwgbGlrZWx5IGZhaWwgYXMgd2VsbC4gdG9cbiAgICAgIC8vIGFkZHJlc3MgdGhpcywgd2UgdXNlIGEgbWFya2VyIHNvIHRoZSBwcm92aWRlciBmcmFtZXdvcmsgY2FuIHNpbXBseVxuICAgICAgLy8gaWdub3JlIHRoZSBzdWJzZXF1ZW50IERFTEVURS5cbiAgICAgIGlmIChldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ0NyZWF0ZScpIHtcbiAgICAgICAgZXh0ZXJuYWwubG9nKCdDUkVBVEUgZmFpbGVkLCByZXNwb25kaW5nIHdpdGggYSBtYXJrZXIgcGh5c2ljYWwgcmVzb3VyY2UgaWQgc28gdGhhdCB0aGUgc3Vic2VxdWVudCBERUxFVEUgd2lsbCBiZSBpZ25vcmVkJyk7XG4gICAgICAgIHJlc3AuUGh5c2ljYWxSZXNvdXJjZUlkID0gQ1JFQVRFX0ZBSUxFRF9QSFlTSUNBTF9JRF9NQVJLRVI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBvdGhlcndpc2UsIGlmIFBoeXNpY2FsUmVzb3VyY2VJZCBpcyBub3Qgc3BlY2lmaWVkLCBzb21ldGhpbmcgaXNcbiAgICAgICAgLy8gdGVycmlibHkgd3JvbmcgYmVjYXVzZSBhbGwgb3RoZXIgZXZlbnRzIHNob3VsZCBoYXZlIGFuIElELlxuICAgICAgICBleHRlcm5hbC5sb2coYEVSUk9SOiBNYWxmb3JtZWQgZXZlbnQuIFwiUGh5c2ljYWxSZXNvdXJjZUlkXCIgaXMgcmVxdWlyZWQ6ICR7SlNPTi5zdHJpbmdpZnkoZXZlbnQpfWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHRoaXMgaXMgYW4gYWN0dWFsIGVycm9yLCBmYWlsIHRoZSBhY3Rpdml0eSBhbHRvZ2V0aGVyIGFuZCBleGlzdC5cbiAgICBhd2FpdCBzdWJtaXRSZXNwb25zZSgnRkFJTEVEJywgcmVzcCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVuZGVyUmVzcG9uc2UoXG4gIGNmblJlcXVlc3Q6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQgJiB7IFBoeXNpY2FsUmVzb3VyY2VJZD86IHN0cmluZyB9LFxuICBoYW5kbGVyUmVzcG9uc2U6IHZvaWQgfCBIYW5kbGVyUmVzcG9uc2UgPSB7IH0pOiBSZXNwb25zZSB7XG5cbiAgLy8gaWYgcGh5c2ljYWwgSUQgaXMgbm90IHJldHVybmVkLCB3ZSBoYXZlIHNvbWUgZGVmYXVsdHMgZm9yIHlvdSBiYXNlZFxuICAvLyBvbiB0aGUgcmVxdWVzdCB0eXBlLlxuICBjb25zdCBwaHlzaWNhbFJlc291cmNlSWQgPSBoYW5kbGVyUmVzcG9uc2UuUGh5c2ljYWxSZXNvdXJjZUlkID8/IGNmblJlcXVlc3QuUGh5c2ljYWxSZXNvdXJjZUlkID8/IGNmblJlcXVlc3QuUmVxdWVzdElkO1xuXG4gIC8vIGlmIHdlIGFyZSBpbiBERUxFVEUgYW5kIHBoeXNpY2FsIElEIHdhcyBjaGFuZ2VkLCBpdCdzIGFuIGVycm9yLlxuICBpZiAoY2ZuUmVxdWVzdC5SZXF1ZXN0VHlwZSA9PT0gJ0RlbGV0ZScgJiYgcGh5c2ljYWxSZXNvdXJjZUlkICE9PSBjZm5SZXF1ZXN0LlBoeXNpY2FsUmVzb3VyY2VJZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgREVMRVRFOiBjYW5ub3QgY2hhbmdlIHRoZSBwaHlzaWNhbCByZXNvdXJjZSBJRCBmcm9tIFwiJHtjZm5SZXF1ZXN0LlBoeXNpY2FsUmVzb3VyY2VJZH1cIiB0byBcIiR7aGFuZGxlclJlc3BvbnNlLlBoeXNpY2FsUmVzb3VyY2VJZH1cIiBkdXJpbmcgZGVsZXRpb25gKTtcbiAgfVxuXG4gIC8vIG1lcmdlIHJlcXVlc3QgZXZlbnQgYW5kIHJlc3VsdCBldmVudCAocmVzdWx0IHByZXZhaWxzKS5cbiAgcmV0dXJuIHtcbiAgICAuLi5jZm5SZXF1ZXN0LFxuICAgIC4uLmhhbmRsZXJSZXNwb25zZSxcbiAgICBQaHlzaWNhbFJlc291cmNlSWQ6IHBoeXNpY2FsUmVzb3VyY2VJZCxcbiAgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gc3VibWl0UmVzcG9uc2Uoc3RhdHVzOiAnU1VDQ0VTUycgfCAnRkFJTEVEJywgZXZlbnQ6IFJlc3BvbnNlKSB7XG4gIGNvbnN0IGpzb246IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlUmVzcG9uc2UgPSB7XG4gICAgU3RhdHVzOiBzdGF0dXMsXG4gICAgUmVhc29uOiBldmVudC5SZWFzb24gPz8gc3RhdHVzLFxuICAgIFN0YWNrSWQ6IGV2ZW50LlN0YWNrSWQsXG4gICAgUmVxdWVzdElkOiBldmVudC5SZXF1ZXN0SWQsXG4gICAgUGh5c2ljYWxSZXNvdXJjZUlkOiBldmVudC5QaHlzaWNhbFJlc291cmNlSWQgfHwgTUlTU0lOR19QSFlTSUNBTF9JRF9NQVJLRVIsXG4gICAgTG9naWNhbFJlc291cmNlSWQ6IGV2ZW50LkxvZ2ljYWxSZXNvdXJjZUlkLFxuICAgIE5vRWNobzogZXZlbnQuTm9FY2hvLFxuICAgIERhdGE6IGV2ZW50LkRhdGEsXG4gIH07XG5cbiAgZXh0ZXJuYWwubG9nKCdzdWJtaXQgcmVzcG9uc2UgdG8gY2xvdWRmb3JtYXRpb24nLCBqc29uKTtcblxuICBjb25zdCByZXNwb25zZUJvZHkgPSBKU09OLnN0cmluZ2lmeShqc29uKTtcbiAgY29uc3QgcGFyc2VkVXJsID0gdXJsLnBhcnNlKGV2ZW50LlJlc3BvbnNlVVJMKTtcbiAgY29uc3QgcmVxID0ge1xuICAgIGhvc3RuYW1lOiBwYXJzZWRVcmwuaG9zdG5hbWUsXG4gICAgcGF0aDogcGFyc2VkVXJsLnBhdGgsXG4gICAgbWV0aG9kOiAnUFVUJyxcbiAgICBoZWFkZXJzOiB7ICdjb250ZW50LXR5cGUnOiAnJywgJ2NvbnRlbnQtbGVuZ3RoJzogcmVzcG9uc2VCb2R5Lmxlbmd0aCB9LFxuICB9O1xuXG4gIGNvbnN0IHJldHJ5T3B0aW9ucyA9IHtcbiAgICBhdHRlbXB0czogNSxcbiAgICBzbGVlcDogMTAwMCxcbiAgfTtcbiAgYXdhaXQgd2l0aFJldHJpZXMocmV0cnlPcHRpb25zLCBleHRlcm5hbC5zZW5kSHR0cFJlcXVlc3QpKHJlcSwgcmVzcG9uc2VCb2R5KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZGVmYXVsdFNlbmRIdHRwUmVxdWVzdChvcHRpb25zOiBodHRwcy5SZXF1ZXN0T3B0aW9ucywgcmVzcG9uc2VCb2R5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVxdWVzdCA9IGh0dHBzLnJlcXVlc3Qob3B0aW9ucywgXyA9PiByZXNvbHZlKCkpO1xuICAgICAgcmVxdWVzdC5vbignZXJyb3InLCByZWplY3QpO1xuICAgICAgcmVxdWVzdC53cml0ZShyZXNwb25zZUJvZHkpO1xuICAgICAgcmVxdWVzdC5lbmQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZWplY3QoZSk7XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdExvZyhmbXQ6IHN0cmluZywgLi4ucGFyYW1zOiBhbnlbXSkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICBjb25zb2xlLmxvZyhmbXQsIC4uLnBhcmFtcyk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmV0cnlPcHRpb25zIHtcbiAgLyoqIEhvdyBtYW55IHJldHJpZXMgKHdpbGwgYXQgbGVhc3QgdHJ5IG9uY2UpICovXG4gIHJlYWRvbmx5IGF0dGVtcHRzOiBudW1iZXI7XG4gIC8qKiBTbGVlcCBiYXNlLCBpbiBtcyAqL1xuICByZWFkb25seSBzbGVlcDogbnVtYmVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2l0aFJldHJpZXM8QSBleHRlbmRzIEFycmF5PGFueT4sIEI+KG9wdGlvbnM6IFJldHJ5T3B0aW9ucywgZm46ICguLi54czogQSkgPT4gUHJvbWlzZTxCPik6ICguLi54czogQSkgPT4gUHJvbWlzZTxCPiB7XG4gIHJldHVybiBhc3luYyAoLi4ueHM6IEEpID0+IHtcbiAgICBsZXQgYXR0ZW1wdHMgPSBvcHRpb25zLmF0dGVtcHRzO1xuICAgIGxldCBtcyA9IG9wdGlvbnMuc2xlZXA7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBmbiguLi54cyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChhdHRlbXB0cy0tIDw9IDApIHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHNsZWVwKE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIG1zKSk7XG4gICAgICAgIG1zICo9IDI7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgob2spID0+IHNldFRpbWVvdXQob2ssIG1zKSk7XG59Il19 \ No newline at end of file diff --git a/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/asset.f86f86755c3b2013542fc4f9405bfe145a86c0bec508dd0b37baabe2055d33f3/index.js b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/asset.f86f86755c3b2013542fc4f9405bfe145a86c0bec508dd0b37baabe2055d33f3/index.js new file mode 100644 index 0000000000000..9f71f540e4994 --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/asset.f86f86755c3b2013542fc4f9405bfe145a86c0bec508dd0b37baabe2055d33f3/index.js @@ -0,0 +1,148 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.handler = void 0; +/*eslint-disable no-console*/ +/* eslint-disable import/no-extraneous-dependencies */ +const aws_sdk_1 = require("aws-sdk"); +async function handler(event) { + const props = event.ResourceProperties.WriterProps; + const exports = props.exports; + const ssm = new aws_sdk_1.SSM({ region: props.region }); + try { + switch (event.RequestType) { + case 'Create': + console.info(`Creating new SSM Parameter exports in region ${props.region}`); + await throwIfAnyInUse(ssm, exports); + await putParameters(ssm, exports); + return; + case 'Update': + const oldProps = event.OldResourceProperties.WriterProps; + const oldExports = oldProps.exports; + const newExports = except(exports, oldExports); + // throw an error to fail the deployment if any export value is changing + const changedExports = changed(oldExports, exports); + if (changedExports.length > 0) { + throw new Error('Some exports have changed!\n' + changedExports.join('\n')); + } + // if we are removing any exports that are in use, then throw an + // error to fail the deployment + const removedExports = except(oldExports, exports); + await throwIfAnyInUse(ssm, removedExports); + // if the ones we are removing are not in use then delete them + await ssm.deleteParameters({ + Names: Object.keys(removedExports), + }).promise(); + // also throw an error if we are creating a new export that already exists for some reason + await throwIfAnyInUse(ssm, newExports); + console.info(`Creating new SSM Parameter exports in region ${props.region}`); + await putParameters(ssm, newExports); + return; + case 'Delete': + // if any of the exports are currently in use then throw an error to fail + // the stack deletion. + await throwIfAnyInUse(ssm, exports); + // if none are in use then delete all of them + await ssm.deleteParameters({ + Names: Object.keys(exports), + }).promise(); + return; + default: + return; + } + } + catch (e) { + console.error('Error processing event: ', e); + throw e; + } +} +exports.handler = handler; +; +/** + * Create parameters for existing exports + */ +async function putParameters(ssm, parameters) { + await Promise.all(Array.from(Object.entries(parameters), ([name, value]) => { + return ssm.putParameter({ + Name: name, + Value: value, + Type: 'String', + }).promise(); + })); +} +/** + * Query for existing parameters that are in use + */ +async function throwIfAnyInUse(ssm, parameters) { + const tagResults = new Map(); + await Promise.all(Object.keys(parameters).map(async (name) => { + const result = await isInUse(ssm, name); + if (result.size > 0) { + tagResults.set(name, result); + } + })); + if (tagResults.size > 0) { + const message = Object.entries(tagResults) + .map((result) => `${result[0]} is in use by stack(s) ${result[1].join(' ')}`) + .join('\n'); + throw new Error(`Exports cannot be updated: \n${message}`); + } +} +/** + * Check if a parameter is in use + */ +async function isInUse(ssm, parameterName) { + const tagResults = new Set(); + try { + const result = await ssm.listTagsForResource({ + ResourceId: parameterName, + ResourceType: 'Parameter', + }).promise(); + result.TagList?.forEach(tag => { + const tagParts = tag.Key.split(':'); + if (tagParts[0] === 'aws-cdk' && tagParts[1] === 'strong-ref') { + tagResults.add(tagParts[2]); + } + }); + } + catch (e) { + // an InvalidResourceId means that the parameter doesn't exist + // which we should ignore since that means it's not in use + if (e.code === 'InvalidResourceId') { + return new Set(); + } + throw e; + } + return tagResults; +} +/** + * Return only the items from source that do not exist in the filter + * + * @param source the source object to perform the filter on + * @param filter filter out items that exist in this object + * @returns any exports that don't exist in the filter + */ +function except(source, filter) { + return Object.keys(source) + .filter(key => (!filter.hasOwnProperty(key))) + .reduce((acc, curr) => { + acc[curr] = source[curr]; + return acc; + }, {}); +} +/** + * Return items that exist in both the the old parameters and the new parameters, + * but have different values + * + * @param oldParams the exports that existed previous to this execution + * @param newParams the exports for the current execution + * @returns any parameters that have different values + */ +function changed(oldParams, newParams) { + return Object.keys(oldParams) + .filter(key => (newParams.hasOwnProperty(key) && oldParams[key] !== newParams[key])) + .reduce((acc, curr) => { + acc.push(curr); + return acc; + }, []); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2QkFBNkI7QUFDN0Isc0RBQXNEO0FBQ3RELHFDQUE4QjtBQUd2QixLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQWtEO0lBQzlFLE1BQU0sS0FBSyxHQUF3QixLQUFLLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDO0lBQ3hFLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUE2QixDQUFDO0lBRXBELE1BQU0sR0FBRyxHQUFHLElBQUksYUFBRyxDQUFDLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQzlDLElBQUk7UUFDRixRQUFRLEtBQUssQ0FBQyxXQUFXLEVBQUU7WUFDekIsS0FBSyxRQUFRO2dCQUNYLE9BQU8sQ0FBQyxJQUFJLENBQUMsZ0RBQWdELEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO2dCQUM3RSxNQUFNLGVBQWUsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQ3BDLE1BQU0sYUFBYSxDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDbEMsT0FBTztZQUNULEtBQUssUUFBUTtnQkFDWCxNQUFNLFFBQVEsR0FBd0IsS0FBSyxDQUFDLHFCQUFxQixDQUFDLFdBQVcsQ0FBQztnQkFDOUUsTUFBTSxVQUFVLEdBQUcsUUFBUSxDQUFDLE9BQTZCLENBQUM7Z0JBQzFELE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUM7Z0JBRS9DLHdFQUF3RTtnQkFDeEUsTUFBTSxjQUFjLEdBQUcsT0FBTyxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDcEQsSUFBSSxjQUFjLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtvQkFDN0IsTUFBTSxJQUFJLEtBQUssQ0FBQyw4QkFBOEIsR0FBRSxjQUFjLENBQUMs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Q0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztTQUM1QyxNQUFNLENBQUMsQ0FBQyxHQUF1QixFQUFFLElBQVksRUFBRSxFQUFFO1FBQ2hELEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDekIsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDWCxDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILFNBQVMsT0FBTyxDQUFDLFNBQTZCLEVBQUUsU0FBNkI7SUFDM0UsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztTQUMxQixNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLElBQUksU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1NBQ25GLE1BQU0sQ0FBQyxDQUFDLEdBQWEsRUFBRSxJQUFZLEVBQUUsRUFBRTtRQUN0QyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2YsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDWCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyplc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlKi9cbi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuaW1wb3J0IHsgU1NNIH0gZnJvbSAnYXdzLXNkayc7XG5pbXBvcnQgeyBDcm9zc1JlZ2lvbkV4cG9ydHMsIEV4cG9ydFdyaXRlckNSUHJvcHMgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50KSB7XG4gIGNvbnN0IHByb3BzOiBFeHBvcnRXcml0ZXJDUlByb3BzID0gZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLldyaXRlclByb3BzO1xuICBjb25zdCBleHBvcnRzID0gcHJvcHMuZXhwb3J0cyBhcyBDcm9zc1JlZ2lvbkV4cG9ydHM7XG5cbiAgY29uc3Qgc3NtID0gbmV3IFNTTSh7IHJlZ2lvbjogcHJvcHMucmVnaW9uIH0pO1xuICB0cnkge1xuICAgIHN3aXRjaCAoZXZlbnQuUmVxdWVzdFR5cGUpIHtcbiAgICAgIGNhc2UgJ0NyZWF0ZSc6XG4gICAgICAgIGNvbnNvbGUuaW5mbyhgQ3JlYXRpbmcgbmV3IFNTTSBQYXJhbWV0ZXIgZXhwb3J0cyBpbiByZWdpb24gJHtwcm9wcy5yZWdpb259YCk7XG4gICAgICAgIGF3YWl0IHRocm93SWZBbnlJblVzZShzc20sIGV4cG9ydHMpO1xuICAgICAgICBhd2FpdCBwdXRQYXJhbWV0ZXJzKHNzbSwgZXhwb3J0cyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIGNhc2UgJ1VwZGF0ZSc6XG4gICAgICAgIGNvbnN0IG9sZFByb3BzOiBFeHBvcnRXcml0ZXJDUlByb3BzID0gZXZlbnQuT2xkUmVzb3VyY2VQcm9wZXJ0aWVzLldyaXRlclByb3BzO1xuICAgICAgICBjb25zdCBvbGRFeHBvcnRzID0gb2xkUHJvcHMuZXhwb3J0cyBhcyBDcm9zc1JlZ2lvbkV4cG9ydHM7XG4gICAgICAgIGNvbnN0IG5ld0V4cG9ydHMgPSBleGNlcHQoZXhwb3J0cywgb2xkRXhwb3J0cyk7XG5cbiAgICAgICAgLy8gdGhyb3cgYW4gZXJyb3IgdG8gZmFpbCB0aGUgZGVwbG95bWVudCBpZiBhbnkgZXhwb3J0IHZhbHVlIGlzIGNoYW5naW5nXG4gICAgICAgIGNvbnN0IGNoYW5nZWRFeHBvcnRzID0gY2hhbmdlZChvbGRFeHBvcnRzLCBleHBvcnRzKTtcbiAgICAgICAgaWYgKGNoYW5nZWRFeHBvcnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvbWUgZXhwb3J0cyBoYXZlIGNoYW5nZWQhXFxuJysgY2hhbmdlZEV4cG9ydHMuam9pbignXFxuJykpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGlmIHdlIGFyZSByZW1vdmluZyBhbnkgZXhwb3J0cyB0aGF0IGFyZSBpbiB1c2UsIHRoZW4gdGhyb3cgYW5cbiAgICAgICAgLy8gZXJyb3IgdG8gZmFpbCB0aGUgZGVwbG95bWVudFxuICAgICAgICBjb25zdCByZW1vdmVkRXhwb3J0cyA9IGV4Y2VwdChvbGRFeHBvcnRzLCBleHBvcnRzKTtcbiAgICAgICAgYXdhaXQgdGhyb3dJZkFueUluVXNlKHNzbSwgcmVtb3ZlZEV4cG9ydHMpO1xuICAgICAgICAvLyBpZiB0aGUgb25lcyB3ZSBhcmUgcmVtb3ZpbmcgYXJlIG5vdCBpbiB1c2UgdGhlbiBkZWxldGUgdGhlbVxuICAgICAgICBhd2FpdCBzc20uZGVsZXRlUGFyYW1ldGVycyh7XG4gICAgICAgICAgTmFtZXM6IE9iamVjdC5rZXlzKHJlbW92ZWRFeHBvcnRzKSxcbiAgICAgICAgfSkucHJvbWlzZSgpO1xuXG4gICAgICAgIC8vIGFsc28gdGhyb3cgYW4gZXJyb3IgaWYgd2UgYXJlIGNyZWF0aW5nIGEgbmV3IGV4cG9ydCB0aGF0IGFscmVhZHkgZXhpc3RzIGZvciBzb21lIHJlYXNvblxuICAgICAgICBhd2FpdCB0aHJvd0lmQW55SW5Vc2Uoc3NtLCBuZXdFeHBvcnRzKTtcbiAgICAgICAgY29uc29sZS5pbmZvKGBDcmVhdGluZyBuZXcgU1NNIFBhcmFtZXRlciBleHBvcnRzIGluIHJlZ2lvbiAke3Byb3BzLnJlZ2lvbn1gKTtcbiAgICAgICAgYXdhaXQgcHV0UGFyYW1ldGVycyhzc20sIG5ld0V4cG9ydHMpO1xuICAgICAgICByZXR1cm47XG4gICAgICBjYXNlICdEZWxldGUnOlxuICAgICAgICAvLyBpZiBhbnkgb2YgdGhlIGV4cG9ydHMgYXJlIGN1cnJlbnRseSBpbiB1c2UgdGhlbiB0aHJvdyBhbiBlcnJvciB0byBmYWlsXG4gICAgICAgIC8vIHRoZSBzdGFjayBkZWxldGlvbi5cbiAgICAgICAgYXdhaXQgdGhyb3dJZkFueUluVXNlKHNzbSwgZXhwb3J0cyk7XG4gICAgICAgIC8vIGlmIG5vbmUgYXJlIGluIHVzZSB0aGVuIGRlbGV0ZSBhbGwgb2YgdGhlbVxuICAgICAgICBhd2FpdCBzc20uZGVsZXRlUGFyYW1ldGVycyh7XG4gICAgICAgICAgTmFtZXM6IE9iamVjdC5rZXlzKGV4cG9ydHMpLFxuICAgICAgICB9KS5wcm9taXNlKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zb2xlLmVycm9yKCdFcnJvciBwcm9jZXNzaW5nIGV2ZW50OiAnLCBlKTtcbiAgICB0aHJvdyBlO1xuICB9XG59O1xuXG4vKipcbiAqIENyZWF0ZSBwYXJhbWV0ZXJzIGZvciBleGlzdGluZyBleHBvcnRzXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHB1dFBhcmFtZXRlcnMoc3NtOiBTU00sIHBhcmFtZXRlcnM6IENyb3NzUmVnaW9uRXhwb3J0cyk6IFByb21pc2U8dm9pZD4ge1xuICBhd2FpdCBQcm9taXNlLmFsbChBcnJheS5mcm9tKE9iamVjdC5lbnRyaWVzKHBhcmFtZXRlcnMpLCAoW25hbWUsIHZhbHVlXSkgPT4ge1xuICAgIHJldHVybiBzc20ucHV0UGFyYW1ldGVyKHtcbiAgICAgIE5hbWU6IG5hbWUsXG4gICAgICBWYWx1ZTogdmFsdWUsXG4gICAgICBUeXBlOiAnU3RyaW5nJyxcbiAgICB9KS5wcm9taXNlKCk7XG4gIH0pKTtcbn1cblxuLyoqXG4gKiBRdWVyeSBmb3IgZXhpc3RpbmcgcGFyYW1ldGVycyB0aGF0IGFyZSBpbiB1c2VcbiAqL1xuYXN5bmMgZnVuY3Rpb24gdGhyb3dJZkFueUluVXNlKHNzbTogU1NNLCBwYXJhbWV0ZXJzOiBDcm9zc1JlZ2lvbkV4cG9ydHMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgdGFnUmVzdWx0czogTWFwPHN0cmluZywgU2V0PHN0cmluZz4+ID0gbmV3IE1hcCgpO1xuICBhd2FpdCBQcm9taXNlLmFsbChPYmplY3Qua2V5cyhwYXJhbWV0ZXJzKS5tYXAoYXN5bmMgKG5hbWU6IHN0cmluZykgPT4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGlzSW5Vc2Uoc3NtLCBuYW1lKTtcbiAgICBpZiAocmVzdWx0LnNpemUgPiAwKSB7XG4gICAgICB0YWdSZXN1bHRzLnNldChuYW1lLCByZXN1bHQpO1xuICAgIH1cbiAgfSkpO1xuXG4gIGlmICh0YWdSZXN1bHRzLnNpemUgPiAwKSB7XG4gICAgY29uc3QgbWVzc2FnZTogc3RyaW5nID0gT2JqZWN0LmVudHJpZXModGFnUmVzdWx0cylcbiAgICAgIC5tYXAoKHJlc3VsdDogW3N0cmluZywgc3RyaW5nW11dKSA9PiBgJHtyZXN1bHRbMF19IGlzIGluIHVzZSBieSBzdGFjayhzKSAke3Jlc3VsdFsxXS5qb2luKCcgJyl9YClcbiAgICAgIC5qb2luKCdcXG4nKTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cG9ydHMgY2Fubm90IGJlIHVwZGF0ZWQ6IFxcbiR7bWVzc2FnZX1gKTtcbiAgfVxufVxuXG4vKipcbiAqIENoZWNrIGlmIGEgcGFyYW1ldGVyIGlzIGluIHVzZVxuICovXG5hc3luYyBmdW5jdGlvbiBpc0luVXNlKHNzbTogU1NNLCBwYXJhbWV0ZXJOYW1lOiBzdHJpbmcpOiBQcm9taXNlPFNldDxzdHJpbmc+PiB7XG4gIGNvbnN0IHRhZ1Jlc3VsdHM6IFNldDxzdHJpbmc+ID0gbmV3IFNldCgpO1xuICB0cnkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNzbS5saXN0VGFnc0ZvclJlc291cmNlKHtcbiAgICAgIFJlc291cmNlSWQ6IHBhcmFtZXRlck5hbWUsXG4gICAgICBSZXNvdXJjZVR5cGU6ICdQYXJhbWV0ZXInLFxuICAgIH0pLnByb21pc2UoKTtcbiAgICByZXN1bHQuVGFnTGlzdD8uZm9yRWFjaCh0YWcgPT4ge1xuICAgICAgY29uc3QgdGFnUGFydHMgPSB0YWcuS2V5LnNwbGl0KCc6Jyk7XG4gICAgICBpZiAodGFnUGFydHNbMF0gPT09ICdhd3MtY2RrJyAmJiB0YWdQYXJ0c1sxXSA9PT0gJ3N0cm9uZy1yZWYnKSB7XG4gICAgICAgIHRhZ1Jlc3VsdHMuYWRkKHRhZ1BhcnRzWzJdKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIGFuIEludmFsaWRSZXNvdXJjZUlkIG1lYW5zIHRoYXQgdGhlIHBhcmFtZXRlciBkb2Vzbid0IGV4aXN0XG4gICAgLy8gd2hpY2ggd2Ugc2hvdWxkIGlnbm9yZSBzaW5jZSB0aGF0IG1lYW5zIGl0J3Mgbm90IGluIHVzZVxuICAgIGlmIChlLmNvZGUgPT09ICdJbnZhbGlkUmVzb3VyY2VJZCcpIHtcbiAgICAgIHJldHVybiBuZXcgU2V0KCk7XG4gICAgfVxuICAgIHRocm93IGU7XG4gIH1cbiAgcmV0dXJuIHRhZ1Jlc3VsdHM7XG59XG5cbi8qKlxuICogUmV0dXJuIG9ubHkgdGhlIGl0ZW1zIGZyb20gc291cmNlIHRoYXQgZG8gbm90IGV4aXN0IGluIHRoZSBmaWx0ZXJcbiAqXG4gKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugb2JqZWN0IHRvIHBlcmZvcm0gdGhlIGZpbHRlciBvblxuICogQHBhcmFtIGZpbHRlciBmaWx0ZXIgb3V0IGl0ZW1zIHRoYXQgZXhpc3QgaW4gdGhpcyBvYmplY3RcbiAqIEByZXR1cm5zIGFueSBleHBvcnRzIHRoYXQgZG9uJ3QgZXhpc3QgaW4gdGhlIGZpbHRlclxuICovXG5mdW5jdGlvbiBleGNlcHQoc291cmNlOiBDcm9zc1JlZ2lvbkV4cG9ydHMsIGZpbHRlcjogQ3Jvc3NSZWdpb25FeHBvcnRzKTogQ3Jvc3NSZWdpb25FeHBvcnRzIHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKHNvdXJjZSlcbiAgICAuZmlsdGVyKGtleSA9PiAoIWZpbHRlci5oYXNPd25Qcm9wZXJ0eShrZXkpKSlcbiAgICAucmVkdWNlKChhY2M6IENyb3NzUmVnaW9uRXhwb3J0cywgY3Vycjogc3RyaW5nKSA9PiB7XG4gICAgICBhY2NbY3Vycl0gPSBzb3VyY2VbY3Vycl07XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHt9KTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gaXRlbXMgdGhhdCBleGlzdCBpbiBib3RoIHRoZSB0aGUgb2xkIHBhcmFtZXRlcnMgYW5kIHRoZSBuZXcgcGFyYW1ldGVycyxcbiAqIGJ1dCBoYXZlIGRpZmZlcmVudCB2YWx1ZXNcbiAqXG4gKiBAcGFyYW0gb2xkUGFyYW1zIHRoZSBleHBvcnRzIHRoYXQgZXhpc3RlZCBwcmV2aW91cyB0byB0aGlzIGV4ZWN1dGlvblxuICogQHBhcmFtIG5ld1BhcmFtcyB0aGUgZXhwb3J0cyBmb3IgdGhlIGN1cnJlbnQgZXhlY3V0aW9uXG4gKiBAcmV0dXJucyBhbnkgcGFyYW1ldGVycyB0aGF0IGhhdmUgZGlmZmVyZW50IHZhbHVlc1xuICovXG5mdW5jdGlvbiBjaGFuZ2VkKG9sZFBhcmFtczogQ3Jvc3NSZWdpb25FeHBvcnRzLCBuZXdQYXJhbXM6IENyb3NzUmVnaW9uRXhwb3J0cyk6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKG9sZFBhcmFtcylcbiAgICAuZmlsdGVyKGtleSA9PiAobmV3UGFyYW1zLmhhc093blByb3BlcnR5KGtleSkgJiYgb2xkUGFyYW1zW2tleV0gIT09IG5ld1BhcmFtc1trZXldKSlcbiAgICAucmVkdWNlKChhY2M6IHN0cmluZ1tdLCBjdXJyOiBzdHJpbmcpID0+IHtcbiAgICAgIGFjYy5wdXNoKGN1cnIpO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCBbXSk7XG59XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/cdk.out b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/cdk.out new file mode 100644 index 0000000000000..145739f539580 --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"22.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61.assets.json b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61.assets.json new file mode 100644 index 0000000000000..e221be027f9c8 --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61.assets.json @@ -0,0 +1,34 @@ +{ + "version": "22.0.0", + "files": { + "f86f86755c3b2013542fc4f9405bfe145a86c0bec508dd0b37baabe2055d33f3": { + "source": { + "path": "asset.f86f86755c3b2013542fc4f9405bfe145a86c0bec508dd0b37baabe2055d33f3", + "packaging": "zip" + }, + "destinations": { + "current_account-us-east-1": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1", + "objectKey": "f86f86755c3b2013542fc4f9405bfe145a86c0bec508dd0b37baabe2055d33f3.zip", + "region": "us-east-1", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-us-east-1" + } + } + }, + "151fa1442d357caf21d6defe3b499266d5fbe2b66340d5f26f0b397618e6bb3e": { + "source": { + "path": "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-us-east-1": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1", + "objectKey": "151fa1442d357caf21d6defe3b499266d5fbe2b66340d5f26f0b397618e6bb3e.json", + "region": "us-east-1", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-us-east-1" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61.template.json b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61.template.json new file mode 100644 index 0000000000000..18c4cea0de6cd --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61.template.json @@ -0,0 +1,162 @@ +{ + "Resources": { + "RedirectCertificatec8615644f6b8e5372f779988c9aad3c31ec249ee76D1272753": { + "Type": "AWS::CertificateManager::Certificate", + "Properties": { + "DomainName": "integ.example.com", + "DomainValidationOptions": [ + { + "DomainName": "integ.example.com", + "HostedZoneId": "Z23ABC4XYZL05B" + }, + { + "DomainName": "integ.example.com", + "HostedZoneId": "Z23ABC4XYZL05B" + } + ], + "SubjectAlternativeNames": [ + "integ.example.com" + ], + "Tags": [ + { + "Key": "Name", + "Value": "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61/RedirectCertificatec8615644f6b8e5372f779988c9aad3c31ec249ee76" + } + ], + "ValidationMethod": "DNS" + } + }, + "ExportsWriteruseast2828FA26B86FBEFA7": { + "Type": "Custom::CrossRegionExportWriter", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "CustomCrossRegionExportWriterCustomResourceProviderHandlerD8786E8A", + "Arn" + ] + }, + "WriterProps": { + "region": "us-east-2", + "exports": { + "/cdk/exports/integ-https-redirect/certificateredirectstackc8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61useast1RefRedirectCertificatec8615644f6b8e5372f779988c9aad3c31ec249ee76D1272753FE4DCC12": { + "Ref": "RedirectCertificatec8615644f6b8e5372f779988c9aad3c31ec249ee76D1272753" + } + } + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "CustomCrossRegionExportWriterCustomResourceProviderRoleC951B1E1": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ] + }, + "ManagedPolicyArns": [ + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + } + ], + "Policies": [ + { + "PolicyName": "Inline", + "PolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:us-east-2:", + { + "Ref": "AWS::AccountId" + }, + ":parameter/cdk/exports/*" + ] + ] + }, + "Action": [ + "ssm:DeleteParameters", + "ssm:ListTagsForResource", + "ssm:GetParameters", + "ssm:PutParameter" + ] + } + ] + } + } + ] + } + }, + "CustomCrossRegionExportWriterCustomResourceProviderHandlerD8786E8A": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1" + }, + "S3Key": "f86f86755c3b2013542fc4f9405bfe145a86c0bec508dd0b37baabe2055d33f3.zip" + }, + "Timeout": 900, + "MemorySize": 128, + "Handler": "__entrypoint__.handler", + "Role": { + "Fn::GetAtt": [ + "CustomCrossRegionExportWriterCustomResourceProviderRoleC951B1E1", + "Arn" + ] + }, + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "CustomCrossRegionExportWriterCustomResourceProviderRoleC951B1E1" + ] + } + }, + "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-route53-patterns/test/integ.hosted-redirect.js.snapshot/integ-https-redirect.assets.json b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/integ-https-redirect.assets.json new file mode 100644 index 0000000000000..75c61d57d421c --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/integ-https-redirect.assets.json @@ -0,0 +1,34 @@ +{ + "version": "22.0.0", + "files": { + "881fb88a24d47c6beb950259ab9414e1d83df8f26c3d62891d2872b4e71648d6": { + "source": { + "path": "asset.881fb88a24d47c6beb950259ab9414e1d83df8f26c3d62891d2872b4e71648d6", + "packaging": "zip" + }, + "destinations": { + "current_account-us-east-2": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-2", + "objectKey": "881fb88a24d47c6beb950259ab9414e1d83df8f26c3d62891d2872b4e71648d6.zip", + "region": "us-east-2", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-us-east-2" + } + } + }, + "a319b5b28789d829846f7567b897cb5b94bbe2fc82080acaa6448f7ceab8c046": { + "source": { + "path": "integ-https-redirect.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-us-east-2": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-2", + "objectKey": "a319b5b28789d829846f7567b897cb5b94bbe2fc82080acaa6448f7ceab8c046.json", + "region": "us-east-2", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-us-east-2" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/integ-https-redirect.template.json b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/integ-https-redirect.template.json new file mode 100644 index 0000000000000..495fadcd05632 --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/integ-https-redirect.template.json @@ -0,0 +1,290 @@ +{ + "Resources": { + "redirectRedirectBucketAA44E2FE": { + "Type": "AWS::S3::Bucket", + "Properties": { + "PublicAccessBlockConfiguration": { + "BlockPublicAcls": true, + "BlockPublicPolicy": true, + "IgnorePublicAcls": true, + "RestrictPublicBuckets": true + }, + "WebsiteConfiguration": { + "RedirectAllRequestsTo": { + "HostName": "aws.amazon.com", + "Protocol": "https" + } + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "redirectRedirectDistributionCFDistribution1A4C48E3": { + "Type": "AWS::CloudFront::Distribution", + "Properties": { + "DistributionConfig": { + "Aliases": [ + "integ.example.com" + ], + "Comment": "Redirect to aws.amazon.com from integ.example.com", + "DefaultCacheBehavior": { + "AllowedMethods": [ + "GET", + "HEAD" + ], + "CachedMethods": [ + "GET", + "HEAD" + ], + "Compress": true, + "ForwardedValues": { + "Cookies": { + "Forward": "none" + }, + "QueryString": false + }, + "TargetOriginId": "origin1", + "ViewerProtocolPolicy": "redirect-to-https" + }, + "DefaultRootObject": "", + "Enabled": true, + "HttpVersion": "http2", + "IPV6Enabled": true, + "Origins": [ + { + "ConnectionAttempts": 3, + "ConnectionTimeout": 10, + "CustomOriginConfig": { + "HTTPPort": 80, + "HTTPSPort": 443, + "OriginKeepaliveTimeout": 5, + "OriginProtocolPolicy": "http-only", + "OriginReadTimeout": 30, + "OriginSSLProtocols": [ + "TLSv1.2" + ] + }, + "DomainName": { + "Fn::Select": [ + 2, + { + "Fn::Split": [ + "/", + { + "Fn::GetAtt": [ + "redirectRedirectBucketAA44E2FE", + "WebsiteURL" + ] + } + ] + } + ] + }, + "Id": "origin1" + } + ], + "PriceClass": "PriceClass_All", + "ViewerCertificate": { + "AcmCertificateArn": { + "Fn::GetAtt": [ + "ExportsReader8B249524", + "/cdk/exports/integ-https-redirect/certificateredirectstackc8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61useast1RefRedirectCertificatec8615644f6b8e5372f779988c9aad3c31ec249ee76D1272753FE4DCC12" + ] + }, + "SslSupportMethod": "sni-only" + } + } + } + }, + "redirectRedirectAliasRecord700dc535A8D685": { + "Type": "AWS::Route53::RecordSet", + "Properties": { + "Name": "integ.example.com.", + "Type": "A", + "AliasTarget": { + "DNSName": { + "Fn::GetAtt": [ + "redirectRedirectDistributionCFDistribution1A4C48E3", + "DomainName" + ] + }, + "HostedZoneId": { + "Fn::FindInMap": [ + "AWSCloudFrontPartitionHostedZoneIdMap", + { + "Ref": "AWS::Partition" + }, + "zoneId" + ] + } + }, + "HostedZoneId": "Z23ABC4XYZL05B" + } + }, + "redirectRedirectAliasRecordSix700dc5B6BB8C6E": { + "Type": "AWS::Route53::RecordSet", + "Properties": { + "Name": "integ.example.com.", + "Type": "AAAA", + "AliasTarget": { + "DNSName": { + "Fn::GetAtt": [ + "redirectRedirectDistributionCFDistribution1A4C48E3", + "DomainName" + ] + }, + "HostedZoneId": { + "Fn::FindInMap": [ + "AWSCloudFrontPartitionHostedZoneIdMap", + { + "Ref": "AWS::Partition" + }, + "zoneId" + ] + } + }, + "HostedZoneId": "Z23ABC4XYZL05B" + } + }, + "ExportsReader8B249524": { + "Type": "Custom::CrossRegionExportReader", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "CustomCrossRegionExportReaderCustomResourceProviderHandler46647B68", + "Arn" + ] + }, + "ReaderProps": { + "region": "us-east-2", + "prefix": "integ-https-redirect", + "imports": { + "/cdk/exports/integ-https-redirect/certificateredirectstackc8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61useast1RefRedirectCertificatec8615644f6b8e5372f779988c9aad3c31ec249ee76D1272753FE4DCC12": "{{resolve:ssm:/cdk/exports/integ-https-redirect/certificateredirectstackc8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61useast1RefRedirectCertificatec8615644f6b8e5372f779988c9aad3c31ec249ee76D1272753FE4DCC12}}" + } + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "CustomCrossRegionExportReaderCustomResourceProviderRole10531BBD": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ] + }, + "ManagedPolicyArns": [ + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + } + ], + "Policies": [ + { + "PolicyName": "Inline", + "PolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:us-east-2:", + { + "Ref": "AWS::AccountId" + }, + ":parameter/cdk/exports/integ-https-redirect/*" + ] + ] + }, + "Action": [ + "ssm:AddTagsToResource", + "ssm:RemoveTagsFromResource", + "ssm:GetParameters" + ] + } + ] + } + } + ] + } + }, + "CustomCrossRegionExportReaderCustomResourceProviderHandler46647B68": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-2" + }, + "S3Key": "881fb88a24d47c6beb950259ab9414e1d83df8f26c3d62891d2872b4e71648d6.zip" + }, + "Timeout": 900, + "MemorySize": 128, + "Handler": "__entrypoint__.handler", + "Role": { + "Fn::GetAtt": [ + "CustomCrossRegionExportReaderCustomResourceProviderRole10531BBD", + "Arn" + ] + }, + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "CustomCrossRegionExportReaderCustomResourceProviderRole10531BBD" + ] + } + }, + "Mappings": { + "AWSCloudFrontPartitionHostedZoneIdMap": { + "aws": { + "zoneId": "Z2FDTNDATAQYW2" + }, + "aws-cn": { + "zoneId": "Z3RFFRIM2A3IF5" + } + } + }, + "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-route53-patterns/test/integ.hosted-redirect.js.snapshot/integ.json b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/integ.json new file mode 100644 index 0000000000000..73c21d7411b5e --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/integ.json @@ -0,0 +1,14 @@ +{ + "enableLookups": true, + "version": "22.0.0", + "testCases": { + "integ-test/DefaultTest": { + "stacks": [ + "integ-https-redirect" + ], + "stackUpdateWorkflow": false, + "assertionStack": "integ-test/DefaultTest/DeployAssert", + "assertionStackName": "integtestDefaultTestDeployAssert24D5C536" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/integtestDefaultTestDeployAssert24D5C536.assets.json b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/integtestDefaultTestDeployAssert24D5C536.assets.json new file mode 100644 index 0000000000000..6aa47f90e9d7f --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/integtestDefaultTestDeployAssert24D5C536.assets.json @@ -0,0 +1,19 @@ +{ + "version": "22.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "integtestDefaultTestDeployAssert24D5C536.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-route53-patterns/test/integ.hosted-redirect.js.snapshot/integtestDefaultTestDeployAssert24D5C536.template.json b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/integtestDefaultTestDeployAssert24D5C536.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/integtestDefaultTestDeployAssert24D5C536.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-route53-patterns/test/integ.hosted-redirect.js.snapshot/manifest.json b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/manifest.json new file mode 100644 index 0000000000000..f3d2ab25d620e --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/manifest.json @@ -0,0 +1,261 @@ +{ + "version": "22.0.0", + "artifacts": { + "integ-https-redirect.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "integ-https-redirect.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "integ-https-redirect": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/us-east-2", + "properties": { + "templateFile": "integ-https-redirect.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-us-east-2", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-us-east-2", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-us-east-2/a319b5b28789d829846f7567b897cb5b94bbe2fc82080acaa6448f7ceab8c046.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "integ-https-redirect.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-us-east-2", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61", + "integ-https-redirect.assets" + ], + "metadata": { + "/integ-https-redirect/redirect/RedirectBucket/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "redirectRedirectBucketAA44E2FE" + } + ], + "/integ-https-redirect/redirect/RedirectDistribution/CFDistribution": [ + { + "type": "aws:cdk:logicalId", + "data": "redirectRedirectDistributionCFDistribution1A4C48E3" + } + ], + "/integ-https-redirect/redirect/RedirectAliasRecord700dc5/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "redirectRedirectAliasRecord700dc535A8D685" + } + ], + "/integ-https-redirect/redirect/RedirectAliasRecordSix700dc5/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "redirectRedirectAliasRecordSix700dc5B6BB8C6E" + } + ], + "/integ-https-redirect/AWSCloudFrontPartitionHostedZoneIdMap": [ + { + "type": "aws:cdk:logicalId", + "data": "AWSCloudFrontPartitionHostedZoneIdMap" + } + ], + "/integ-https-redirect/ExportsReader/Resource/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "ExportsReader8B249524" + } + ], + "/integ-https-redirect/Custom::CrossRegionExportReaderCustomResourceProvider/Role": [ + { + "type": "aws:cdk:logicalId", + "data": "CustomCrossRegionExportReaderCustomResourceProviderRole10531BBD" + } + ], + "/integ-https-redirect/Custom::CrossRegionExportReaderCustomResourceProvider/Handler": [ + { + "type": "aws:cdk:logicalId", + "data": "CustomCrossRegionExportReaderCustomResourceProviderHandler46647B68" + } + ], + "/integ-https-redirect/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/integ-https-redirect/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ], + "redirectRedirectCertificateCertificateRequestorFunctionServiceRole9E01E94F": [ + { + "type": "aws:cdk:logicalId", + "data": "redirectRedirectCertificateCertificateRequestorFunctionServiceRole9E01E94F", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" + ] + } + ], + "redirectRedirectCertificateCertificateRequestorFunctionServiceRoleDefaultPolicy7AC24A96": [ + { + "type": "aws:cdk:logicalId", + "data": "redirectRedirectCertificateCertificateRequestorFunctionServiceRoleDefaultPolicy7AC24A96", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" + ] + } + ], + "redirectRedirectCertificateCertificateRequestorFunctionBBD1548C": [ + { + "type": "aws:cdk:logicalId", + "data": "redirectRedirectCertificateCertificateRequestorFunctionBBD1548C", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" + ] + } + ], + "redirectRedirectCertificateCertificateRequestorResourceBB4D62C1": [ + { + "type": "aws:cdk:logicalId", + "data": "redirectRedirectCertificateCertificateRequestorResourceBB4D62C1", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" + ] + } + ] + }, + "displayName": "integ-https-redirect" + }, + "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/us-east-1", + "properties": { + "templateFile": "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-us-east-1", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-us-east-1", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1/151fa1442d357caf21d6defe3b499266d5fbe2b66340d5f26f0b397618e6bb3e.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-us-east-1", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61.assets" + ], + "metadata": { + "/certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61/RedirectCertificatec8615644f6b8e5372f779988c9aad3c31ec249ee76/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "RedirectCertificatec8615644f6b8e5372f779988c9aad3c31ec249ee76D1272753" + } + ], + "/certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61/ExportsWriteruseast2828FA26B/Resource/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "ExportsWriteruseast2828FA26B86FBEFA7" + } + ], + "/certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61/Custom::CrossRegionExportWriterCustomResourceProvider/Role": [ + { + "type": "aws:cdk:logicalId", + "data": "CustomCrossRegionExportWriterCustomResourceProviderRoleC951B1E1" + } + ], + "/certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61/Custom::CrossRegionExportWriterCustomResourceProvider/Handler": [ + { + "type": "aws:cdk:logicalId", + "data": "CustomCrossRegionExportWriterCustomResourceProviderHandlerD8786E8A" + } + ], + "/certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61" + }, + "integtestDefaultTestDeployAssert24D5C536.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "integtestDefaultTestDeployAssert24D5C536.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "integtestDefaultTestDeployAssert24D5C536": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "integtestDefaultTestDeployAssert24D5C536.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": [ + "integtestDefaultTestDeployAssert24D5C536.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": [ + "integtestDefaultTestDeployAssert24D5C536.assets" + ], + "metadata": { + "/integ-test/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/integ-test/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "integ-test/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/tree.json b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/tree.json new file mode 100644 index 0000000000000..e09494c03c2b5 --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.js.snapshot/tree.json @@ -0,0 +1,537 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "integ-https-redirect": { + "id": "integ-https-redirect", + "path": "integ-https-redirect", + "children": { + "HostedZone": { + "id": "HostedZone", + "path": "integ-https-redirect/HostedZone", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "redirect": { + "id": "redirect", + "path": "integ-https-redirect/redirect", + "children": { + "RedirectBucket": { + "id": "RedirectBucket", + "path": "integ-https-redirect/redirect/RedirectBucket", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-https-redirect/redirect/RedirectBucket/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::Bucket", + "aws:cdk:cloudformation:props": { + "publicAccessBlockConfiguration": { + "blockPublicAcls": true, + "blockPublicPolicy": true, + "ignorePublicAcls": true, + "restrictPublicBuckets": true + }, + "websiteConfiguration": { + "redirectAllRequestsTo": { + "hostName": "aws.amazon.com", + "protocol": "https" + } + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-s3.CfnBucket", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-s3.Bucket", + "version": "0.0.0" + } + }, + "RedirectDistribution": { + "id": "RedirectDistribution", + "path": "integ-https-redirect/redirect/RedirectDistribution", + "children": { + "CFDistribution": { + "id": "CFDistribution", + "path": "integ-https-redirect/redirect/RedirectDistribution/CFDistribution", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CloudFront::Distribution", + "aws:cdk:cloudformation:props": { + "distributionConfig": { + "comment": "Redirect to aws.amazon.com from integ.example.com", + "enabled": true, + "defaultRootObject": "", + "httpVersion": "http2", + "priceClass": "PriceClass_All", + "ipv6Enabled": true, + "origins": [ + { + "id": "origin1", + "domainName": { + "Fn::Select": [ + 2, + { + "Fn::Split": [ + "/", + { + "Fn::GetAtt": [ + "redirectRedirectBucketAA44E2FE", + "WebsiteURL" + ] + } + ] + } + ] + }, + "customOriginConfig": { + "httpPort": 80, + "httpsPort": 443, + "originKeepaliveTimeout": 5, + "originReadTimeout": 30, + "originProtocolPolicy": "http-only", + "originSslProtocols": [ + "TLSv1.2" + ] + }, + "connectionAttempts": 3, + "connectionTimeout": 10 + } + ], + "defaultCacheBehavior": { + "allowedMethods": [ + "GET", + "HEAD" + ], + "cachedMethods": [ + "GET", + "HEAD" + ], + "compress": true, + "forwardedValues": { + "queryString": false, + "cookies": { + "forward": "none" + } + }, + "targetOriginId": "origin1", + "viewerProtocolPolicy": "redirect-to-https" + }, + "aliases": [ + "integ.example.com" + ], + "viewerCertificate": { + "acmCertificateArn": { + "Fn::GetAtt": [ + "ExportsReader8B249524", + "/cdk/exports/integ-https-redirect/certificateredirectstackc8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61useast1RefRedirectCertificatec8615644f6b8e5372f779988c9aad3c31ec249ee76D1272753FE4DCC12" + ] + }, + "sslSupportMethod": "sni-only" + } + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-cloudfront.CfnDistribution", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-cloudfront.CloudFrontWebDistribution", + "version": "0.0.0" + } + }, + "RedirectAliasRecord700dc5": { + "id": "RedirectAliasRecord700dc5", + "path": "integ-https-redirect/redirect/RedirectAliasRecord700dc5", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-https-redirect/redirect/RedirectAliasRecord700dc5/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Route53::RecordSet", + "aws:cdk:cloudformation:props": { + "name": "integ.example.com.", + "type": "A", + "aliasTarget": { + "hostedZoneId": { + "Fn::FindInMap": [ + "AWSCloudFrontPartitionHostedZoneIdMap", + { + "Ref": "AWS::Partition" + }, + "zoneId" + ] + }, + "dnsName": { + "Fn::GetAtt": [ + "redirectRedirectDistributionCFDistribution1A4C48E3", + "DomainName" + ] + } + }, + "hostedZoneId": "Z23ABC4XYZL05B" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-route53.CfnRecordSet", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-route53.ARecord", + "version": "0.0.0" + } + }, + "RedirectAliasRecordSix700dc5": { + "id": "RedirectAliasRecordSix700dc5", + "path": "integ-https-redirect/redirect/RedirectAliasRecordSix700dc5", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-https-redirect/redirect/RedirectAliasRecordSix700dc5/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Route53::RecordSet", + "aws:cdk:cloudformation:props": { + "name": "integ.example.com.", + "type": "AAAA", + "aliasTarget": { + "hostedZoneId": { + "Fn::FindInMap": [ + "AWSCloudFrontPartitionHostedZoneIdMap", + { + "Ref": "AWS::Partition" + }, + "zoneId" + ] + }, + "dnsName": { + "Fn::GetAtt": [ + "redirectRedirectDistributionCFDistribution1A4C48E3", + "DomainName" + ] + } + }, + "hostedZoneId": "Z23ABC4XYZL05B" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-route53.CfnRecordSet", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-route53.AaaaRecord", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-route53-patterns.HttpsRedirect", + "version": "0.0.0" + } + }, + "AWSCloudFrontPartitionHostedZoneIdMap": { + "id": "AWSCloudFrontPartitionHostedZoneIdMap", + "path": "integ-https-redirect/AWSCloudFrontPartitionHostedZoneIdMap", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnMapping", + "version": "0.0.0" + } + }, + "ExportsReader": { + "id": "ExportsReader", + "path": "integ-https-redirect/ExportsReader", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-https-redirect/ExportsReader/Resource", + "children": { + "Default": { + "id": "Default", + "path": "integ-https-redirect/ExportsReader/Resource/Default", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CustomResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.168" + } + }, + "Custom::CrossRegionExportReaderCustomResourceProvider": { + "id": "Custom::CrossRegionExportReaderCustomResourceProvider", + "path": "integ-https-redirect/Custom::CrossRegionExportReaderCustomResourceProvider", + "children": { + "Staging": { + "id": "Staging", + "path": "integ-https-redirect/Custom::CrossRegionExportReaderCustomResourceProvider/Staging", + "constructInfo": { + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" + } + }, + "Role": { + "id": "Role", + "path": "integ-https-redirect/Custom::CrossRegionExportReaderCustomResourceProvider/Role", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + }, + "Handler": { + "id": "Handler", + "path": "integ-https-redirect/Custom::CrossRegionExportReaderCustomResourceProvider/Handler", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CustomResourceProvider", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "integ-https-redirect/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "integ-https-redirect/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61": { + "id": "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61", + "path": "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61", + "children": { + "RedirectCertificatec8615644f6b8e5372f779988c9aad3c31ec249ee76": { + "id": "RedirectCertificatec8615644f6b8e5372f779988c9aad3c31ec249ee76", + "path": "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61/RedirectCertificatec8615644f6b8e5372f779988c9aad3c31ec249ee76", + "children": { + "Resource": { + "id": "Resource", + "path": "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61/RedirectCertificatec8615644f6b8e5372f779988c9aad3c31ec249ee76/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CertificateManager::Certificate", + "aws:cdk:cloudformation:props": { + "domainName": "integ.example.com", + "domainValidationOptions": [ + { + "domainName": "integ.example.com", + "hostedZoneId": "Z23ABC4XYZL05B" + }, + { + "domainName": "integ.example.com", + "hostedZoneId": "Z23ABC4XYZL05B" + } + ], + "subjectAlternativeNames": [ + "integ.example.com" + ], + "tags": [ + { + "key": "Name", + "value": "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61/RedirectCertificatec8615644f6b8e5372f779988c9aad3c31ec249ee76" + } + ], + "validationMethod": "DNS" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-certificatemanager.CfnCertificate", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-certificatemanager.Certificate", + "version": "0.0.0" + } + }, + "ExportsWriteruseast2828FA26B": { + "id": "ExportsWriteruseast2828FA26B", + "path": "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61/ExportsWriteruseast2828FA26B", + "children": { + "Resource": { + "id": "Resource", + "path": "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61/ExportsWriteruseast2828FA26B/Resource", + "children": { + "Default": { + "id": "Default", + "path": "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61/ExportsWriteruseast2828FA26B/Resource/Default", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CustomResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.168" + } + }, + "Custom::CrossRegionExportWriterCustomResourceProvider": { + "id": "Custom::CrossRegionExportWriterCustomResourceProvider", + "path": "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61/Custom::CrossRegionExportWriterCustomResourceProvider", + "children": { + "Staging": { + "id": "Staging", + "path": "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61/Custom::CrossRegionExportWriterCustomResourceProvider/Staging", + "constructInfo": { + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" + } + }, + "Role": { + "id": "Role", + "path": "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61/Custom::CrossRegionExportWriterCustomResourceProvider/Role", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + }, + "Handler": { + "id": "Handler", + "path": "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61/Custom::CrossRegionExportWriterCustomResourceProvider/Handler", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CustomResourceProvider", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "certificate-redirect-stack-c8dcaeced090b732e39f9a17bfcca0bf8d20ce4f61/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "integ-test": { + "id": "integ-test", + "path": "integ-test", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "integ-test/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "integ-test/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.168" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "integ-test/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "integ-test/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "integ-test/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.168" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.ts b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.ts new file mode 100644 index 0000000000000..1c6a2dff626aa --- /dev/null +++ b/packages/@aws-cdk/aws-route53-patterns/test/integ.hosted-redirect.ts @@ -0,0 +1,42 @@ +import { PublicHostedZone } from '@aws-cdk/aws-route53'; +import { Stack, App } from '@aws-cdk/core'; +// import { ROUTE53_PATTERNS_USE_CERTIFICATE } from '@aws-cdk/cx-api'; +import { IntegTest } from '@aws-cdk/integ-tests'; +import { HttpsRedirect } from '../lib'; +const hostedZoneId = process.env.CDK_INTEG_HOSTED_ZONE_ID ?? process.env.HOSTED_ZONE_ID; +if (!hostedZoneId) throw new Error('For this test you must provide your own HostedZoneId as an env var "HOSTED_ZONE_ID"'); +const hostedZoneName = process.env.CDK_INTEG_HOSTED_ZONE_NAME ?? process.env.HOSTED_ZONE_NAME; +if (!hostedZoneName) throw new Error('For this test you must provide your own HostedZoneName as an env var "HOSTED_ZONE_NAME"'); +const domainName = process.env.CDK_INTEG_DOMAIN_NAME ?? process.env.DOMAIN_NAME; +if (!domainName) throw new Error('For this test you must provide your own Domain Name as an env var "DOMAIN_NAME"'); + +const app = new App({ + // uncomment this to test the old behavior + // postCliContext: { + // [ROUTE53_PATTERNS_USE_CERTIFICATE]: false, + // }, +}); +const testCase = new Stack(app, 'integ-https-redirect', { + crossRegionReferences: true, + env: { + account: process.env.CDK_DEFAULT_ACCOUNT, + region: 'us-east-2', // specifying region to test cross region functionality + }, +}); + +const hostedZone = PublicHostedZone.fromHostedZoneAttributes(testCase, 'HostedZone', { + hostedZoneId, + zoneName: hostedZoneName, +}); +new HttpsRedirect(testCase, 'redirect', { + zone: hostedZone, + recordNames: [`integ.${hostedZoneName}`], + targetDomain: 'aws.amazon.com', +}); + +new IntegTest(app, 'integ-test', { + testCases: [testCase], + enableLookups: true, + stackUpdateWorkflow: false, +}); + diff --git a/packages/@aws-cdk/cx-api/FEATURE_FLAGS.md b/packages/@aws-cdk/cx-api/FEATURE_FLAGS.md index d13ecb366dbb9..3f568d83e28ad 100644 --- a/packages/@aws-cdk/cx-api/FEATURE_FLAGS.md +++ b/packages/@aws-cdk/cx-api/FEATURE_FLAGS.md @@ -17,6 +17,7 @@ Flags come in three types: | Flag | Summary | Since | Type | | ----- | ----- | ----- | ----- | +| [@aws-cdk/aws-route53-patters:useCertificate](#aws-cdkaws-route53-pattersusecertificate) | Use the official `Certificate` resource instead of `DnsValidatedCertificate` | V2·NEXT | (default) | | [@aws-cdk/core:newStyleStackSynthesis](#aws-cdkcorenewstylestacksynthesis) | Switch to new stack synthesis method which enables CI/CD | 2.0.0 | (fix) | | [@aws-cdk/core:stackRelativeExports](#aws-cdkcorestackrelativeexports) | Name exports based on the construct paths relative to the stack, rather than the global construct path | 2.0.0 | (fix) | | [@aws-cdk/aws-rds:lowercaseDbIdentifier](#aws-cdkaws-rdslowercasedbidentifier) | Force lowercasing of RDS Cluster names in CDK | 2.0.0 | (fix) | @@ -72,7 +73,9 @@ The following json shows the current recommended set of flags, as `cdk init` wou "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, "@aws-cdk/aws-iam:standardizedServicePrincipals": true, "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, + "@aws-cdk/aws-route53-patters:useCertificate": true "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, "@aws-cdk/customresources:installLatestAwsSdkDefault": false } @@ -304,6 +307,24 @@ Encryption can also be configured explicitly using the `encrypted` property. **Compatibility with old behavior:** Pass the `encrypted: false` property to the `FileSystem` construct to disable encryption. +### @aws-cdk/aws-route53-patters:useCertificate + +*Use the official `Certificate` resource instead of `DnsValidatedCertificate`* (default) + +Enable this feature flag to use the official CloudFormation supported `Certificate` resource instead +of the deprecated `DnsValidatedCertificate` construct. If this flag is enabled and you are creating +the stack in a region other than us-east-1 then you must also set `crossRegionReferences=true` on the +stack. + + +| Since | Default | Recommended | +| ----- | ----- | ----- | +| (not in v1) | | | +| V2·NEXT | `false` | `true` | + +**Compatibility with old behavior:** Define a `DnsValidatedCertificate` explicitly and pass in the `certificate` property + + ### @aws-cdk/core:newStyleStackSynthesis *Switch to new stack synthesis method which enables CI/CD* (fix) diff --git a/packages/@aws-cdk/cx-api/lib/features.ts b/packages/@aws-cdk/cx-api/lib/features.ts index 8219c5b80192f..49f529567c170 100644 --- a/packages/@aws-cdk/cx-api/lib/features.ts +++ b/packages/@aws-cdk/cx-api/lib/features.ts @@ -76,6 +76,7 @@ export const EVENTS_TARGET_QUEUE_SAME_ACCOUNT = '@aws-cdk/aws-events:eventsTarge export const IAM_STANDARDIZED_SERVICE_PRINCIPALS = '@aws-cdk/aws-iam:standardizedServicePrincipals'; export const ECS_DISABLE_EXPLICIT_DEPLOYMENT_CONTROLLER_FOR_CIRCUIT_BREAKER = '@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker'; export const S3_SERVER_ACCESS_LOGS_USE_BUCKET_POLICY = '@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy'; +export const ROUTE53_PATTERNS_USE_CERTIFICATE = '@aws-cdk/aws-route53-patters:useCertificate'; export const AWS_CUSTOM_RESOURCE_LATEST_SDK_DEFAULT = '@aws-cdk/customresources:installLatestAwsSdkDefault'; export const FLAGS: Record = { @@ -595,6 +596,21 @@ export const FLAGS: Record = { recommendedValue: true, }, + ////////////////////////////////////////////////////////////////////// + [ROUTE53_PATTERNS_USE_CERTIFICATE]: { + type: FlagType.ApiDefault, + summary: 'Use the official `Certificate` resource instead of `DnsValidatedCertificate`', + detailsMd: ` + Enable this feature flag to use the official CloudFormation supported \`Certificate\` resource instead + of the deprecated \`DnsValidatedCertificate\` construct. If this flag is enabled and you are creating + the stack in a region other than us-east-1 then you must also set \`crossRegionReferences=true\` on the + stack. + `, + introducedIn: { v2: 'V2·NEXT' }, + recommendedValue: true, + compatibilityWithOldBehaviorMd: 'Define a `DnsValidatedCertificate` explicitly and pass in the `certificate` property', + }, + ////////////////////////////////////////////////////////////////////// [AWS_CUSTOM_RESOURCE_LATEST_SDK_DEFAULT]: { type: FlagType.ApiDefault,