{
  "Description": "Building on AWS VPC",  
  "Parameters": {
    "KeyName": {
      "Description": "Choose an existing EC2 KeyPair",
      "Type": "AWS::EC2::KeyPair::KeyName"
    }
  },
  "Mappings": {
    "AWSRegionToAMI": {
      "us-west-2": {
        "AMI": "ami-32cf7b4a"
      }
    }
  },
  "Resources": {
    "VPC": {
      "Type": "AWS::EC2::VPC",
      "Properties": {
        "CidrBlock": "10.1.0.0/16",
        "Tags": [
          {
            "Key": "Name",
            "Value": "edx-build-aws-vpc"
          }
        ]
      }
    },
    "InternetGateway": {
      "Type": "AWS::EC2::InternetGateway",
      "Properties": {
        "Tags": [
          {
            "Key": "Name",
            "Value": "edx-igw"
          }
        ]
      }
    },
    "AttachGateway": {
      "Type": "AWS::EC2::VPCGatewayAttachment",
      "Properties": {
        "VpcId": {
          "Ref": "VPC"
        },
        "InternetGatewayId": {
          "Ref": "InternetGateway"
        }
      }
    },
    "PublicSubnet1": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "AvailabilityZone": {
          "Fn::Select": [
            "0",
            {
              "Fn::GetAZs": ""
            }
          ]
        },
        "CidrBlock": "10.1.1.0/24",
        "VpcId": {
          "Ref": "VPC"
        },
        "MapPublicIpOnLaunch": "true",
        "Tags": [
          {
            "Key": "Name",
            "Value": "edx-subnet-public-a"
          }
        ]
      }
    },
    "PublicSubnet2": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "AvailabilityZone": {
          "Fn::Select": [
            "1",
            {
              "Fn::GetAZs": ""
            }
          ]
        },
        "CidrBlock": "10.1.2.0/24",
        "VpcId": {
          "Ref": "VPC"
        },
        "MapPublicIpOnLaunch": "true",
        "Tags": [
          {
            "Key": "Name",
            "Value": "edx-subnet-public-b"
          }
        ]
      }
    },
    "PublicRouteTable": {
      "Type": "AWS::EC2::RouteTable",
      "Properties": {
        "VpcId": {
          "Ref": "VPC"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "edx-routetable-public"
          }
        ]
      }
    },
    "PublicDefaultRoute": {
      "Type": "AWS::EC2::Route",
      "DependsOn": "AttachGateway",
      "Properties": {
        "DestinationCidrBlock": "0.0.0.0/0",
        "GatewayId": {
          "Ref": "InternetGateway"
        },
        "RouteTableId": {
          "Ref": "PublicRouteTable"
        }
      }
    },
    "PublicRouteAssociation1": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "RouteTableId": {
          "Ref": "PublicRouteTable"
        },
        "SubnetId": {
          "Ref": "PublicSubnet1"
        }
      }
    },
    "PublicRouteAssociation2": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "RouteTableId": {
          "Ref": "PublicRouteTable"
        },
        "SubnetId": {
          "Ref": "PublicSubnet2"
        }
      }
    },
    "PrivateSubnet1": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "AvailabilityZone": {
          "Fn::Select": [
            "0",
            {
              "Fn::GetAZs": ""
            }
          ]
        },
        "CidrBlock": "10.1.3.0/24",
        "VpcId": {
          "Ref": "VPC"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "edx-subnet-private-a"
          }
        ]
      }
    },
    "PrivateSubnet2": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "AvailabilityZone": {
          "Fn::Select": [
            "1",
            {
              "Fn::GetAZs": ""
            }
          ]
        },
        "CidrBlock": "10.1.4.0/24",
        "VpcId": {
          "Ref": "VPC"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "edx-subnet-private-b"
          }
        ]
      }
    },
    "PrivateRouteTable": {
      "Type": "AWS::EC2::RouteTable",
      "Properties": {
        "VpcId": {
          "Ref": "VPC"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "edx-routetable-private"
          }
        ]
      }
    },
    "PrivateRoute": {
      "Type": "AWS::EC2::Route",
      "Properties": {
        "RouteTableId": {
          "Ref": "PrivateRouteTable"
        },
        "DestinationCidrBlock": "0.0.0.0/0",
        "InstanceId": {
          "Ref": "NATInstance"
        }
      }
    },
    "PrivateRouteAssociation1": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "RouteTableId": {
          "Ref": "PrivateRouteTable"
        },
        "SubnetId": {
          "Ref": "PrivateSubnet1"
        }
      }
    },
    "PrivateRouteAssociation2": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "RouteTableId": {
          "Ref": "PrivateRouteTable"
        },
        "SubnetId": {
          "Ref": "PrivateSubnet2"
        }
      }
    },
    "NATInstance": {
      "Type": "AWS::EC2::Instance",
      "DependsOn":"AttachGateway",
      "Properties": {
        "ImageId": {
          "Fn::FindInMap": [
            "AWSRegionToAMI",
            {
              "Ref": "AWS::Region"
            },
            "AMI"
          ]
        },
        "KeyName": {
          "Ref": "KeyName"
        },
        "InstanceType": "t2.micro",
        "NetworkInterfaces": [
          {
            "DeviceIndex": "0",
            "AssociatePublicIpAddress": "true",
            "SubnetId": {
              "Ref": "PublicSubnet2"
            },
            "GroupSet": [
              {
                "Ref": "NATSecurityGroup"
              }
            ]
          }
        ],
        "SourceDestCheck": "false",
        "Tags": [
          {
            "Key": "Name",
            "Value": "edx-nat-instance"
          }
        ],
        "UserData": {
          "Fn::Base64": {
            "Fn::Join": [
              "",
              [
                "#!/bin/bash \n",
                "yum -y update \n",
                "echo 1 > /proc/sys/net/ipv4/ip_forward \n",
                "echo 0 > /proc/sys/net/ipv4/conf/eth0/send_redirects \n",
                "/sbin/iptables -t nat -A POSTROUTING -o eth0 -s 0.0.0.0/0 -j MASQUERADE \n",
                "/sbin/iptables-save > /etc/sysconfig/iptables \n",
                "mkdir -p /etc/sysctl.d/ \n",
                "cat <<EOF > /etc/sysctl.d/nat.conf \n",
                "net.ipv4.ip_forward = 1 \n",
                "net.ipv4.conf.eth0.send_redirects = 0 \n",
                "EOF \n"
              ]
            ]
          }
        }
      }
    },
    "NATSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription": "Enable internal access to the NAT device",
        "VpcId": {
          "Ref": "VPC"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "edx-nat-sg"
          }
        ],
        "SecurityGroupIngress": [
          {
            "IpProtocol": "-1",
            "FromPort": "0",
            "ToPort": "1024",
            "CidrIp": "10.1.3.0/24"
          },
          {
            "IpProtocol": "-1",
            "FromPort": "0",
            "ToPort": "1024",
            "CidrIp": "10.1.4.0/24"
          }
        ]
      }
    }
  },
  "Outputs": {
    "PublicSubnet1" : {
      "Description" : "Public Subnet 1",
      "Value" : { "Ref": "PublicSubnet1" }
    },
    "PublicSubnet2" : {
      "Description" : "Public Subnet 2",
      "Value" : { "Ref": "PublicSubnet2" }
    },
    "PrivateSubnet1" : {
      "Description" : "Private Subnet 1",
      "Value" : { "Ref": "PrivateSubnet1" }
    },
    "PrivateSubnet2" : {
      "Description" : "Private Subnet 2",
      "Value" : { "Ref": "PrivateSubnet2" }
    },
    "NATInstance" : {
      "Description" : "NAT Instance Public IP",
      "Value" : { "Fn::GetAtt" : [ "NATInstance", "PublicIp" ] }
    },
  }
}
