From 46d7a9a4cb4fc5d1bac27e22fb2e66cf35e08f8a Mon Sep 17 00:00:00 2001 From: briancaffey Date: Wed, 4 Jan 2023 00:31:59 -0500 Subject: [PATCH] feat(refactor): big refactor of base and app constructs --- .gitignore | 1 + .projenrc.js | 2 +- cdk.context.json | 10 - src/constructs/ad-hoc/app/index.ts | 12 +- src/constructs/ad-hoc/base/index.ts | 160 +--- src/constructs/internal/alb/index.ts | 76 ++ src/constructs/internal/bastion/index.ts | 74 ++ src/constructs/internal/ecs/redis/index.ts | 19 +- src/constructs/internal/sg/index.ts | 40 + src/examples/ad-hoc/base/config/dev.json | 4 + src/examples/ad-hoc/base/index.ts | 37 +- test.txt | 876 +++++++++++++++++++++ 12 files changed, 1132 insertions(+), 179 deletions(-) delete mode 100644 cdk.context.json create mode 100644 src/constructs/internal/alb/index.ts create mode 100644 src/constructs/internal/bastion/index.ts create mode 100644 src/constructs/internal/sg/index.ts create mode 100644 src/examples/ad-hoc/base/config/dev.json create mode 100644 test.txt diff --git a/.gitignore b/.gitignore index 4d632d0..6fb8159 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,7 @@ cdk.out notes app.yml base.yml +cdk.context.json !/.projenrc.js /test-reports/ junit.xml diff --git a/.projenrc.js b/.projenrc.js index bed6198..67f20bd 100644 --- a/.projenrc.js +++ b/.projenrc.js @@ -8,7 +8,7 @@ const project = new awscdk.AwsCdkConstructLibrary({ repositoryUrl: 'git@github.com:briancaffey/cdk-django.git', // https://github.com/projen/projen/issues/1941 bundledDeps: ['@types/jest@27.4.1'], - gitignore: ['cdk.out', 'notes', 'app.yml', 'base.yml'], + gitignore: ['cdk.out', 'notes', 'app.yml', 'base.yml', 'cdk.context.json'], // deps: [], /* Runtime dependencies of this module. */ // description: undefined, /* The description is just a string that helps people understand the purpose of the package. */ diff --git a/cdk.context.json b/cdk.context.json deleted file mode 100644 index 20c9076..0000000 --- a/cdk.context.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "availability-zones:account=733623710918:region=us-east-1": [ - "us-east-1a", - "us-east-1b", - "us-east-1c", - "us-east-1d", - "us-east-1e", - "us-east-1f" - ] -} diff --git a/src/constructs/ad-hoc/app/index.ts b/src/constructs/ad-hoc/app/index.ts index 2a9051d..4b580df 100644 --- a/src/constructs/ad-hoc/app/index.ts +++ b/src/constructs/ad-hoc/app/index.ts @@ -27,8 +27,8 @@ export interface AdHocAppProps { readonly listener: ApplicationListener; // application specific props - readonly backendVersion: string; - readonly frontendVersion: string; + readonly backendVersion?: string; + readonly frontendVersion?: string; readonly djangoSettingsModule?: string; } @@ -38,8 +38,6 @@ export class AdHocApp extends Construct { super(scope, id); const stackName = Stack.of(this).stackName; - // const awsAccountId = Stack.of(this).account; - // const awsRegion = Stack.of(this).region; // custom resource to get the highest available listener rule priority // then take the next two highest priorities and use them for the frontend and backend listener rule priorities @@ -48,7 +46,8 @@ export class AdHocApp extends Construct { // const highestPriorityRule = new HighestPriorityRule(this, 'HighestPriorityRule', { listener: props.listener }); const backendEcrRepo = Repository.fromRepositoryName(this, 'BackendRepo', 'backend'); - const backendImage = new EcrImage(backendEcrRepo, props.backendVersion); + const backendVersion = props.frontendVersion ?? 'latest'; + const backendImage = new EcrImage(backendEcrRepo, backendVersion); const frontendEcrRepo = Repository.fromRepositoryName(this, 'FrontendRepo', 'frontend'); const frontendVersion = props.frontendVersion ?? 'latest'; @@ -94,8 +93,7 @@ export class AdHocApp extends Construct { taskRole: ecsRoles.ecsTaskRole, executionRole: ecsRoles.taskExecutionRole, image: ContainerImage.fromRegistry('redis:5.0.3-alpine'), - containerName: 'redis', - family: 'redis', + name: 'redis', serviceDiscoveryNamespace: props.serviceDiscoveryNamespace, }); diff --git a/src/constructs/ad-hoc/base/index.ts b/src/constructs/ad-hoc/base/index.ts index d5aeb29..26e2c0e 100644 --- a/src/constructs/ad-hoc/base/index.ts +++ b/src/constructs/ad-hoc/base/index.ts @@ -1,27 +1,16 @@ -import { - Duration, - Fn, - RemovalPolicy, - Stack, -} from 'aws-cdk-lib'; -import { BastionHostLinux, CfnInstance, IVpc, Peer, Port, SecurityGroup, SubnetType, UserData } from 'aws-cdk-lib/aws-ec2'; -import { - ApplicationProtocol, - ApplicationListener, - ApplicationLoadBalancer, - ApplicationTargetGroup, - ListenerCertificate, - TargetType, - ListenerAction, -} from 'aws-cdk-lib/aws-elasticloadbalancingv2'; +import { RemovalPolicy, Stack } from 'aws-cdk-lib'; +import { IVpc, SecurityGroup } from 'aws-cdk-lib/aws-ec2'; +import { ApplicationListener, ApplicationLoadBalancer } from 'aws-cdk-lib/aws-elasticloadbalancingv2'; import { DatabaseInstance } from 'aws-cdk-lib/aws-rds'; import { Bucket } from 'aws-cdk-lib/aws-s3'; import { PrivateDnsNamespace } from 'aws-cdk-lib/aws-servicediscovery'; import { Construct } from 'constructs'; +import { AlbResources } from '../../internal/alb'; +import { BastionHostResources } from '../../internal/bastion'; import { RdsInstance } from '../../internal/rds'; +import { SecurityGroupResources } from '../../internal/sg'; import { ApplicationVpc } from '../../internal/vpc'; -// TODO: add props export interface AdHocBaseProps { readonly certificateArn: string; readonly domainName: string; @@ -32,6 +21,7 @@ export class AdHocBase extends Construct { public vpc: IVpc; public alb: ApplicationLoadBalancer; public appSecurityGroup: SecurityGroup; + public albSecurityGroup: SecurityGroup; public serviceDiscoveryNamespace: PrivateDnsNamespace; public databaseInstance: DatabaseInstance; public assetsBucket: Bucket; @@ -41,17 +31,16 @@ export class AdHocBase extends Construct { constructor(scope: Construct, id: string, props: AdHocBaseProps) { super(scope, id); - // get the stack name - const stackName = Stack.of(this).stackName; + const foo = this.node.tryGetContext('config').extraEnvVars; + + console.log(foo); - // the domain name to use for the ad hoc environments + const stackName = Stack.of(this).stackName; this.domainName = props.domainName; - // vpc - const vpc = new ApplicationVpc(scope, 'Vpc'); - this.vpc = vpc.vpc; + const applicationVpc = new ApplicationVpc(scope, 'Vpc'); + this.vpc = applicationVpc.vpc; - // one bucket for all environments const assetsBucket = new Bucket(scope, 'AssetsBucket', { bucketName: `${props.domainName.replace('.', '-')}-${stackName}-assets-bucket`, removalPolicy: RemovalPolicy.DESTROY, @@ -59,82 +48,20 @@ export class AdHocBase extends Construct { }); this.assetsBucket = assetsBucket; - // security group for the ALB - const albSecurityGroup = new SecurityGroup(scope, 'AlbSecurityGroup', { - vpc: this.vpc, - }); - - // allow internet traffic from port 80 and 443 to the ALB for HTTP and HTTPS - albSecurityGroup.addIngressRule(Peer.anyIpv4(), Port.tcp(443), 'HTTPS'); - albSecurityGroup.addIngressRule(Peer.anyIpv4(), Port.tcp(80), 'HTTP'); - - // create application security group - const appSecurityGroup = new SecurityGroup(scope, 'AppSecurityGroup', { + const { albSecurityGroup, appSecurityGroup } = new SecurityGroupResources(this, 'SecurityGroupResources', { vpc: this.vpc, }); - appSecurityGroup.connections.allowFrom(appSecurityGroup, Port.allTcp()); - appSecurityGroup.connections.allowTo(appSecurityGroup, Port.allTcp()); - + this.albSecurityGroup = albSecurityGroup; this.appSecurityGroup = appSecurityGroup; - // allow traffic from ALB security group to the application security group - appSecurityGroup.addIngressRule(albSecurityGroup, Port.allTcp(), 'ALB'); - - // load balancer - const loadBalancer = new ApplicationLoadBalancer(scope, 'LoadBalancer', { - vpc: this.vpc, - securityGroup: albSecurityGroup, - internetFacing: true, - vpcSubnets: { - subnetType: SubnetType.PUBLIC, - }, - }); - this.alb = loadBalancer; - - // application target group - // Target group with duration-based stickiness with load-balancer generated cookie - // const defaultTargetGroup = - new ApplicationTargetGroup(this, 'default-target-group', { - targetType: TargetType.INSTANCE, - port: 80, - stickinessCookieDuration: Duration.minutes(5), + const { alb, listener } = new AlbResources(this, 'AlbResources', { + albSecurityGroup, vpc: this.vpc, - healthCheck: { - path: '/api/health-check/', // TODO parametrize this - interval: Duration.minutes(5), - timeout: Duration.minutes(2), - healthyThresholdCount: 2, - unhealthyThresholdCount: 3, - port: '80', // TODO parametrize this - }, + certificateArn: props.certificateArn, }); + this.alb = alb; + this.listener = listener; - // listener - HTTP - new ApplicationListener(this, 'http-listener', { - loadBalancer: loadBalancer, - port: 80, - protocol: ApplicationProtocol.HTTP, - defaultAction: ListenerAction.redirect({ - protocol: ApplicationProtocol.HTTPS, - port: '443', - permanent: false, - }), - }); - - // listener - HTTPS - const httpsListener = new ApplicationListener(this, 'https-listener', { - loadBalancer: loadBalancer, - port: 443, - protocol: ApplicationProtocol.HTTPS, - certificates: [ListenerCertificate.fromArn(props.certificateArn)], - defaultAction: ListenerAction.fixedResponse(200, { - contentType: 'text/plain', - messageBody: 'Fixed content response', - }), - }); - this.listener = httpsListener; - - // Service Discovery namespace const serviceDiscoveryPrivateDnsNamespace = new PrivateDnsNamespace(this, 'ServiceDiscoveryNamespace', { vpc: this.vpc, // TODO: add stack name as part of the name @@ -142,7 +69,6 @@ export class AdHocBase extends Construct { }); this.serviceDiscoveryNamespace = serviceDiscoveryPrivateDnsNamespace; - // RDS const rdsInstance = new RdsInstance(this, 'RdsInstance', { vpc: this.vpc, appSecurityGroup: appSecurityGroup, @@ -151,50 +77,10 @@ export class AdHocBase extends Construct { this.databaseInstance = rdsInstance.rdsInstance; const { dbInstanceEndpointAddress } = rdsInstance.rdsInstance; - const socatForwarderString = ` -package_upgrade: true -packages: - - postgresql - - socat -write_files: - - content: | - # /etc/systemd/system/socat-forwarder.service - [Unit] - Description=socat forwarder service - After=socat-forwarder.service - Requires=socat-forwarder.service - - [Service] - Type=simple - StandardOutput=syslog - StandardError=syslog - SyslogIdentifier=socat-forwarder - - ExecStart=/usr/bin/socat -d -d TCP4-LISTEN:5432,fork TCP4:${dbInstanceEndpointAddress}:5432 - Restart=always - - [Install] - WantedBy=multi-user.target - path: /etc/systemd/system/socat-forwarder.service - -runcmd: - - [ systemctl, daemon-reload ] - - [ systemctl, enable, socat-forwarder.service ] - # https://dustymabe.com/2015/08/03/installingstarting-systemd-services-using-cloud-init/ - - [ systemctl, start, --no-block, socat-forwarder.service ] -`; - - const bastionHost = new BastionHostLinux(this, 'BastionHost', { + new BastionHostResources(this, 'BastionHostResources', { + appSecurityGroup, vpc: this.vpc, - securityGroup: appSecurityGroup, + rdsAddress: dbInstanceEndpointAddress, }); - - const bastionHostUserData = UserData.forLinux({ shebang: '#cloud-config' }); - - bastionHostUserData.addCommands(socatForwarderString); - - const cfnBastionHost = bastionHost.instance.node.defaultChild as CfnInstance; - - cfnBastionHost.addPropertyOverride('UserData', Fn.base64(bastionHostUserData.render())); } } diff --git a/src/constructs/internal/alb/index.ts b/src/constructs/internal/alb/index.ts new file mode 100644 index 0000000..0b4da1e --- /dev/null +++ b/src/constructs/internal/alb/index.ts @@ -0,0 +1,76 @@ +// import { Stack } from 'aws-cdk-lib'; +import { Duration } from 'aws-cdk-lib'; +import { IVpc, SecurityGroup, SubnetType } from 'aws-cdk-lib/aws-ec2'; +import { ApplicationListener, ApplicationLoadBalancer, ApplicationProtocol, ApplicationTargetGroup, ListenerAction, ListenerCertificate, TargetType } from 'aws-cdk-lib/aws-elasticloadbalancingv2'; +import { Construct } from 'constructs'; + + +interface AlbResourcesProps { + readonly vpc: IVpc; + readonly albSecurityGroup: SecurityGroup; + readonly certificateArn: string; +} + +export class AlbResources extends Construct { + // public rdsInstance: DatabaseInstance; + public readonly alb: ApplicationLoadBalancer; + public readonly listener: ApplicationListener; + + constructor(scope: Construct, id: string, props: AlbResourcesProps) { + super(scope, id); + + const loadBalancer = new ApplicationLoadBalancer(scope, 'LoadBalancer', { + vpc: props.vpc, + securityGroup: props.albSecurityGroup, + internetFacing: true, + vpcSubnets: { + subnetType: SubnetType.PUBLIC, + }, + }); + this.alb = loadBalancer; + + // application target group + // Target group with duration-based stickiness with load-balancer generated cookie + // const defaultTargetGroup = + new ApplicationTargetGroup(this, 'default-target-group', { + targetType: TargetType.INSTANCE, + port: 80, + stickinessCookieDuration: Duration.minutes(5), + vpc: props.vpc, + healthCheck: { + path: '/api/health-check/', // TODO parametrize this + interval: Duration.minutes(5), + timeout: Duration.minutes(2), + healthyThresholdCount: 2, + unhealthyThresholdCount: 3, + port: '80', // TODO parametrize this + }, + }); + + // listener - HTTP + new ApplicationListener(this, 'http-listener', { + loadBalancer: loadBalancer, + port: 80, + protocol: ApplicationProtocol.HTTP, + defaultAction: ListenerAction.redirect({ + protocol: ApplicationProtocol.HTTPS, + port: '443', + permanent: false, + }), + }); + + // listener - HTTPS + const httpsListener = new ApplicationListener(this, 'https-listener', { + loadBalancer: loadBalancer, + port: 443, + protocol: ApplicationProtocol.HTTPS, + certificates: [ListenerCertificate.fromArn(props.certificateArn)], + defaultAction: ListenerAction.fixedResponse(200, { + contentType: 'text/plain', + messageBody: 'Fixed content response', + }), + }); + this.listener = httpsListener; + + } +} \ No newline at end of file diff --git a/src/constructs/internal/bastion/index.ts b/src/constructs/internal/bastion/index.ts new file mode 100644 index 0000000..3fcb28f --- /dev/null +++ b/src/constructs/internal/bastion/index.ts @@ -0,0 +1,74 @@ +import { Fn } from 'aws-cdk-lib'; +import { IVpc, SecurityGroup, BastionHostLinux, UserData, CfnInstance, InstanceType, InstanceClass, InstanceSize } from 'aws-cdk-lib/aws-ec2'; +import { Construct } from 'constructs'; + + +interface BastionHostResourcesProps { + readonly instanceClass?: InstanceClass; + readonly instanceSize?: InstanceSize; + readonly rdsAddress: string; + readonly vpc: IVpc; + readonly appSecurityGroup: SecurityGroup; +} + +export class BastionHostResources extends Construct { + public instanceClass: InstanceClass; + public instanceSize: InstanceSize; + public instanceId: string; + + constructor(scope: Construct, id: string, props: BastionHostResourcesProps) { + super(scope, id); + + this.instanceClass = props.instanceClass ?? InstanceClass.T3; + this.instanceSize = props.instanceSize ?? InstanceSize.NANO; + + const socatForwarderString = ` +package_upgrade: true +packages: + - postgresql + - socat +write_files: + - content: | + # /etc/systemd/system/socat-forwarder.service + [Unit] + Description=socat forwarder service + After=socat-forwarder.service + Requires=socat-forwarder.service + + [Service] + Type=simple + StandardOutput=syslog + StandardError=syslog + SyslogIdentifier=socat-forwarder + + ExecStart=/usr/bin/socat -d -d TCP4-LISTEN:5432,fork TCP4:${props.rdsAddress}:5432 + Restart=always + + [Install] + WantedBy=multi-user.target + path: /etc/systemd/system/socat-forwarder.service + +runcmd: + - [ systemctl, daemon-reload ] + - [ systemctl, enable, socat-forwarder.service ] + # https://dustymabe.com/2015/08/03/installingstarting-systemd-services-using-cloud-init/ + - [ systemctl, start, --no-block, socat-forwarder.service ] +`; + + const bastionHost = new BastionHostLinux(this, 'BastionHost', { + vpc: props.vpc, + securityGroup: props.appSecurityGroup, + instanceType: InstanceType.of(this.instanceClass, this.instanceSize), + }); + this.instanceId = bastionHost.instanceId; + + const bastionHostUserData = UserData.forLinux({ shebang: '#cloud-config' }); + + bastionHostUserData.addCommands(socatForwarderString); + + const cfnBastionHost = bastionHost.instance.node.defaultChild as CfnInstance; + + cfnBastionHost.addPropertyOverride('UserData', Fn.base64(bastionHostUserData.render())); + + } +} \ No newline at end of file diff --git a/src/constructs/internal/ecs/redis/index.ts b/src/constructs/internal/ecs/redis/index.ts index 6be35d7..2876f34 100644 --- a/src/constructs/internal/ecs/redis/index.ts +++ b/src/constructs/internal/ecs/redis/index.ts @@ -18,6 +18,7 @@ import { Construct } from 'constructs'; export interface RedisProps { + readonly name: string; readonly cluster: Cluster; readonly vpc: IVpc; readonly cpu?: number; @@ -25,10 +26,8 @@ export interface RedisProps { readonly appSecurityGroup: ISecurityGroup; readonly image: ContainerImage; readonly useSpot?: boolean; - readonly containerName: string; readonly taskRole: Role; readonly executionRole: Role; - readonly family: string; readonly environmentVariables: { [key: string]: string }; readonly serviceDiscoveryNamespace: PrivateDnsNamespace; }; @@ -40,10 +39,9 @@ export class RedisService extends Construct { const stackName = Stack.of(this).stackName; // define log group and logstream - const logGroupName = `/ecs/${stackName}/${props.containerName}/`; - const streamPrefix = props.containerName; + const logGroupName = `/ecs/${stackName}/${props.name}/`; + const streamPrefix = props.name; - // define log group and logstream const logGroup = new LogGroup(this, 'LogGroup', { logGroupName, retention: RetentionDays.ONE_DAY, @@ -52,7 +50,7 @@ export class RedisService extends Construct { new LogStream(this, 'LogStream', { logGroup, - logStreamName: props.containerName, + logStreamName: props.name, }); // task definition @@ -60,12 +58,12 @@ export class RedisService extends Construct { cpu: props.cpu ?? 256, executionRole: props.executionRole, taskRole: props.taskRole, - family: props.family, + family: props.name, }); - taskDefinition.addContainer(props.containerName, { + taskDefinition.addContainer(props.name, { image: props.image, - containerName: props.containerName, + containerName: props.name, environment: props.environmentVariables, essential: true, logging: LogDriver.awsLogs({ @@ -76,7 +74,6 @@ export class RedisService extends Construct { const useSpot = props.useSpot ?? false; - // TODO: add service discovery service const cloudMapService = props.serviceDiscoveryNamespace.createService('Service', { name: `${stackName}-redis`, @@ -101,7 +98,7 @@ export class RedisService extends Construct { desiredCount: 1, enableExecuteCommand: true, securityGroups: [props.appSecurityGroup], - serviceName: `${stackName}-${props.containerName}`, + serviceName: `${stackName}-${props.name}`, vpcSubnets: { subnets: props.vpc.privateSubnets, }, diff --git a/src/constructs/internal/sg/index.ts b/src/constructs/internal/sg/index.ts new file mode 100644 index 0000000..c2141a8 --- /dev/null +++ b/src/constructs/internal/sg/index.ts @@ -0,0 +1,40 @@ +// import { Stack } from 'aws-cdk-lib'; +import { IVpc, Peer, Port, SecurityGroup } from 'aws-cdk-lib/aws-ec2'; +import { Construct } from 'constructs'; + + +interface SecurityGroupResourcesProps { + readonly vpc: IVpc; +} + +export class SecurityGroupResources extends Construct { + // public rdsInstance: DatabaseInstance; + public readonly albSecurityGroup: SecurityGroup; + public readonly appSecurityGroup: SecurityGroup; + + constructor(scope: Construct, id: string, props: SecurityGroupResourcesProps) { + super(scope, id); + + // security group for the ALB + const albSecurityGroup = new SecurityGroup(scope, 'AlbSecurityGroup', { + vpc: props.vpc, + }); + this.albSecurityGroup = albSecurityGroup; + + // allow internet traffic from port 80 and 443 to the ALB for HTTP and HTTPS + albSecurityGroup.addIngressRule(Peer.anyIpv4(), Port.tcp(443), 'HTTPS'); + albSecurityGroup.addIngressRule(Peer.anyIpv4(), Port.tcp(80), 'HTTP'); + + // create application security group + const appSecurityGroup = new SecurityGroup(scope, 'AppSecurityGroup', { + vpc: props.vpc, + }); + appSecurityGroup.connections.allowFrom(appSecurityGroup, Port.allTcp()); + appSecurityGroup.connections.allowTo(appSecurityGroup, Port.allTcp()); + + this.appSecurityGroup = appSecurityGroup; + + // allow traffic from ALB security group to the application security group + appSecurityGroup.addIngressRule(albSecurityGroup, Port.allTcp(), 'ALB'); + } +} \ No newline at end of file diff --git a/src/examples/ad-hoc/base/config/dev.json b/src/examples/ad-hoc/base/config/dev.json new file mode 100644 index 0000000..7de3b8f --- /dev/null +++ b/src/examples/ad-hoc/base/config/dev.json @@ -0,0 +1,4 @@ +{ + "foo": "bar", + "extraEnvVars": {"alpha": "1", "beta": "2"} +} \ No newline at end of file diff --git a/src/examples/ad-hoc/base/index.ts b/src/examples/ad-hoc/base/index.ts index 8f94fdf..5705ee3 100644 --- a/src/examples/ad-hoc/base/index.ts +++ b/src/examples/ad-hoc/base/index.ts @@ -1,29 +1,40 @@ +import * as fs from 'fs'; import { App, Stack, Tags } from 'aws-cdk-lib'; import { AdHocApp } from '../../../constructs/ad-hoc/app'; -// import { IListenerCertificate } from 'aws-cdk-lib/aws-elasticloadbalancingv2'; import { AdHocBase } from '../../../constructs/ad-hoc/base'; -const env = { - region: process.env.AWS_DEFAULT_REGION || 'us-east-1', - account: process.env.AWS_ACCOUNT_ID, -}; +const adHocBaseEnvName = process.env.AD_HOC_BASE_NAME || 'dev'; +const adHocAppEnvName = process.env.AD_HOC_APP_NAME || 'alpha'; + + +// interface contextInterface { +// foo: string; +// biz: number; +// bar: number[]; +// } +var context = JSON.parse(fs.readFileSync(`src/examples/ad-hoc/base/config/${adHocBaseEnvName}.json`, 'utf8')); + // https://docs.aws.amazon.com/cdk/v2/guide/stack_how_to_create_multiple_stacks.html const app = new App(); -const baseStack = new Stack(app, 'TestAdHocBaseStack', { env, stackName: 'test-ad-hoc-base' }); +const env = { + account: process.env.CDK_DEFAULT_ACCOUNT, + region: process.env.CDK_DEFAULT_REGION, +}; -const appStack = new Stack(app, 'TestAdHocAppStack', { env, stackName: 'test-ad-hoc-app' }); +const baseStack = new Stack(app, 'TestAdHocBaseStack', { env, stackName: adHocBaseEnvName }); +baseStack.node.setContext('config', context); -let certArn = process.env.CERTIFICATE_ARN || 'arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012'; +const appStack = new Stack(app, 'TestAdHocAppStack', { env, stackName: adHocAppEnvName }); -const adHocBase = new AdHocBase(baseStack, 'AdHocBase', { - certificateArn: certArn, - domainName: process.env.DOMAIN_NAME || 'example.com', -}); +const certificateArn = process.env.ACM_CERTIFICATE_ARN || 'arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012'; +const domainName = process.env.DOMAIN_NAME || 'example.com'; + +const adHocBase = new AdHocBase(baseStack, 'AdHocBase', { certificateArn, domainName }); const addHocApp = new AdHocApp(appStack, 'AdHocApp', { - baseStackName: 'test-ad-hoc-base', + baseStackName: adHocBaseEnvName, vpc: adHocBase.vpc, alb: adHocBase.alb, appSecurityGroup: adHocBase.appSecurityGroup, diff --git a/test.txt b/test.txt new file mode 100644 index 0000000..1324fdb --- /dev/null +++ b/test.txt @@ -0,0 +1,876 @@ +cdk synth --app='lib/examples/ad-hoc/base/index.js' -e TestAdHocBaseStack +{ alpha: '1', beta: '2' } +Resources: + AdHocBaseAlbSecurityGroupFBDF6CD4: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: TestAdHocBaseStack/AdHocBase/AlbSecurityGroup + SecurityGroupEgress: + - CidrIp: 0.0.0.0/0 + Description: Allow all outbound traffic by default + IpProtocol: "-1" + SecurityGroupIngress: + - CidrIp: 0.0.0.0/0 + Description: HTTPS + FromPort: 443 + IpProtocol: tcp + ToPort: 443 + - CidrIp: 0.0.0.0/0 + Description: HTTP + FromPort: 80 + IpProtocol: tcp + ToPort: 80 + Tags: + - Key: stack + Value: AdHocBaseStack + VpcId: + Ref: VpcC3027511 + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/AlbSecurityGroup/Resource + AdHocBaseAppSecurityGroup4C5C61DC: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: TestAdHocBaseStack/AdHocBase/AppSecurityGroup + SecurityGroupEgress: + - CidrIp: 0.0.0.0/0 + Description: Allow all outbound traffic by default + IpProtocol: "-1" + Tags: + - Key: stack + Value: AdHocBaseStack + VpcId: + Ref: VpcC3027511 + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/AppSecurityGroup/Resource + AdHocBaseAppSecurityGroupfromTestAdHocBaseStackAdHocBaseAppSecurityGroup4979D05BALLPORTS8036C3A1: + Type: AWS::EC2::SecurityGroupIngress + Properties: + IpProtocol: tcp + Description: from TestAdHocBaseStackAdHocBaseAppSecurityGroup4979D05B:ALL PORTS + FromPort: 0 + GroupId: + Fn::GetAtt: + - AdHocBaseAppSecurityGroup4C5C61DC + - GroupId + SourceSecurityGroupId: + Fn::GetAtt: + - AdHocBaseAppSecurityGroup4C5C61DC + - GroupId + ToPort: 65535 + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/AppSecurityGroup/from TestAdHocBaseStackAdHocBaseAppSecurityGroup4979D05B:ALL PORTS + AdHocBaseAppSecurityGroupfromTestAdHocBaseStackAdHocBaseAlbSecurityGroup2D3FD034ALLPORTSA66A6E11: + Type: AWS::EC2::SecurityGroupIngress + Properties: + IpProtocol: tcp + Description: ALB + FromPort: 0 + GroupId: + Fn::GetAtt: + - AdHocBaseAppSecurityGroup4C5C61DC + - GroupId + SourceSecurityGroupId: + Fn::GetAtt: + - AdHocBaseAlbSecurityGroupFBDF6CD4 + - GroupId + ToPort: 65535 + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/AppSecurityGroup/from TestAdHocBaseStackAdHocBaseAlbSecurityGroup2D3FD034:ALL PORTS + AdHocBaseAppSecurityGroupfromTestAdHocBaseStackAdHocBaseAlbSecurityGroup2D3FD03480001C2B23DB: + Type: AWS::EC2::SecurityGroupIngress + Properties: + IpProtocol: tcp + Description: Load balancer to target + FromPort: 8000 + GroupId: + Fn::GetAtt: + - AdHocBaseAppSecurityGroup4C5C61DC + - GroupId + SourceSecurityGroupId: + Fn::GetAtt: + - AdHocBaseAlbSecurityGroupFBDF6CD4 + - GroupId + ToPort: 8000 + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/AppSecurityGroup/from TestAdHocBaseStackAdHocBaseAlbSecurityGroup2D3FD034:8000 + AdHocBaseAppSecurityGroupfromTestAdHocBaseStackAdHocBaseAlbSecurityGroup2D3FD034806B5B3801: + Type: AWS::EC2::SecurityGroupIngress + Properties: + IpProtocol: tcp + Description: Load balancer to target + FromPort: 80 + GroupId: + Fn::GetAtt: + - AdHocBaseAppSecurityGroup4C5C61DC + - GroupId + SourceSecurityGroupId: + Fn::GetAtt: + - AdHocBaseAlbSecurityGroupFBDF6CD4 + - GroupId + ToPort: 80 + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/AppSecurityGroup/from TestAdHocBaseStackAdHocBaseAlbSecurityGroup2D3FD034:80 + AdHocBaseAlbResourcesdefaulttargetgroup9E94F880: + Type: AWS::ElasticLoadBalancingV2::TargetGroup + Properties: + HealthCheckIntervalSeconds: 300 + HealthCheckPath: /api/health-check/ + HealthCheckPort: "80" + HealthCheckTimeoutSeconds: 120 + HealthyThresholdCount: 2 + Port: 80 + Protocol: HTTP + Tags: + - Key: stack + Value: AdHocBaseStack + TargetGroupAttributes: + - Key: stickiness.enabled + Value: "true" + - Key: stickiness.type + Value: lb_cookie + - Key: stickiness.lb_cookie.duration_seconds + Value: "300" + TargetType: instance + UnhealthyThresholdCount: 3 + VpcId: + Ref: VpcC3027511 + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/AlbResources/default-target-group/Resource + AdHocBaseAlbResourceshttplistenerDC17C921: + Type: AWS::ElasticLoadBalancingV2::Listener + Properties: + DefaultActions: + - RedirectConfig: + Port: "443" + Protocol: HTTPS + StatusCode: HTTP_302 + Type: redirect + LoadBalancerArn: + Ref: AdHocBaseLoadBalancerBB0B50C8 + Port: 80 + Protocol: HTTP + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/AlbResources/http-listener/Resource + AdHocBaseAlbResourceshttpslistener0881D48F: + Type: AWS::ElasticLoadBalancingV2::Listener + Properties: + DefaultActions: + - FixedResponseConfig: + ContentType: text/plain + MessageBody: Fixed content response + StatusCode: "200" + Type: fixed-response + LoadBalancerArn: + Ref: AdHocBaseLoadBalancerBB0B50C8 + Certificates: + - CertificateArn: arn:aws:acm:us-east-1:733623710918:certificate/948b8c39-99f0-47b7-b347-fa8fa131d0e1 + Port: 443 + Protocol: HTTPS + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/AlbResources/https-listener/Resource + AdHocBaseLoadBalancerBB0B50C8: + Type: AWS::ElasticLoadBalancingV2::LoadBalancer + Properties: + LoadBalancerAttributes: + - Key: deletion_protection.enabled + Value: "false" + Scheme: internet-facing + SecurityGroups: + - Fn::GetAtt: + - AdHocBaseAlbSecurityGroupFBDF6CD4 + - GroupId + Subnets: + - Ref: VpcingressSubnet1Subnet556A1F96 + - Ref: VpcingressSubnet2Subnet3CAAAA0B + Tags: + - Key: stack + Value: AdHocBaseStack + Type: application + DependsOn: + - VpcingressSubnet1DefaultRoute89ED95C8 + - VpcingressSubnet1RouteTableAssociationB6BAE862 + - VpcingressSubnet2DefaultRouteA7D45F1A + - VpcingressSubnet2RouteTableAssociation19E43D13 + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/LoadBalancer/Resource + AdHocBaseServiceDiscoveryNamespace86737BAB: + Type: AWS::ServiceDiscovery::PrivateDnsNamespace + Properties: + Name: dev-sd-ns + Vpc: + Ref: VpcC3027511 + Tags: + - Key: stack + Value: AdHocBaseStack + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/ServiceDiscoveryNamespace/Resource + AdHocBaseServiceDiscoveryNamespaceServiceEB345BEC: + Type: AWS::ServiceDiscovery::Service + Properties: + DnsConfig: + DnsRecords: + - TTL: 30 + Type: A + NamespaceId: + Fn::GetAtt: + - AdHocBaseServiceDiscoveryNamespace86737BAB + - Id + RoutingPolicy: MULTIVALUE + Name: alpha-redis + NamespaceId: + Fn::GetAtt: + - AdHocBaseServiceDiscoveryNamespace86737BAB + - Id + Tags: + - Key: stack + Value: AdHocBaseStack + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/ServiceDiscoveryNamespace/Service/Resource + AdHocBaseRdsInstanceRdsSecurityGroupC62EF8A4: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: TestAdHocBaseStack/AdHocBase/RdsInstance/RdsSecurityGroup + GroupName: devRdsSecurityGroup + SecurityGroupEgress: + - CidrIp: 0.0.0.0/0 + Description: Allow all outbound traffic by default + IpProtocol: "-1" + SecurityGroupIngress: + - CidrIp: 0.0.0.0/0 + Description: RDS + FromPort: 5432 + IpProtocol: tcp + ToPort: 5432 + Tags: + - Key: stack + Value: AdHocBaseStack + VpcId: + Ref: VpcC3027511 + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/RdsInstance/RdsSecurityGroup/Resource + AdHocBaseRdsInstanceRdsSecurityGroupfromTestAdHocBaseStackAdHocBaseAppSecurityGroup4979D05B543204BC410F: + Type: AWS::EC2::SecurityGroupIngress + Properties: + IpProtocol: tcp + Description: AppSecurityGroup + FromPort: 5432 + GroupId: + Fn::GetAtt: + - AdHocBaseRdsInstanceRdsSecurityGroupC62EF8A4 + - GroupId + SourceSecurityGroupId: + Fn::GetAtt: + - AdHocBaseAppSecurityGroup4C5C61DC + - GroupId + ToPort: 5432 + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/RdsInstance/RdsSecurityGroup/from TestAdHocBaseStackAdHocBaseAppSecurityGroup4979D05B:5432 + AdHocBaseRdsInstanceSubnetGroup6618A74F: + Type: AWS::RDS::DBSubnetGroup + Properties: + DBSubnetGroupDescription: Subnet group for RdsInstance database + SubnetIds: + - Ref: VpcapplicationSubnet1SubnetC8835CB0 + - Ref: VpcapplicationSubnet2SubnetEF05B07F + Tags: + - Key: stack + Value: AdHocBaseStack + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/RdsInstance/RdsInstance/SubnetGroup/Default + AdHocBaseRdsInstance89538199: + Type: AWS::RDS::DBInstance + Properties: + AllocatedStorage: "100" + CopyTagsToSnapshot: true + DBInstanceClass: db.t3.micro + DBInstanceIdentifier: devrdsinstance + DBSubnetGroupName: + Ref: AdHocBaseRdsInstanceSubnetGroup6618A74F + Engine: postgres + EngineVersion: "13.4" + MasterUsername: + Fn::Join: + - "" + - - "{{resolve:secretsmanager:" + - Ref: AdHocBasedbSecretA712D32A + - :SecretString:username::}} + MasterUserPassword: + Fn::Join: + - "" + - - "{{resolve:secretsmanager:" + - Ref: AdHocBasedbSecretA712D32A + - :SecretString:password::}} + Port: "5432" + PubliclyAccessible: false + StorageType: gp2 + Tags: + - Key: stack + Value: AdHocBaseStack + VPCSecurityGroups: + - Fn::GetAtt: + - AdHocBaseRdsInstanceRdsSecurityGroupC62EF8A4 + - GroupId + UpdateReplacePolicy: Snapshot + DeletionPolicy: Snapshot + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/RdsInstance/RdsInstance/Resource + AdHocBasedbSecretA712D32A: + Type: AWS::SecretsManager::Secret + Properties: + Description: secret for rds + GenerateSecretString: + ExcludePunctuation: true + GenerateStringKey: password + IncludeSpace: false + SecretStringTemplate: '{"username":"postgres"}' + Name: DB_SECRET_NAME + Tags: + - Key: stack + Value: AdHocBaseStack + UpdateReplacePolicy: Delete + DeletionPolicy: Delete + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/dbSecret/Resource + AdHocBasedbSecretAttachment9F9E4CE9: + Type: AWS::SecretsManager::SecretTargetAttachment + Properties: + SecretId: + Ref: AdHocBasedbSecretA712D32A + TargetId: + Ref: AdHocBaseRdsInstance89538199 + TargetType: AWS::RDS::DBInstance + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/dbSecret/Attachment/Resource + AdHocBaseBastionHostResourcesBastionHostInstanceRoleA63988C4: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Statement: + - Action: sts:AssumeRole + Effect: Allow + Principal: + Service: ec2.amazonaws.com + Version: "2012-10-17" + Tags: + - Key: Name + Value: BastionHost + - Key: stack + Value: AdHocBaseStack + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/BastionHostResources/BastionHost/Resource/InstanceRole/Resource + AdHocBaseBastionHostResourcesBastionHostInstanceRoleDefaultPolicyAAA7C61C: + Type: AWS::IAM::Policy + Properties: + PolicyDocument: + Statement: + - Action: + - ssmmessages:* + - ssm:UpdateInstanceInformation + - ec2messages:* + Effect: Allow + Resource: "*" + Version: "2012-10-17" + PolicyName: AdHocBaseBastionHostResourcesBastionHostInstanceRoleDefaultPolicyAAA7C61C + Roles: + - Ref: AdHocBaseBastionHostResourcesBastionHostInstanceRoleA63988C4 + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/BastionHostResources/BastionHost/Resource/InstanceRole/DefaultPolicy/Resource + AdHocBaseBastionHostResourcesBastionHostInstanceProfile15CA1625: + Type: AWS::IAM::InstanceProfile + Properties: + Roles: + - Ref: AdHocBaseBastionHostResourcesBastionHostInstanceRoleA63988C4 + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/BastionHostResources/BastionHost/Resource/InstanceProfile + AdHocBaseBastionHostResourcesBastionHost0BDF523D: + Type: AWS::EC2::Instance + Properties: + AvailabilityZone: us-east-1a + IamInstanceProfile: + Ref: AdHocBaseBastionHostResourcesBastionHostInstanceProfile15CA1625 + ImageId: + Ref: SsmParameterValueawsserviceamiamazonlinuxlatestamzn2amihvmx8664gp2C96584B6F00A464EAD1953AFF4B05118Parameter + InstanceType: t3.nano + SecurityGroupIds: + - Fn::GetAtt: + - AdHocBaseAppSecurityGroup4C5C61DC + - GroupId + SubnetId: + Ref: VpcapplicationSubnet1SubnetC8835CB0 + Tags: + - Key: Name + Value: BastionHost + - Key: stack + Value: AdHocBaseStack + UserData: + Fn::Base64: + Fn::Join: + - "" + - - |- + #cloud-config + + package_upgrade: true + packages: + - postgresql + - socat + write_files: + - content: | + # /etc/systemd/system/socat-forwarder.service + [Unit] + Description=socat forwarder service + After=socat-forwarder.service + Requires=socat-forwarder.service + + [Service] + Type=simple + StandardOutput=syslog + StandardError=syslog + SyslogIdentifier=socat-forwarder + + ExecStart=/usr/bin/socat -d -d TCP4-LISTEN:5432,fork TCP4: + - Fn::GetAtt: + - AdHocBaseRdsInstance89538199 + - Endpoint.Address + - | + :5432 + Restart=always + + [Install] + WantedBy=multi-user.target + path: /etc/systemd/system/socat-forwarder.service + + runcmd: + - [ systemctl, daemon-reload ] + - [ systemctl, enable, socat-forwarder.service ] + # https://dustymabe.com/2015/08/03/installingstarting-systemd-services-using-cloud-init/ + - [ systemctl, start, --no-block, socat-forwarder.service ] + DependsOn: + - AdHocBaseBastionHostResourcesBastionHostInstanceRoleDefaultPolicyAAA7C61C + - AdHocBaseBastionHostResourcesBastionHostInstanceRoleA63988C4 + Metadata: + aws:cdk:path: TestAdHocBaseStack/AdHocBase/BastionHostResources/BastionHost/Resource/Resource + VpcC3027511: + Type: AWS::EC2::VPC + Properties: + CidrBlock: 10.0.0.0/16 + EnableDnsHostnames: true + EnableDnsSupport: true + InstanceTenancy: default + Tags: + - Key: Name + Value: dev-vpc + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/Resource + VpcingressSubnet1Subnet556A1F96: + Type: AWS::EC2::Subnet + Properties: + VpcId: + Ref: VpcC3027511 + AvailabilityZone: us-east-1a + CidrBlock: 10.0.0.0/24 + MapPublicIpOnLaunch: true + Tags: + - Key: aws-cdk:subnet-name + Value: ingress + - Key: aws-cdk:subnet-type + Value: Public + - Key: Name + Value: TestAdHocBaseStack/Vpc/Vpc/ingressSubnet1 + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/ingressSubnet1/Subnet + VpcingressSubnet1RouteTableA12D5868: + Type: AWS::EC2::RouteTable + Properties: + VpcId: + Ref: VpcC3027511 + Tags: + - Key: Name + Value: TestAdHocBaseStack/Vpc/Vpc/ingressSubnet1 + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/ingressSubnet1/RouteTable + VpcingressSubnet1RouteTableAssociationB6BAE862: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: + Ref: VpcingressSubnet1RouteTableA12D5868 + SubnetId: + Ref: VpcingressSubnet1Subnet556A1F96 + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/ingressSubnet1/RouteTableAssociation + VpcingressSubnet1DefaultRoute89ED95C8: + Type: AWS::EC2::Route + Properties: + RouteTableId: + Ref: VpcingressSubnet1RouteTableA12D5868 + DestinationCidrBlock: 0.0.0.0/0 + GatewayId: + Ref: VpcIGW488B0FEB + DependsOn: + - VpcVPCGW42EC8516 + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/ingressSubnet1/DefaultRoute + VpcingressSubnet1EIPAA060F17: + Type: AWS::EC2::EIP + Properties: + Domain: vpc + Tags: + - Key: Name + Value: TestAdHocBaseStack/Vpc/Vpc/ingressSubnet1 + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/ingressSubnet1/EIP + VpcingressSubnet1NATGateway3F81BEBE: + Type: AWS::EC2::NatGateway + Properties: + SubnetId: + Ref: VpcingressSubnet1Subnet556A1F96 + AllocationId: + Fn::GetAtt: + - VpcingressSubnet1EIPAA060F17 + - AllocationId + Tags: + - Key: Name + Value: TestAdHocBaseStack/Vpc/Vpc/ingressSubnet1 + DependsOn: + - VpcingressSubnet1DefaultRoute89ED95C8 + - VpcingressSubnet1RouteTableAssociationB6BAE862 + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/ingressSubnet1/NATGateway + VpcingressSubnet2Subnet3CAAAA0B: + Type: AWS::EC2::Subnet + Properties: + VpcId: + Ref: VpcC3027511 + AvailabilityZone: us-east-1b + CidrBlock: 10.0.1.0/24 + MapPublicIpOnLaunch: true + Tags: + - Key: aws-cdk:subnet-name + Value: ingress + - Key: aws-cdk:subnet-type + Value: Public + - Key: Name + Value: TestAdHocBaseStack/Vpc/Vpc/ingressSubnet2 + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/ingressSubnet2/Subnet + VpcingressSubnet2RouteTable99284E2B: + Type: AWS::EC2::RouteTable + Properties: + VpcId: + Ref: VpcC3027511 + Tags: + - Key: Name + Value: TestAdHocBaseStack/Vpc/Vpc/ingressSubnet2 + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/ingressSubnet2/RouteTable + VpcingressSubnet2RouteTableAssociation19E43D13: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: + Ref: VpcingressSubnet2RouteTable99284E2B + SubnetId: + Ref: VpcingressSubnet2Subnet3CAAAA0B + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/ingressSubnet2/RouteTableAssociation + VpcingressSubnet2DefaultRouteA7D45F1A: + Type: AWS::EC2::Route + Properties: + RouteTableId: + Ref: VpcingressSubnet2RouteTable99284E2B + DestinationCidrBlock: 0.0.0.0/0 + GatewayId: + Ref: VpcIGW488B0FEB + DependsOn: + - VpcVPCGW42EC8516 + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/ingressSubnet2/DefaultRoute + VpcapplicationSubnet1SubnetC8835CB0: + Type: AWS::EC2::Subnet + Properties: + VpcId: + Ref: VpcC3027511 + AvailabilityZone: us-east-1a + CidrBlock: 10.0.2.0/24 + MapPublicIpOnLaunch: false + Tags: + - Key: aws-cdk:subnet-name + Value: application + - Key: aws-cdk:subnet-type + Value: Private + - Key: Name + Value: TestAdHocBaseStack/Vpc/Vpc/applicationSubnet1 + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/applicationSubnet1/Subnet + VpcapplicationSubnet1RouteTable97F01B17: + Type: AWS::EC2::RouteTable + Properties: + VpcId: + Ref: VpcC3027511 + Tags: + - Key: Name + Value: TestAdHocBaseStack/Vpc/Vpc/applicationSubnet1 + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/applicationSubnet1/RouteTable + VpcapplicationSubnet1RouteTableAssociationC7CBA21B: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: + Ref: VpcapplicationSubnet1RouteTable97F01B17 + SubnetId: + Ref: VpcapplicationSubnet1SubnetC8835CB0 + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/applicationSubnet1/RouteTableAssociation + VpcapplicationSubnet1DefaultRoute40B46D2E: + Type: AWS::EC2::Route + Properties: + RouteTableId: + Ref: VpcapplicationSubnet1RouteTable97F01B17 + DestinationCidrBlock: 0.0.0.0/0 + NatGatewayId: + Ref: VpcingressSubnet1NATGateway3F81BEBE + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/applicationSubnet1/DefaultRoute + VpcapplicationSubnet2SubnetEF05B07F: + Type: AWS::EC2::Subnet + Properties: + VpcId: + Ref: VpcC3027511 + AvailabilityZone: us-east-1b + CidrBlock: 10.0.3.0/24 + MapPublicIpOnLaunch: false + Tags: + - Key: aws-cdk:subnet-name + Value: application + - Key: aws-cdk:subnet-type + Value: Private + - Key: Name + Value: TestAdHocBaseStack/Vpc/Vpc/applicationSubnet2 + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/applicationSubnet2/Subnet + VpcapplicationSubnet2RouteTable4AF03023: + Type: AWS::EC2::RouteTable + Properties: + VpcId: + Ref: VpcC3027511 + Tags: + - Key: Name + Value: TestAdHocBaseStack/Vpc/Vpc/applicationSubnet2 + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/applicationSubnet2/RouteTable + VpcapplicationSubnet2RouteTableAssociationB436DB82: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: + Ref: VpcapplicationSubnet2RouteTable4AF03023 + SubnetId: + Ref: VpcapplicationSubnet2SubnetEF05B07F + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/applicationSubnet2/RouteTableAssociation + VpcapplicationSubnet2DefaultRoute72C531CC: + Type: AWS::EC2::Route + Properties: + RouteTableId: + Ref: VpcapplicationSubnet2RouteTable4AF03023 + DestinationCidrBlock: 0.0.0.0/0 + NatGatewayId: + Ref: VpcingressSubnet1NATGateway3F81BEBE + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/applicationSubnet2/DefaultRoute + VpcIGW488B0FEB: + Type: AWS::EC2::InternetGateway + Properties: + Tags: + - Key: Name + Value: dev-vpc + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/IGW + VpcVPCGW42EC8516: + Type: AWS::EC2::VPCGatewayAttachment + Properties: + VpcId: + Ref: VpcC3027511 + InternetGatewayId: + Ref: VpcIGW488B0FEB + Metadata: + aws:cdk:path: TestAdHocBaseStack/Vpc/Vpc/VPCGW + AssetsBucket5CB76180: + Type: AWS::S3::Bucket + Properties: + BucketName: jamescaffey-com-dev-assets-bucket + Tags: + - Key: aws-cdk:auto-delete-objects + Value: "true" + UpdateReplacePolicy: Delete + DeletionPolicy: Delete + Metadata: + aws:cdk:path: TestAdHocBaseStack/AssetsBucket/Resource + AssetsBucketPolicyFFACF6C4: + Type: AWS::S3::BucketPolicy + Properties: + Bucket: + Ref: AssetsBucket5CB76180 + PolicyDocument: + Statement: + - Action: + - s3:GetBucket* + - s3:List* + - s3:DeleteObject* + Effect: Allow + Principal: + AWS: + Fn::GetAtt: + - CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092 + - Arn + Resource: + - Fn::GetAtt: + - AssetsBucket5CB76180 + - Arn + - Fn::Join: + - "" + - - Fn::GetAtt: + - AssetsBucket5CB76180 + - Arn + - /* + Version: "2012-10-17" + Metadata: + aws:cdk:path: TestAdHocBaseStack/AssetsBucket/Policy/Resource + AssetsBucketAutoDeleteObjectsCustomResource51BA1286: + Type: Custom::S3AutoDeleteObjects + Properties: + ServiceToken: + Fn::GetAtt: + - CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F + - Arn + BucketName: + Ref: AssetsBucket5CB76180 + DependsOn: + - AssetsBucketPolicyFFACF6C4 + UpdateReplacePolicy: Delete + DeletionPolicy: Delete + Metadata: + aws:cdk:path: TestAdHocBaseStack/AssetsBucket/AutoDeleteObjectsCustomResource/Default + CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092: + 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 + Metadata: + aws:cdk:path: TestAdHocBaseStack/Custom::S3AutoDeleteObjectsCustomResourceProvider/Role + CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F: + Type: AWS::Lambda::Function + Properties: + Code: + S3Bucket: cdk-hnb659fds-assets-733623710918-us-east-1 + S3Key: 6babbac1f25446ab4660ead0ad5972e3a7742f50c6d8326af98a8bcd5d485335.zip + Timeout: 900 + MemorySize: 128 + Handler: __entrypoint__.handler + Role: + Fn::GetAtt: + - CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092 + - Arn + Runtime: nodejs14.x + Description: + Fn::Join: + - "" + - - "Lambda function for auto-deleting objects in " + - Ref: AssetsBucket5CB76180 + - " S3 bucket." + DependsOn: + - CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092 + Metadata: + aws:cdk:path: TestAdHocBaseStack/Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler + aws:asset:path: asset.6babbac1f25446ab4660ead0ad5972e3a7742f50c6d8326af98a8bcd5d485335 + aws:asset:property: Code + CDKMetadata: + Type: AWS::CDK::Metadata + Properties: + Analytics: v2:deflate64:H4sIAAAAAAAA/31TwW7bMAz9lt0VdW2HFjsmzdAFKFojKXodaJl11diSIVLuAsP/PslybGMrduLjEyU+PUpX8tt3+fULfNBKFcdVpXPZHRjUUQTqV4fqKuSovNN8unfWN+Lu1fyf2JnSIZHYALG25qclftDG/xY7QwxGYdwx4ZdGxfwluxOZzyutDj43yMOpE9pbz/gMeYUzP3NrIqs0xGZTcQQ/dlkMj8D3wPgBJ5E53QY4H7wzjC7gc0FSMmZrDka81Wi4F1jF26jKQpFDFZRrU7bBm3XTBM1D72dwZTjp7MkyXVQ9aGI06GLJhJfrocNm6DDWLPJeELpWKyw0KduiO8luvNLW0CPUSA0kfz+jD2lzGtgAe+EKkt0WGHIgnIaSDJqust38Q5xLoyTlkKkGAyW64bW4cX4JpZDsmC2dC/5e6YWGWnZ7m6Y9xMwGf4bxzOgsIXP2VVdRybXsNl4dU/cRpTDvWuZ9H5knz41nsUey3kV7PLGt5zRI+HwpNG51EcdHhBx+TRkexaARXDCd48CMLVC+00V7eSMvb8NPeyetV84b1jXKfYp/AAl+IjuFAwAA + Metadata: + aws:cdk:path: TestAdHocBaseStack/CDKMetadata/Default +Outputs: + AdHocBaseBastionHostResourcesBastionHostBastionHostId6632FD2E: + Description: Instance ID of the bastion host. Use this to connect via SSM Session Manager + Value: + Ref: AdHocBaseBastionHostResourcesBastionHost0BDF523D + ExportsOutputFnGetAttAdHocBaseLoadBalancerBB0B50C8DNSNameA313B41E: + Value: + Fn::GetAtt: + - AdHocBaseLoadBalancerBB0B50C8 + - DNSName + Export: + Name: dev:ExportsOutputFnGetAttAdHocBaseLoadBalancerBB0B50C8DNSNameA313B41E + ExportsOutputRefVpcapplicationSubnet1SubnetC8835CB09E1D11C0: + Value: + Ref: VpcapplicationSubnet1SubnetC8835CB0 + Export: + Name: dev:ExportsOutputRefVpcapplicationSubnet1SubnetC8835CB09E1D11C0 + ExportsOutputRefVpcapplicationSubnet2SubnetEF05B07F72BAD207: + Value: + Ref: VpcapplicationSubnet2SubnetEF05B07F + Export: + Name: dev:ExportsOutputRefVpcapplicationSubnet2SubnetEF05B07F72BAD207 + ExportsOutputFnGetAttAdHocBaseAppSecurityGroup4C5C61DCGroupIdE7EA3E56: + Value: + Fn::GetAtt: + - AdHocBaseAppSecurityGroup4C5C61DC + - GroupId + Export: + Name: dev:ExportsOutputFnGetAttAdHocBaseAppSecurityGroup4C5C61DCGroupIdE7EA3E56 + ExportsOutputFnGetAttAdHocBaseServiceDiscoveryNamespaceServiceEB345BECArn2676953B: + Value: + Fn::GetAtt: + - AdHocBaseServiceDiscoveryNamespaceServiceEB345BEC + - Arn + Export: + Name: dev:ExportsOutputFnGetAttAdHocBaseServiceDiscoveryNamespaceServiceEB345BECArn2676953B + ExportsOutputRefAssetsBucket5CB761808BF2E271: + Value: + Ref: AssetsBucket5CB76180 + Export: + Name: dev:ExportsOutputRefAssetsBucket5CB761808BF2E271 + ExportsOutputFnGetAttAdHocBaseRdsInstance89538199EndpointAddress23906A25: + Value: + Fn::GetAtt: + - AdHocBaseRdsInstance89538199 + - Endpoint.Address + Export: + Name: dev:ExportsOutputFnGetAttAdHocBaseRdsInstance89538199EndpointAddress23906A25 + ExportsOutputRefVpcC302751171D26A23: + Value: + Ref: VpcC3027511 + Export: + Name: dev:ExportsOutputRefVpcC302751171D26A23 + ExportsOutputRefAdHocBaseAlbResourceshttpslistener0881D48FFF5EA30C: + Value: + Ref: AdHocBaseAlbResourceshttpslistener0881D48F + Export: + Name: dev:ExportsOutputRefAdHocBaseAlbResourceshttpslistener0881D48FFF5EA30C +Parameters: + SsmParameterValueawsserviceamiamazonlinuxlatestamzn2amihvmx8664gp2C96584B6F00A464EAD1953AFF4B05118Parameter: + Type: AWS::SSM::Parameter::Value + Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 + 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. +