Architecture#

aws_devops-Expriment drawio (1)

Customers

  • TREND MICRO

When to use/use cases?

Best practices

Essential Concepts

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 development
this.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 department
this.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-holder
new 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 TGW
this.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 gateway
this.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 connection
this.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 table
this.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-attachment
const 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-attachment
const 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-propogation
new 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-propogation
new 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 update
for (var subnet of props.developmentVpc.isolatedSubnets) {
var route = new aws_ec2.CfnRoute(this, 'RouteToProdVpcDepartment', {
routeTableId: subnet.routeTable.routeTableId,
// vpc cidr here
destinationCidrBlock: props.productionVpc.vpcCidrBlock,
transitGatewayId: props.transitGateway.ref
})
// route.addDependsOn(vpcDevTgwAttach);
route.addDependsOn(tgwDevVpcAttachment)
}

production vpc subnets route update

// production vpc subnets route update
for (var subnet of props.productionVpc.isolatedSubnets) {
var route = new aws_ec2.CfnRoute(this, 'RouteToDevVpcDepartment', {
routeTableId: subnet.routeTable.routeTableId,
// vpc cidr here
destinationCidrBlock: 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