Architecture#
Customers
When to use/use cases?
- A central hub which connects many VPCs
- Inter-region peering
- Direct Connect - Direct Connect GW - TGW Transit VIF
- Direct Connect - TGW Public VIF (VPN)
Best practices
- Re-invent 2020 Nicola Arnoldi 4:08
- Direct connection location
- docs aws RECOMMENDED
- TGW FAQ
- Quota: 5000 attachments, 50Gbps per VPC attachment, and ...
Essential Concepts
- TGW attachment, association, propogation, route table
- TGW VPC attachment
- TGW VPN attachment
- TGW peering attachment
- BGP
- Quota
Deploy Order#
Step 1. Crean an AWS base network#
cdk deploy AwsBaseNetwork
Step 2. Create a simulated on-prem (place-holder) HERE#
cdk deploy SimulatedOnPrem
take note the EIP for step 3 (customer gateway)
Step 3. Transit Gateway, Customer Gateway, VPN Connection#
cdk deploy TgwAndVpnAndCgw
Download the configuration (generic) from AWS VPN Site-to-Site. Take note params for step 4.
template-parameters-psk-auth.json
{"ParameterKey": "pAuthType","ParameterValue": "psk"},{"ParameterKey": "pTunnel1PskSecretName","ParameterValue": "pTunnel1PskSecretName"},{"ParameterKey": "pTunnel1VgwOutsideIpAddress","ParameterValue": "34.227.182.74"},{"ParameterKey": "pTunnel1CgwInsideIpAddress","ParameterValue": "169.254.86.242/30"},{"ParameterKey": "pTunnel1VgwInsideIpAddress","ParameterValue": "169.254.86.241/30"},{"ParameterKey": "pTunnel1VgwBgpAsn","ParameterValue": "65001"},{"ParameterKey": "pTunnel1BgpNeighborIpAddress","ParameterValue": "169.254.86.241"},
create 2 secrete keys for psk
Step 4. Deploy the Simulated On-Prem with StrongSwan#
./manage-stack -s vpn-gateway-1 --region us-east-1 template-parameters-psk-auth.json
Step 5. Update TGW Routes, VPC Subnet Routes#
Option 1. By code
cdk deploy TgwRouteAttachment
Option 2. By hands
create TGW attachment for VPC, VPN
check the default TGW route table
update subnet route tables for VPCs
Step 1-2. AWS Base Network Stack#
vpc for development department
// vpc-ec2 for dev developmentthis.developmentVpc = new VpcWithEc2(this, 'Development', {prefix: 'Development',cidr: cfnParams[this.region].DevelopmentCidr,cidrMask: cfnParams[this.region].CidrMask,ec2Role: this.ec2Role})
vpc for production department
// vpc-ec2 prod departmentthis.productionVpc = new VpcWithEc2(this, 'Production', {prefix: 'Production',cidr: cfnParams[this.region].ProductionCidr,cidrMask: cfnParams[this.region].CidrMask,ec2Role: this.ec2Role})
simulated on-premise (place-holder)
// simulated on-premise place-holdernew SimulatedOnPrem(app, 'SimulatedOnPrem', {prefix: 'OnPrem-',cidr: cfnParams[REGION].OnPremCidr,cidrMask: cfnParams[REGION].CidrMask,env: {region: REGION}})
Step 3. Transit Gateway, Customer Gateway, VPN Connection#
create a TGW
// create an TGWthis.cfnTransitGateway = new aws_ec2.CfnTransitGateway(this,props.prefix!.concat('-TGW').toString(),{amazonSideAsn: props.amazonSideAsn,description: 'TGW for hybrid networking',autoAcceptSharedAttachments: 'enable',defaultRouteTableAssociation: 'enable',defaultRouteTablePropagation: 'enable',dnsSupport: 'enable',vpnEcmpSupport: 'enable',multicastSupport: 'enable',tags: [{key: 'Name',value: props.prefix!.concat('-TGW').toString()}]})
create a customer gateway
// create a customer gatewaythis.cfnCustomerGateway = new aws_ec2.CfnCustomerGateway(this,props.prefix!.concat('-CGW').toString(),{bgpAsn: props.customerSideAsn!,ipAddress: props.onPremIpAddress!,type: 'ipsec.1',tags: [{key: 'Name',value: props.prefix!.concat('-CGW').toString()}]})
create a vpn connection
// create the site-to-site VPN connectionthis.cfnVPNConnection = new aws_ec2.CfnVPNConnection(this,props.prefix!.concat('-VPN').toString(),{transitGatewayId: this.cfnTransitGateway.ref,customerGatewayId: this.cfnCustomerGateway.ref,staticRoutesOnly: false,type: 'ipsec.1',tags: [{key: 'Name',value: props.prefix!.concat('-VPN').toString()}]})
Step 4. Deploy the Simulated On-Prem with StrongSwan#
create 2 secret keys for psk
update template-parameters-psk-auth.json
run
./manage-stack -s vpn-gateway-1 --region us-east-1 template-parameters-psk-auth.json
wait and check both tunnel UP
sudo strongswan status
Step 5.1 Transit Gateway Routes, Attachments#
create a tgw route table
// tgw route tablethis.cfnTransitGatewayRouteTable = new aws_ec2.CfnTransitGatewayRouteTable(this,props.prefix!.concat('-RouteTable').toString(),{transitGatewayId: props.transitGateway.ref,tags: [{key: 'Name',value: props.prefix!.concat('-RouteTable').toString()}]})
create development tgw-development-vpc-attachment
// create development tgw-development-vpc-attachmentconst tgwDevVpcAttachment = new aws_ec2.CfnTransitGatewayAttachment(this,props.prefix!.concat('dev-vpc-tgw-attachment').toString(),{transitGatewayId: props.transitGateway.ref,vpcId: props.developmentVpc.vpcId,subnetIds: props.developmentVpc.isolatedSubnets.map(subnet => subnet.subnetId),tags: [{key: 'Name',value: props.prefix!.concat('dev-vpc-tgw-attachment').toString()}]})
create development tgw-production-vpc-attachment
// create development tgw-production-vpc-attachmentconst tgwProdVpcAttachment = new aws_ec2.CfnTransitGatewayAttachment(this,props.prefix!.concat('prod-vpc-tgw-attachment').toString(),{transitGatewayId: props.transitGateway.ref,vpcId: props.productionVpc.vpcId,subnetIds: props.productionVpc.isolatedSubnets.map(subnet => subnet.subnetId),tags: [{key: 'Name',value: props.prefix!.concat('prod-vpc-tgw-attachment').toString()}]})
development-vpc-attachment and tgw-table association
const tgwDevVpcAttRoutTableAssociation =new aws_ec2.CfnTransitGatewayRouteTableAssociation(this,'dev-vpc-attachment-tgw-route-table-association',{transitGatewayRouteTableId: this.cfnTransitGatewayRouteTable.ref,transitGatewayAttachmentId: tgwDevVpcAttachment.ref})
production-vpc-attachment and tgw-table association
const tgwProdVpcAttRoutTableAssociation =new aws_ec2.CfnTransitGatewayRouteTableAssociation(this,'prod-vpc-attachment-tgw-route-table-association',{transitGatewayRouteTableId: this.cfnTransitGatewayRouteTable.ref,transitGatewayAttachmentId: tgwProdVpcAttachment.ref})
dev-vpc-attachment tgw-propogation
// dev-vpc-attachment tgw-propogationnew aws_ec2.CfnTransitGatewayRouteTablePropagation(this,'dev-vpc-attachment-tgw-route-table-propogation',{transitGatewayRouteTableId: this.cfnTransitGatewayRouteTable.ref,transitGatewayAttachmentId: tgwDevVpcAttachment.ref})
prod-vpc-attachment tgw-propogation
// prod-vpc-attachment tgw-propogationnew aws_ec2.CfnTransitGatewayRouteTablePropagation(this,'prod-vpc-attachment-tgw-route-table-propogation',{transitGatewayRouteTableId: this.cfnTransitGatewayRouteTable.ref,transitGatewayAttachmentId: tgwProdVpcAttachment.ref})
Step 5.2 VPC Subnet Routes Update#
development vpc subnets route update
// development vpc subnets route updatefor (var subnet of props.developmentVpc.isolatedSubnets) {var route = new aws_ec2.CfnRoute(this, 'RouteToProdVpcDepartment', {routeTableId: subnet.routeTable.routeTableId,// vpc cidr heredestinationCidrBlock: props.productionVpc.vpcCidrBlock,transitGatewayId: props.transitGateway.ref})// route.addDependsOn(vpcDevTgwAttach);route.addDependsOn(tgwDevVpcAttachment)}
production vpc subnets route update
// production vpc subnets route updatefor (var subnet of props.productionVpc.isolatedSubnets) {var route = new aws_ec2.CfnRoute(this, 'RouteToDevVpcDepartment', {routeTableId: subnet.routeTable.routeTableId,// vpc cidr heredestinationCidrBlock: props.developmentVpc.vpcCidrBlock,transitGatewayId: props.transitGateway.ref})// route.addDependsOn(vpcDevTgwAttach);route.addDependsOn(tgwDevVpcAttachment)}
on-prem vpc same
TODO
Check and Troubleshooting#
from an EC2 in the simulated on-prem ping VPCs
ping
from an EC2 in a VPC ping other VPCs and on-prem
ping
on the strongswan instance
sudo tcpdump -eni any icmp
optionally
Reachability Analyzer Path