├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── bin └── egress_vpc-tg-demo.ts ├── cdk.json ├── img ├── AWS_Systems_Manager_Session_Manager.png ├── AWS_Systems_Manager_start_session.png └── egressVPC_TG_CDK.png ├── lib └── egress_vpc-tg-demo-stack.ts ├── package.json └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | *.js 2 | *.d.ts 3 | node_modules 4 | 5 | # CDK asset staging directory 6 | .cdk.staging 7 | cdk.out 8 | package-lock.json 9 | .DS_Store 10 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *master* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | 61 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. 62 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Transit Gateway Demo Stack: Egress-VPC Design Pattern 2 | 3 | > This CDK project demonstrates a shared egress-VPC design pattern. Furthermore, the stack uses AWS Systems Manager Session Manager to securely access a demo EC2 instance in a private VPC / subnet. 4 | 5 | ## Solution Overview 6 | 7 | The architecture diagram that follows shows the egress VPC pattern and elements created by the template. The private VPC contains a single EC2 instance. It lacks a direct route to the internet and has no public subnets or internet gateway. Instead, traffic destined for the internet is routed to the Transit Gateway. 8 | 9 | The second VPC contains two pairs of public and private subnets, an internet gateway and two NAT gateways. Both VPCs are attached to the Transit Gateway, which allows north-south connectivity. All relevant routes are depicted in tables connected by dotted lines. 10 | 11 | ![Diagram](img/egressVPC_TG_CDK.png) 12 | 13 | ## Walkthrough 14 | 15 | In this section you will familiarize yourself with using [AWS Cloud Development Kit](https://docs.aws.amazon.com/cdk/latest/guide/home.html) (CDK) by downloading and deploying an egress VPC demo into your AWS account. 16 | 17 | This will include: 18 | 19 | - Installing CDK and closing this [demo repository](https://github.com/aws-samples/aws-transit-gateway-egress-vpc-pattern) 20 | - Deploying the example environment into your AWS account 21 | - Familiarizing yourself with the egress VPC pattern and the associated constructs and routing 22 | - Securely accessing the shell of a fully private EC2 instance via [AWS Systems Manager Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html) 23 | 24 | ### Prerequisites 25 | 26 | - An [AWS account](https://signin.aws.amazon.com/signin?redirect_uri=https%3A%2F%2Fportal.aws.amazon.com%2Fbilling%2Fsignup%2Fresume&client_id=signup) 27 | - Installed and authenticated [AWS CLI](https://docs.aws.amazon.com/en_pv/cli/latest/userguide/cli-chap-install.html) (authenticate with an [IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/getting-started.html) user or an [AWS STS](https://docs.aws.amazon.com/STS/latest/APIReference/Welcome.html) Security Token) 28 | - AWS [CDK](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html) installed (typically via `npm install aws-cdk -g`) 29 | 30 | ### Let’s get you started 31 | 32 | 1. Make sure that you completed the prerequisite above and git pulled the CDK example by running the following command in a local directory: `git clone git@github.com:aws-samples/aws-transit-gateway-egress-vpc-pattern.git` 33 | 34 | 2. Open the repository in your preferred local editor and inspect lib/egress_vpc-tg-demo-stack.ts 35 | 36 | 3. Run `npm install` to include dependencies 37 | 38 | 4. Run `npm run build` once or keep a separate terminal window open running `npm run watch` to start compilation to JavaScript in watch mode 39 | 40 | 5. Run `cdk synth` and check out the synthesized [AWS CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html) YAML syntax that will be used for deployment of the stack. Due to the higher-level programming languages used in CDK and the use of constructor libraries the CDK code is significantly more compact and more powerful than conventional markup. 41 | 42 | 6. Now you can deploy the stack simply by running `cdk deploy` and observe the progress in your terminal window 43 | 44 | 7. Once stack creation is complete open the AWS Console, select the AWS Systems Manager, choose the automatically listed instance we created with the stack and click on “Start Session” 45 | ![AWS Systems Manager - Managed Instances](img/AWS_Systems_Manager_start_session.png) 46 | 47 | 8. Execute any command to test internet connectivity, for instance a nice and simple `ping amazon.com` 48 | ![AWS Systems Manager Session Manager](img/AWS_Systems_Manager_Session_Manager.png) 49 | 50 | ## Good to know and explore 51 | 52 | - The image to create the EC2 instance is selected based on a higher level constructor [AmazonLinuxImage](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-ec2.AmazonLinuxImage.html) and the AMI ID is automatically retrieved via the SSM parameter store. This means that the stack can be deployed to multiple regions and will automatically retrieve the latest managed image of the selected OS. By default CDK will use your default AWS cli configuration, however multiple environments can easily be [integrated](https://docs.aws.amazon.com/cdk/latest/guide/environments.html) via CDK native functionality. 53 | 54 | - AWS Systems Manager Agent (SSM Agent) is included in the utilized AMI and requires two managed policies to work, which are attached to the instance’s role. 55 | 56 | - The CDK template includes commented out examples of adding [VPC Endpoint for Systems Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/setup-create-vpc.html) and illustrates the use of mandatory, as well as optional endpoints. 57 | 58 | ## Useful CDK commands 59 | 60 | - `npm run build` compile typescript to js 61 | - `npm run watch` watch for changes and compile 62 | - `cdk deploy` deploy this stack to your default AWS account/region 63 | - `cdk diff` compare deployed stack with current state 64 | - `cdk synth` emits the synthesized CloudFormation template 65 | 66 | ## Cleaning up 67 | 68 | To avoid incurring future charges, delete the resources by simply running `cdk destroy` and confirm deletion. 69 | 70 | ## License 71 | 72 | This library is licensed under the MIT-0 License. See the LICENSE file. 73 | -------------------------------------------------------------------------------- /bin/egress_vpc-tg-demo.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import 'source-map-support/register'; 3 | import cdk = require('@aws-cdk/core'); 4 | import { EgressVpcTgDemoStack } from '../lib/egress_vpc-tg-demo-stack'; 5 | 6 | const app = new cdk.App(); 7 | new EgressVpcTgDemoStack(app, 'EgressVpcTgDemoStack'); 8 | -------------------------------------------------------------------------------- /cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "npx ts-node bin/egress_vpc-tg-demo.ts" 3 | } 4 | -------------------------------------------------------------------------------- /img/AWS_Systems_Manager_Session_Manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-transit-gateway-egress-vpc-pattern/bb8f793b3e232b4cac90bf9972a8cddce16738a7/img/AWS_Systems_Manager_Session_Manager.png -------------------------------------------------------------------------------- /img/AWS_Systems_Manager_start_session.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-transit-gateway-egress-vpc-pattern/bb8f793b3e232b4cac90bf9972a8cddce16738a7/img/AWS_Systems_Manager_start_session.png -------------------------------------------------------------------------------- /img/egressVPC_TG_CDK.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-transit-gateway-egress-vpc-pattern/bb8f793b3e232b4cac90bf9972a8cddce16738a7/img/egressVPC_TG_CDK.png -------------------------------------------------------------------------------- /lib/egress_vpc-tg-demo-stack.ts: -------------------------------------------------------------------------------- 1 | import cdk = require('@aws-cdk/core'); 2 | import ec2 = require('@aws-cdk/aws-ec2'); 3 | import { SubnetType, CfnRoute} from '@aws-cdk/aws-ec2'; 4 | import { ManagedPolicy, Role, ServicePrincipal, CfnInstanceProfile, PolicyDocument, PolicyStatement, Effect } from '@aws-cdk/aws-iam'; 5 | 6 | export class EgressVpcTgDemoStack extends cdk.Stack { 7 | constructor(scope: cdk.Construct, id: string, props ? : cdk.StackProps) { 8 | super(scope, id, props); 9 | //set-up egress and private VPCs 10 | const egressVPC = new ec2.Vpc(this, 'Egress VPC', { 11 | cidr: "10.0.1.0/26", 12 | //natGateways: 1, add this to limit numer of deployed NAT gateways 13 | subnetConfiguration: [{ 14 | cidrMask: 28, 15 | name: 'Public - EgressVPC SubNet', 16 | subnetType: SubnetType.PUBLIC, 17 | }, 18 | { 19 | cidrMask: 28, 20 | name: 'Private - EgressVPC SubNet', 21 | subnetType: SubnetType.PRIVATE, 22 | }, 23 | ] 24 | }); 25 | const privateVPC = new ec2.Vpc(this, 'Private VPC', { 26 | cidr: "10.0.2.0/26", 27 | maxAzs: 1, 28 | enableDnsHostnames: true, 29 | enableDnsSupport: true, 30 | subnetConfiguration: [{ 31 | cidrMask: 28, 32 | name: 'Isolated Subnet - privateVPC', 33 | subnetType: SubnetType.ISOLATED, 34 | }], 35 | }); 36 | // Security Group to be used by EC2 instances in isolated subnet and accessed via Systems Manager 37 | const ssmPrivateSG = new ec2.SecurityGroup(this, 'SSMPrivateSecurityGroup', { 38 | vpc: privateVPC, 39 | securityGroupName: 'Demo EC2 Instance Security Group', 40 | description: 'Demo EC2 Instance Security Group', 41 | allowAllOutbound: true, 42 | }); 43 | 44 | // uncomment below lines to add private link endpoints for Systems Manager 45 | 46 | // adding interface endpoints for Systems Manger use - only 443 from EC2-SG to Interface Endpoints necessary 47 | // const ssmIE = privateVPC.addInterfaceEndpoint('SSM', { 48 | // service: ec2.InterfaceVpcEndpointAwsService.SSM, 49 | // privateDnsEnabled: true, 50 | // subnets: { subnetType: ec2.SubnetType.ISOLATED, onePerAz: true }, 51 | // }); 52 | // ssmIE.connections.allowFrom(ssmPrivateSG, ec2.Port.tcp(443), 'Allow from SSM IE Private SG'); 53 | 54 | // const ssmMessagesIE = privateVPC.addInterfaceEndpoint('SSM-Messages', { 55 | // service: ec2.InterfaceVpcEndpointAwsService.SSM_MESSAGES, 56 | // privateDnsEnabled: true, 57 | // subnets: { subnetType: ec2.SubnetType.ISOLATED, onePerAz: true }, 58 | // }); 59 | // ssmMessagesIE.connections.allowFrom(ssmPrivateSG, ec2.Port.tcp(443), 'Allow from SSM Messages IE Private SG'); 60 | 61 | // const ec2IE = privateVPC.addInterfaceEndpoint('EC2', { 62 | // service: ec2.InterfaceVpcEndpointAwsService.EC2, 63 | // privateDnsEnabled: true, 64 | // subnets: { subnetType: ec2.SubnetType.ISOLATED, onePerAz: true }, 65 | // }); 66 | // ec2IE.connections.allowFrom(ssmPrivateSG, ec2.Port.tcp(443), 'Allow from EC2 IE Private SG'); 67 | 68 | // const ec2Messages = privateVPC.addInterfaceEndpoint('EC2-messages', { 69 | // service: ec2.InterfaceVpcEndpointAwsService.EC2_MESSAGES, 70 | // privateDnsEnabled: true, 71 | // subnets: { subnetType: ec2.SubnetType.ISOLATED, onePerAz: true }, 72 | // }); 73 | // ec2Messages.connections.allowFrom(ssmPrivateSG, ec2.Port.tcp(443), 'Allow from EC2 Messages IE Private SG'); 74 | 75 | // privateVPC.addGatewayEndpoint('S3-SSM', { 76 | // service: ec2.GatewayVpcEndpointAwsService.S3, 77 | // subnets: [{ subnetType: ec2.SubnetType.ISOLATED, onePerAz: true }], 78 | // }); 79 | 80 | //Create TG gateway 81 | const TransitGateway = new ec2.CfnTransitGateway(this, 'Transit_Gateway', { 82 | description: "Transit Gateway", 83 | vpnEcmpSupport: 'enable', 84 | defaultRouteTableAssociation: 'disable', 85 | defaultRouteTablePropagation: 'disable', 86 | tags: [{ 87 | key: 'Name', 88 | value: "Transit Gateway" 89 | }], 90 | }); 91 | //attach VPCs to gateway 92 | const TransitGatewayAttachmentEgress = new ec2.CfnTransitGatewayAttachment(this, 'TransitGatewayAttachmentEgress', { 93 | transitGatewayId: TransitGateway.ref, 94 | vpcId: egressVPC.vpcId, 95 | subnetIds: [egressVPC.privateSubnets[0].subnetId, egressVPC.privateSubnets[1].subnetId], 96 | tags: [{ 97 | key: 'Name', 98 | value: "TG-Egress-VPC-Private_SubNet-Attachment" 99 | }], 100 | }); 101 | TransitGatewayAttachmentEgress.addDependsOn(TransitGateway); 102 | 103 | const TransitGatewayAttachmentPrivate = new ec2.CfnTransitGatewayAttachment(this, 'TransitGatewayAttachmentPrivate', { 104 | transitGatewayId: TransitGateway.ref, 105 | vpcId: privateVPC.vpcId, 106 | subnetIds: [privateVPC.isolatedSubnets[0].subnetId], 107 | tags: [{ 108 | key: 'Name', 109 | value: "TG-Private-VPC-Private_SubNet-Attachment" 110 | }], 111 | }); 112 | TransitGatewayAttachmentEgress.addDependsOn(TransitGateway); 113 | 114 | //add routes 115 | for (let subnet of egressVPC.publicSubnets) { 116 | new CfnRoute(this, subnet.node.uniqueId, { 117 | routeTableId: subnet.routeTable.routeTableId, 118 | destinationCidrBlock: privateVPC.vpcCidrBlock, 119 | transitGatewayId: TransitGateway.ref, 120 | }).addDependsOn(TransitGatewayAttachmentEgress); 121 | }; 122 | 123 | for (let subnet of privateVPC.isolatedSubnets) { 124 | new CfnRoute(this, subnet.node.uniqueId, { 125 | routeTableId: subnet.routeTable.routeTableId, 126 | destinationCidrBlock: "0.0.0.0/0", 127 | transitGatewayId: TransitGateway.ref, 128 | }).addDependsOn(TransitGatewayAttachmentPrivate); 129 | }; 130 | 131 | //add TG Route Domain (fancy name for route table) and internet egress route 132 | const TGRouteTable = new ec2.CfnTransitGatewayRouteTable(this, "TGEgressRouteTable", { 133 | transitGatewayId: TransitGateway.ref, 134 | tags: [{ 135 | key: 'Name', 136 | value: "TG Route Domain" 137 | }], 138 | }); 139 | const TransitGatewayRouteTable = new ec2.CfnTransitGatewayRoute(this, "TransitGatewayToEgressVPCRoute", { 140 | transitGatewayRouteTableId: TGRouteTable.ref, 141 | transitGatewayAttachmentId: TransitGatewayAttachmentEgress.ref, 142 | destinationCidrBlock: "0.0.0.0/0" 143 | }); 144 | const TGRouteTableAssociationEgressVPC = new ec2.CfnTransitGatewayRouteTableAssociation(this, 'EgressVPC_TG_Association', { 145 | transitGatewayAttachmentId: TransitGatewayAttachmentEgress.ref, 146 | transitGatewayRouteTableId: TransitGatewayRouteTable.transitGatewayRouteTableId, 147 | }); 148 | const TGRouteTablePropagationEgressVPC = new ec2.CfnTransitGatewayRouteTablePropagation(this, 'EgressVPC_TG_Propagation', { 149 | transitGatewayAttachmentId: TransitGatewayAttachmentEgress.ref, 150 | transitGatewayRouteTableId: TransitGatewayRouteTable.transitGatewayRouteTableId, 151 | }); 152 | const TGRouteTableAssociationPrivateVPC = new ec2.CfnTransitGatewayRouteTableAssociation(this, 'PrivateVPC_TG_Association', { 153 | transitGatewayAttachmentId: TransitGatewayAttachmentPrivate.ref, 154 | transitGatewayRouteTableId: TransitGatewayRouteTable.transitGatewayRouteTableId, 155 | }); 156 | const TGRouteTablePropagationPrivateVPC = new ec2.CfnTransitGatewayRouteTablePropagation(this, 'PrivateVPC_TG_Propagation', { 157 | transitGatewayAttachmentId: TransitGatewayAttachmentPrivate.ref, 158 | transitGatewayRouteTableId: TransitGatewayRouteTable.transitGatewayRouteTableId, 159 | }); 160 | 161 | // Time to test the routes. 162 | 163 | //Getting latest Amazon Linux AMI 164 | const latestLinuxAMI = new ec2.AmazonLinuxImage({ 165 | generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2, 166 | edition: ec2.AmazonLinuxEdition.STANDARD, 167 | virtualization: ec2.AmazonLinuxVirt.HVM, 168 | storage: ec2.AmazonLinuxStorage.GENERAL_PURPOSE, 169 | }); 170 | //ssm agent Role - we don't want to rely on a bastion host 171 | const SSMRole = new Role(this, 'SSMRole', { 172 | assumedBy: new ServicePrincipal('ec2.amazonaws.com'), 173 | managedPolicies: [ 174 | ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore'), 175 | ManagedPolicy.fromAwsManagedPolicyName('CloudWatchAgentServerPolicy'), 176 | ], 177 | // optional inline policy for S3 SSM 178 | inlinePolicies: { 179 | ssmS3policy: new PolicyDocument({ 180 | statements: [ 181 | new PolicyStatement({ 182 | effect: Effect.ALLOW, 183 | actions: [ 184 | 's3:GetObject' 185 | ], 186 | resources: [ 187 | 'arn:aws:s3:::aws-ssm-' + this.region +'/*', 188 | 'arn:aws:s3:::aws-windows-downloads-' + this.region +'/*', 189 | 'arn:aws:s3:::amazon-ssm-' +this.region+'/*', 190 | 'arn:aws:s3:::amazon-ssm-packages-' + this.region +'/*', 191 | 'arn:aws:s3:::' + this.region +'-birdwatcher-prod/*', 192 | 'arn:aws:s3:::patch-baseline-snapshot-' + this.region +'/*' 193 | ] 194 | }) 195 | ] 196 | }) 197 | } 198 | }); 199 | 200 | //Launch instance in private VPC subnet 201 | const demoInstance = new ec2.CfnInstance(this, "Demo Instance", { 202 | subnetId: privateVPC.isolatedSubnets[0].subnetId, 203 | imageId: latestLinuxAMI.getImage(this).imageId, 204 | instanceType: "t2.nano", 205 | iamInstanceProfile: new CfnInstanceProfile(this, "DemoEC2_InstanceProfile", { 206 | roles: [SSMRole.roleName] 207 | }).ref, 208 | tags: [{ 209 | key: 'Name', 210 | value: "Demo instance" 211 | }], 212 | securityGroupIds: [ssmPrivateSG.securityGroupId] //The Security Group we created earlier, linked to private interface endpoints 213 | }); 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egress_vpc-tg-demo", 3 | "version": "1.0.0", 4 | "bin": { 5 | "egress_vpc-tg-demo": "bin/egress_vpc-tg-demo.js" 6 | }, 7 | "scripts": { 8 | "build": "tsc", 9 | "watch": "tsc -w", 10 | "cdk": "cdk" 11 | }, 12 | "devDependencies": { 13 | "@types/node": "8.10.52", 14 | "aws-cdk": "1.27.0", 15 | "ts-node": "^8.6.2", 16 | "typescript": "^3.8.3" 17 | }, 18 | "dependencies": { 19 | "@aws-cdk/aws-ec2": "1.27.0", 20 | "@aws-cdk/aws-iam": "1.27.0", 21 | "@aws-cdk/core": "1.27.0", 22 | "source-map-support": "^0.5.16" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target":"ES2018", 4 | "module": "commonjs", 5 | "lib": ["es2016", "es2017.object", "es2017.string"], 6 | "declaration": true, 7 | "strict": true, 8 | "noImplicitAny": true, 9 | "strictNullChecks": true, 10 | "noImplicitThis": true, 11 | "alwaysStrict": true, 12 | "noUnusedLocals": false, 13 | "noUnusedParameters": false, 14 | "noImplicitReturns": true, 15 | "noFallthroughCasesInSwitch": false, 16 | "inlineSourceMap": true, 17 | "inlineSources": true, 18 | "experimentalDecorators": true, 19 | "strictPropertyInitialization":false 20 | }, 21 | "exclude": ["cdk.out"] 22 | } 23 | --------------------------------------------------------------------------------