{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "XtremeData f2mdbx CloudFormation Marketplace, creates new VPC, NAT, S3 endpt; templ r4.3; f2mdbx v2.1.1",

  "Metadata" : 
  {
    "AWS::CloudFormation::Interface" :
    {
      "ParameterGroups" :
      [
        {
          "Parameters" : [ "InstanceType", "AvailabilityZone", "HeadPublicIpAddress",  "CreatePlacementGroup", "EncryptVolumes", "KeyName" ]
        }
      ]
    }
  },



  "Parameters" : 
  {

    "KeyName" : 
    {
      "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instances",
      "Type" : "AWS::EC2::KeyPair::KeyName",
      "ConstraintDescription" : "must be a valid Key pair name."
    },

    "InstanceType" : 
    {
      "Description" : "EC2 instance type",
      "Type" : "String",
      "Default" : "m6i.8xlarge",
      "AllowedValues" : [ "m5.4xlarge", "m5.8xlarge", "m6i.4xlarge", "m6i.8xlarge", "m6i.12xlarge", "m6i.16xlarge", "c6i.8xlarge", "c6i.12xlarge", "c6i.16xlarge"],
      "ConstraintDescription" : "must be a valid EC2 instance type."
    },

    "AvailabilityZone" :
    {
      "Description" : "Availability Zone",
      "Type" : "AWS::EC2::AvailabilityZone::Name",
      "ConstraintDescription" : "must be a valid availabilty zone."
    },

    "HeadPublicIpAddress" : 
    {
      "Description" : "Assign head node public IP",
      "Type" : "String",
      "Default" : "true",
      "AllowedValues" : ["true","false"],
      "ConstraintDescription" : "must be true or false."
    },

    "EncryptVolumes" : 
    {
      "Description" : "Encrypt EBS volumes",
      "Type" : "String",
      "Default" : "false",
      "AllowedValues" : ["true","false"],
      "ConstraintDescription" : "must be true or false."
    },

    "CreatePlacementGroup" : 
    {
      "Description" : "Create Placement Group",
      "Type" : "String",
      "Default" : "true",
      "AllowedValues" : ["true","false"],
      "ConstraintDescription" : "must be true or false."
    }

  },



  "Mappings" : 
  {
    "AWSRegion2AMI" : 
    {
      "us-east-1"      : {"AMI" : "ami-00a9197d6c2c01374"},
      "us-east-2"      : {"AMI" : "ami-068bdb9695bb08236"},
      "us-west-1"      : {"AMI" : "ami-01174c061cb093844"},
      "us-west-2"      : {"AMI" : "ami-0ff9e8b4283626260"},
      "us-gov-east-1"  : {"AMI" : "ami-0edc263319d3614b2"},
      "us-gov-west-1"  : {"AMI" : "ami-00503f4b95fb753dd"}
    },

    "Constants" : 
    {
      "InstanceValues"   : {"DataNodes" : "0"}
    },

    "EBSOptimization" :
    {
      "m5.4xlarge"  : {"Optimized" : "false"},
      "m5.8xlarge"  : {"Optimized" : "false"},
      "m6i.4xlarge"  : {"Optimized" : "false"},
      "m6i.8xlarge"  : {"Optimized" : "false"},
      "m6i.12xlarge"  : {"Optimized" : "false"},
      "m6i.16xlarge"    : {"Optimized" : "false"},
      "c6i.8xlarge"    : {"Optimized" : "false"},
	  "c6i.12xlarge"	: {"Optimized" : "false"}, 	
	  "c6i.16xlarge"	: {"Optimized" : "false"}	
    }
  },



  "Resources": 
  {
    "Vpc" : {
      "Type" : "AWS::EC2::VPC",
      "Properties" : {
        "CidrBlock" : "10.0.0.0/16",
        "EnableDnsSupport" : "true",
        "EnableDnsHostnames" : "true",
        "Tags" : [ 
          {"Key" : "Application", "Value" : {"Ref" : "AWS::StackId"} },
          {"Key" : "Name", "Value" : {"Ref" : "AWS::StackName"} }
        ]
      }
    },
  
    "InternetGateway" : {
      "Type" : "AWS::EC2::InternetGateway",
      "Properties" : {
        "Tags" : [ 
          {"Key" : "Application", "Value" : {"Ref" : "AWS::StackId"} },
          {"Key" : "Name", "Value" : {"Ref" : "AWS::StackName"} }
        ]
      }
    },

    "AttachGateway" : {
      "Type" : "AWS::EC2::VPCGatewayAttachment",
      "Properties" : {
        "VpcId" : { "Ref" : "Vpc" },
        "InternetGatewayId" : {"Ref" : "InternetGateway" }
      }
    },

    "EIP" : {
      "DependsOn" : "AttachGateway",
      "Type" : "AWS::EC2::EIP",
      "Properties" : {
        "Domain" : "vpc"
      }
    },

    "NatGateway" : {
      "Type" : "AWS::EC2::NatGateway",
      "DependsOn" : "EIP",
      "Properties" : {
        "AllocationId" : { "Fn::GetAtt" : [ "EIP", "AllocationId" ] },
        "SubnetId" : {"Ref" : "PublicSubnet" }
      }
    },

    "VPCEndpoint" : {
      "Type" : "AWS::EC2::VPCEndpoint",
      "Properties" : {
        "RouteTableIds" : [ {"Ref" : "PublicRouteTable"}, {"Ref" : "PrivateRouteTable"} ],
        "ServiceName" : { "Fn::Join": [ "", [ "com.amazonaws.", { "Ref": "AWS::Region" }, ".s3" ] ] },
        "VpcId" : {"Ref" : "Vpc"}
      }
    },

    "PublicSubnet" : {
      "Type" : "AWS::EC2::Subnet",
      "Properties" : {
        "VpcId" : { "Ref" : "Vpc" },
        "CidrBlock" : "10.0.1.0/24",
        "AvailabilityZone" : { "Ref" : "AvailabilityZone" },
        "Tags" : [
          {"Key" : "Application", "Value" : {"Ref" : "AWS::StackId"} },
          {"Key" : "Name", "Value" : {"Fn::Join" : ["", [{"Ref" : "AWS::StackName"}, "-Public"]] } }
        ]
      }
    },

    "PublicRouteTable" : {
      "Type" : "AWS::EC2::RouteTable",
      "Properties" : {
        "VpcId" : {"Ref" : "Vpc"},
        "Tags" : [
          {"Key" : "Application", "Value" : {"Ref" : "AWS::StackId"} },
          {"Key" : "Name", "Value" : {"Fn::Join" : [ "", [{"Ref" : "AWS::StackName"}, "-Public"]] } }
        ]
      }
    },

    "PublicRoute" : {
      "Type" : "AWS::EC2::Route",
      "DependsOn" : "AttachGateway",
      "Properties" : {
        "RouteTableId" : {"Ref" : "PublicRouteTable" },
        "DestinationCidrBlock" : "0.0.0.0/0",
        "GatewayId" : {"Ref" : "InternetGateway"}
      }
    },

    "PublicSubnetRouteTableAssociation" : {
      "Type" : "AWS::EC2::SubnetRouteTableAssociation",
      "Properties" : {
        "SubnetId" : {"Ref" : "PublicSubnet" },
        "RouteTableId" : {"Ref" : "PublicRouteTable"}
      }
    },


    "PrivateSubnet" : {
      "Type" : "AWS::EC2::Subnet",
      "Properties" : {
        "VpcId" : { "Ref" : "Vpc" },
        "CidrBlock" : "10.0.0.0/24",
        "AvailabilityZone" : { "Ref" : "AvailabilityZone" },
        "Tags" : [
          {"Key" : "Application", "Value" : {"Ref" : "AWS::StackId"} },
          {"Key" : "Name", "Value" : {"Fn::Join" : [ "", [{"Ref" : "AWS::StackName"}, "-Private"]] } }
        ]
      }
    },

    "PrivateRouteTable" : {
      "Type" : "AWS::EC2::RouteTable",
      "Properties" : {
        "VpcId" : {"Ref" : "Vpc"},
        "Tags" : [
          {"Key" : "Application", "Value" : {"Ref" : "AWS::StackId"} },
          {"Key" : "Name", "Value" : {"Fn::Join" : [ "", [{"Ref" : "AWS::StackName"}, "-Private"]] } }
        ]
      }
    },

    "PrivateRoute" : {
      "Type" : "AWS::EC2::Route",
      "DependsOn" : "NatGateway",
      "Properties" : {
        "RouteTableId" : {"Ref" : "PrivateRouteTable" },
        "DestinationCidrBlock" : "0.0.0.0/0",
        "NatGatewayId" : {"Ref" : "NatGateway"}
      }
    },

    "PrivateSubnetRouteTableAssociation" : {
      "Type" : "AWS::EC2::SubnetRouteTableAssociation",
      "Properties" : {
        "SubnetId" : {"Ref" : "PrivateSubnet" },
        "RouteTableId" : {"Ref" : "PrivateRouteTable"}
      }
    },


    "dbxSG": 
    {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": 
      {
        "GroupDescription": "Enable dbX Access",
        "VpcId" : {"Ref" : "Vpc"},
        "SecurityGroupIngress": [
          {"IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": "0.0.0.0/0"},
          {"IpProtocol": "tcp", "FromPort": "2443", "ToPort": "2443", "CidrIp": "0.0.0.0/0"},
          {"IpProtocol": "tcp", "FromPort": "8444", "ToPort": "8444", "CidrIp": "0.0.0.0/0"},
          {"IpProtocol": "tcp", "FromPort": "8446", "ToPort": "8446", "CidrIp": "0.0.0.0/0"},
          {"IpProtocol": "tcp", "FromPort": "2400", "ToPort": "2400", "CidrIp": "0.0.0.0/0"}
        ]
      }
    },

    "dbxSGIngress" : 
    {
      "Type": "AWS::EC2::SecurityGroupIngress",
      "Properties": 
      {
        "GroupId": { "Ref": "dbxSG" },
        "IpProtocol": "tcp",
        "FromPort": "0",
        "ToPort": "65535",
        "SourceSecurityGroupId": { "Ref": "dbxSG" }
      }
    },

    "dbxSGIngress2" : 
    {
      "Type": "AWS::EC2::SecurityGroupIngress",
      "Properties": 
      {
        "GroupId": { "Ref": "dbxSG" },
        "IpProtocol": "udp",
        "FromPort": "0",
        "ToPort": "65535",
        "SourceSecurityGroupId": { "Ref": "dbxSG" }
      }
    },

    "dbxSGIngress3" : 
    {
      "Type": "AWS::EC2::SecurityGroupIngress",
      "Properties": 
      {
        "GroupId": { "Ref": "dbxSG" },
        "IpProtocol": "icmp",
        "FromPort": "-1",
        "ToPort": "-1",
        "SourceSecurityGroupId": { "Ref": "dbxSG" }
      }
    },

    "PlacementGroup" : 
    {
      "Condition" : "UsePlacementGroup",
      "Type" : "AWS::EC2::PlacementGroup",
      "Properties" : {
      "Strategy" : "cluster"
      }
    },

    "dbXHeadInstance": 
    {
      "Type": "AWS::EC2::Instance",
      "DependsOn" : "InternetGateway",
      "Properties": 
      {
        "UserData" : { "Fn::Base64" : {"Fn::Join" : [ "\n", [
          "#cloud-config",
          {"Fn::Join" : [ ": ", ["repo_update", "false"] ] },
          {"Fn::Join" : [ ": ", ["repo_upgrade", "none"] ] },
          {"Fn::Join" : [ ": ", ["package_upgrade", "false"] ] },
          "",
          "runcmd:",
          {"Fn::Join" : [ " ", [" - xdc provision +y +hdata", {"Fn::Join" : [ "=", ["--data", { "Fn::FindInMap" : [ "Constants", "InstanceValues", "DataNodes" ] } ] ] }, {"Fn::Join" : [ "=", ["--checkin_timeout", "900"] ] } ] ] },
          " - xdc bootable on",
          "",
          "#dbx",
          {"Fn::Join" : [ " : ", ["dbx-cluster", { "Ref" : "AWS::StackName" }] ] }
        ] ] }},
        "ImageId" : { "Fn::FindInMap" : [ "AWSRegion2AMI", {"Ref" : "AWS::Region"}, "AMI" ] },
        "InstanceType": {"Ref" : "InstanceType"},
        "EbsOptimized" : { "Fn::FindInMap" : [ "EBSOptimization", {"Ref" : "InstanceType"}, "Optimized" ] },
        "KeyName": {"Ref" : "KeyName"},
        "PlacementGroupName": {"Fn::If" : ["UsePlacementGroup",{"Ref" : "PlacementGroup"},{"Ref" : "AWS::NoValue"}] },
        "NetworkInterfaces" : [{
          "GroupSet"                 : [{"Ref" : "dbxSG"}],
          "AssociatePublicIpAddress" : {"Ref" : "HeadPublicIpAddress"},
          "DeviceIndex"              : "0",
          "DeleteOnTermination"      : "true",
          "SubnetId"                 : {"Fn::If" : [ "CreateHeadPublicIP", {"Ref" : "PublicSubnet"}, {"Ref" : "PrivateSubnet"} ] },
          "PrivateIpAddress"         : {"Fn::If" : [ "CreateHeadPublicIP", "10.0.1.10", "10.0.0.10" ] }
        }],
        "Tags" : [
          { "Key" : "Name", "Value" : {"Fn::Join" : [ "-", [{ "Ref" : "AWS::StackName" }, "Head"] ] } },
          { "Key" : "Application", "Value" : { "Ref" : "AWS::StackId"} },
          { "Key" : "SGDependency" , "Value" : { "Ref" : "dbxSGIngress" } }
        ],
        "BlockDeviceMappings" : [
        {
          "DeviceName" : "/dev/sdn",
          "Ebs" : {
            "VolumeType" : "gp2",
            "DeleteOnTermination" : "true",
            "Encrypted" : {"Ref" : "EncryptVolumes"},
            "VolumeSize" : "128"
          }
        },
		{
          "DeviceName" : "/dev/sdo",
          "Ebs" : {
            "VolumeType" : "gp2",
            "DeleteOnTermination" : "true",
            "Encrypted" : {"Ref" : "EncryptVolumes"},
            "VolumeSize" : "128"
          }
        },
		{
          "DeviceName" : "/dev/sdp",
          "Ebs" : {
            "VolumeType" : "gp2",
            "DeleteOnTermination" : "true",
            "Encrypted" : {"Ref" : "EncryptVolumes"},
            "VolumeSize" : "128"
          }
        },
		{
          "DeviceName" : "/dev/sdq",
          "Ebs" : {
            "VolumeType" : "gp2",
            "DeleteOnTermination" : "true",
            "Encrypted" : {"Ref" : "EncryptVolumes"},
            "VolumeSize" : "128"
          }
        },
        {
          "DeviceName" : "/dev/sdr",
          "Ebs" : {
            "VolumeType" : "gp2",
            "DeleteOnTermination" : "true",
            "Encrypted" : {"Ref" : "EncryptVolumes"},
            "VolumeSize" : "128"
          }
        },
		{
          "DeviceName" : "/dev/sds",
          "Ebs" : {
            "VolumeType" : "gp2",
            "DeleteOnTermination" : "true",
            "Encrypted" : {"Ref" : "EncryptVolumes"},
            "VolumeSize" : "128"
          }
        },
		{
          "DeviceName" : "/dev/sdt",
          "Ebs" : {
            "VolumeType" : "gp2",
            "DeleteOnTermination" : "true",
            "Encrypted" : {"Ref" : "EncryptVolumes"},
            "VolumeSize" : "128"
          }
        },
		{
          "DeviceName" : "/dev/sdu",
          "Ebs" : {
            "VolumeType" : "gp2",
            "DeleteOnTermination" : "true",
            "Encrypted" : {"Ref" : "EncryptVolumes"},
            "VolumeSize" : "128"
          }
        }
        ]
      }
    }
  },



  "Conditions" : {
    "CreateHeadPublicIP" : {"Fn::Equals" : [{"Ref" : "HeadPublicIpAddress"}, "true"]},
    "UsePlacementGroup" : {"Fn::Equals" : [{"Ref" : "CreatePlacementGroup"}, "true"]}
  },



  "Outputs" : {
    "HeadPrivateIP" : {
      "Description" : "Head node private IP address",
      "Value" : {"Fn::GetAtt" : [ "dbXHeadInstance", "PrivateIp" ]}
    },
    "HeadPublicDNS" : {
      "Description" : "Head node public DNS name",
      "Value" : {"Fn::GetAtt" : [ "dbXHeadInstance", "PublicDnsName" ]},
      "Condition" : "CreateHeadPublicIP" 
    },
    "HeadPublicIP" : {
      "Description" : "Head node public IP address",
      "Value" : {"Fn::GetAtt" : [ "dbXHeadInstance", "PublicIp" ]},
      "Condition" : "CreateHeadPublicIP" 
    },
    "HeadPublicSSH" : {
      "Description" : "Head node public ssh login",
      "Value" : {"Fn::Join" : [ "", ["ec2-user@", {"Fn::GetAtt" : [ "dbXHeadInstance", "PublicIp" ]} ] ]},
      "Condition" : "CreateHeadPublicIP" 
    },
    "nLitePublicURL" : {
      "Description" : "nLite URL",
      "Value" : {"Fn::Join" : [ "", ["https://", {"Fn::GetAtt" : [ "dbXHeadInstance", "PublicIp" ]}, ":2443/f2md" ] ]},
      "Condition" : "CreateHeadPublicIP" 
    }
  }
}
