Skip to content

Instantly share code, notes, and snippets.

@echang0929
Last active May 9, 2022 04:09
Show Gist options
  • Save echang0929/5a084b3763d6c68c7099187e523aec9e to your computer and use it in GitHub Desktop.
Save echang0929/5a084b3763d6c68c7099187e523aec9e to your computer and use it in GitHub Desktop.
######################################
### Part I: Prepare for Network Environments and VM Instances
######################################
### 1.1 Setup AWS Network Environment
aws configure set default.region us-west-1
vid=$(aws ec2 create-vpc --cidr-block 192.168.0.0/16)
VPC_ID=$(echo $vid | jq -r '.Vpc.VpcId')
sbn=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block 192.168.1.0/24)
SUBNET_ID=$(echo $sbn | jq -r '.Subnet.SubnetId')
igw=$(aws ec2 create-internet-gateway)
IGW_ID=$(echo $igw | jq -r '.InternetGateway.InternetGatewayId')
aws ec2 attach-internet-gateway --vpc-id $VPC_ID --internet-gateway-id $IGW_ID
rtb=$(aws ec2 create-route-table --vpc-id $VPC_ID)
RTB_ID=$(echo $rtb | jq -r '.RouteTable.RouteTableId')
aws ec2 create-route --route-table-id $RTB_ID --destination-cidr-block 0.0.0.0/0 --gateway-id $IGW_ID
aws ec2 associate-route-table --route-table-id $RTB_ID --subnet-id $SUBNET_ID
### 1.2 Create AWS VM Instance
KEY_NAME=tim-vpn
aws ec2 create-key-pair --key-name $KEY_NAME --query 'KeyMaterial' --output text > $KEY_NAME.pem
chmod 400 $KEY_NAME.pem
GROUP_NAME=vpn-access
grp=$(aws ec2 create-security-group --group-name $GROUP_NAME --description "Security group for vpn access" --vpc-id $VPC_ID)
GROUP_ID=$(echo $grp | jq -r '.GroupId')
aws ec2 authorize-security-group-ingress --group-id $GROUP_ID --protocol tcp --port 22 --cidr 123.118.7.149/32
aws ec2 authorize-security-group-ingress --group-id $GROUP_ID --protocol icmp --port -1 --cidr 0.0.0.0/0
AMI_ID=$(aws ec2 describe-images --owners self amazon --filters "Name=virtualization-type,Values=hvm" \
| jq -r '.Images | .[0].ImageId')
ist=$(aws ec2 run-instances \
--image-id $AMI_ID \
--count 1 \
--instance-type t2.micro \
--key-name $KEY_NAME \
--security-group-ids $GROUP_ID \
--subnet-id $SUBNET_ID \
--associate-public-ip-address)
INSTANCE_ID=$(echo $ist | jq -r '.Instances | .[0].InstanceId')
INSTANCE_IP=$(aws ec2 describe-instances --instance-id $INSTANCE_ID \
| jq -r '.Reservations | .[0].Instances | .[0].PublicIpAddress')
aws ec2 describe-instances --instance-id $INSTANCE_ID | jq -r '.Reservations | .[0].Instances | .[0].State.Name'
ssh -i "$KEY_NAME.pem" ubuntu@$INSTANCE_IP
### 1.3 Setup GCP Network Environment
NETWORK=tim-vpc
gcloud compute networks create $NETWORK \
--subnet-mode custom \
--bgp-routing-mode global
SUBNET_NAME=tim-subnet-east1
SUBNET_REGION=us-east1
IP_ADDRESS_RANGE=10.1.1.0/24
gcloud compute networks subnets create $SUBNET_NAME \
--network $NETWORK \
--region $SUBNET_REGION \
--range $IP_ADDRESS_RANGE
### 1.4 Create GCP VM Instance
VM_NAME=tim-vm
gcloud compute instances create $VM_NAME \
--subnet=$SUBNET_NAME
FIREWALL_ALLOW_ICMP=allow-icmp
gcloud compute firewall-rules create $FIREWALL_ALLOW_ICMP --network $NETWORK --allow icmp --source-ranges 0.0.0.0/0
FIREWALL_ALLOW_SSH=allow-ssh-from-console
gcloud compute firewall-rules create $FIREWALL_ALLOW_SSH --network $NETWORK --allow tcp:22 --source-ranges 35.235.240.0/20
gcloud compute ssh $VM_NAME --tunnel-through-iap
######################################
### Part II: Build VPN Connections between GCP and AWS
######################################
### 2.1 Create GCP VPN Components
HA_VPN_GATEWAY_NAME=tim-ha-vgw-central1
REGION=us-central1
gcloud compute vpn-gateways create $HA_VPN_GATEWAY_NAME \
--network $NETWORK \
--region $REGION
ROUTER_NAME=tim-router
GOOGLE_ASN=65001
gcloud compute routers create $ROUTER_NAME \
--region $REGION \
--network $NETWORK \
--asn $GOOGLE_ASN \
--advertisement-mode custom \
--set-advertisement-groups all_subnets
cmd=$(gcloud compute vpn-gateways describe $HA_VPN_GATEWAY_NAME \
--region=$REGION --format=json \
| jq -r --arg p0 "INTERFACE_0_IP_ADDRESS=" --arg p1 "INTERFACE_1_IP_ADDRESS=" \
'.vpnInterfaces | $p0+(.[0].ipAddress), $p1+(.[1].ipAddress)')
eval "$cmd"
### 2.2 Create AWS VPN Components
cg0=$(aws ec2 create-customer-gateway --type ipsec.1 --public-ip $INTERFACE_0_IP_ADDRESS --bgp-asn $GOOGLE_ASN)
CUSTOMER_GATEWAY_0=$(echo $cg0 | jq -r '.CustomerGateway.CustomerGatewayId')
cg1=$(aws ec2 create-customer-gateway --type ipsec.1 --public-ip $INTERFACE_1_IP_ADDRESS --bgp-asn $GOOGLE_ASN)
CUSTOMER_GATEWAY_1=$(echo $cg1 | jq -r '.CustomerGateway.CustomerGatewayId')
AWS_SIDE_ASN=65101
## >> Option 1: Setup VPN Gateway
vgi=$(aws ec2 create-vpn-gateway --type ipsec.1 --amazon-side-asn $AWS_SIDE_ASN)
VPN_GATEWAY_ID=$(echo $vgi | jq -r '.VpnGateway.VpnGatewayId')
aws ec2 attach-vpn-gateway --vpn-gateway-id $VPN_GATEWAY_ID --vpc-id $VPC_ID
aws ec2 enable-vgw-route-propagation --gateway-id $VPN_GATEWAY_ID --route-table-id $RTB_ID
vc0=$(aws ec2 create-vpn-connection \
--type ipsec.1 \
--customer-gateway-id $CUSTOMER_GATEWAY_0 \
--vpn-gateway-id $VPN_GATEWAY_ID) \
VPN_CONNECTION_0=$(echo -E $vc0 | jq -r '.VpnConnection.VpnConnectionId')
vc1=$(aws ec2 create-vpn-connection \
--type ipsec.1 \
--customer-gateway-id $CUSTOMER_GATEWAY_1 \
--vpn-gateway-id $VPN_GATEWAY_ID) \
VPN_CONNECTION_1=$(echo -E $vc1 | jq -r '.VpnConnection.VpnConnectionId')
## << End of Setup VPN Gateway
## >> Option 2: Setup Transit Gateway
tgi=$(aws ec2 create-transit-gateway \
--options=AmazonSideAsn=$AWS_SIDE_ASN,AutoAcceptSharedAttachments=enable,DefaultRouteTableAssociation=enable,DefaultRouteTablePropagation=enable,VpnEcmpSupport=enable,DnsSupport=enable)
TRANSIT_GATEWAY_ID=$(echo $tgi | jq -r '.TransitGateway.TransitGatewayId')
tva=$(aws ec2 create-transit-gateway-vpc-attachment \
--transit-gateway-id $TRANSIT_GATEWAY_ID \
--vpc-id $VPC_ID \
--subnet-id $SUBNET_ID)
TRANSIT_GATEWAY_ATTACHMENT_ID=$(echo $tva | jq -r '.TransitGatewayVpcAttachment.TransitGatewayAttachmentId')
aws ec2 create-route --route-table-id $RTB_ID --destination-cidr-block $IP_ADDRESS_RANGE --gateway-id $TRANSIT_GATEWAY_ID
vc0=$(aws ec2 create-vpn-connection \
--type ipsec.1 \
--customer-gateway-id $CUSTOMER_GATEWAY_0 \
--transit-gateway-id $TRANSIT_GATEWAY_ID)
VPN_CONNECTION_0=$(echo -E $vc0 | jq -r '.VpnConnection.VpnConnectionId')
vc1=$(aws ec2 create-vpn-connection \
--type ipsec.1 \
--customer-gateway-id $CUSTOMER_GATEWAY_1 \
--transit-gateway-id $TRANSIT_GATEWAY_ID)
VPN_CONNECTION_1=$(echo -E $vc1 | jq -r '.VpnConnection.VpnConnectionId')
## << End of Setup Transit Gateway
cmd0=$(echo -E $vc0 | jq -r '.VpnConnection.CustomerGatewayConfiguration' | yq -p=xml -o=json | jq -r \
--arg vpgw_outside_ip_00 "AWS_GW_IP_0=" \
--arg pre_shared_key_00 "SHARED_SECRET_0=" \
--arg cgw_inside_ip_00 "GOOGLE_BGP_IP_TUNNEL_0=" \
--arg vpgw_inside_ip_00 "AWS_T0_IP=" \
--arg vpgw_outside_ip_01 "AWS_GW_IP_1=" \
--arg pre_shared_key_01 "SHARED_SECRET_1=" \
--arg cgw_inside_ip_01 "GOOGLE_BGP_IP_TUNNEL_1=" \
--arg vpgw_inside_ip_01 "AWS_T1_IP=" \
'.vpn_connection.ipsec_tunnel |
$vpgw_outside_ip_00+(.[0].vpn_gateway.tunnel_outside_address.ip_address),
$pre_shared_key_00+(.[0].ike.pre_shared_key),
$cgw_inside_ip_00+(.[0].customer_gateway.tunnel_inside_address.ip_address),
$vpgw_inside_ip_00+(.[0].vpn_gateway.tunnel_inside_address.ip_address),
$vpgw_outside_ip_01+(.[1].vpn_gateway.tunnel_outside_address.ip_address),
$pre_shared_key_01+(.[1].ike.pre_shared_key),
$cgw_inside_ip_01+(.[1].customer_gateway.tunnel_inside_address.ip_address),
$vpgw_inside_ip_01+(.[1].vpn_gateway.tunnel_inside_address.ip_address)')
cmd1=$(echo -E $vc1 | jq -r '.VpnConnection.CustomerGatewayConfiguration' | yq -p=xml -o=json | jq -r \
--arg vpgw_outside_ip_10 "AWS_GW_IP_2=" \
--arg pre_shared_key_10 "SHARED_SECRET_2=" \
--arg cgw_inside_ip_10 "GOOGLE_BGP_IP_TUNNEL_2=" \
--arg vpgw_inside_ip_10 "AWS_T2_IP=" \
--arg vpgw_outside_ip_11 "AWS_GW_IP_3=" \
--arg pre_shared_key_11 "SHARED_SECRET_3=" \
--arg cgw_inside_ip_11 "GOOGLE_BGP_IP_TUNNEL_3=" \
--arg vpgw_inside_ip_11 "AWS_T3_IP=" \
'.vpn_connection.ipsec_tunnel |
$vpgw_outside_ip_10+(.[0].vpn_gateway.tunnel_outside_address.ip_address),
$pre_shared_key_10+(.[0].ike.pre_shared_key),
$cgw_inside_ip_10+(.[0].customer_gateway.tunnel_inside_address.ip_address),
$vpgw_inside_ip_10+(.[0].vpn_gateway.tunnel_inside_address.ip_address),
$vpgw_outside_ip_11+(.[1].vpn_gateway.tunnel_outside_address.ip_address),
$pre_shared_key_11+(.[1].ike.pre_shared_key),
$cgw_inside_ip_11+(.[1].customer_gateway.tunnel_inside_address.ip_address),
$vpgw_inside_ip_11+(.[1].vpn_gateway.tunnel_inside_address.ip_address)')
eval "$cmd0"
eval "$cmd1"
### 2.3 Back to GCP to Add More Components
PEER_GATEWAY_NAME=tim-pgw
gcloud compute external-vpn-gateways create $PEER_GATEWAY_NAME --interfaces \
0=$AWS_GW_IP_0,1=$AWS_GW_IP_1,2=$AWS_GW_IP_2,3=$AWS_GW_IP_3
VPN_TUNNEL_0=tim-tunnel-0
gcloud compute vpn-tunnels create $VPN_TUNNEL_0 \
--peer-external-gateway $PEER_GATEWAY_NAME \
--peer-external-gateway-interface 0 \
--region $REGION \
--ike-version 2 \
--shared-secret $SHARED_SECRET_0 \
--router $ROUTER_NAME \
--vpn-gateway $HA_VPN_GATEWAY_NAME \
--interface 0
VPN_TUNNEL_1=tim-tunnel-1
gcloud compute vpn-tunnels create $VPN_TUNNEL_1 \
--peer-external-gateway $PEER_GATEWAY_NAME \
--peer-external-gateway-interface 1 \
--region $REGION \
--ike-version 2 \
--shared-secret $SHARED_SECRET_1 \
--router $ROUTER_NAME \
--vpn-gateway $HA_VPN_GATEWAY_NAME \
--interface 0
VPN_TUNNEL_2=tim-tunnel-2
gcloud compute vpn-tunnels create $VPN_TUNNEL_2 \
--peer-external-gateway $PEER_GATEWAY_NAME \
--peer-external-gateway-interface 2 \
--region $REGION \
--ike-version 2 \
--shared-secret $SHARED_SECRET_2 \
--router $ROUTER_NAME \
--vpn-gateway $HA_VPN_GATEWAY_NAME \
--interface 1
VPN_TUNNEL_3=tim-tunnel-3
gcloud compute vpn-tunnels create $VPN_TUNNEL_3 \
--peer-external-gateway $PEER_GATEWAY_NAME \
--peer-external-gateway-interface 3 \
--region $REGION \
--ike-version 2 \
--shared-secret $SHARED_SECRET_3 \
--router $ROUTER_NAME \
--vpn-gateway $HA_VPN_GATEWAY_NAME \
--interface 1
INTERFACE_NAME_0=tim-int-0
gcloud compute routers add-interface $ROUTER_NAME \
--interface-name $INTERFACE_NAME_0 \
--vpn-tunnel $VPN_TUNNEL_0 \
--ip-address $GOOGLE_BGP_IP_TUNNEL_0 \
--mask-length 30 \
--region $REGION
INTERFACE_NAME_1=tim-int-1
gcloud compute routers add-interface $ROUTER_NAME \
--interface-name $INTERFACE_NAME_1 \
--vpn-tunnel $VPN_TUNNEL_1 \
--ip-address $GOOGLE_BGP_IP_TUNNEL_1 \
--mask-length 30 \
--region $REGION
INTERFACE_NAME_2=tim-int-2
gcloud compute routers add-interface $ROUTER_NAME \
--interface-name $INTERFACE_NAME_2 \
--vpn-tunnel $VPN_TUNNEL_2 \
--ip-address $GOOGLE_BGP_IP_TUNNEL_2 \
--mask-length 30 \
--region $REGION
INTERFACE_NAME_3=tim-int-3
gcloud compute routers add-interface $ROUTER_NAME \
--interface-name $INTERFACE_NAME_3 \
--vpn-tunnel $VPN_TUNNEL_3 \
--ip-address $GOOGLE_BGP_IP_TUNNEL_3 \
--mask-length 30 \
--region $REGION
PEER_NAME_0=tim-aws-conn0-tunn0
gcloud compute routers add-bgp-peer $ROUTER_NAME \
--peer-name $PEER_NAME_0 \
--peer-asn $AWS_SIDE_ASN \
--interface $INTERFACE_NAME_0 \
--peer-ip-address $AWS_T0_IP \
--region $REGION
PEER_NAME_1=tim-aws-conn0-tunn1
gcloud compute routers add-bgp-peer $ROUTER_NAME \
--peer-name $PEER_NAME_1 \
--peer-asn $AWS_SIDE_ASN \
--interface $INTERFACE_NAME_1 \
--peer-ip-address $AWS_T1_IP \
--region $REGION
PEER_NAME_2=tim-aws-conn1-tunn0
gcloud compute routers add-bgp-peer $ROUTER_NAME \
--peer-name $PEER_NAME_2 \
--peer-asn $AWS_SIDE_ASN \
--interface $INTERFACE_NAME_2 \
--peer-ip-address $AWS_T2_IP \
--region $REGION
PEER_NAME_3=tim-aws-conn1-tunn1
gcloud compute routers add-bgp-peer $ROUTER_NAME \
--peer-name $PEER_NAME_3 \
--peer-asn $AWS_SIDE_ASN \
--interface $INTERFACE_NAME_3 \
--peer-ip-address $AWS_T3_IP \
--region $REGION
### 2.4 Test and Verify VPN and Its Tunnels
gcloud compute routers get-status $ROUTER_NAME \
--region $REGION \
--format='flattened(result.bgpPeerStatus[].name, result.bgpPeerStatus[].ipAddress, result.bgpPeerStatus[].peerIpAddress)'
gcloud compute vpn-tunnels list
gcloud compute vpn-tunnels describe $VPN_TUNNEL_0 \
--region $REGION \
--format='flattened(status,detailedStatus)'
gcloud compute vpn-tunnels describe $VPN_TUNNEL_1 \
--region $REGION \
--format='flattened(status,detailedStatus)'
gcloud compute vpn-tunnels describe $VPN_TUNNEL_2 \
--region $REGION \
--format='flattened(status,detailedStatus)'
gcloud compute vpn-tunnels describe $VPN_TUNNEL_3 \
--region $REGION \
--format='flattened(status,detailedStatus)'
gcloud compute routers get-status $ROUTER_NAME \
--region $REGION \
--format="flattened(result.bestRoutes)"
######################################
### Part III: Clean VPN Components and Cloud Environments
######################################
### 3.1 Remove GCP VPN Components
gcloud compute routers remove-bgp-peer $ROUTER_NAME --peer-name $PEER_NAME_0 --region $REGION
gcloud compute routers remove-bgp-peer $ROUTER_NAME --peer-name $PEER_NAME_1 --region $REGION
gcloud compute routers remove-bgp-peer $ROUTER_NAME --peer-name $PEER_NAME_2 --region $REGION
gcloud compute routers remove-bgp-peer $ROUTER_NAME --peer-name $PEER_NAME_3 --region $REGION
gcloud compute routers remove-interface $ROUTER_NAME --interface-name $INTERFACE_NAME_0 --region $REGION
gcloud compute routers remove-interface $ROUTER_NAME --interface-name $INTERFACE_NAME_1 --region $REGION
gcloud compute routers remove-interface $ROUTER_NAME --interface-name $INTERFACE_NAME_2 --region $REGION
gcloud compute routers remove-interface $ROUTER_NAME --interface-name $INTERFACE_NAME_3 --region $REGION
gcloud compute vpn-tunnels delete $VPN_TUNNEL_0 --region $REGION
gcloud compute vpn-tunnels delete $VPN_TUNNEL_1 --region $REGION
gcloud compute vpn-tunnels delete $VPN_TUNNEL_2 --region $REGION
gcloud compute vpn-tunnels delete $VPN_TUNNEL_3 --region $REGION
gcloud compute external-vpn-gateways delete $PEER_GATEWAY_NAME
gcloud compute routers delete $ROUTER_NAME --region $REGION
gcloud compute vpn-gateways delete $HA_VPN_GATEWAY_NAME --region $REGION
### 3.2 Remove GCP VM Instance and Network Environment
gcloud compute instances delete $VM_NAME
gcloud compute networks subnets delete $SUBNET_NAME --region $SUBNET_REGION
gcloud compute firewall-rules delete $FIREWALL_ALLOW_ICMP
gcloud compute firewall-rules delete $FIREWALL_ALLOW_SSH
gcloud compute networks delete $NETWORK
### 3.3 Remove AWS VPN Components
aws ec2 delete-vpn-connection --vpn-connection-id $VPN_CONNECTION_0
aws ec2 delete-vpn-connection --vpn-connection-id $VPN_CONNECTION_1
## >> Option 1: Delete VPN Gateway
aws ec2 detach-vpn-gateway --vpn-gateway-id $VPN_GATEWAY_ID --vpc-id $VPC_ID
aws ec2 delete-vpn-gateway --vpn-gateway-id $VPN_GATEWAY_ID
## << End of Delete VPN Gateway
## >> Option 2: Delete Transit Gateway
aws ec2 delete-transit-gateway-vpc-attachment --transit-gateway-attachment-id $TRANSIT_GATEWAY_ATTACHMENT_ID
aws ec2 delete-transit-gateway --transit-gateway-id $TRANSIT_GATEWAY_ID
## << End of Delete Transit Gateway
aws ec2 delete-customer-gateway --customer-gateway-id $CUSTOMER_GATEWAY_0
aws ec2 delete-customer-gateway --customer-gateway-id $CUSTOMER_GATEWAY_1
### 3.4 Remove AWS VM Instance and Network Environment
aws ec2 terminate-instances --instance-ids $INSTANCE_ID
aws ec2 delete-security-group --group-id $GROUP_ID
aws ec2 delete-subnet --subnet-id $SUBNET_ID
aws ec2 delete-route-table --route-table-id $RTB_ID
aws ec2 delete-key-pair --key-name $KEY_NAME
aws ec2 detach-internet-gateway --internet-gateway-id $IGW_ID --vpc-id $VPC_ID
aws ec2 delete-internet-gateway --internet-gateway-id $IGW_ID
aws ec2 delete-vpc --vpc-id $VPC_ID
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment