diff --git a/packages/@aws-cdk/aws-apprunner/README.md b/packages/@aws-cdk/aws-apprunner/README.md index 0af5e1bf09f5a..5e1c1c2b7f7e8 100644 --- a/packages/@aws-cdk/aws-apprunner/README.md +++ b/packages/@aws-cdk/aws-apprunner/README.md @@ -134,3 +134,29 @@ ECR image repositories (but not for ECR Public repositories). If not defined, a when required. See [App Runner IAM Roles](https://docs.aws.amazon.com/apprunner/latest/dg/security_iam_service-with-iam.html#security_iam_service-with-iam-roles) for more details. + +## VPC Connector + +To associate an App Runner service with a custom VPC, define `vpcConnector` for the service. + +```ts +import * as ec2 from '@aws-cdk/aws-ec2'; + +const vpc = new ec2.Vpc(this, 'Vpc', { + cidr: '10.0.0.0/16', +}); + +const vpcConnector = new apprunner.VpcConnector(this, 'VpcConnector', { + vpc, + vpcSubnets: vpc.selectSubnets({ subnetType: ec2.SubnetType.PUBLIC }), + vpcConnectorName: 'MyVpcConnector', +}); + +new apprunner.Service(this, 'Service', { + source: apprunner.Source.fromEcrPublic({ + imageConfiguration: { port: 8000 }, + imageIdentifier: 'public.ecr.aws/aws-containers/hello-app-runner:latest', + }), + vpcConnector, +}); +``` diff --git a/packages/@aws-cdk/aws-apprunner/lib/index.ts b/packages/@aws-cdk/aws-apprunner/lib/index.ts index 1aedf192186b1..3c5400bf44a0d 100644 --- a/packages/@aws-cdk/aws-apprunner/lib/index.ts +++ b/packages/@aws-cdk/aws-apprunner/lib/index.ts @@ -1,3 +1,4 @@ // AWS::AppRunner CloudFormation Resources: export * from './apprunner.generated'; export * from './service'; +export * from './vpc-connector'; diff --git a/packages/@aws-cdk/aws-apprunner/lib/service.ts b/packages/@aws-cdk/aws-apprunner/lib/service.ts index 90309845f3fdf..cddaf2210a6de 100644 --- a/packages/@aws-cdk/aws-apprunner/lib/service.ts +++ b/packages/@aws-cdk/aws-apprunner/lib/service.ts @@ -4,6 +4,7 @@ import * as iam from '@aws-cdk/aws-iam'; import * as cdk from '@aws-cdk/core'; import { Construct } from 'constructs'; import { CfnService } from './apprunner.generated'; +import { IVpcConnector } from './vpc-connector'; /** * The image repository types @@ -524,6 +525,13 @@ export interface ServiceProps { * @default - auto-generated if undefined. */ readonly serviceName?: string; + + /** + * Settings for an App Runner VPC connector to associate with the service. + * + * @default - no VPC connector, uses the DEFAULT egress type instead + */ + readonly vpcConnector?: IVpcConnector; } /** @@ -792,6 +800,12 @@ export class Service extends cdk.Resource { imageRepository: source.imageRepository ? this.renderImageRepository() : undefined, codeRepository: source.codeRepository ? this.renderCodeConfiguration() : undefined, }, + networkConfiguration: { + egressConfiguration: { + egressType: this.props.vpcConnector ? 'VPC' : 'DEFAULT', + vpcConnectorArn: this.props.vpcConnector?.vpcConnectorArn, + }, + }, }); // grant required privileges for the role diff --git a/packages/@aws-cdk/aws-apprunner/lib/vpc-connector.ts b/packages/@aws-cdk/aws-apprunner/lib/vpc-connector.ts new file mode 100644 index 0000000000000..8d09e5665a777 --- /dev/null +++ b/packages/@aws-cdk/aws-apprunner/lib/vpc-connector.ts @@ -0,0 +1,154 @@ +import * as ec2 from '@aws-cdk/aws-ec2'; +import { Connections } from '@aws-cdk/aws-ec2'; +import * as cdk from '@aws-cdk/core'; +import { Construct } from 'constructs'; +import { CfnVpcConnector } from './apprunner.generated'; + +/** + * Properties of the AppRunner VPC Connector + */ +export interface VpcConnectorProps { + /** + * The VPC for the VPC Connector. + */ + readonly vpc: ec2.IVpc; + + /** + * Where to place the VPC Connector within the VPC. + * + * @default - Private subnets. + */ + readonly vpcSubnets?: ec2.SubnetSelection; + + /** + * A list of IDs of security groups that App Runner should use for access to AWS resources under the specified subnets. + * + * @default - a new security group will be created in the specified VPC + */ + readonly securityGroups?: ec2.ISecurityGroup[]; + + /** + * The name for the VpcConnector. + * + * @default - a name generated by CloudFormation + */ + readonly vpcConnectorName?: string; +} + +/** + * Attributes for the App Runner VPC Connector + */ +export interface VpcConnectorAttributes { + /** + * The name of the VPC connector. + */ + readonly vpcConnectorName: string; + + /** + * The ARN of the VPC connector. + */ + readonly vpcConnectorArn: string; + + /** + * The revision of the VPC connector. + */ + readonly vpcConnectorRevision: number; + + /** + * The security groups associated with the VPC connector. + */ + readonly securityGroups: ec2.ISecurityGroup[]; +} + +/** + * Represents the App Runner VPC Connector. + */ +export interface IVpcConnector extends cdk.IResource, ec2.IConnectable { + /** + * The Name of the VPC connector. + * @attribute + */ + readonly vpcConnectorName: string; + + /** + * The ARN of the VPC connector. + * @attribute + */ + readonly vpcConnectorArn: string; + + /** + * The revision of the VPC connector. + * @attribute + */ + readonly vpcConnectorRevision: number; +} + +/** + * The App Runner VPC Connector + * + * @resource AWS::AppRunner::VpcConnector + */ +export class VpcConnector extends cdk.Resource implements IVpcConnector { + /** + * Import from VPC connector attributes. + */ + public static fromVpcConnectorAttributes(scope: Construct, id: string, attrs: VpcConnectorAttributes): IVpcConnector { + const vpcConnectorArn = attrs.vpcConnectorArn; + const vpcConnectorName = attrs.vpcConnectorName; + const vpcConnectorRevision = attrs.vpcConnectorRevision; + const securityGroups = attrs.securityGroups; + + class Import extends cdk.Resource { + public readonly vpcConnectorArn = vpcConnectorArn + public readonly vpcConnectorName = vpcConnectorName + public readonly vpcConnectorRevision = vpcConnectorRevision + public readonly connections = new Connections({ securityGroups }); + } + + return new Import(scope, id); + } + + /** + * The ARN of the VPC connector. + * @attribute + */ + readonly vpcConnectorArn: string; + + /** + * The revision of the VPC connector. + * @attribute + */ + readonly vpcConnectorRevision: number; + + /** + * The name of the VPC connector. + * @attribute + */ + readonly vpcConnectorName: string; + + /** + * Allows specifying security group connections for the VPC connector. + */ + public readonly connections: Connections + + public constructor(scope: Construct, id: string, props: VpcConnectorProps) { + super(scope, id, { + physicalName: props.vpcConnectorName, + }); + + const securityGroups = props.securityGroups?.length ? + props.securityGroups + : [new ec2.SecurityGroup(this, 'SecurityGroup', { vpc: props.vpc })]; + + const resource = new CfnVpcConnector(this, 'Resource', { + subnets: props.vpc.selectSubnets(props.vpcSubnets).subnetIds, + securityGroups: cdk.Lazy.list({ produce: () => this.connections.securityGroups.map(sg => sg.securityGroupId) }), + vpcConnectorName: this.physicalName, + }); + + this.vpcConnectorArn = resource.attrVpcConnectorArn; + this.vpcConnectorRevision = resource.attrVpcConnectorRevision; + this.vpcConnectorName = resource.ref; + this.connections = new Connections({ securityGroups }); + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apprunner/package.json b/packages/@aws-cdk/aws-apprunner/package.json index c77f373636afc..7b40424e102e8 100644 --- a/packages/@aws-cdk/aws-apprunner/package.json +++ b/packages/@aws-cdk/aws-apprunner/package.json @@ -83,6 +83,7 @@ }, "license": "Apache-2.0", "devDependencies": { + "@aws-cdk/aws-ec2": "0.0.0", "@aws-cdk/assertions": "0.0.0", "@aws-cdk/cdk-build-tools": "0.0.0", "@aws-cdk/integ-runner": "0.0.0", @@ -91,6 +92,7 @@ "@types/jest": "^27.5.0" }, "dependencies": { + "@aws-cdk/aws-ec2": "0.0.0", "@aws-cdk/aws-ecr": "0.0.0", "@aws-cdk/aws-ecr-assets": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", @@ -98,6 +100,7 @@ "constructs": "^3.3.69" }, "peerDependencies": { + "@aws-cdk/aws-ec2": "0.0.0", "@aws-cdk/aws-ecr": "0.0.0", "@aws-cdk/aws-ecr-assets": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", diff --git a/packages/@aws-cdk/aws-apprunner/test/integ.service-vpc-connector.ts b/packages/@aws-cdk/aws-apprunner/test/integ.service-vpc-connector.ts new file mode 100644 index 0000000000000..5a3aa23eb8008 --- /dev/null +++ b/packages/@aws-cdk/aws-apprunner/test/integ.service-vpc-connector.ts @@ -0,0 +1,51 @@ +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as cdk from '@aws-cdk/core'; +import { Service, Source, VpcConnector } from '../lib'; + + +const app = new cdk.App(); + +const stack = new cdk.Stack(app, 'integ-apprunner'); + +// Scenario 6: Create the service from ECR public with a VPC Connector +const vpc = new ec2.Vpc(stack, 'Vpc', { + cidr: '10.0.0.0/16', +}); + +const securityGroup = new ec2.SecurityGroup(stack, 'SecurityGroup', { vpc }); + +const vpcConnector = new VpcConnector(stack, 'VpcConnector', { + vpc, + vpcSubnets: vpc.selectSubnets({ subnetType: ec2.SubnetType.PUBLIC }), + securityGroups: [securityGroup], + vpcConnectorName: 'MyVpcConnector', +}); + +const service6 = new Service(stack, 'Service6', { + source: Source.fromEcrPublic({ + imageConfiguration: { + port: 8000, + }, + imageIdentifier: 'public.ecr.aws/aws-containers/hello-app-runner:latest', + }), + vpcConnector, +}); +new cdk.CfnOutput(stack, 'URL6', { value: `https://${service6.serviceUrl}` }); + +// Scenario 7: Create the service from ECR public and associate it with an existing VPC Connector + +const service7 = new Service(stack, 'Service7', { + source: Source.fromEcrPublic({ + imageConfiguration: { + port: 8000, + }, + imageIdentifier: 'public.ecr.aws/aws-containers/hello-app-runner:latest', + }), + vpcConnector: VpcConnector.fromVpcConnectorAttributes(stack, 'ImportedVpcConnector', { + vpcConnectorArn: vpcConnector.vpcConnectorArn, + vpcConnectorName: vpcConnector.vpcConnectorName, + vpcConnectorRevision: vpcConnector.vpcConnectorRevision, + securityGroups: [securityGroup], + }), +}); +new cdk.CfnOutput(stack, 'URL7', { value: `https://${service7.serviceUrl}` }); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apprunner/test/service-ecr-public.integ.snapshot/cdk.out b/packages/@aws-cdk/aws-apprunner/test/service-ecr-public.integ.snapshot/cdk.out index 90bef2e09ad39..ccdfc1ff96a9d 100644 --- a/packages/@aws-cdk/aws-apprunner/test/service-ecr-public.integ.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-apprunner/test/service-ecr-public.integ.snapshot/cdk.out @@ -1 +1 @@ -{"version":"17.0.0"} \ No newline at end of file +{"version":"19.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apprunner/test/service-ecr-public.integ.snapshot/integ-apprunner-ecr-public.template.json b/packages/@aws-cdk/aws-apprunner/test/service-ecr-public.integ.snapshot/integ-apprunner-ecr-public.template.json index ad07cf72e64eb..13f4def8b26ef 100644 --- a/packages/@aws-cdk/aws-apprunner/test/service-ecr-public.integ.snapshot/integ-apprunner-ecr-public.template.json +++ b/packages/@aws-cdk/aws-apprunner/test/service-ecr-public.integ.snapshot/integ-apprunner-ecr-public.template.json @@ -13,7 +13,12 @@ "ImageRepositoryType": "ECR_PUBLIC" } }, - "InstanceConfiguration": {} + "InstanceConfiguration": {}, + "NetworkConfiguration": { + "EgressConfiguration": { + "EgressType": "DEFAULT" + } + } } } }, diff --git a/packages/@aws-cdk/aws-apprunner/test/service-ecr-public.integ.snapshot/integ.json b/packages/@aws-cdk/aws-apprunner/test/service-ecr-public.integ.snapshot/integ.json index 90395ae79156b..42cd66bbc9c57 100644 --- a/packages/@aws-cdk/aws-apprunner/test/service-ecr-public.integ.snapshot/integ.json +++ b/packages/@aws-cdk/aws-apprunner/test/service-ecr-public.integ.snapshot/integ.json @@ -1,7 +1,7 @@ { - "version": "18.0.0", + "version": "19.0.0", "testCases": { - "aws-apprunner/test/integ.service-ecr-public": { + "integ.service-ecr-public": { "stacks": [ "integ-apprunner-ecr-public" ], diff --git a/packages/@aws-cdk/aws-apprunner/test/service-ecr-public.integ.snapshot/manifest.json b/packages/@aws-cdk/aws-apprunner/test/service-ecr-public.integ.snapshot/manifest.json index bb1cbea0d7abe..3c4bb3afcaaf3 100644 --- a/packages/@aws-cdk/aws-apprunner/test/service-ecr-public.integ.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-apprunner/test/service-ecr-public.integ.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "17.0.0", + "version": "19.0.0", "artifacts": { "Tree": { "type": "cdk:tree", diff --git a/packages/@aws-cdk/aws-apprunner/test/service-ecr-public.integ.snapshot/tree.json b/packages/@aws-cdk/aws-apprunner/test/service-ecr-public.integ.snapshot/tree.json index 39ccf8fe21ce3..fabf1d07f35f1 100644 --- a/packages/@aws-cdk/aws-apprunner/test/service-ecr-public.integ.snapshot/tree.json +++ b/packages/@aws-cdk/aws-apprunner/test/service-ecr-public.integ.snapshot/tree.json @@ -36,7 +36,12 @@ "imageRepositoryType": "ECR_PUBLIC" } }, - "instanceConfiguration": {} + "instanceConfiguration": {}, + "networkConfiguration": { + "egressConfiguration": { + "egressType": "DEFAULT" + } + } } }, "constructInfo": { diff --git a/packages/@aws-cdk/aws-apprunner/test/service-ecr.integ.snapshot/cdk.out b/packages/@aws-cdk/aws-apprunner/test/service-ecr.integ.snapshot/cdk.out index 90bef2e09ad39..ccdfc1ff96a9d 100644 --- a/packages/@aws-cdk/aws-apprunner/test/service-ecr.integ.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-apprunner/test/service-ecr.integ.snapshot/cdk.out @@ -1 +1 @@ -{"version":"17.0.0"} \ No newline at end of file +{"version":"19.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apprunner/test/service-ecr.integ.snapshot/integ-apprunner.template.json b/packages/@aws-cdk/aws-apprunner/test/service-ecr.integ.snapshot/integ-apprunner.template.json index 79a19f11646f9..ff824c136d367 100644 --- a/packages/@aws-cdk/aws-apprunner/test/service-ecr.integ.snapshot/integ-apprunner.template.json +++ b/packages/@aws-cdk/aws-apprunner/test/service-ecr.integ.snapshot/integ-apprunner.template.json @@ -104,7 +104,12 @@ "ImageRepositoryType": "ECR" } }, - "InstanceConfiguration": {} + "InstanceConfiguration": {}, + "NetworkConfiguration": { + "EgressConfiguration": { + "EgressType": "DEFAULT" + } + } } }, "Service2AccessRole759CA73D": { @@ -211,7 +216,12 @@ "ImageRepositoryType": "ECR" } }, - "InstanceConfiguration": {} + "InstanceConfiguration": {}, + "NetworkConfiguration": { + "EgressConfiguration": { + "EgressType": "DEFAULT" + } + } } } }, diff --git a/packages/@aws-cdk/aws-apprunner/test/service-ecr.integ.snapshot/integ.json b/packages/@aws-cdk/aws-apprunner/test/service-ecr.integ.snapshot/integ.json index 6855e7d68342b..7f2b10ccc26db 100644 --- a/packages/@aws-cdk/aws-apprunner/test/service-ecr.integ.snapshot/integ.json +++ b/packages/@aws-cdk/aws-apprunner/test/service-ecr.integ.snapshot/integ.json @@ -1,7 +1,7 @@ { - "version": "18.0.0", + "version": "19.0.0", "testCases": { - "aws-apprunner/test/integ.service-ecr": { + "integ.service-ecr": { "stacks": [ "integ-apprunner" ], diff --git a/packages/@aws-cdk/aws-apprunner/test/service-ecr.integ.snapshot/manifest.json b/packages/@aws-cdk/aws-apprunner/test/service-ecr.integ.snapshot/manifest.json index 324b4451eba40..bffcc4f7dbc5d 100644 --- a/packages/@aws-cdk/aws-apprunner/test/service-ecr.integ.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-apprunner/test/service-ecr.integ.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "17.0.0", + "version": "19.0.0", "artifacts": { "Tree": { "type": "cdk:tree", diff --git a/packages/@aws-cdk/aws-apprunner/test/service-ecr.integ.snapshot/tree.json b/packages/@aws-cdk/aws-apprunner/test/service-ecr.integ.snapshot/tree.json index aabd91ca530cb..ff5da659d20cf 100644 --- a/packages/@aws-cdk/aws-apprunner/test/service-ecr.integ.snapshot/tree.json +++ b/packages/@aws-cdk/aws-apprunner/test/service-ecr.integ.snapshot/tree.json @@ -189,7 +189,12 @@ "imageRepositoryType": "ECR" } }, - "instanceConfiguration": {} + "instanceConfiguration": {}, + "networkConfiguration": { + "egressConfiguration": { + "egressType": "DEFAULT" + } + } } }, "constructInfo": { @@ -358,7 +363,12 @@ "imageRepositoryType": "ECR" } }, - "instanceConfiguration": {} + "instanceConfiguration": {}, + "networkConfiguration": { + "egressConfiguration": { + "egressType": "DEFAULT" + } + } } }, "constructInfo": { diff --git a/packages/@aws-cdk/aws-apprunner/test/service-github.integ.snapshot/cdk.out b/packages/@aws-cdk/aws-apprunner/test/service-github.integ.snapshot/cdk.out index 90bef2e09ad39..ccdfc1ff96a9d 100644 --- a/packages/@aws-cdk/aws-apprunner/test/service-github.integ.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-apprunner/test/service-github.integ.snapshot/cdk.out @@ -1 +1 @@ -{"version":"17.0.0"} \ No newline at end of file +{"version":"19.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apprunner/test/service-github.integ.snapshot/integ-apprunner.template.json b/packages/@aws-cdk/aws-apprunner/test/service-github.integ.snapshot/integ-apprunner.template.json index 45a652f05cd26..d82fea7a58804 100644 --- a/packages/@aws-cdk/aws-apprunner/test/service-github.integ.snapshot/integ-apprunner.template.json +++ b/packages/@aws-cdk/aws-apprunner/test/service-github.integ.snapshot/integ-apprunner.template.json @@ -18,7 +18,12 @@ } } }, - "InstanceConfiguration": {} + "InstanceConfiguration": {}, + "NetworkConfiguration": { + "EgressConfiguration": { + "EgressType": "DEFAULT" + } + } } }, "Service5AD92B5A5": { @@ -45,7 +50,12 @@ } } }, - "InstanceConfiguration": {} + "InstanceConfiguration": {}, + "NetworkConfiguration": { + "EgressConfiguration": { + "EgressType": "DEFAULT" + } + } } } }, diff --git a/packages/@aws-cdk/aws-apprunner/test/service-github.integ.snapshot/integ.json b/packages/@aws-cdk/aws-apprunner/test/service-github.integ.snapshot/integ.json index 7ab280afd038e..bc3842dd5623c 100644 --- a/packages/@aws-cdk/aws-apprunner/test/service-github.integ.snapshot/integ.json +++ b/packages/@aws-cdk/aws-apprunner/test/service-github.integ.snapshot/integ.json @@ -1,7 +1,7 @@ { - "version": "18.0.0", + "version": "19.0.0", "testCases": { - "aws-apprunner/test/integ.service-github": { + "integ.service-github": { "stacks": [ "integ-apprunner" ], diff --git a/packages/@aws-cdk/aws-apprunner/test/service-github.integ.snapshot/manifest.json b/packages/@aws-cdk/aws-apprunner/test/service-github.integ.snapshot/manifest.json index 6c01e7ee8308a..75c99ad50d910 100644 --- a/packages/@aws-cdk/aws-apprunner/test/service-github.integ.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-apprunner/test/service-github.integ.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "17.0.0", + "version": "19.0.0", "artifacts": { "Tree": { "type": "cdk:tree", diff --git a/packages/@aws-cdk/aws-apprunner/test/service-github.integ.snapshot/tree.json b/packages/@aws-cdk/aws-apprunner/test/service-github.integ.snapshot/tree.json index fea5bce262629..528d5a9c71b60 100644 --- a/packages/@aws-cdk/aws-apprunner/test/service-github.integ.snapshot/tree.json +++ b/packages/@aws-cdk/aws-apprunner/test/service-github.integ.snapshot/tree.json @@ -41,7 +41,12 @@ } } }, - "instanceConfiguration": {} + "instanceConfiguration": {}, + "networkConfiguration": { + "egressConfiguration": { + "egressType": "DEFAULT" + } + } } }, "constructInfo": { @@ -94,7 +99,12 @@ } } }, - "instanceConfiguration": {} + "instanceConfiguration": {}, + "networkConfiguration": { + "egressConfiguration": { + "egressType": "DEFAULT" + } + } } }, "constructInfo": { diff --git a/packages/@aws-cdk/aws-apprunner/test/service-vpc-connector.integ.snapshot/cdk.out b/packages/@aws-cdk/aws-apprunner/test/service-vpc-connector.integ.snapshot/cdk.out new file mode 100644 index 0000000000000..ccdfc1ff96a9d --- /dev/null +++ b/packages/@aws-cdk/aws-apprunner/test/service-vpc-connector.integ.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"19.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apprunner/test/service-vpc-connector.integ.snapshot/integ-apprunner.template.json b/packages/@aws-cdk/aws-apprunner/test/service-vpc-connector.integ.snapshot/integ-apprunner.template.json new file mode 100644 index 0000000000000..dd82250830dd0 --- /dev/null +++ b/packages/@aws-cdk/aws-apprunner/test/service-vpc-connector.integ.snapshot/integ-apprunner.template.json @@ -0,0 +1,513 @@ +{ + "Resources": { + "Vpc8378EB38": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "integ-apprunner/Vpc" + } + ] + } + }, + "VpcPublicSubnet1Subnet5C2D37C4": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.0.0/18", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "integ-apprunner/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet1RouteTable6C95E38E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-apprunner/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet1RouteTableAssociation97140677": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + }, + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + } + } + }, + "VpcPublicSubnet1DefaultRoute3DA9E72A": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VpcIGWD7BA715C" + } + }, + "DependsOn": [ + "VpcVPCGWBF912B6E" + ] + }, + "VpcPublicSubnet1EIPD7E02669": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "integ-apprunner/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet1NATGateway4D7517AA": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + "AllocationId": { + "Fn::GetAtt": [ + "VpcPublicSubnet1EIPD7E02669", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-apprunner/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet2Subnet691E08A3": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.64.0/18", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "integ-apprunner/Vpc/PublicSubnet2" + } + ] + } + }, + "VpcPublicSubnet2RouteTable94F7E489": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-apprunner/Vpc/PublicSubnet2" + } + ] + } + }, + "VpcPublicSubnet2RouteTableAssociationDD5762D8": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet2RouteTable94F7E489" + }, + "SubnetId": { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + } + } + }, + "VpcPublicSubnet2DefaultRoute97F91067": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet2RouteTable94F7E489" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VpcIGWD7BA715C" + } + }, + "DependsOn": [ + "VpcVPCGWBF912B6E" + ] + }, + "VpcPublicSubnet2EIP3C605A87": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "integ-apprunner/Vpc/PublicSubnet2" + } + ] + } + }, + "VpcPublicSubnet2NATGateway9182C01D": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + }, + "AllocationId": { + "Fn::GetAtt": [ + "VpcPublicSubnet2EIP3C605A87", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-apprunner/Vpc/PublicSubnet2" + } + ] + } + }, + "VpcPrivateSubnet1Subnet536B997A": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.128.0/18", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "integ-apprunner/Vpc/PrivateSubnet1" + } + ] + } + }, + "VpcPrivateSubnet1RouteTableB2C5B500": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-apprunner/Vpc/PrivateSubnet1" + } + ] + } + }, + "VpcPrivateSubnet1RouteTableAssociation70C59FA6": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet1RouteTableB2C5B500" + }, + "SubnetId": { + "Ref": "VpcPrivateSubnet1Subnet536B997A" + } + } + }, + "VpcPrivateSubnet1DefaultRouteBE02A9ED": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet1RouteTableB2C5B500" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VpcPublicSubnet1NATGateway4D7517AA" + } + } + }, + "VpcPrivateSubnet2Subnet3788AAA1": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.192.0/18", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "integ-apprunner/Vpc/PrivateSubnet2" + } + ] + } + }, + "VpcPrivateSubnet2RouteTableA678073B": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-apprunner/Vpc/PrivateSubnet2" + } + ] + } + }, + "VpcPrivateSubnet2RouteTableAssociationA89CAD56": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet2RouteTableA678073B" + }, + "SubnetId": { + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" + } + } + }, + "VpcPrivateSubnet2DefaultRoute060D2087": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet2RouteTableA678073B" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VpcPublicSubnet2NATGateway9182C01D" + } + } + }, + "VpcIGWD7BA715C": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "integ-apprunner/Vpc" + } + ] + } + }, + "VpcVPCGWBF912B6E": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "InternetGatewayId": { + "Ref": "VpcIGWD7BA715C" + } + } + }, + "SecurityGroupDD263621": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "integ-apprunner/SecurityGroup", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "VpcConnectorE3A78531": { + "Type": "AWS::AppRunner::VpcConnector", + "Properties": { + "Subnets": [ + { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + } + ], + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "SecurityGroupDD263621", + "GroupId" + ] + } + ], + "VpcConnectorName": "MyVpcConnector" + } + }, + "Service6DF16DDFB": { + "Type": "AWS::AppRunner::Service", + "Properties": { + "SourceConfiguration": { + "AuthenticationConfiguration": {}, + "ImageRepository": { + "ImageConfiguration": { + "Port": "8000" + }, + "ImageIdentifier": "public.ecr.aws/aws-containers/hello-app-runner:latest", + "ImageRepositoryType": "ECR_PUBLIC" + } + }, + "InstanceConfiguration": {}, + "NetworkConfiguration": { + "EgressConfiguration": { + "EgressType": "VPC", + "VpcConnectorArn": { + "Fn::GetAtt": [ + "VpcConnectorE3A78531", + "VpcConnectorArn" + ] + } + } + } + } + }, + "Service7E1F980B2": { + "Type": "AWS::AppRunner::Service", + "Properties": { + "SourceConfiguration": { + "AuthenticationConfiguration": {}, + "ImageRepository": { + "ImageConfiguration": { + "Port": "8000" + }, + "ImageIdentifier": "public.ecr.aws/aws-containers/hello-app-runner:latest", + "ImageRepositoryType": "ECR_PUBLIC" + } + }, + "InstanceConfiguration": {}, + "NetworkConfiguration": { + "EgressConfiguration": { + "EgressType": "VPC", + "VpcConnectorArn": { + "Fn::GetAtt": [ + "VpcConnectorE3A78531", + "VpcConnectorArn" + ] + } + } + } + } + } + }, + "Outputs": { + "URL6": { + "Value": { + "Fn::Join": [ + "", + [ + "https://", + { + "Fn::GetAtt": [ + "Service6DF16DDFB", + "ServiceUrl" + ] + } + ] + ] + } + }, + "URL7": { + "Value": { + "Fn::Join": [ + "", + [ + "https://", + { + "Fn::GetAtt": [ + "Service7E1F980B2", + "ServiceUrl" + ] + } + ] + ] + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apprunner/test/service-vpc-connector.integ.snapshot/integ.json b/packages/@aws-cdk/aws-apprunner/test/service-vpc-connector.integ.snapshot/integ.json new file mode 100644 index 0000000000000..14b7f0c7211e4 --- /dev/null +++ b/packages/@aws-cdk/aws-apprunner/test/service-vpc-connector.integ.snapshot/integ.json @@ -0,0 +1,14 @@ +{ + "version": "19.0.0", + "testCases": { + "integ.service-vpc-connector": { + "stacks": [ + "integ-apprunner" + ], + "diffAssets": false, + "stackUpdateWorkflow": true + } + }, + "synthContext": {}, + "enableLookups": false +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apprunner/test/service-vpc-connector.integ.snapshot/manifest.json b/packages/@aws-cdk/aws-apprunner/test/service-vpc-connector.integ.snapshot/manifest.json new file mode 100644 index 0000000000000..3f7ab502b43a0 --- /dev/null +++ b/packages/@aws-cdk/aws-apprunner/test/service-vpc-connector.integ.snapshot/manifest.json @@ -0,0 +1,196 @@ +{ + "version": "19.0.0", + "artifacts": { + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + }, + "integ-apprunner": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "integ-apprunner.template.json", + "validateOnSynth": false + }, + "metadata": { + "/integ-apprunner/Vpc/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Vpc8378EB38" + } + ], + "/integ-apprunner/Vpc/PublicSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet1Subnet5C2D37C4" + } + ], + "/integ-apprunner/Vpc/PublicSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet1RouteTable6C95E38E" + } + ], + "/integ-apprunner/Vpc/PublicSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet1RouteTableAssociation97140677" + } + ], + "/integ-apprunner/Vpc/PublicSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet1DefaultRoute3DA9E72A" + } + ], + "/integ-apprunner/Vpc/PublicSubnet1/EIP": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet1EIPD7E02669" + } + ], + "/integ-apprunner/Vpc/PublicSubnet1/NATGateway": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet1NATGateway4D7517AA" + } + ], + "/integ-apprunner/Vpc/PublicSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet2Subnet691E08A3" + } + ], + "/integ-apprunner/Vpc/PublicSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet2RouteTable94F7E489" + } + ], + "/integ-apprunner/Vpc/PublicSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet2RouteTableAssociationDD5762D8" + } + ], + "/integ-apprunner/Vpc/PublicSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet2DefaultRoute97F91067" + } + ], + "/integ-apprunner/Vpc/PublicSubnet2/EIP": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet2EIP3C605A87" + } + ], + "/integ-apprunner/Vpc/PublicSubnet2/NATGateway": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet2NATGateway9182C01D" + } + ], + "/integ-apprunner/Vpc/PrivateSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPrivateSubnet1Subnet536B997A" + } + ], + "/integ-apprunner/Vpc/PrivateSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPrivateSubnet1RouteTableB2C5B500" + } + ], + "/integ-apprunner/Vpc/PrivateSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPrivateSubnet1RouteTableAssociation70C59FA6" + } + ], + "/integ-apprunner/Vpc/PrivateSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPrivateSubnet1DefaultRouteBE02A9ED" + } + ], + "/integ-apprunner/Vpc/PrivateSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPrivateSubnet2Subnet3788AAA1" + } + ], + "/integ-apprunner/Vpc/PrivateSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPrivateSubnet2RouteTableA678073B" + } + ], + "/integ-apprunner/Vpc/PrivateSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPrivateSubnet2RouteTableAssociationA89CAD56" + } + ], + "/integ-apprunner/Vpc/PrivateSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPrivateSubnet2DefaultRoute060D2087" + } + ], + "/integ-apprunner/Vpc/IGW": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcIGWD7BA715C" + } + ], + "/integ-apprunner/Vpc/VPCGW": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcVPCGWBF912B6E" + } + ], + "/integ-apprunner/SecurityGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "SecurityGroupDD263621" + } + ], + "/integ-apprunner/VpcConnector/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcConnectorE3A78531" + } + ], + "/integ-apprunner/Service6/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Service6DF16DDFB" + } + ], + "/integ-apprunner/URL6": [ + { + "type": "aws:cdk:logicalId", + "data": "URL6" + } + ], + "/integ-apprunner/Service7/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Service7E1F980B2" + } + ], + "/integ-apprunner/URL7": [ + { + "type": "aws:cdk:logicalId", + "data": "URL7" + } + ] + }, + "displayName": "integ-apprunner" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apprunner/test/service-vpc-connector.integ.snapshot/tree.json b/packages/@aws-cdk/aws-apprunner/test/service-vpc-connector.integ.snapshot/tree.json new file mode 100644 index 0000000000000..7639465033d25 --- /dev/null +++ b/packages/@aws-cdk/aws-apprunner/test/service-vpc-connector.integ.snapshot/tree.json @@ -0,0 +1,862 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "@aws-cdk/core.Construct", + "version": "0.0.0" + } + }, + "integ-apprunner": { + "id": "integ-apprunner", + "path": "integ-apprunner", + "children": { + "Vpc": { + "id": "Vpc", + "path": "integ-apprunner/Vpc", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-apprunner/Vpc/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPC", + "aws:cdk:cloudformation:props": { + "cidrBlock": "10.0.0.0/16", + "enableDnsHostnames": true, + "enableDnsSupport": true, + "instanceTenancy": "default", + "tags": [ + { + "key": "Name", + "value": "integ-apprunner/Vpc" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnVPC", + "version": "0.0.0" + } + }, + "PublicSubnet1": { + "id": "PublicSubnet1", + "path": "integ-apprunner/Vpc/PublicSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "integ-apprunner/Vpc/PublicSubnet1/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "Vpc8378EB38" + }, + "availabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.0.0/18", + "mapPublicIpOnLaunch": true, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Public" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Public" + }, + { + "key": "Name", + "value": "integ-apprunner/Vpc/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "integ-apprunner/Vpc/PublicSubnet1/Acl", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "integ-apprunner/Vpc/PublicSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "Vpc8378EB38" + }, + "tags": [ + { + "key": "Name", + "value": "integ-apprunner/Vpc/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "integ-apprunner/Vpc/PublicSubnet1/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + }, + "subnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "integ-apprunner/Vpc/PublicSubnet1/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + }, + "destinationCidrBlock": "0.0.0.0/0", + "gatewayId": { + "Ref": "VpcIGWD7BA715C" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRoute", + "version": "0.0.0" + } + }, + "EIP": { + "id": "EIP", + "path": "integ-apprunner/Vpc/PublicSubnet1/EIP", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::EIP", + "aws:cdk:cloudformation:props": { + "domain": "vpc", + "tags": [ + { + "key": "Name", + "value": "integ-apprunner/Vpc/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnEIP", + "version": "0.0.0" + } + }, + "NATGateway": { + "id": "NATGateway", + "path": "integ-apprunner/Vpc/PublicSubnet1/NATGateway", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", + "aws:cdk:cloudformation:props": { + "subnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + "allocationId": { + "Fn::GetAtt": [ + "VpcPublicSubnet1EIPD7E02669", + "AllocationId" + ] + }, + "tags": [ + { + "key": "Name", + "value": "integ-apprunner/Vpc/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnNatGateway", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.PublicSubnet", + "version": "0.0.0" + } + }, + "PublicSubnet2": { + "id": "PublicSubnet2", + "path": "integ-apprunner/Vpc/PublicSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "integ-apprunner/Vpc/PublicSubnet2/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "Vpc8378EB38" + }, + "availabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.64.0/18", + "mapPublicIpOnLaunch": true, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Public" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Public" + }, + { + "key": "Name", + "value": "integ-apprunner/Vpc/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "integ-apprunner/Vpc/PublicSubnet2/Acl", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "integ-apprunner/Vpc/PublicSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "Vpc8378EB38" + }, + "tags": [ + { + "key": "Name", + "value": "integ-apprunner/Vpc/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "integ-apprunner/Vpc/PublicSubnet2/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VpcPublicSubnet2RouteTable94F7E489" + }, + "subnetId": { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "integ-apprunner/Vpc/PublicSubnet2/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VpcPublicSubnet2RouteTable94F7E489" + }, + "destinationCidrBlock": "0.0.0.0/0", + "gatewayId": { + "Ref": "VpcIGWD7BA715C" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRoute", + "version": "0.0.0" + } + }, + "EIP": { + "id": "EIP", + "path": "integ-apprunner/Vpc/PublicSubnet2/EIP", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::EIP", + "aws:cdk:cloudformation:props": { + "domain": "vpc", + "tags": [ + { + "key": "Name", + "value": "integ-apprunner/Vpc/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnEIP", + "version": "0.0.0" + } + }, + "NATGateway": { + "id": "NATGateway", + "path": "integ-apprunner/Vpc/PublicSubnet2/NATGateway", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", + "aws:cdk:cloudformation:props": { + "subnetId": { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + }, + "allocationId": { + "Fn::GetAtt": [ + "VpcPublicSubnet2EIP3C605A87", + "AllocationId" + ] + }, + "tags": [ + { + "key": "Name", + "value": "integ-apprunner/Vpc/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnNatGateway", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.PublicSubnet", + "version": "0.0.0" + } + }, + "PrivateSubnet1": { + "id": "PrivateSubnet1", + "path": "integ-apprunner/Vpc/PrivateSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "integ-apprunner/Vpc/PrivateSubnet1/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "Vpc8378EB38" + }, + "availabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.128.0/18", + "mapPublicIpOnLaunch": false, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Private" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Private" + }, + { + "key": "Name", + "value": "integ-apprunner/Vpc/PrivateSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "integ-apprunner/Vpc/PrivateSubnet1/Acl", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "integ-apprunner/Vpc/PrivateSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "Vpc8378EB38" + }, + "tags": [ + { + "key": "Name", + "value": "integ-apprunner/Vpc/PrivateSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "integ-apprunner/Vpc/PrivateSubnet1/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VpcPrivateSubnet1RouteTableB2C5B500" + }, + "subnetId": { + "Ref": "VpcPrivateSubnet1Subnet536B997A" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "integ-apprunner/Vpc/PrivateSubnet1/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VpcPrivateSubnet1RouteTableB2C5B500" + }, + "destinationCidrBlock": "0.0.0.0/0", + "natGatewayId": { + "Ref": "VpcPublicSubnet1NATGateway4D7517AA" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.PrivateSubnet", + "version": "0.0.0" + } + }, + "PrivateSubnet2": { + "id": "PrivateSubnet2", + "path": "integ-apprunner/Vpc/PrivateSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "integ-apprunner/Vpc/PrivateSubnet2/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "Vpc8378EB38" + }, + "availabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.192.0/18", + "mapPublicIpOnLaunch": false, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Private" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Private" + }, + { + "key": "Name", + "value": "integ-apprunner/Vpc/PrivateSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "integ-apprunner/Vpc/PrivateSubnet2/Acl", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "integ-apprunner/Vpc/PrivateSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "Vpc8378EB38" + }, + "tags": [ + { + "key": "Name", + "value": "integ-apprunner/Vpc/PrivateSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "integ-apprunner/Vpc/PrivateSubnet2/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VpcPrivateSubnet2RouteTableA678073B" + }, + "subnetId": { + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "integ-apprunner/Vpc/PrivateSubnet2/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VpcPrivateSubnet2RouteTableA678073B" + }, + "destinationCidrBlock": "0.0.0.0/0", + "natGatewayId": { + "Ref": "VpcPublicSubnet2NATGateway9182C01D" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.PrivateSubnet", + "version": "0.0.0" + } + }, + "IGW": { + "id": "IGW", + "path": "integ-apprunner/Vpc/IGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::InternetGateway", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "integ-apprunner/Vpc" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnInternetGateway", + "version": "0.0.0" + } + }, + "VPCGW": { + "id": "VPCGW", + "path": "integ-apprunner/Vpc/VPCGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "Vpc8378EB38" + }, + "internetGatewayId": { + "Ref": "VpcIGWD7BA715C" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnVPCGatewayAttachment", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.Vpc", + "version": "0.0.0" + } + }, + "SecurityGroup": { + "id": "SecurityGroup", + "path": "integ-apprunner/SecurityGroup", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-apprunner/SecurityGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "integ-apprunner/SecurityGroup", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSecurityGroup", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.SecurityGroup", + "version": "0.0.0" + } + }, + "VpcConnector": { + "id": "VpcConnector", + "path": "integ-apprunner/VpcConnector", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-apprunner/VpcConnector/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::AppRunner::VpcConnector", + "aws:cdk:cloudformation:props": { + "subnets": [ + { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + } + ], + "securityGroups": [ + { + "Fn::GetAtt": [ + "SecurityGroupDD263621", + "GroupId" + ] + } + ], + "vpcConnectorName": "MyVpcConnector" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apprunner.CfnVpcConnector", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apprunner.VpcConnector", + "version": "0.0.0" + } + }, + "Service6": { + "id": "Service6", + "path": "integ-apprunner/Service6", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-apprunner/Service6/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::AppRunner::Service", + "aws:cdk:cloudformation:props": { + "sourceConfiguration": { + "authenticationConfiguration": {}, + "imageRepository": { + "imageConfiguration": { + "port": "8000" + }, + "imageIdentifier": "public.ecr.aws/aws-containers/hello-app-runner:latest", + "imageRepositoryType": "ECR_PUBLIC" + } + }, + "instanceConfiguration": {}, + "networkConfiguration": { + "egressConfiguration": { + "egressType": "VPC", + "vpcConnectorArn": { + "Fn::GetAtt": [ + "VpcConnectorE3A78531", + "VpcConnectorArn" + ] + } + } + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apprunner.CfnService", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apprunner.Service", + "version": "0.0.0" + } + }, + "URL6": { + "id": "URL6", + "path": "integ-apprunner/URL6", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnOutput", + "version": "0.0.0" + } + }, + "ImportedVpcConnector": { + "id": "ImportedVpcConnector", + "path": "integ-apprunner/ImportedVpcConnector", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Service7": { + "id": "Service7", + "path": "integ-apprunner/Service7", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-apprunner/Service7/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::AppRunner::Service", + "aws:cdk:cloudformation:props": { + "sourceConfiguration": { + "authenticationConfiguration": {}, + "imageRepository": { + "imageConfiguration": { + "port": "8000" + }, + "imageIdentifier": "public.ecr.aws/aws-containers/hello-app-runner:latest", + "imageRepositoryType": "ECR_PUBLIC" + } + }, + "instanceConfiguration": {}, + "networkConfiguration": { + "egressConfiguration": { + "egressType": "VPC", + "vpcConnectorArn": { + "Fn::GetAtt": [ + "VpcConnectorE3A78531", + "VpcConnectorArn" + ] + } + } + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apprunner.CfnService", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apprunner.Service", + "version": "0.0.0" + } + }, + "URL7": { + "id": "URL7", + "path": "integ-apprunner/URL7", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnOutput", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apprunner/test/service.test.ts b/packages/@aws-cdk/aws-apprunner/test/service.test.ts index 2d5285d06f7fa..2bef83769fff5 100644 --- a/packages/@aws-cdk/aws-apprunner/test/service.test.ts +++ b/packages/@aws-cdk/aws-apprunner/test/service.test.ts @@ -1,10 +1,11 @@ import * as path from 'path'; import { Template } from '@aws-cdk/assertions'; +import * as ec2 from '@aws-cdk/aws-ec2'; import * as ecr from '@aws-cdk/aws-ecr'; import * as ecr_assets from '@aws-cdk/aws-ecr-assets'; import * as iam from '@aws-cdk/aws-iam'; import * as cdk from '@aws-cdk/core'; -import { Service, GitHubConnection, Runtime, Source, Cpu, Memory, ConfigurationSourceType } from '../lib'; +import { Service, GitHubConnection, Runtime, Source, Cpu, Memory, ConfigurationSourceType, VpcConnector } from '../lib'; test('create a service with ECR Public(image repository type: ECR_PUBLIC)', () => { // GIVEN @@ -29,6 +30,11 @@ test('create a service with ECR Public(image repository type: ECR_PUBLIC)', () = ImageRepositoryType: 'ECR_PUBLIC', }, }, + NetworkConfiguration: { + EgressConfiguration: { + EgressType: 'DEFAULT', + }, + }, }); }); @@ -73,6 +79,11 @@ test('custom environment variables and start commands are allowed for imageConfi ImageRepositoryType: 'ECR_PUBLIC', }, }, + NetworkConfiguration: { + EgressConfiguration: { + EgressType: 'DEFAULT', + }, + }, }); }); @@ -115,6 +126,11 @@ test('custom environment variables and start commands are allowed for imageConfi ImageRepositoryType: 'ECR_PUBLIC', }, }, + NetworkConfiguration: { + EgressConfiguration: { + EgressType: 'DEFAULT', + }, + }, }); }); @@ -183,6 +199,11 @@ test('create a service from existing ECR repository(image repository type: ECR)' ImageRepositoryType: 'ECR', }, }, + NetworkConfiguration: { + EgressConfiguration: { + EgressType: 'DEFAULT', + }, + }, }); }); @@ -254,6 +275,11 @@ test('create a service with local assets(image repository type: ECR)', () => { ImageRepositoryType: 'ECR', }, }, + NetworkConfiguration: { + EgressConfiguration: { + EgressType: 'DEFAULT', + }, + }, }); }); @@ -290,6 +316,11 @@ test('create a service with github repository', () => { }, }, }, + NetworkConfiguration: { + EgressConfiguration: { + EgressType: 'DEFAULT', + }, + }, }); }); @@ -332,6 +363,11 @@ test('create a service with github repository - undefined branch name is allowed }, }, }, + NetworkConfiguration: { + EgressConfiguration: { + EgressType: 'DEFAULT', + }, + }, }); }); @@ -392,6 +428,11 @@ test('create a service with github repository - buildCommand, environment and st }, }, }, + NetworkConfiguration: { + EgressConfiguration: { + EgressType: 'DEFAULT', + }, + }, }); }); @@ -447,6 +488,11 @@ test('undefined imageConfiguration port is allowed', () => { ImageRepositoryType: 'ECR_PUBLIC', }, }, + NetworkConfiguration: { + EgressConfiguration: { + EgressType: 'DEFAULT', + }, + }, }); }); @@ -519,6 +565,11 @@ test('custom IAM access role and instance role are allowed', () => { ], }, }, + NetworkConfiguration: { + EgressConfiguration: { + EgressType: 'DEFAULT', + }, + }, }); }); @@ -540,6 +591,11 @@ test('cpu and memory properties are allowed', () => { Cpu: '1 vCPU', Memory: '3 GB', }, + NetworkConfiguration: { + EgressConfiguration: { + EgressType: 'DEFAULT', + }, + }, }); }); @@ -561,6 +617,11 @@ test('custom cpu and memory units are allowed', () => { Cpu: 'Some vCPU', Memory: 'Some GB', }, + NetworkConfiguration: { + EgressConfiguration: { + EgressType: 'DEFAULT', + }, + }, }); }); @@ -583,3 +644,63 @@ test('environment variable with a prefix of AWSAPPRUNNER should throw an error', }); }).toThrow('Environment variable key AWSAPPRUNNER_FOO with a prefix of AWSAPPRUNNER is not allowed'); }); + +test('specifying a vpcConnector should assign the service to it and set the egressType to VPC', () => { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'demo-stack'); + + const vpc = new ec2.Vpc(stack, 'Vpc', { + cidr: '10.0.0.0/16', + }); + + const securityGroup = new ec2.SecurityGroup(stack, 'SecurityGroup', { vpc }); + + const vpcConnector = new VpcConnector(stack, 'VpcConnector', { + securityGroups: [securityGroup], + vpc, + vpcSubnets: vpc.selectSubnets({ subnetType: ec2.SubnetType.PUBLIC }), + vpcConnectorName: 'MyVpcConnector', + }); + // WHEN + new Service(stack, 'DemoService', { + source: Source.fromEcrPublic({ + imageIdentifier: 'public.ecr.aws/aws-containers/hello-app-runner:latest', + }), + vpcConnector, + }); + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::AppRunner::Service', { + NetworkConfiguration: { + EgressConfiguration: { + EgressType: 'VPC', + VpcConnectorArn: { + 'Fn::GetAtt': [ + 'VpcConnectorE3A78531', + 'VpcConnectorArn', + ], + }, + }, + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::AppRunner::VpcConnector', { + Subnets: [ + { + Ref: 'VpcPublicSubnet1Subnet5C2D37C4', + }, + { + Ref: 'VpcPublicSubnet2Subnet691E08A3', + }, + ], + SecurityGroups: [ + { + 'Fn::GetAtt': [ + 'SecurityGroupDD263621', + 'GroupId', + ], + }, + ], + VpcConnectorName: 'MyVpcConnector', + }); +}); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apprunner/test/vpc-connector.test.ts b/packages/@aws-cdk/aws-apprunner/test/vpc-connector.test.ts new file mode 100644 index 0000000000000..7eef67f924381 --- /dev/null +++ b/packages/@aws-cdk/aws-apprunner/test/vpc-connector.test.ts @@ -0,0 +1,151 @@ +import { Template } from '@aws-cdk/assertions'; +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as cdk from '@aws-cdk/core'; +import { VpcConnector } from '../lib'; + +test('create a vpcConnector with all properties', () => { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'demo-stack'); + + const vpc = new ec2.Vpc(stack, 'Vpc', { + cidr: '10.0.0.0/16', + }); + + const securityGroup = new ec2.SecurityGroup(stack, 'SecurityGroup', { vpc }); + // WHEN + new VpcConnector(stack, 'VpcConnector', { + securityGroups: [securityGroup], + vpc, + vpcSubnets: vpc.selectSubnets({ subnetType: ec2.SubnetType.PUBLIC }), + vpcConnectorName: 'MyVpcConnector', + }); + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::AppRunner::VpcConnector', { + Subnets: [ + { + Ref: 'VpcPublicSubnet1Subnet5C2D37C4', + }, + { + Ref: 'VpcPublicSubnet2Subnet691E08A3', + }, + ], + SecurityGroups: [ + { + 'Fn::GetAtt': [ + 'SecurityGroupDD263621', + 'GroupId', + ], + }, + ], + VpcConnectorName: 'MyVpcConnector', + }); +}); + +test('create a vpcConnector without a name', () => { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'demo-stack'); + + const vpc = new ec2.Vpc(stack, 'Vpc', { + cidr: '10.0.0.0/16', + }); + + const securityGroup = new ec2.SecurityGroup(stack, 'SecurityGroup', { vpc }); + // WHEN + new VpcConnector(stack, 'VpcConnector', { + securityGroups: [securityGroup], + vpc, + vpcSubnets: vpc.selectSubnets({ subnetType: ec2.SubnetType.PUBLIC }), + }); + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::AppRunner::VpcConnector', { + Subnets: [ + { + Ref: 'VpcPublicSubnet1Subnet5C2D37C4', + }, + { + Ref: 'VpcPublicSubnet2Subnet691E08A3', + }, + ], + SecurityGroups: [ + { + 'Fn::GetAtt': [ + 'SecurityGroupDD263621', + 'GroupId', + ], + }, + ], + }); +}); + +test('create a vpcConnector without a security group should create one', () => { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'demo-stack'); + + const vpc = new ec2.Vpc(stack, 'Vpc', { + cidr: '10.0.0.0/16', + }); + + // WHEN + new VpcConnector(stack, 'VpcConnector', { + vpc, + vpcSubnets: vpc.selectSubnets({ subnetType: ec2.SubnetType.PUBLIC }), + }); + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::AppRunner::VpcConnector', { + Subnets: [ + { + Ref: 'VpcPublicSubnet1Subnet5C2D37C4', + }, + { + Ref: 'VpcPublicSubnet2Subnet691E08A3', + }, + ], + SecurityGroups: [ + { + 'Fn::GetAtt': [ + 'VpcConnectorSecurityGroup33FAF25D', + 'GroupId', + ], + }, + ], + }); +}); + +test('create a vpcConnector with an empty security group array should create one', () => { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'demo-stack'); + + const vpc = new ec2.Vpc(stack, 'Vpc', { + cidr: '10.0.0.0/16', + }); + + // WHEN + new VpcConnector(stack, 'VpcConnector', { + vpc, + vpcSubnets: vpc.selectSubnets({ subnetType: ec2.SubnetType.PUBLIC }), + securityGroups: [], + }); + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::AppRunner::VpcConnector', { + Subnets: [ + { + Ref: 'VpcPublicSubnet1Subnet5C2D37C4', + }, + { + Ref: 'VpcPublicSubnet2Subnet691E08A3', + }, + ], + SecurityGroups: [ + { + 'Fn::GetAtt': [ + 'VpcConnectorSecurityGroup33FAF25D', + 'GroupId', + ], + }, + ], + }); +}); \ No newline at end of file