---
AWSTemplateFormatVersion: "2010-09-09"

Description: Establishes an OpenVPN server in a public subnet within a new VPC

Parameters:
  InstanceAMI:
    Description: OpenVPN AMI
    Type: String
    Default: ami-bc3566ab

  InstanceType:
    Description: OpenVPN Instance Type
    Type: String
    AllowedValues:
      - t2.nano
      - t2.micro
      - t2.small
      - t2.medium
      - t2.large
    Default: t2.micro

  KeyName:
    Description: SSH Key Name
    Type: AWS::EC2::KeyPair::KeyName

  AdminPassword:
    Description: OpenVPN Admin Password
    Type: String
    NoEcho: true
    MinLength: 8
    MaxLength: 32
    ConstraintDescription: Must be at least 8 chars long

  RouteAllTraffic:
    Description: Should all local traffic go over VPN when connected?
    Type: Number
    AllowedValues:
      - 0
      - 1
    Default: 1

  UseVPNDNS:
    Description: Should client use VPN supplied DNS when connected?
    Type: Number
    AllowedValues:
      - 0
      - 1
    Default: 1

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: "10.0.0.0/16"
      Tags:
      - Key: Name
        Value: OpenVPN

  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: "10.0.0.0/24"
      Tags:
      - Key: Name
        Value: OpenVPN Public Subnet

  InternetGateway:
    Type: AWS::EC2::InternetGateway

  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  RouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC

  Route:
    Type: AWS::EC2::Route
    DependsOn: AttachGateway
    Properties:
      RouteTableId: !Ref RouteTable
      DestinationCidrBlock: "0.0.0.0/0"
      GatewayId: !Ref InternetGateway

  SubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet
      RouteTableId: !Ref RouteTable

  IPAddress:
    Type: AWS::EC2::EIP
    Properties:
      Domain: "vpc"

  SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref VPC
      GroupDescription: Security group for OpenVPN Server
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 443
        ToPort: 443
        CidrIp: "0.0.0.0/0"
      - IpProtocol: tcp
        FromPort: 943
        ToPort: 943
        CidrIp: "0.0.0.0/0"
      - IpProtocol: udp
        FromPort: 1194
        ToPort: 1194
        CidrIp: "0.0.0.0/0"

  OpenVPNInstance:
    Type: AWS::EC2::Instance
    DependsOn: IPAddress
    Properties:
      ImageId: !Ref InstanceAMI
      InstanceType: t2.nano
      KeyName: !Ref KeyName
      SecurityGroupIds:
      - !Ref SecurityGroup
      SubnetId: !Ref PublicSubnet
      Tags:
       - Key: Name
         Value: OpenVPN Instance
      UserData:
        Fn::Base64: !Sub |
          public_hostname=${IPAddress}
          admin_user=openvpn
          admin_pw=${AdminPassword}
          reroute_gw=${RouteAllTraffic}
          reroute_dns=${UseVPNDNS}

  IPAssociaton:
    Type: AWS::EC2::EIPAssociation
    DependsOn: OpenVPNInstance
    Properties:
      AllocationId: !GetAtt IPAddress.AllocationId
      InstanceId: !Ref OpenVPNInstance

Outputs:
  OpenVPNServerAdminURL:
    Description: OpenVPN Administration URL
    Value: !Sub https://${IPAddress}:943/admin
  OpenVPNServerURL:
    Description: OpenVPN Server URL
    Value: !Sub https://${IPAddress}
