---
AWSTemplateFormatVersion: '2010-09-09'
Description: BGP Site-to-Site VPN Connection by Levon Becker v20160425-1400
Parameters:
  Owner:
    Description: Enter Team or Individual Name Responsible for the Stack.
    Type: String
    Default: FirstName LastName
  Project:
    Description: Enter Project Name.
    Type: String
    Default: VPN Connection Creation
  DeleteAfter:
    Description: Enter Date It's Ok to Delete the Stack or 'Never' if meant to be
      persistent.
    Type: String
    Default: 00/00/201x
  VPC:
    Description: Select VPC.
    Type: AWS::EC2::VPC::Id
  PublicRouteTable:
    Description: Enter Public Route Table ID. (Skip if Not Including Public)
    Type: String
    Default: rtb-0000000
  PrivateRouteTable:
    Description: Enter Private Route Table ID.
    Type: String
    Default: rtb-0000000
  PublicNetworkAcl:
    Description: Enter Public Network ACL ID. (Skip if Not Including Public)
    Type: String
    Default: acl-0000000
  PrivateNetworkAcl:
    Description: Enter Private Network ACL ID.
    Type: String
    Default: acl-0000000
  RemoteVpnDeviceIp:
    Description: Enter External IP Address of the Customer VPN Device.
    Type: String
    MinLength: '7'
    MaxLength: '12'
    Default: 0.0.0.0
    AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})"
    ConstraintDescription: Must be a valid IP Address x.x.x.x
  RemoteNetworkCidr:
    Description: Enter Remote Network IP Range CIDR (i.e. 192.168.100.0/24).
    Type: String
    MinLength: '11'
    MaxLength: '18'
    Default: 192.168.100.0/24
    AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
    ConstraintDescription: Must be a valid CIDR range of the form x.x.x.x/x.
  RemoteBgpAsn:
    Description: Enter Remote VPN Device BGP ASN.
    Type: String
    MinLength: '4'
    MaxLength: '5'
    Default: '65000'
    AllowedPattern: "(\\d{4,5})"
    ConstraintDescription: Must be a valid CIDR range of the form x.x.x.x/x.
  IncludePublicSubnets:
    Description: Select whether to include the Public Subnets in VPN Access or not.
    Type: String
    Default: 'true'
    AllowedValues:
    - 'true'
    - 'false'
  AllowOfficeNetworktoPublicRuleNumber:
    Description: Enter Public Network ACL Rule Number to Allow Office Network. (Skip
      if Not Including Public)
    Type: Number
    Default: '125'
  AllowOfficeNetworktoPrivateRuleNumber:
    Description: Enter Private Network ACL Rule Number to Allow Office Network.
    Type: Number
    Default: '125'
Conditions:
  IncludePublic:
    Fn::Equals:
    - Ref: IncludePublicSubnets
    - 'true'
  ExcludePublic:
    Fn::Equals:
    - Ref: IncludePublicSubnets
    - 'false'
Resources:
  VPNGateway:
    Type: AWS::EC2::VPNGateway
    Properties:
      Type: ipsec.1
      Tags:
      - Key: Name
        Value:
          Ref: AWS::StackName
      - Key: Owner
        Value:
          Ref: Owner
      - Key: Project
        Value:
          Ref: Project
      - Key: DeleteAfter
        Value:
          Ref: DeleteAfter
  VPNGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId:
        Ref: VPC
      VpnGatewayId:
        Ref: VPNGateway
  CustomerGateway:
    Type: AWS::EC2::CustomerGateway
    Properties:
      Type: ipsec.1
      BgpAsn:
        Ref: RemoteBgpAsn
      IpAddress:
        Ref: RemoteVpnDeviceIp
      Tags:
      - Key: Name
        Value:
          Ref: AWS::StackName
      - Key: Owner
        Value:
          Ref: Owner
      - Key: Project
        Value:
          Ref: Project
      - Key: DeleteAfter
        Value:
          Ref: DeleteAfter
      - Key: VPN
        Value:
          Fn::Join:
          - ''
          - - 'Gateway to '
            - Ref: RemoteVpnDeviceIp
  VPNConnection:
    Type: AWS::EC2::VPNConnection
    DependsOn:
    - CustomerGateway
    - VPNGateway
    Properties:
      Type: ipsec.1
      StaticRoutesOnly: 'false'
      CustomerGatewayId:
        Ref: CustomerGateway
      VpnGatewayId:
        Ref: VPNGateway
      Tags:
      - Key: Name
        Value:
          Ref: AWS::StackName
      - Key: Owner
        Value:
          Ref: Owner
      - Key: Project
        Value:
          Ref: Project
      - Key: DeleteAfter
        Value:
          Ref: DeleteAfter
      - Key: VPN
        Value:
          Fn::Join:
          - ''
          - - 'Connection to '
            - Ref: RemoteNetworkCidr
  VPNGatewayRoutePropagationBoth:
    Condition: IncludePublic
    Type: AWS::EC2::VPNGatewayRoutePropagation
    DependsOn:
    - VPNGateway
    - VPNConnection
    Properties:
      RouteTableIds:
      - Ref: PrivateRouteTable
      - Ref: PublicRouteTable
      VpnGatewayId:
        Ref: VPNGateway
  VPNGatewayRoutePropagationPrivateOnly:
    Condition: ExcludePublic
    Type: AWS::EC2::VPNGatewayRoutePropagation
    DependsOn:
    - VPNGateway
    - VPNConnection
    Properties:
      RouteTableIds:
      - Ref: PrivateRouteTable
      VpnGatewayId:
        Ref: VPNGateway
  InboundPublicNetworkAclEntryOfficeNetwork:
    Condition: IncludePublic
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      NetworkAclId:
        Ref: PublicNetworkAcl
      RuleNumber:
        Ref: AllowOfficeNetworktoPublicRuleNumber
      Protocol: "-1"
      RuleAction: allow
      Egress: 'false'
      CidrBlock:
        Ref: RemoteNetworkCidr
      PortRange:
        From: '0'
        To: '65535'
  InboundPrivateNetworkAclEntryOfficeNetwork:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      NetworkAclId:
        Ref: PrivateNetworkAcl
      RuleNumber:
        Ref: AllowOfficeNetworktoPrivateRuleNumber
      Protocol: "-1"
      RuleAction: allow
      Egress: 'false'
      CidrBlock:
        Ref: RemoteNetworkCidr
      PortRange:
        From: '0'
        To: '65535'
Outputs:
  Owner:
    Description: Team or Individual that Owns this Formation.
    Value:
      Ref: Owner
  Project:
    Description: The project name
    Value:
      Ref: Project
  VPC:
    Description: VPC Used
    Value:
      Ref: VPC
  RemoteVpnDeviceIp:
    Description: Remote VPN Device IP Used.
    Value:
      Ref: RemoteVpnDeviceIp
  RemoteNetworkCidr:
    Description: Remote Network CIDR Used.
    Value:
      Ref: RemoteNetworkCidr
  IncludePublic:
    Description: Include Public Subnets?
    Value:
      Ref: IncludePublicSubnets
  AllowOfficeToPublicRuleNumber:
    Condition: IncludePublic
    Description: Allow Office Network to Public Subnets Rule Number Used.
    Value:
      Ref: AllowOfficeNetworktoPublicRuleNumber
  AllowOfficeToPrivateRuleNumber:
    Description: Allow Office Network to Private Subnets Rule Number Used.
    Value:
      Ref: AllowOfficeNetworktoPrivateRuleNumber
  DeleteAfter:
    Description: It is ok to delete the Formation after this date
    Value:
      Ref: DeleteAfter
Metadata:
  TemplateAuthor: 'Levon Becker'
  AWS::CloudFormation::Interface:
    ParameterGroups:
    - Label:
        default: Ownership
      Parameters:
      - Owner
      - Project
      - DeleteAfter
    - Label:
        default: Remote Network Configuration
      Parameters:
      - RemoteVpnDeviceIp
      - RemoteNetworkCidr
      - RemoteBgpAsn
    - Label:
        default: AWS Network Configuration
      Parameters:
      - VPC
      - PrivateRouteTable
      - PrivateNetworkAcl
      - AllowOfficeNetworktoPrivateRuleNumber
    - Label:
        default: Include Public Subnet Access (Optional)
      Parameters:
      - IncludePublicSubnets
      - PublicRouteTable
      - PublicNetworkAcl
      - AllowOfficeNetworktoPublicRuleNumber
    ParameterLabels:
      Owner:
        default: Team or Individual Owner
      DeleteAfter:
        default: Delete After Date
      PublicRouteTable:
        default: Public Route Table
      PrivateRouteTable:
        default: Private Route Table
      PublicNetworkAcl:
        default: Public Network ACL
      PrivateNetworkAcl:
        default: Private Network ACL
      IncludePublicSubnets:
        default: Include Public Subnets?
      AllowOfficeNetworktoPublicRuleNumber:
        default: Public Rule Number
      AllowOfficeNetworktoPrivateRuleNumber:
        default: Private Rule Number
      RemoteVpnDeviceIp:
        default: VPN Device IP
      RemoteNetworkCidr:
        default: Network CIDR Block
      RemoteBgpAsn:
        default: VPN Device BGP ASN
