├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── images └── diagram.png └── transitgateway-egress-solution-v2.yaml /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 | ## Blog: How to use Transit Gateway to create a single exit point to the internet from multiple VPCs 2 | 3 | ### Introduction 4 | 5 | The cloudformation in this project are intended to be used in support of the AWS blog article here: https://aws.amazon.com/blogs/networking-and-content-delivery/creating-a-single-internet-exit-point-from-multiple-vpcs-using-aws-transit-gateway/ 6 | 7 | The files contained here are as follows: 8 | 9 | |File | Description | 10 | |----------------------------------------|-----------------------------------------------------------------------------| 11 | |`transitgateway-egress-solution-v2.yaml`|The cloudformation template to create the solution in the blog | 12 | 13 | The cloudformation automatically creates the solution highlighted in the blog, and will populate the VPC route tables with the correct routes after creation of the transit gateway attachments. This function has recently been added to cloudformation. 14 | 15 | 16 | The purpose of the cloudformation is to create this architecture... 17 | 18 | ![Network Architecture](images/diagram.png) 19 | 20 | ### Running the cloudformation template 21 | 22 | You can either upload the cloudformation template to an S3 bucket in the same region as you want to deploy it, or upload it as part of running the cloudformation from the console. 23 | 24 | This should then create the entire environment, update the VPC route tables and be ready for you to play with. 25 | 26 | ### How I tested the deployed environment 27 | 28 | For testing, I just created a linux instance in each of the app subnets, and also one in the public egress subnet. This public one, i gave a public as well as private IP address, so i could ssh in. I then created the appropriate security groups so that ssh and ICMP were permitted, and proved that i could ping and ssh between all the instances. 29 | 30 | 31 | ## License 32 | 33 | This library is licensed under the MIT-0 License. See the LICENSE file. 34 | -------------------------------------------------------------------------------- /images/diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/transit-gateway-single-exit-point/4cbbb75621e8d83704727d08c9c988a1dd50b347/images/diagram.png -------------------------------------------------------------------------------- /transitgateway-egress-solution-v2.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Description: The template creates TGW & an Egress VPC for internet. 3 | 4 | It is a heavily modified version of the original template, created by shkahma@ which can be found here 5 | https://github.com/aws-samples/aws-transit-gateway-egress-vpc-demo. Most of the modification is because 6 | cloudformation now supports the creation of routes within a VPC route table, where the target is a 7 | transit gateway 8 | 9 | 10 | Parameters: 11 | 12 | AppCidr: 13 | Description: Default route for adding to app VPCs route tables 14 | Type: String 15 | Default: '0.0.0.0/0' 16 | 17 | EgressPublicCidr: 18 | Description: CIDR range to be added to public egress VPC route table 19 | Type: String 20 | Default: '10.0.0.0/8' 21 | 22 | 23 | Resources: 24 | 25 | #egress vpc and subnet creation 26 | 27 | EgressVPC: 28 | Type: AWS::EC2::VPC 29 | Properties: 30 | CidrBlock: 192.168.0.0/16 31 | Tags: 32 | - Key: Name 33 | Value: Egress-VPC 34 | 35 | PublicEgressVpcSubnet1: 36 | Type: AWS::EC2::Subnet 37 | Properties: 38 | VpcId: !Ref 'EgressVPC' 39 | CidrBlock: 192.168.1.0/24 40 | AvailabilityZone: 41 | Fn::Select: 42 | - 0 43 | - Fn::GetAZs: "" 44 | Tags: 45 | - Key: Application 46 | Value: !Ref 'AWS::StackId' 47 | - Key: Name 48 | Value: Egress-Public-AZ1 49 | 50 | PublicEgressVpcSubnet2: 51 | Type: AWS::EC2::Subnet 52 | Properties: 53 | VpcId: !Ref 'EgressVPC' 54 | CidrBlock: 192.168.2.0/24 55 | AvailabilityZone: 56 | Fn::Select: 57 | - 1 58 | - Fn::GetAZs: "" 59 | Tags: 60 | - Key: Application 61 | Value: !Ref 'AWS::StackId' 62 | - Key: Name 63 | Value: Egress-Public-AZ2 64 | 65 | PrivateEgressSubnet1: 66 | Type: AWS::EC2::Subnet 67 | Properties: 68 | VpcId: !Ref 'EgressVPC' 69 | CidrBlock: 192.168.3.0/24 70 | AvailabilityZone: 71 | Fn::Select: 72 | - 0 73 | - Fn::GetAZs: "" 74 | Tags: 75 | - Key: Application 76 | Value: !Ref 'AWS::StackId' 77 | - Key: Name 78 | Value: Egress-Private-AZ1 79 | 80 | PrivateEgressSubnet2: 81 | Type: AWS::EC2::Subnet 82 | Properties: 83 | VpcId: !Ref 'EgressVPC' 84 | CidrBlock: 192.168.4.0/24 85 | AvailabilityZone: 86 | Fn::Select: 87 | - 1 88 | - Fn::GetAZs: "" 89 | Tags: 90 | - Key: Application 91 | Value: !Ref 'AWS::StackId' 92 | - Key: Name 93 | Value: Egress-Private-AZ2 94 | 95 | #igw and NAT gw creation 96 | 97 | InternetGateway: 98 | Type: AWS::EC2::InternetGateway 99 | Properties: 100 | Tags: 101 | - Key: Application 102 | Value: !Ref 'AWS::StackId' 103 | AttachIGW: 104 | Type: AWS::EC2::VPCGatewayAttachment 105 | Properties: 106 | VpcId: !Ref 'EgressVPC' 107 | InternetGatewayId: !Ref 'InternetGateway' 108 | IPAddress1: 109 | Type: AWS::EC2::EIP 110 | DependsOn: AttachIGW 111 | Properties: 112 | Domain: vpc 113 | 114 | # you only need the second EIP if you deploy 2 NAT gateways. The cloudformation for that is included here, but commented out. 115 | # this means that the cloudformation matches the blog post, but you can edit it to create 2 NAT gateways. 116 | 117 | # IPAddress2: 118 | # Type: AWS::EC2::EIP 119 | # DependsOn: AttachIGW 120 | # Properties: 121 | # Domain: vpc 122 | 123 | NATGateway1: 124 | Type: AWS::EC2::NatGateway 125 | Properties: 126 | AllocationId: !GetAtt IPAddress1.AllocationId 127 | SubnetId: !Ref PublicEgressVpcSubnet1 128 | Tags: 129 | - Key: Application 130 | Value: !Ref 'AWS::StackId' 131 | 132 | # removed as this is not included in the blog post 133 | 134 | # NATGateway2: 135 | # Type: AWS::EC2::NatGateway 136 | # Properties: 137 | # AllocationId: !GetAtt IPAddress2.AllocationId 138 | # SubnetId: !Ref PublicEgressVpcSubnet2 139 | # Tags: 140 | # - Key: Application 141 | # Value: !Ref 'AWS::StackId' 142 | 143 | 144 | 145 | #Egress route table configuration 146 | 147 | EgressRouteTable: 148 | Type: AWS::EC2::RouteTable 149 | Properties: 150 | VpcId: !Ref 'EgressVPC' 151 | Tags: 152 | - Key: Application 153 | Value: !Ref 'AWS::StackId' 154 | - Key: Name 155 | Value: Egress-Public-RT 156 | PrivateEgressRouteTable1: 157 | Type: AWS::EC2::RouteTable 158 | Properties: 159 | VpcId: !Ref 'EgressVPC' 160 | Tags: 161 | - Key: Application 162 | Value: !Ref 'AWS::StackId' 163 | - Key: Name 164 | Value: Egress-Private-RT-AZ1 165 | 166 | # This would be needed if you had 2 NAT gateways. 167 | 168 | # PrivateEgressRouteTable2: 169 | # Type: AWS::EC2::RouteTable 170 | # Properties: 171 | # VpcId: !Ref 'EgressVPC' 172 | # Tags: 173 | # - Key: Application 174 | # Value: !Ref 'AWS::StackId' 175 | # - Key: Name 176 | # Value: Egress-Private-RT-AZ2 177 | 178 | Route: 179 | Type: AWS::EC2::Route 180 | DependsOn: AttachIGW 181 | Properties: 182 | RouteTableId: !Ref 'EgressRouteTable' 183 | DestinationCidrBlock: 0.0.0.0/0 184 | GatewayId: !Ref 'InternetGateway' 185 | SubnetRouteTableAssociation: 186 | Type: AWS::EC2::SubnetRouteTableAssociation 187 | Properties: 188 | SubnetId: !Ref 'PublicEgressVpcSubnet1' 189 | RouteTableId: !Ref 'EgressRouteTable' 190 | SubnetRouteTableAssociation2: 191 | Type: AWS::EC2::SubnetRouteTableAssociation 192 | Properties: 193 | SubnetId: !Ref 'PublicEgressVpcSubnet2' 194 | RouteTableId: !Ref 'EgressRouteTable' 195 | 196 | PrivateEgressRoute1: 197 | Type: AWS::EC2::Route 198 | DependsOn: AttachIGW 199 | Properties: 200 | RouteTableId: !Ref 'PrivateEgressRouteTable1' 201 | DestinationCidrBlock: 0.0.0.0/0 202 | NatGatewayId: !Ref 'NATGateway1' 203 | 204 | # This would be needed if you had 2 NAT gateways. 205 | 206 | # PrivateEgressRoute2: 207 | # Type: AWS::EC2::Route 208 | # DependsOn: AttachIGW 209 | # Properties: 210 | # RouteTableId: !Ref 'PrivateEgressRouteTable2' 211 | # DestinationCidrBlock: 0.0.0.0/0 212 | # NatGatewayId: !Ref 'NATGateway2' 213 | 214 | PrivateEgressRouteTable1Association: 215 | Type: AWS::EC2::SubnetRouteTableAssociation 216 | Properties: 217 | SubnetId: !Ref 'PrivateEgressSubnet1' 218 | RouteTableId: !Ref 'PrivateEgressRouteTable1' 219 | PrivateEgressRouteTable2Association: 220 | Type: AWS::EC2::SubnetRouteTableAssociation 221 | Properties: 222 | SubnetId: !Ref 'PrivateEgressSubnet2' 223 | RouteTableId: !Ref 'PrivateEgressRouteTable1' 224 | # RouteTableId: !Ref 'PrivateEgressRouteTable2' # replace the previous line with this association if you have 2 NAT gateways. 225 | 226 | # App vpc and subnet creation 227 | 228 | App1VPC: 229 | Type: AWS::EC2::VPC 230 | Properties: 231 | CidrBlock: 10.0.0.0/16 232 | Tags: 233 | - Key: Application 234 | Value: !Ref 'AWS::StackId' 235 | - Key: Name 236 | Value: App1-VPC 237 | App1Subnet1: 238 | Type: AWS::EC2::Subnet 239 | Properties: 240 | VpcId: !Ref 'App1VPC' 241 | CidrBlock: 10.0.1.0/24 242 | AvailabilityZone: 243 | Fn::Select: 244 | - 0 245 | - Fn::GetAZs: "" 246 | Tags: 247 | - Key: Application 248 | Value: !Ref 'AWS::StackId' 249 | - Key: Name 250 | Value: App1-Private-AZ1 251 | App1Subnet2: 252 | Type: AWS::EC2::Subnet 253 | Properties: 254 | VpcId: !Ref 'App1VPC' 255 | CidrBlock: 10.0.2.0/24 256 | AvailabilityZone: 257 | Fn::Select: 258 | - 1 259 | - Fn::GetAZs: "" 260 | Tags: 261 | - Key: Application 262 | Value: !Ref 'AWS::StackId' 263 | - Key: Name 264 | Value: App1-Private-AZ2 265 | App1RouteTable: 266 | Type: AWS::EC2::RouteTable 267 | Properties: 268 | VpcId: !Ref 'App1VPC' 269 | Tags: 270 | - Key: Application 271 | Value: !Ref 'AWS::StackId' 272 | - Key: Name 273 | Value: App1-PrivateRouteTable 274 | App1Subnet1RouteTableAssociation: 275 | Type: AWS::EC2::SubnetRouteTableAssociation 276 | Properties: 277 | SubnetId: !Ref 'App1Subnet1' 278 | RouteTableId: !Ref 'App1RouteTable' 279 | App1Subnet2RouteTableAssociation: 280 | Type: AWS::EC2::SubnetRouteTableAssociation 281 | Properties: 282 | SubnetId: !Ref 'App1Subnet2' 283 | RouteTableId: !Ref 'App1RouteTable' 284 | 285 | App2VPC: 286 | Type: AWS::EC2::VPC 287 | Properties: 288 | CidrBlock: 10.1.0.0/16 289 | Tags: 290 | - Key: Application 291 | Value: !Ref 'AWS::StackId' 292 | - Key: Name 293 | Value: App2-VPC 294 | App2Subnet1: 295 | Type: AWS::EC2::Subnet 296 | Properties: 297 | VpcId: !Ref 'App2VPC' 298 | CidrBlock: 10.1.1.0/24 299 | AvailabilityZone: 300 | Fn::Select: 301 | - 0 302 | - Fn::GetAZs: "" 303 | Tags: 304 | - Key: Application 305 | Value: !Ref 'AWS::StackId' 306 | - Key: Name 307 | Value: App2-Private-AZ1 308 | App2Subnet2: 309 | Type: AWS::EC2::Subnet 310 | Properties: 311 | VpcId: !Ref 'App2VPC' 312 | CidrBlock: 10.1.2.0/24 313 | AvailabilityZone: 314 | Fn::Select: 315 | - 1 316 | - Fn::GetAZs: "" 317 | Tags: 318 | - Key: Application 319 | Value: !Ref 'AWS::StackId' 320 | - Key: Name 321 | Value: App2-Private-AZ2 322 | App2RouteTable: 323 | Type: AWS::EC2::RouteTable 324 | Properties: 325 | VpcId: !Ref 'App2VPC' 326 | Tags: 327 | - Key: Application 328 | Value: !Ref 'AWS::StackId' 329 | - Key: Name 330 | Value: App2-PrivateRouteTable 331 | App2SubnetRouteTableAssociation: 332 | Type: AWS::EC2::SubnetRouteTableAssociation 333 | Properties: 334 | SubnetId: !Ref 'App2Subnet1' 335 | RouteTableId: !Ref 'App2RouteTable' 336 | App2Subnet2RouteTableAssociation: 337 | Type: AWS::EC2::SubnetRouteTableAssociation 338 | Properties: 339 | SubnetId: !Ref 'App2Subnet2' 340 | RouteTableId: !Ref 'App2RouteTable' 341 | 342 | 343 | #transit gateway creation 344 | 345 | TransitGateway: 346 | Type: "AWS::EC2::TransitGateway" 347 | Properties: 348 | AutoAcceptSharedAttachments: enable 349 | DefaultRouteTableAssociation: "disable" 350 | DefaultRouteTablePropagation: "disable" 351 | Description: A transit gateway to support a single egress subnet 352 | Tags: 353 | - Key: Name 354 | Value: TGW-Internet 355 | 356 | 357 | # attach subnets to TGW 358 | 359 | EgressVpcAttachment: 360 | Type: "AWS::EC2::TransitGatewayAttachment" 361 | Properties: 362 | SubnetIds: 363 | - !Ref 'PrivateEgressSubnet1' 364 | - !Ref 'PrivateEgressSubnet2' 365 | Tags: 366 | - Key: Name 367 | Value: Egress-Attachment 368 | TransitGatewayId: !Ref TransitGateway 369 | VpcId: !Ref EgressVPC 370 | App1Attachment: 371 | Type: "AWS::EC2::TransitGatewayAttachment" 372 | Properties: 373 | SubnetIds: 374 | - !Ref 'App1Subnet1' 375 | - !Ref 'App1Subnet2' 376 | Tags: 377 | - Key: Name 378 | Value: App1-Attachment 379 | TransitGatewayId: !Ref TransitGateway 380 | VpcId: !Ref App1VPC 381 | App2Attachment: 382 | Type: "AWS::EC2::TransitGatewayAttachment" 383 | Properties: 384 | SubnetIds: 385 | - !Ref 'App2Subnet1' 386 | - !Ref 'App2Subnet2' 387 | Tags: 388 | - Key: Name 389 | Value: App2-Attachment 390 | TransitGatewayId: !Ref TransitGateway 391 | VpcId: !Ref App2VPC 392 | 393 | #define TGW route tables 394 | 395 | EgressTransitGatewayRouteTable: 396 | Type: "AWS::EC2::TransitGatewayRouteTable" 397 | Properties: 398 | Tags: 399 | - Key: Name 400 | Value: Egress-RouteTable 401 | TransitGatewayId: !Ref TransitGateway 402 | 403 | AppTransitGatewayRouteTable: 404 | Type: "AWS::EC2::TransitGatewayRouteTable" 405 | Properties: 406 | Tags: 407 | - Key: Name 408 | Value: App-RouteTable 409 | TransitGatewayId: !Ref TransitGateway 410 | 411 | #add a default route and black hole to the app route table 412 | 413 | AppDefaultTGWRoute: 414 | Type: "AWS::EC2::TransitGatewayRoute" 415 | Properties: 416 | DestinationCidrBlock: 0.0.0.0/0 417 | TransitGatewayAttachmentId: !Ref EgressVpcAttachment 418 | TransitGatewayRouteTableId: !Ref AppTransitGatewayRouteTable 419 | 420 | AppBlackhole10Route: 421 | Type: "AWS::EC2::TransitGatewayRoute" 422 | Properties: 423 | Blackhole: Yes 424 | DestinationCidrBlock: 10.0.0.0/8 425 | TransitGatewayRouteTableId: !Ref AppTransitGatewayRouteTable 426 | 427 | AppBlackhole172Route: 428 | Type: "AWS::EC2::TransitGatewayRoute" 429 | Properties: 430 | Blackhole: Yes 431 | DestinationCidrBlock: 172.16.0.0/12 432 | TransitGatewayRouteTableId: !Ref AppTransitGatewayRouteTable 433 | 434 | # We have not added a 192.168.0.0/16 black hole as for testing you may want to put an instance in the public subnet. 435 | # However, if you are only using the egress vpc as a route out, with a NAT gateway or similar proxy/NAT function, 436 | # then you can add the bloack hole for 192.168.0.0/16 as well 437 | 438 | # AppBlackhole192Route: 439 | # Type: "AWS::EC2::TransitGatewayRoute" 440 | # Properties: 441 | # Blackhole: Yes 442 | # DestinationCidrBlock: 192.168.0.0/16 443 | # TransitGatewayRouteTableId: !Ref AppTransitGatewayRouteTable 444 | 445 | App1Route: 446 | Type: "AWS::EC2::TransitGatewayRoute" 447 | Properties: 448 | DestinationCidrBlock: 10.0.0.0/16 449 | TransitGatewayAttachmentId: !Ref App1Attachment 450 | TransitGatewayRouteTableId: !Ref EgressTransitGatewayRouteTable 451 | 452 | App2Route: 453 | Type: "AWS::EC2::TransitGatewayRoute" 454 | Properties: 455 | DestinationCidrBlock: 10.1.0.0/16 456 | TransitGatewayAttachmentId: !Ref App2Attachment 457 | TransitGatewayRouteTableId: !Ref EgressTransitGatewayRouteTable 458 | 459 | 460 | #TGW associations 461 | 462 | EgressVpcTgwAssociation: 463 | Type: "AWS::EC2::TransitGatewayRouteTableAssociation" 464 | Properties: 465 | TransitGatewayAttachmentId: !Ref EgressVpcAttachment 466 | TransitGatewayRouteTableId: !Ref EgressTransitGatewayRouteTable 467 | App1VpcTgwAssociation: 468 | Type: "AWS::EC2::TransitGatewayRouteTableAssociation" 469 | Properties: 470 | TransitGatewayAttachmentId: !Ref App1Attachment 471 | TransitGatewayRouteTableId: !Ref AppTransitGatewayRouteTable 472 | App2VpcTgwAssociation: 473 | Type: "AWS::EC2::TransitGatewayRouteTableAssociation" 474 | Properties: 475 | TransitGatewayAttachmentId: !Ref App2Attachment 476 | TransitGatewayRouteTableId: !Ref AppTransitGatewayRouteTable 477 | 478 | # Update VPC route tables to point towards transit gateway for appropriate target CIDR ranges 479 | 480 | UpdateApp1RouteTable: 481 | Type: AWS::EC2::Route 482 | DependsOn: App1Attachment 483 | Properties: 484 | RouteTableId: !Ref App1RouteTable 485 | DestinationCidrBlock: !Ref AppCidr 486 | TransitGatewayId: !Ref TransitGateway 487 | 488 | UpdateApp2RouteTable: 489 | Type: AWS::EC2::Route 490 | DependsOn: App2Attachment 491 | Properties: 492 | RouteTableId: !Ref App2RouteTable 493 | DestinationCidrBlock: !Ref AppCidr 494 | TransitGatewayId: !Ref TransitGateway 495 | 496 | UpdateEgressRouteTable: 497 | Type: AWS::EC2::Route 498 | DependsOn: EgressVpcAttachment 499 | Properties: 500 | RouteTableId: !Ref EgressRouteTable 501 | DestinationCidrBlock: !Ref EgressPublicCidr 502 | TransitGatewayId: !Ref TransitGateway 503 | 504 | 505 | Outputs: 506 | Name: 507 | Value: !Ref AWS::StackName 508 | TransitGateway: 509 | Value: !Ref TransitGateway 510 | --------------------------------------------------------------------------------