{ "AWSTemplateFormatVersion" : "2010-09-09", "Description" : "CloudFormation template to create a micro MapR cluster using Docker in a single AWS VM", "Parameters" : { "ClusterNodeType" : { "Type" : "String", "Default" : "m4.4xlarge", "Description" : "Instance Type for MapR Cluster nodes; select m3/m4 or i2 instance types for us-west-1 and sa-east-1", "AllowedValues" : [ "m4.2xlarge", "m4.4xlarge", "r3.2xlarge", "r3.4xlarge", "r4.2xlarge", "r4.4xlarge", "d2.2xlarge", "d2.4xlarge", "d2.8xlarge", "i2.xlarge", "i2.2xlarge" ] , "ConstraintDescription" : "Must be a valid EC2 instance type." }, "InstanceSpotPrice": { "Type": "String", "Default" : "0.00", "Description": "Spot Price to bid for requested instances (0.00 will result in using on-demand instances)", "AllowedPattern" : "([0-9]{1}[.]{1}[0-9]{2})", "ConstraintDescription" : "Must be decimal numeric value" }, "PersistentStorage": { "Type": "Number", "Default": "5", "Description" : "Allocated EBS storage for each block device (in GB; 5 drives)", "MinValue": "2", "MaxValue": "8", "ConstraintDescription" : "No more than 10 GB per device." }, "KeyName": { "Type": "AWS::EC2::KeyPair::KeyName", "Description": "Name of an existing EC2 KeyPair within the AWS account; all instances will launch with this KeyPair", "MinLength": "1" }, "MapRVersion" : { "Type" : "String", "Default" : "5.2.0", "Description" : "MapR Converge Data Platform version 5.2.0, MEP-1.1", "AllowedValues" : [ "5.2.0" ], "ConstraintDescription" : "Supported versions of MapR within AWS Marketplace" }, "VpcSubnetId" : { "Type" : "String", "Default" : "subnet-00000000", "Description" : "VPC Subnet for cluster deployment; specifying subnet-00000000 will result in new VPC being created", "AllowedPattern" : "subnet-(\\w{8})", "ConstraintDescription" : "must be a valid AWS subnet (subnet-xxxxxxx}" }, "RemoteAccessCIDR" : { "Type" : "String", "Default" : "0.0.0.0/0", "Description" : "For newly created VPC's, allow inbound network traffic from this address range (0.0.0.0/0 will allow all)", "MinLength": "9", "MaxLength": "18", "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" } }, "Mappings" : { "MapRVersion2Vindex" : { "5.2.0" : { "Vindex" : "520" } }, "AWSRegionVindex2AMI" : { "us-east-1" : { "520" : "ami-7a8f986d" }, "us-west-2" : { "520" : "ami-0d73c46d" }, "eu-central-1" : { "520" : "ami-947bbbfb" }, "eu-west-1" : { "520" : "ami-03173470" }, "ap-southeast-2" : { "520" : "ami-358bb056" }, "ap-northeast-1" : { "520" : "ami-561a7031" } }, "SubnetConfig" : { "VPC" : { "CIDR" : "10.9.0.0/16" }, "Public" : { "CIDR" : "10.9.1.0/24" }, "MySQLDB" : { "CIDR" : "10.9.2.0/24" } } }, "Conditions" : { "EnableWaitConditions" : { "Fn::Equals" : [ "1" , "1" ] }, "EphemeralStorage" : { "Fn::Equals" : [ { "Ref" : "PersistentStorage" } , "0" ] }, "OnDemandInstances" : { "Fn::Equals" : [ { "Ref" : "InstanceSpotPrice" } , "0.00" ] }, "NewPrivateVPC" : { "Fn::Equals" : [ { "Ref" : "VpcSubnetId" } , "subnet-00000000" ] } }, "Resources" : { "VPC" : { "Type" : "AWS::EC2::VPC", "Condition" : "NewPrivateVPC", "Properties" : { "CidrBlock" : { "Fn::FindInMap" : [ "SubnetConfig", "VPC", "CIDR" ]}, "EnableDnsHostnames" : "true", "EnableDnsSupport" : "true", "Tags" : [ {"Key" : "Application", "Value" : "MapR Marketplace Deploymnent" } ] } }, "InternetGateway" : { "Type" : "AWS::EC2::InternetGateway", "Condition" : "NewPrivateVPC" }, "AttachGateway" : { "Type" : "AWS::EC2::VPCGatewayAttachment", "Condition" : "NewPrivateVPC", "Properties" : { "VpcId" : { "Ref" : "VPC" }, "InternetGatewayId" : { "Ref" : "InternetGateway" } } }, "PublicSubnet" : { "Type" : "AWS::EC2::Subnet", "Condition" : "NewPrivateVPC", "Properties" : { "VpcId" : { "Ref" : "VPC" }, "CidrBlock" : { "Fn::FindInMap" : [ "SubnetConfig", "Public", "CIDR" ]}, "Tags" : [ {"Key" : "Application", "Value" : "MapR" }, {"Key" : "Network", "Value" : "Public" } ] } }, "PublicRouteTable" : { "Type" : "AWS::EC2::RouteTable", "Condition" : "NewPrivateVPC", "Properties" : { "VpcId" : { "Ref" : "VPC" } } }, "PublicRoute" : { "Type" : "AWS::EC2::Route", "Condition" : "NewPrivateVPC", "DependsOn" : "AttachGateway", "Properties" : { "RouteTableId" : { "Ref" : "PublicRouteTable" }, "DestinationCidrBlock" : "0.0.0.0/0", "GatewayId" : { "Ref" : "InternetGateway" } } }, "PublicSubnetRouteTableAssociation" : { "Type" : "AWS::EC2::SubnetRouteTableAssociation", "Condition" : "NewPrivateVPC", "Properties" : { "SubnetId" : { "Ref" : "PublicSubnet" }, "RouteTableId" : { "Ref" : "PublicRouteTable" } } }, "DefaultSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Condition" : "NewPrivateVPC", "Properties" : { "GroupDescription" : "Default Security group for all the Nodes", "VpcId" : {"Ref" : "VPC"}, "SecurityGroupIngress" : [ { "IpProtocol" : "icmp", "FromPort" : "-1", "ToPort" : "-1", "CidrIp" : { "Fn::FindInMap" : [ "SubnetConfig", "VPC", "CIDR" ]} }, { "IpProtocol" : "tcp", "FromPort" : "0", "ToPort" : "65535", "CidrIp" : { "Fn::FindInMap" : [ "SubnetConfig", "VPC", "CIDR" ]} }, { "IpProtocol" : "udp", "FromPort" : "0", "ToPort" : "65535", "CidrIp" : { "Fn::FindInMap" : [ "SubnetConfig", "VPC", "CIDR" ]} }, { "IpProtocol" : "tcp", "FromPort" : "8443", "ToPort" : "8443", "CidrIp" : { "Ref" : "RemoteAccessCIDR" } }, { "IpProtocol" : "tcp", "FromPort" : "8088", "ToPort" : "8088", "CidrIp" : { "Ref" : "RemoteAccessCIDR" } }, { "IpProtocol" : "tcp", "FromPort" : "8042", "ToPort" : "8042", "CidrIp" : { "Ref" : "RemoteAccessCIDR" } }, { "IpProtocol" : "tcp", "FromPort" : "19888", "ToPort" : "19888", "CidrIp" : { "Ref" : "RemoteAccessCIDR" } }, { "IpProtocol" : "tcp", "FromPort" : "8047", "ToPort" : "8047", "CidrIp" : { "Ref" : "RemoteAccessCIDR" } }, { "IpProtocol" : "tcp", "FromPort" : "31010", "ToPort" : "31010", "CidrIp" : { "Ref" : "RemoteAccessCIDR" } }, { "IpProtocol" : "tcp", "FromPort" : "10000", "ToPort" : "10000", "CidrIp" : { "Ref" : "RemoteAccessCIDR" } }, { "IpProtocol" : "tcp", "FromPort" : "9443", "ToPort" : "9443", "CidrIp" : { "Ref" : "RemoteAccessCIDR" } }, { "IpProtocol" : "tcp", "FromPort" : "2049", "ToPort" : "2049", "CidrIp" : { "Ref" : "RemoteAccessCIDR" } }, { "IpProtocol" : "tcp", "FromPort" : "111", "ToPort" : "111", "CidrIp" : { "Ref" : "RemoteAccessCIDR" } }, { "IpProtocol" : "udp", "FromPort" : "111", "ToPort" : "111", "CidrIp" : { "Ref" : "RemoteAccessCIDR" } }, { "IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "RemoteAccessCIDR" } } ] } }, "InstanceIAMRole": { "Properties": { "AssumeRolePolicyDocument": { "Statement": [{ "Action": [ "sts:AssumeRole" ], "Effect": "Allow", "Principal": { "Service": [ "ec2.amazonaws.com" ] } }], "Version": "2012-10-17" }, "Path": "/", "Policies": [{ "PolicyDocument": { "Statement": [{ "Action": [ "ec2:CreateTags", "ec2:DescribeInstances", "cloudformation:DescribeStackResources", "s3:Get*" , "s3:List*" ], "Effect": "Allow", "Resource": "*" }] }, "PolicyName": "DescribeAccessEC2andCFN" }] }, "Type": "AWS::IAM::Role" }, "InstanceProfile": { "Properties": { "Path": "/", "Roles": [{ "Ref": "InstanceIAMRole" } ] }, "Type": "AWS::IAM::InstanceProfile" }, "ClusterCompleteHandle" : { "Type" : "AWS::CloudFormation::WaitConditionHandle" }, "ClusterCompleteCondition" : { "Type" : "AWS::CloudFormation::WaitCondition", "DependsOn" : "ClusterNodes", "Properties" : { "Handle" : { "Ref" : "ClusterCompleteHandle" }, "Timeout" : "600", "Count" : "1" } }, "ClusterNodes" : { "Type" : "AWS::AutoScaling::AutoScalingGroup", "Properties" : { "VPCZoneIdentifier" : [ { "Fn::If" : [ "NewPrivateVPC", { "Ref" : "PublicSubnet" }, {"Ref" : "VpcSubnetId"} ] } ], "LaunchConfigurationName" : { "Ref" : "ClusterNodeLaunchConfig" }, "MinSize" : 1, "MaxSize" : 1, "DesiredCapacity" : 1 }, "CreationPolicy": { "ResourceSignal": { "Count": "1", "Timeout": "PT90M" } } }, "ClusterNodeLaunchConfig" : { "Type" : "AWS::AutoScaling::LaunchConfiguration", "Properties" : { "BlockDeviceMappings" : {"Fn::If" : ["EphemeralStorage",[ { "DeviceName" : "/dev/sdb", "VirtualName": "ephemeral0" }, { "DeviceName" : "/dev/sdc", "VirtualName": "ephemeral1" }, { "DeviceName" : "/dev/sdd", "VirtualName": "ephemeral2" }, { "DeviceName" : "/dev/sde", "VirtualName": "ephemeral3" }, { "DeviceName" : "/dev/sdf", "VirtualName": "ephemeral4" }, { "DeviceName" : "/dev/sdg", "VirtualName": "ephemeral5" }, { "DeviceName" : "/dev/sdh", "VirtualName": "ephemeral6" }, { "DeviceName" : "/dev/sdi", "VirtualName": "ephemeral7" }, { "DeviceName" : "/dev/sdj", "VirtualName": "ephemeral8" }, { "DeviceName" : "/dev/sdk", "VirtualName": "ephemeral9" }, { "DeviceName" : "/dev/sdl", "VirtualName": "ephemeral10" }, { "DeviceName" : "/dev/sdm", "VirtualName": "ephemeral11" } ],[ { "DeviceName" : "/dev/xvdb", "Ebs" : { "VolumeSize" : {"Ref" : "PersistentStorage"}, "DeleteOnTermination" : "True" } }, { "DeviceName" : "/dev/xvdc", "Ebs" : { "VolumeSize" : {"Ref" : "PersistentStorage"}, "DeleteOnTermination" : "True" } }, { "DeviceName" : "/dev/xvdd", "Ebs" : { "VolumeSize" : {"Ref" : "PersistentStorage"}, "DeleteOnTermination" : "True" } }, { "DeviceName" : "/dev/xvde", "Ebs" : { "VolumeSize" : {"Ref" : "PersistentStorage"}, "DeleteOnTermination" : "True" } }, { "DeviceName" : "/dev/xvdf", "Ebs" : { "VolumeSize" : {"Ref" : "PersistentStorage"}, "DeleteOnTermination" : "True" } } ]]}, "ImageId" : { "Fn::FindInMap" : [ "AWSRegionVindex2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "MapRVersion2Vindex", { "Ref" : "MapRVersion" }, "Vindex" ] } ] }, "SecurityGroups" : [ { "Fn::If" : [ "NewPrivateVPC", { "Ref" : "DefaultSecurityGroup" }, {"Ref" : "AWS::NoValue"} ] } ] , "InstanceType" : { "Ref" : "ClusterNodeType" }, "SpotPrice" : { "Fn::If" : [ "OnDemandInstances", {"Ref" : "AWS::NoValue"}, { "Ref" : "InstanceSpotPrice" } ] }, "KeyName" : { "Ref" : "KeyName" }, "AssociatePublicIpAddress" : "true", "IamInstanceProfile" : { "Ref" : "InstanceProfile" }, "UserData": { "Fn::Base64": { "Fn::Join": ["",[ "#!/bin/bash\n", "\n", "## Signal that the node is up\n", "/opt/aws/bin/cfn-signal -e 0 --stack ", {"Ref":"AWS::StackName"}, " --region ", {"Ref": "AWS::Region"}, " --resource ClusterNodes\n", "\n", "## Tag the instance (now that we're sure of launch index\n", "instance_id=$(curl -f http://169.254.169.254/latest/meta-data/instance-id)\n", "if [ -n \"$instance_id\" ] ; then\n", " instance_tag=mapr520_docker\n", " aws ec2 create-tags", " --region ", {"Ref": "AWS::Region"}, " --resources $instance_id --tags Key=Name,Value=$instance_tag\n", "fi\n", "## If all went well, signal success (must be done by ALL nodes)\n", "/opt/aws/bin/cfn-signal -e 0 -r 'MapR Installation complete' '", { "Ref" : "ClusterCompleteHandle" }, "'\n", "\n", "## Wait for all nodes to issue the signal\n", "resourceStatus=$(aws cloudformation describe-stack-resources ", "--region ", {"Ref": "AWS::Region"}, " ", "--stack-name ", {"Ref":"AWS::StackName"}, " --logical-resource-id ClusterCompleteCondition ", "--query StackResources[].ResourceStatus --output text )\n", "while [ \"$resourceStatus\" != \"CREATE_COMPLETE\" ]\n", "do\n", " sleep 10\n", " resourceStatus=$(aws cloudformation describe-stack-resources ", "--region ", {"Ref": "AWS::Region"}, " ", "--stack-name ", {"Ref":"AWS::StackName"}, " --logical-resource-id ClusterCompleteCondition ", "--query StackResources[].ResourceStatus --output text )\n", "done\n", "\n" ]]} } } } }, }