Browse Source

Merge pull request #13 from mdr-engineering/feature/ftd_MSOCI-1277_home-grown-router

Brings up test instances for XDR-Interconnects
Frederick Damstra 5 years ago
parent
commit
86fd54f1a7

+ 3 - 0
test/aws-us-gov/mdr-test-c2/018-xdr-interconnect-instances/README.md

@@ -0,0 +1,3 @@
+# XDR Interconnect Instances
+
+Instances to interconnect govcloud with commercial

+ 727 - 0
test/aws-us-gov/mdr-test-c2/018-xdr-interconnect-instances/example.cft

@@ -0,0 +1,727 @@
+# Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+AWSTemplateFormatVersion: '2010-09-09'
+
+Description: strongSwan VPN Gateway as an EC2 Instance
+
+Metadata:
+  AWS::CloudFormation::Interface:
+    ParameterGroups:
+    - Label:
+        default: System Classification
+      Parameters:
+      - pOrg
+      - pSystem
+      - pApp
+    - Label:
+        default: System Environment
+      Parameters:
+      - pEnvPurpose
+    - Label:
+        default: VPN Tunnel 1
+      Parameters:
+      - pTunnel1Psk
+      - pTunnel1VgwOutsideIpAddress
+      - pTunnel1VgwInsideCidr
+      - pTunnel1CgwInsideCidr
+      - pTunnel1BgpAsn
+      - pTunnel1BgpNeighborIpAddress
+    - Label:
+        default: VPN Tunnel 2
+      Parameters:
+      - pTunnel2Psk
+      - pTunnel2VgwOutsideIpAddress
+      - pTunnel2VgwInsideCidr
+      - pTunnel2CgwInsideCidr
+      - pTunnel2BgpAsn
+      - pTunnel2BgpNeighborIpAddress
+    - Label:
+        default: Local Network Configuration
+      Parameters:
+      - pVpcId
+      - pVpcCidr
+      - pSubnetId
+      - pUseElasticIp
+      - pEipAllocationId
+      - pLocalBgpAsn
+    - Label:
+        default: EC2  
+      Parameters:
+      - pAmiId
+      - pInstanceType
+
+    ParameterLabels:
+      pOrg:
+        default: Organization Identifier
+      pSystem:
+        default: System Identifier
+      pApp:
+        default: Application Identifier
+      pEnvPurpose:
+        default: Environment Purpose
+
+      pTunnel1Psk:
+        default: VPN Tunnel 1 Pre-Shared Key
+      pTunnel1VgwOutsideIpAddress:
+        default: VPN Tunnel 1 Virtual Private Gateway Outside IP Address
+      pTunnel1VgwInsideCidr:
+        default: VPN Tunnel 1 Virtual Private Gateway Inside CIDR
+      pTunnel1CgwInsideCidr:
+        default: VPN Tunnel 1 Customer Gateway Inside CIDR
+      pTunnel1BgpAsn:
+        default: VPN Tunnel 1 BGP ASN
+      pTunnel1BgpNeighborIpAddress:
+        default: VPN Tunnel 1 BGP Neighbor IP Address
+
+      pTunnel2Psk:
+        default: VPN Tunnel 2 Pre-Shared Key
+      pTunnel2VgwOutsideIpAddress:
+        default: VPN Tunnel 2 Virtual Private Gateway Outside IP Address
+      pTunnel2VgwInsideCidr:
+        default: VPN Tunnel 2 Virtual Private Gateway Inside CIDR
+      pTunnel2CgwInsideCidr:
+        default: VPN Tunnel 2 Customer Gateway Inside CIDR
+      pTunnel2BgpAsn:
+        default: VPN Tunnel 2 BGP ASN
+      pTunnel2BgpNeighborIpAddress:
+        default: VPN Tunnel 2 BGP Neighbor IP Address
+
+      pUseElasticIp:
+        default: Use Elastic IP Address? (true/false)
+      pEipAllocationId:
+        default: Elastic IP Address Allocation ID
+      pLocalBgpAsn:
+        default: Local VPN Gateway's BGP ASN
+      pVpcId:
+        default: VPC ID
+      pVpcCidr:
+        default: VPC CIDR Block
+      pSubnetId:
+        default: Subnet ID for VPN Gateway
+
+      pInstanceType:
+        default: EC2 Instance Type
+      pAmiId:
+        default: EC2 AMI ID
+
+Parameters:
+  pOrg:
+    Type: String
+    Description: Used to qualify resource names
+    Default: example
+
+  pSystem:
+    Type: String
+    Description: Used to qualify resource names
+    Default: infra
+
+  pApp:
+    Type: String
+    Description: Used to qualify resource names
+    Default: vpngw
+
+  pEnvPurpose:
+    Type: String
+    Description: Used to qualify resource names. 10 characters max.
+    AllowedPattern: '^[a-zA-Z0-9-_]{1,10}$'
+  
+  pTunnel1Psk:
+    Description: VPN Tunnel 1 Pre-Shared Key
+    Type: String
+
+  pTunnel1VgwOutsideIpAddress:
+    Description: VPN Tunnel 1 Virtual Private Gateway Outside IP Address
+    Type: String
+
+  pTunnel1VgwInsideCidr:
+    Description: VPN Tunnel 1 Virtual Private Gateway Inside CIDR
+    Type: String
+    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|3[0-8]))$ 
+
+  pTunnel1CgwInsideCidr:
+    Description:  VPN Tunnel 1 Customer Gateway Inside CIDR
+    Type: String
+    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|3[0-8]))$ 
+
+  pTunnel1BgpAsn:
+    Description: VPN Tunnel 1 BGP ASN
+    Type: Number
+    Default: 64512
+
+  pTunnel1BgpNeighborIpAddress:
+    Description: VPN Tunnel 1 BGP Neighbor IP Address
+    Type: String
+  
+  pTunnel2Psk:
+    Description: VPN Tunnel 2 Pre-Shared Key
+    Type: String
+
+  pTunnel2VgwOutsideIpAddress:
+    Description: VPN Tunnel 2 Virtual Private Gateway Outside IP Address
+    Type: String
+
+  pTunnel2VgwInsideCidr:
+    Description: VPN Tunnel 2 Virtual Private Gateway Inside CIDR
+    Type: String
+    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|3[0-8]))$ 
+
+  pTunnel2CgwInsideCidr:
+    Description:  VPN Tunnel 2 Customer Gateway Inside CIDR
+    Type: String
+    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|3[0-8]))$ 
+  
+  pTunnel2BgpAsn:
+    Description: VPN Tunnel 2 BGP ASN
+    Type: Number
+    Default: 64512
+    
+  pUseElasticIp:
+    Type: String
+    Description: Whether Elastic IP address is to be used.
+    Default: false
+    AllowedValues: [true, false]
+
+  pEipAllocationId:
+    Description: Elastic IP Address Alocation ID
+    Type: String
+
+  pLocalBgpAsn:
+    Description: Local VPN Gateway's BGP ASN
+    Type: Number
+    Default: 65000
+
+  pTunnel2BgpNeighborIpAddress:
+    Description: VPN Tunnel 2 BGP Neighbor IP Address
+    Type: String
+
+  pVpcId:
+    Description: VPC ID
+    Type: AWS::EC2::VPC::Id
+
+  pVpcCidr:
+    Description: VPC CIDR Block
+    Type: String
+    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
+
+  pSubnetId:
+    Description: Subnet ID for VPN Gateway
+    Type: AWS::EC2::Subnet::Id
+
+  pInstanceType:
+    Description: EC2 Instance Type
+    Type: String
+    Default: t3a.micro
+    AllowedValues:
+      - t3a.micro
+      - t3a.small
+      - t3a.medium
+    ConstraintDescription: must be a valid EC2 instance type.
+
+  pAmiId:
+    Description: EC2 AMI ID
+    Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
+    Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-ebs'
+
+Rules:
+  SubnetsInVPC:
+    Assertions:
+      - Assert:
+          'Fn::EachMemberIn':
+            - 'Fn::ValueOfAll':
+                - 'AWS::EC2::Subnet::Id'
+                - VpcId
+            - 'Fn::RefAll': 'AWS::EC2::VPC::Id'
+        AssertDescription: All subnets must in the VPC
+
+Conditions:
+  cUseElasticIp: !Equals [ !Ref 'pUseElasticIp', true ]
+
+Resources:
+  rInstanceSecurityGroup:
+    Type: AWS::EC2::SecurityGroup
+    Properties:
+      GroupName: !Sub '${pSystem}-${pApp}-ec2-${pEnvPurpose}'
+      VpcId: !Ref pVpcId
+      GroupDescription: Allow traffic from other VPN gateway and all locally sourced traffic
+      SecurityGroupIngress:
+        - IpProtocol: udp
+          FromPort: 500
+          ToPort: 500
+          CidrIp: !Sub '${pTunnel1VgwOutsideIpAddress}/32'
+        - IpProtocol: udp
+          FromPort: 500
+          ToPort: 500
+          CidrIp: !Sub '${pTunnel2VgwOutsideIpAddress}/32'
+        - IpProtocol: udp
+          FromPort: 4500
+          ToPort: 4500
+          CidrIp: !Sub '${pTunnel1VgwOutsideIpAddress}/32'
+        - IpProtocol: udp
+          FromPort: 4500
+          ToPort: 4500
+          CidrIp: !Sub '${pTunnel2VgwOutsideIpAddress}/32'
+        - IpProtocol: '50'
+          CidrIp: !Sub '${pTunnel1VgwOutsideIpAddress}/32'
+        - IpProtocol: '50'
+          CidrIp: !Sub '${pTunnel2VgwOutsideIpAddress}/32'
+        - IpProtocol: '51'
+          CidrIp: !Sub '${pTunnel1VgwOutsideIpAddress}/32'
+        - IpProtocol: '51'
+          CidrIp: !Sub '${pTunnel2VgwOutsideIpAddress}/32'
+        - IpProtocol: '-1'
+          FromPort: 0
+          ToPort: 65535
+          CidrIp: !Ref pVpcCidr
+
+  rLaunchTemplate:
+    Type: AWS::EC2::LaunchTemplate
+    Properties: 
+      LaunchTemplateName: !Sub '${pSystem}-${pApp}-${pEnvPurpose}'
+      LaunchTemplateData: 
+        InstanceType: !Ref pInstanceType
+        ImageId: !Ref pAmiId
+        IamInstanceProfile: 
+          Arn: !GetAtt rInstanceProfile.Arn
+        NetworkInterfaces:
+          - DeviceIndex: 0
+            DeleteOnTermination: true
+            Description: !Sub '${pSystem}-${pApp}-${pEnvPurpose}'
+            Groups:
+              - !Ref rInstanceSecurityGroup
+            AssociatePublicIpAddress: !Ref pUseElasticIp
+        UserData:
+          Fn::Base64: !Sub |
+            #!/bin/bash -xe
+            yum install -y aws-cfn-bootstrap
+
+            /opt/aws/bin/cfn-init -v \
+                --stack ${AWS::StackName} \
+                --resource rLaunchTemplate \
+                --configsets All \
+                --region ${AWS::Region}
+
+            /opt/aws/bin/cfn-signal -e $? \
+                '${rVpnGatewayWaitHandle}'
+    Metadata:
+      AWS::CloudFormation::Init:
+        configSets:
+          All:
+            - 01-ConfigureCloudWatchMetrics
+            - 02-ConfigureCloudWatchLogsAgent
+            - 03-InstallEpel
+            - 04-ConfigureVpnGateway
+        01-ConfigureCloudWatchMetrics:
+          packages:
+            yum:
+              perl-Switch: []
+              perl-DateTime: []
+              perl-Sys-Syslog: []
+              perl-LWP-Protocol-https: []
+              perl-Digest-SHA.x86_64: []
+          sources:
+            /home/ec2-user: >-
+              https://aws-cloudwatch.s3.amazonaws.com/downloads/CloudWatchMonitoringScripts-1.2.2.zip
+          files:
+            /home/ec2-user/crontab:
+              content: !Sub |
+                */1 * * * * ~/aws-scripts-mon/mon-put-instance-data.pl --aws-iam-role=${rRole} --mem-used --memory-units=megabytes --mem-util --disk-space-util --disk-space-used --disk-space-avail --disk-path=/
+              mode: '000600'
+              owner: ec2-user
+              group: ec2-user
+          commands:
+            01-yum-update:
+              command: yum update -y
+            02-monitoring-cron:
+              command: >-
+                chmod +x /home/ec2-user/aws-scripts-mon/*.pl && crontab -u
+                ec2-user /home/ec2-user/crontab && rm /home/ec2-user/crontab
+        02-ConfigureCloudWatchLogsAgent:
+          packages:
+            yum:
+              awslogs: []
+          files:
+            /etc/awslogs/awslogs.conf:
+              content: !Sub |
+                [general]
+                state_file= /var/awslogs/state/agent-state
+
+                [/var/log/cloud-init.log]
+                file = /var/log/cloud-init.log
+                log_group_name = ${rCloudWatchLogsAgentGroup}
+                log_stream_name = {instance_id}/cloud-init.log
+                datetime_format =
+
+                [/var/log/cloud-init-output.log]
+                file = /var/log/cloud-init-output.log
+                log_group_name = ${rCloudWatchLogsAgentGroup}
+                log_stream_name = {instance_id}/cloud-init-output.log
+                datetime_format =
+
+                [/var/log/cfn-init.log]
+                file = /var/log/cfn-init.log
+                log_group_name = ${rCloudWatchLogsAgentGroup}
+                log_stream_name = {instance_id}/cfn-init.log
+                datetime_format =
+
+                [/var/log/cfn-wire.log]
+                file = /var/log/cfn-wire.log
+                log_group_name = ${rCloudWatchLogsAgentGroup}
+                log_stream_name = {instance_id}/cfn-wire.log
+                datetime_format =
+
+                [/var/log/charon.log]
+                file = /var/log/charon.log
+                log_group_name = ${rCloudWatchLogsAgentGroup}
+                log_stream_name = {instance_id}/charon.log
+                datetime_format =
+
+                [/var/log/quagga/zebra.log]
+                file = /var/log/quagga/zebra.log
+                log_group_name = ${rCloudWatchLogsAgentGroup}
+                log_stream_name = {instance_id}/zebra.log
+                datetime_format =
+
+                [/var/log/quagga/bgpd.log]
+                file = /var/log/quagga/bgpd.log
+                log_group_name = ${rCloudWatchLogsAgentGroup}
+                log_stream_name = {instance_id}/bgpd.log
+                datetime_format =
+              mode: '000444'
+              owner: root
+              group: root
+            /etc/awslogs/awscli.conf:
+              content: !Sub |
+                [plugins]
+                cwlogs = cwlogs
+                [default]
+                region = ${AWS::Region}
+              mode: '000444'
+              owner: root
+              group: root
+          commands:
+            01-create-awslogs-state-file:
+              command: mkdir -p /var/awslogs/state
+            02-enable-awslogsd:
+              command: systemctl enable awslogsd.service
+            03-start-awslogsd:
+              command: systemctl start awslogsd
+        03-InstallEpel:
+          commands:
+            01-install-epel:
+              command: amazon-linux-extras install epel -y
+        04-ConfigureVpnGateway:
+          packages:
+            yum:
+              strongswan: []
+              ntp: []
+              quagga: []
+          files:
+            /etc/strongswan/strongswan.conf:
+              content: |
+                # strongswan.conf - strongSwan configuration file
+                #
+                # Refer to the strongswan.conf(5) manpage for details
+                #
+                # Configuration changes should be made in the included files
+                charon {
+                  plugins {
+                    include strongswan.d/charon/*.conf
+                  }
+                  load_modular = yes
+                  filelog {
+                    charon {
+                      path = /var/log/charon.log
+                      time_format = %b %e %T
+                      ike_name = yes
+                      append = yes
+                    }
+                  }
+                }
+              mode: '000600'
+              owner: root
+              group: root
+            /etc/strongswan/ipsec.conf:
+              content: !Sub |
+                conn %default
+                  leftauth=psk
+                  rightauth=psk
+                  ike=aes256-sha256-modp2048s256,aes128-sha1-modp1024!
+                  ikelifetime=28800s
+                  aggressive=no
+                  esp=aes128-sha256-modp2048s256,aes128-sha1-modp1024!
+                  lifetime=3600s
+                  type=tunnel
+                  dpddelay=10s
+                  dpdtimeout=30s
+                  keyexchange=ikev1
+                  rekey=yes
+                  reauth=no
+                  dpdaction=restart
+                  closeaction=restart
+                  left=%defaultroute
+                  leftsubnet=0.0.0.0/0,::/0
+                  rightsubnet=0.0.0.0/0,::/0
+                  leftupdown=/etc/strongswan/ipsec-vti.sh
+                  installpolicy=yes
+                  compress=no
+                  mobike=no
+
+                conn AWS-VPC-TUNNEL-1
+                  left=%any
+                  right=${pTunnel1VgwOutsideIpAddress}
+                  auto=start
+                  mark=100
+
+                conn AWS-VPC-TUNNEL-2
+                  left=%any
+                  right=${pTunnel2VgwOutsideIpAddress}
+                  auto=start
+                  mark=200
+              mode: '000600'
+              owner: root
+              group: root
+            /etc/strongswan/ipsec-vti.sh:
+              content: !Sub |
+                #!/bin/bash
+                
+                #@ /etc/strongswan/ipsec-vti.sh (Centos) or /etc/strongswan.d/ipsec-vti.sh (Ubuntu)
+                
+                # AWS VPC Hardware VPN Strongswan updown Script
+                
+                # Usage Instructions:
+                # Add "install_routes = no" to /etc/strongswan/strongswan.d/charon.conf or /etc/strongswan.d/charon.conf
+                # Add "install_virtual_ip = no" to /etc/strongswan/strongswan.d/charon.conf or /etc/strongswan.d/charon.conf
+                # For Ubuntu: Add "leftupdown=/etc/strongswan.d/ipsec-vti.sh" to /etc/ipsec.conf
+                # For RHEL/Centos: Add "leftupdown=/etc/strongswan/ipsec-vti.sh" to /etc/strongswan/ipsec.conf
+                # For RHEL/Centos 6 and below: git clone git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git && cd iproute2 && make && cp ./ip/ip /usr/local/sbin/ip
+                
+                # Adjust the below according to the Generic Gateway Configuration file provided to you by AWS.
+                # Sample: http://docs.aws.amazon.com/AmazonVPC/latest/NetworkAdminGuide/GenericConfig.html
+                
+                IP=$(which ip)
+                IPTABLES=$(which iptables)
+                
+                PLUTO_MARK_OUT_ARR=(${!PLUTO_MARK_OUT//// })
+                PLUTO_MARK_IN_ARR=(${!PLUTO_MARK_IN//// })
+                case "$PLUTO_CONNECTION" in
+                  AWS-VPC-TUNNEL-1)
+                    VTI_INTERFACE=vti1
+                    VTI_LOCALADDR=${pTunnel1CgwInsideCidr}
+                    VTI_REMOTEADDR=${pTunnel1VgwInsideCidr}
+                    ;;
+                  AWS-VPC-TUNNEL-2)
+                    VTI_INTERFACE=vti2
+                    VTI_LOCALADDR=${pTunnel2CgwInsideCidr}
+                    VTI_REMOTEADDR=${pTunnel2VgwInsideCidr}
+                    ;;
+                esac
+                
+                case "${!PLUTO_VERB}" in
+                    up-client)
+                        #$IP tunnel add ${!VTI_INTERFACE} mode vti local ${!PLUTO_ME} remote ${!PLUTO_PEER} okey ${!PLUTO_MARK_OUT_ARR[0]} ikey ${!PLUTO_MARK_IN_ARR[0]}
+                        $IP link add ${!VTI_INTERFACE} type vti local ${!PLUTO_ME} remote ${!PLUTO_PEER} okey ${!PLUTO_MARK_OUT_ARR[0]} ikey ${!PLUTO_MARK_IN_ARR[0]}
+                        sysctl -w net.ipv4.conf.${!VTI_INTERFACE}.disable_policy=1
+                        sysctl -w net.ipv4.conf.${!VTI_INTERFACE}.rp_filter=2 || sysctl -w net.ipv4.conf.${!VTI_INTERFACE}.rp_filter=0
+                        $IP addr add ${!VTI_LOCALADDR} remote ${!VTI_REMOTEADDR} dev ${!VTI_INTERFACE}
+                        $IP link set ${!VTI_INTERFACE} up mtu 1436
+                	      $IPTABLES -t mangle -I FORWARD -o ${!VTI_INTERFACE} -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
+                        $IPTABLES -t mangle -I INPUT -p esp -s ${!PLUTO_PEER} -d ${!PLUTO_ME} -j MARK --set-xmark ${!PLUTO_MARK_IN}
+                        $IP route flush table 220
+                        #/etc/init.d/bgpd reload || /etc/init.d/quagga force-reload bgpd
+                        ;;
+                    down-client)
+                        #$IP tunnel del ${!VTI_INTERFACE}
+                        $IP link del ${!VTI_INTERFACE}
+                	      $IPTABLES -t mangle -D FORWARD -o ${!VTI_INTERFACE} -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
+                        $IPTABLES -t mangle -D INPUT -p esp -s ${!PLUTO_PEER} -d ${!PLUTO_ME} -j MARK --set-xmark ${!PLUTO_MARK_IN}
+                        ;;
+                esac
+              mode: '000700'
+              owner: root
+              group: root
+            /etc/strongswan/ipsec.secrets:
+              content: !Sub |
+                ${pTunnel1VgwOutsideIpAddress} : PSK "${pTunnel1Psk}"
+                ${pTunnel2VgwOutsideIpAddress} : PSK "${pTunnel2Psk}"
+              mode: '000600'
+              owner: root
+              group: root
+            /etc/quagga/zebra.conf:
+              content: |
+                hostname {HOSTNAME}
+                password zebra
+                enable password zebra
+                !
+                log file /var/log/quagga/zebra.log
+                !
+                ! Configure interfaces
+                interface lo
+                ! Change preferred source ip address of received routes
+                route-map RM_SET_SRC permit 10
+                  set src {PRIVATE_IP}
+                ip protocol bgp route-map RM_SET_SRC
+                !
+                line vty
+              mode: '000600'
+              owner: quagga
+              group: quagga
+            /etc/quagga/bgpd.conf:
+              content: !Sub |
+                hostname bgpd
+                password zebra
+                enable password zebra
+                !
+                log file /var/log/quagga/bgpd.log
+                !
+                debug bgp events
+                debug bgp filters
+                debug bgp fsm
+                debug bgp keepalives
+                debug bgp updates
+                !
+                router bgp ${pLocalBgpAsn}
+                  bgp router-id {PRIVATE_IP} 
+                  network ${pVpcCidr}
+                  neighbor ${pTunnel1BgpNeighborIpAddress} remote-as ${pTunnel1BgpAsn}
+                  neighbor ${pTunnel2BgpNeighborIpAddress} remote-as ${pTunnel2BgpAsn}
+                  neighbor ${pTunnel2BgpNeighborIpAddress} route-map RM_LOWER_PRIORITY out
+                !
+                route-map RM_LOWER_PRIORITY permit 10
+                  set as-path prepend ${pLocalBgpAsn} ${pLocalBgpAsn} ${pLocalBgpAsn}
+                !
+                line vty
+              mode: '000600'
+              owner: quagga
+              group: quagga
+            /etc/sysctl.conf:
+              content: |
+                # sysctl settings are defined through files in
+                # /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
+                #
+                # Vendors settings live in /usr/lib/sysctl.d/.
+                # To override a whole file, create a new file with the same in
+                # /etc/sysctl.d/ and put new settings there. To override
+                # only specific settings, add a file with a lexically later
+                # name in /etc/sysctl.d/ and put new settings there.
+                #
+                # For more information, see sysctl.conf(5) and sysctl.d(5).
+                
+                net.ipv4.ip_forward = 1
+                net.ipv4.conf.all.send_redirects = 0
+                net.ipv4.conf.default.send_redirects = 0
+                net.ipv4.tcp_max_syn_backlog = 1280
+                net.ipv4.icmp_echo_ignore_broadcasts = 1
+                net.ipv4.conf.all.accept_source_route = 0
+                net.ipv4.conf.all.accept_redirects = 0
+                net.ipv4.conf.all.secure_redirects = 0
+                net.ipv4.conf.all.log_martians = 1
+                net.ipv4.conf.default.accept_source_route = 0
+                net.ipv4.conf.default.accept_redirects = 0
+                net.ipv4.conf.default.secure_redirects = 0
+                net.ipv4.icmp_echo_ignore_broadcasts = 1
+                net.ipv4.icmp_ignore_bogus_error_responses = 1
+                net.ipv4.tcp_syncookies = 1
+                net.ipv4.conf.all.rp_filter = 1
+                net.ipv4.conf.default.rp_filter = 1
+                net.ipv4.tcp_mtu_probing = 1
+              mode: '000600'
+              owner: root
+              group: root
+          commands:
+            00-sed-instance-specific-settings:
+              command: >- 
+                ipaddr=$(curl 169.254.169.254/latest/meta-data/local-ipv4) &&
+                sed -i -e "s/{PRIVATE_IP}/${ipaddr}/" /etc/quagga/zebra.conf && 
+                sed -i -e "s/{PRIVATE_IP}/${ipaddr}/" /etc/quagga/bgpd.conf && 
+                hostname=$(curl 169.254.169.254/latest/meta-data/local-hostname) &&
+                sed -i -e "s/{HOSTNAME}/${hostname}/" /etc/quagga/zebra.conf
+            01-load-sysctl-changes:
+              command: sysctl -p /etc/sysctl.conf
+            02-enable-ip-forwarding:
+              command: >- 
+                sysctl -w net.ipv4.ip_forward=1 && 
+                sysctl -w net.ipv4.conf.eth0.disable_xfrm=1 && 
+                sysctl -w net.ipv4.conf.eth0.disable_policy=1
+            03-enable-start-ntpd:
+              command: >- 
+                systemctl enable ntpd && 
+                systemctl start  ntpd
+            04-enable-start-strongswan:
+              command: >- 
+                systemctl enable strongswan && 
+                systemctl start  strongswan
+            05-enable-start-zebra:
+              command: >- 
+                systemctl enable zebra && 
+                systemctl start  zebra
+            06-enable-start-bgpd:
+              command: >- 
+                systemctl enable bgpd && 
+                systemctl start  bgpd
+
+  rVpnGatewayEipAssociation:
+    Type: AWS::EC2::EIPAssociation
+    Condition: cUseElasticIp
+    Properties:
+      AllocationId: !Ref pEipAllocationId
+      InstanceId: !Ref rVpnGateway
+
+  rVpnGateway:
+    Type: AWS::EC2::Instance
+    Properties:
+      LaunchTemplate:
+        LaunchTemplateId:
+          Ref: rLaunchTemplate
+        Version:
+          Fn::GetAtt:
+            [ rLaunchTemplate, LatestVersionNumber ]
+      NetworkInterfaces:
+        - DeviceIndex: '0'
+          SubnetId: !Ref pSubnetId
+      SourceDestCheck: false
+      Tags:
+        - Key: Name
+          Value: !Sub '${pSystem}-${pApp}-${pEnvPurpose}'
+
+  rVpnGatewayWaitHandle: 
+   Type: AWS::CloudFormation::WaitConditionHandle
+
+  rVpnGatewayWaitCondition1: 
+    Type: AWS::CloudFormation::WaitCondition
+    DependsOn: rVpnGateway
+    Properties: 
+      Handle: 
+        Ref: rVpnGatewayWaitHandle
+      Timeout: '300'
+      Count: 1
+
+  rRole:
+    Type: AWS::IAM::Role
+    Properties:
+      RoleName: !Sub '${pOrg}-${pSystem}-${pApp}-${pEnvPurpose}-svc-cloud-watch-ssm'
+      Path: !Sub '/${pOrg}/${pSystem}/${pApp}/'
+      AssumeRolePolicyDocument:
+        Version: 2012-10-17
+        Statement:
+          -
+            Effect: Allow
+            Principal:
+              Service: ec2.amazonaws.com
+            Action: sts:AssumeRole
+      ManagedPolicyArns:
+        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
+        - arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
+
+  rInstanceProfile:
+    Type: AWS::IAM::InstanceProfile
+    Properties:
+      InstanceProfileName: !Sub '${pSystem}-${pApp}-${pEnvPurpose}'
+      Path: !Sub '/${pOrg}/${pSystem}/${pApp}/'
+      Roles:
+        - !Ref rRole
+
+  rCloudWatchLogsAgentGroup:
+    Type: AWS::Logs::LogGroup
+    Properties:
+      LogGroupName: !Sub '/${pSystem}/${pApp}/ec2/${pEnvPurpose}'
+      RetentionInDays: 1

+ 44 - 0
test/aws-us-gov/mdr-test-c2/018-xdr-interconnect-instances/terragrunt.hcl

@@ -0,0 +1,44 @@
+locals {
+  # If you want to use any of the variables in _this_ file, you have to load them here.
+  # However, they will all be available as inputs to the module loaded in terraform.source
+  # below.
+  environment_vars = read_terragrunt_config(find_in_parent_folders("env.hcl"))
+  partition_vars = read_terragrunt_config(find_in_parent_folders("partition.hcl"))
+  region_vars = read_terragrunt_config(find_in_parent_folders("region.hcl"))
+  account_vars = read_terragrunt_config(find_in_parent_folders("account.hcl"))
+  global_vars = read_terragrunt_config(find_in_parent_folders("globals.hcl"))
+}
+
+# Terragrunt will copy the Terraform configurations specified by the source parameter, along with any files in the
+# working directory, into a temporary folder, and execute your Terraform commands in that folder.
+terraform {
+  # Double slash is intentional and required to show root of modules
+  source = "git@github.mdr.defpoint.com:mdr-engineering/xdr-terraform-modules.git//base/xdr_interconnects?ref=v0.3.0"
+}
+
+dependency "security_vpc" {
+  config_path = "../015-security-vpc"
+}
+
+#dependency "palo_alto_bootstrap" {
+#  config_path = "../017-palo-alto-bootstrap"
+#}
+
+# Include all settings from the root terragrunt.hcl file
+include {
+  path = find_in_parent_folders()
+}
+
+# These are the variables we have to pass in to use the module specified in the terragrunt source above
+inputs = {
+  # All of the inputs from the inherited hcl files are available automatically
+  # (via the `inputs` section of the root `terragrunt.hcl`). However, modules
+  # will be more flexible if you specify particular input values.
+  tags = {
+    Purpose = "Palo Alto Firewalls"
+    Terraform = "aws/${basename(get_parent_terragrunt_dir())}/${path_relative_to_include()}/"
+  }
+  security_vpc = dependency.security_vpc.outputs.vpc_id
+  azs = dependency.security_vpc.outputs.azs
+  subnet_id_map = dependency.security_vpc.outputs.subnet_id_map
+}

+ 45 - 0
test/aws-us-gov/mdr-test-c2/020-transit-gateway-interconnect-vpn/terragrunt.hcl

@@ -0,0 +1,45 @@
+locals {
+  # If you want to use any of the variables in _this_ file, you have to load them here.
+  # However, they will all be available as inputs to the module loaded in terraform.source
+  # below.
+
+  # e.g. inherited variables:
+  environment_vars = read_terragrunt_config(find_in_parent_folders("env.hcl"))
+  partition_vars = read_terragrunt_config(find_in_parent_folders("partition.hcl"))
+  #region_vars = read_terragrunt_config(find_in_parent_folders("region.hcl"))
+  account_vars = read_terragrunt_config(find_in_parent_folders("account.hcl"))
+  #global_vars = read_terragrunt_config(find_in_parent_folders("globals.hcl"))
+}
+
+# Terragrunt will copy the Terraform configurations specified by the source parameter, along with any files in the
+# working directory, into a temporary folder, and execute your Terraform commands in that folder.
+terraform {
+  # Double slash is intentional and required to show root of modules
+  source = "git@github.mdr.defpoint.com:mdr-engineering/xdr-terraform-modules.git//base/transit-gateway-interconnect-vpn?ref=v0.3.0"
+}
+
+dependency "transit-gateway-hub" {
+  config_path = "../008-transit-gateway-hub"
+}
+
+dependency "palo-alto-firewalls" {
+  config_path = "../../../../common/aws-us-gov/afs-mdr-common-services-gov/018-palo-alto-firewalls"
+}
+
+# Include all settings from the root terragrunt.hcl file
+include {
+  path = find_in_parent_folders()
+}
+
+# These are the variables we have to pass in to use the module specified in the terragrunt source above
+inputs = {
+  # All of the inputs from the inherited hcl files are available automatically
+  # (via the `inputs` section of the root `terragrunt.hcl`). However, modules
+  # will be more flexible if you specify particular input values.
+  name = "${local.partition_vars.locals.aws_partition_alias}-${local.environment_vars.locals.environment}"
+  tags = {
+    Purpose = "Transit Gateway VPN"
+    Terraform = "aws/${basename(get_parent_terragrunt_dir())}/${path_relative_to_include()}/"
+  }
+  firewall_public_ips = dependency.palo-alto-firewalls.outputs.untrusted_ips
+}

+ 7 - 1
test/aws-us-gov/mdr-test-c2/account.hcl

@@ -14,5 +14,11 @@ locals {
   test_instance_key_name = "fdamstra" # They with which to provision the test instance
 
   # AS Number used for various resources, but not every account needs one.
-  asn = 64710
+  asn = 64720
+
+  # XDR-Interconnects
+  xdr_interconnect_asn = 64700
+  xdr_interconnects_instance_type = "t3a.micro"
+  xdr_interconnects_key_name = "fdamstra" # DO NOT CHANGE
+  xdr_interconnects_count = 2
 }