{
  "AWSTemplateFormatVersion" : "2010-09-09",
  "Description" : "ArcGIS CloudFormation Template: Creates VPC and other networking AWS resources. **WARNING** You will be billed by AWS for the AWS resources if you create a stack from this template.",
  "Parameters" : {
    "AZs" : {
      "Type" : "List<AWS::EC2::AvailabilityZone::Name>",
      "Description" : "Select two availability zones for your VPC subnets"
    },
    "CIDR" : {
      "Description":"VPC CIDR",
      "Type" : "String", 
      "Default" : "10.0.0.0/16",
      "AllowedPattern" : "^([0-9]{1,3}\\.){3}[0-9]{1,3}(\\/([0-9]|[1-2][0-9]|3[0-2]))?$"
    },
    "PublicSubnet1CIDR": {
      "Description" : "CIDR block of VPC public subnet 1",
      "Type" : "String",
      "Default" : "10.0.0.0/24",
      "AllowedPattern" : "^([0-9]{1,3}\\.){3}[0-9]{1,3}(\\/([0-9]|[1-2][0-9]|3[0-2]))?$"
    },
    "PublicSubnet2CIDR": {
      "Description" : "CIDR block of VPC public subnet 2",
      "Type" : "String",
      "Default" : "10.0.1.0/24",
      "AllowedPattern" : "^([0-9]{1,3}\\.){3}[0-9]{1,3}(\\/([0-9]|[1-2][0-9]|3[0-2]))?$"
    },
    "PrivateSubnet1CIDR": {
      "Description" : "CIDR block of VPC private subnet 1",
      "Type" : "String",
      "Default" : "10.0.2.0/24",
      "AllowedPattern" : "^([0-9]{1,3}\\.){3}[0-9]{1,3}(\\/([0-9]|[1-2][0-9]|3[0-2]))?$"
    },
    "PrivateSubnet2CIDR": {
      "Description" : "CIDR block of VPC private subnet 2",
      "Type" : "String",
      "Default" : "10.0.3.0/24",
      "AllowedPattern" : "^([0-9]{1,3}\\.){3}[0-9]{1,3}(\\/([0-9]|[1-2][0-9]|3[0-2]))?$"
    },
	"NATEIPAllocationID": {
	  "Description": "Allocation ID of Elastic IP address for NAT (eipalloc-XXXXXXXX)",
	  "Type": "String",
	  "AllowedPattern": "eipalloc-.*"
	}
  },
  "Metadata" : {
      "AWS::CloudFormation::Interface" : {
        "ParameterGroups" : [ {
          "Label" : { "default" : "VPC Configuration" },
          "Parameters" : [ "AZs", "CIDR" ]
        },
        {
          "Label" : { "default":"Public Subnet Configuration" },
          "Parameters" : [ "PublicSubnet1CIDR", "PublicSubnet2CIDR" ]
        },
        {
          "Label" : { "default":"Private Subnet Configuration" },
          "Parameters" : [ "PrivateSubnet1CIDR", "PrivateSubnet2CIDR" ]
        },
		{
          "Label" : { "default":"NAT Configuration" },
          "Parameters" : [ "NATEIPAllocationID" ]
        }]
      }
    },
  "Conditions" : {
    "CreateDHCPOptions" : {"Fn::Equals" : [{"Ref" : "AWS::Region"}, "us-east-1"]}	
  },
  "Resources" : {
    "VPC" : {
      "Type" : "AWS::EC2::VPC",
      "Properties" : {
        "CidrBlock" : {"Ref": "CIDR"},
        "EnableDnsHostnames" : true,
        "Tags" : [ {
          "Key" : "Name",
          "Value" : {"Ref" : "AWS::StackName"}
        }, {
          "Key" : "Application",
          "Value" : "arcgis-vpc"
        }, {
          "Key" : "Network",
          "Value" : "Public"
        } ]
      }
    },
    "DHCPOptions" : {
      "Type" : "AWS::EC2::DHCPOptions",
      "Condition" : "CreateDHCPOptions",
      "Properties" : {
        "DomainName" : "ec2.internal",
        "DomainNameServers" : [ "AmazonProvidedDNS" ],
        "Tags" : [ { "Key" : "Name", "Value" : {"Ref" : "AWS::StackName"} } ]
      }
    },
    "VPCDHCPOptionsAssociation" : {
      "Type" : "AWS::EC2::VPCDHCPOptionsAssociation",
      "Condition" : "CreateDHCPOptions",
      "Properties" : {
        "VpcId" : {"Ref" : "VPC"},
        "DhcpOptionsId" : {"Ref" : "DHCPOptions"}
      }
    },
    "InternetGateway" : {
      "Type" : "AWS::EC2::InternetGateway",
      "Properties" : {
        "Tags" : [ {
          "Key" : "Application",
          "Value" : {"Ref" : "AWS::StackName"}
        }, {
          "Key" : "Network",
          "Value" : "Public"
        } ]
      }
    },
    "AttachGateway" : {
      "Type" : "AWS::EC2::VPCGatewayAttachment",
      "Properties" : {
        "VpcId" : {"Ref" : "VPC"},
        "InternetGatewayId" : {"Ref" : "InternetGateway"}
      }
    },
	"PublicSubnetRouteTable" : {
      "Type" : "AWS::EC2::RouteTable",
      "Properties" : {
        "VpcId" : {"Ref" : "VPC"},
        "Tags" : [ {
          "Key" : "Application",
          "Value" : {"Ref" : "AWS::StackName"}
        }, {
          "Key" : "Network",
          "Value" : "Public"
        } ]
      }
    },
    "InternetGatewayRoute" : {
      "Type" : "AWS::EC2::Route",
      "DependsOn" : "AttachGateway",
      "Properties" : {
        "RouteTableId" : {"Ref" : "PublicSubnetRouteTable"},
        "DestinationCidrBlock" : "0.0.0.0/0",
        "GatewayId" : {"Ref" : "InternetGateway"}
      }
    },
    "PublicSubnet1" : {
      "Type" : "AWS::EC2::Subnet",
      "Properties" : {
        "VpcId" : {"Ref" : "VPC"},
        "CidrBlock" : {"Ref": "PublicSubnet1CIDR"},
        "AvailabilityZone" : {"Fn::Select" : [ 0, {"Ref" : "AZs"} ]},
        "Tags" : [ {
          "Key" : "Name", 
          "Value" : {"Fn::Join" : ["", [{"Ref" : "AWS::StackName"}, "-publicsubnet1"]]}
        }, {
          "Key" : "Application",
          "Value" : "arcgis-networking"
        }, {
          "Key" : "Network",
          "Value" : "Public"
        } ]
      }
    },
    "PublicSubnet2" : {
      "Type" : "AWS::EC2::Subnet",
      "Properties" : {
        "VpcId" : {"Ref": "VPC"},
        "CidrBlock" : {"Ref": "PublicSubnet2CIDR"},
        "AvailabilityZone" : {"Fn::Select" : [ 1, {"Ref" : "AZs"} ]},
        "Tags" : [ {
          "Key" : "Name", 
          "Value" : {"Fn::Join" : ["", [{"Ref" : "AWS::StackName"}, "-publicsubnet2"]]}
        }, {
          "Key" : "Application",
          "Value" : "arcgis-networking"
        }, {
          "Key" : "Network",
          "Value" : "Public"
        } ]
      }
    },
    "PrivateSubnet1" : {
      "Type" : "AWS::EC2::Subnet",
      "Properties" : {
        "VpcId" : {"Ref": "VPC"},
        "CidrBlock" : {"Ref": "PrivateSubnet1CIDR"},
        "AvailabilityZone" : {"Fn::Select" : [ 0, {"Ref" : "AZs"} ]},
        "Tags" : [ {
          "Key" : "Name", 
          "Value" : {"Fn::Join" : ["", [{"Ref" : "AWS::StackName"}, "-PrivateSubnet1"]]}
        }, {
          "Key" : "Application",
          "Value" : "arcgis-networking"
        }, {
          "Key" : "Network",
          "Value" : "Public"
        } ]
      }
    },
    "PrivateSubnet2" : {
      "Type" : "AWS::EC2::Subnet",
      "Properties" : {
        "VpcId" : {"Ref": "VPC"},
        "CidrBlock" : {"Ref": "PrivateSubnet2CIDR"},
        "AvailabilityZone" : {"Fn::Select" : [ 1, {"Ref" : "AZs"} ]},
        "Tags" : [ {
          "Key" : "Name", 
          "Value" : {"Fn::Join" : ["", [{"Ref" : "AWS::StackName"}, "-PrivateSubnet2"]]}
        }, {
          "Key" : "Application",
          "Value" : "arcgis-networking"
        }, {
          "Key" : "Network",
          "Value" : "Public"
        } ]
      }
    },
    "PublicSubnet1RouteTableAssociation" : {
      "Type" : "AWS::EC2::SubnetRouteTableAssociation",
      "Properties" : {
        "SubnetId" : {"Ref" : "PublicSubnet1"},
        "RouteTableId" : {"Ref" : "PublicSubnetRouteTable"}
      }
    },
    "PublicSubnet2RouteTableAssociation" : {
      "Type" : "AWS::EC2::SubnetRouteTableAssociation",
      "Properties" : {
        "SubnetId" : {"Ref" : "PublicSubnet2"},
        "RouteTableId" : {"Ref" : "PublicSubnetRouteTable" }
      }
    },	
	"NatGateway" : {
      "Type" : "AWS::EC2::NatGateway",	  
	  "DependsOn" : "PublicSubnet2",
      "Properties" : {
		"AllocationId" : {"Ref" : "NATEIPAllocationID"},
		"SubnetId" : { "Ref" : "PublicSubnet2"},
        "Tags" : [ {
          "Key" : "Application",
          "Value" : {"Ref" : "AWS::StackName"}
        }, {
          "Key" : "Network",
          "Value" : "Public"
        } ]
      }
    },
	"PrivateSubnetRouteTable" : {
      "Type" : "AWS::EC2::RouteTable",	 
      "Properties" : {
        "VpcId" : {"Ref" : "VPC"},
        "Tags" : [ {
          "Key" : "Application",
          "Value" : {"Ref" : "AWS::StackName"}
        }, {
          "Key" : "Network",
          "Value" : "Public"
        } ]
      }
    },
    "NATGatewayRoute" : {
      "Type" : "AWS::EC2::Route",        
      "Properties" : {
        "RouteTableId" : {"Ref" : "PrivateSubnetRouteTable"},
        "DestinationCidrBlock" : "0.0.0.0/0",
        "NatGatewayId" : {"Ref" : "NatGateway"}
      }
    },  
	"PrivateSubnet1RouteTableAssociation" : {
      "Type" : "AWS::EC2::SubnetRouteTableAssociation",	 
      "Properties" : {
        "SubnetId" : {"Ref" : "PrivateSubnet1"},
        "RouteTableId" : {"Ref" : "PrivateSubnetRouteTable"}
      }
    },
    "PrivateSubnet2RouteTableAssociation" : {
      "Type" : "AWS::EC2::SubnetRouteTableAssociation",	  
      "Properties" : {
        "SubnetId" : {"Ref" : "PrivateSubnet2"},
        "RouteTableId" : {"Ref" : "PrivateSubnetRouteTable" }
      }
    },	
    "S3Endpoint" : {
      "Type" : "AWS::EC2::VPCEndpoint",
      "Properties" : {
        "PolicyDocument" : {
          "Version":"2012-10-17",
          "Statement":[{
            "Effect":"Allow",
            "Principal": "*",
            "Action":["s3:*"],
            "Resource":["*"]
          }]
        },
        "RouteTableIds" : [ {"Ref" : "PublicSubnetRouteTable"}, {"Ref" : "PrivateSubnetRouteTable"}],
        "ServiceName" : { "Fn::Join": [ "", [ "com.amazonaws.", { "Ref": "AWS::Region" }, ".s3" ] ] },
        "VpcId" : {"Ref" : "VPC"}
      }
    }
  },
  "Outputs" : {
    "VPCId" : {
      "Description" : "VPC ID",
      "Value" :  {"Ref" : "VPC"}
    },
    "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"}
    }
  }
}
