{

    "Description": "An example template which launches and bootstraps a cluster of eight CC2 EC2 instances for high performance computational tasks using spot pricing. Includes StarCluster, Grid Engine and NFS.",
    "AWSTemplateFormatVersion": "2010-09-09",
    "Parameters": {
        "AccountNumber": {
            "Description": "Twelve digit AWS account number.",
            "Type": "String",
            "NoEcho": "True"
        },
        "KeyName": {
            "Description": "Name of an existing EC2 Key Pair used to log into the StarCluster controller instance.",
            "Type": "String"
        },
        "ClusterSize": {
            "Description": "Number of instances to provision as compute nodes in the cluster.",
            "Type": "Number"
        },
        "InstanceType": {
            "Description": "Instance type to provision as compute nodes in the cluster.",
            "Type": "String"
        },
        "ClusterKeypair": {
            "Description": "Unique name of the new key pair StarCluster will use for cluster access.",
            "Type": "String"
        },
        "SpotPrice": {
            "Description": "Maximum spot price in USD (e.g.: 1.50).",
            "Type": "Number"
        },
        "SSHLocation" : {
    		"Description" : "The IP address range that can be used to SSH to the EC2 instances",
  		  	"Type": "String",
    		"MinLength": "9",
    		"MaxLength": "18",
    		"Default": "0.0.0.0/0",
    		"AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
    		"ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
   		}
    },
    "Mappings": {
        "AWSInstanceType2Arch": {
            "t1.micro": {
                "Arch": "64"
            },
            "m1.small": {
                "Arch": "64"
            },
            "m1.medium": {
                "Arch": "64"
            },
            "m1.large": {
                "Arch": "64"
            },
            "m1.xlarge": {
                "Arch": "64"
            },
            "m2.xlarge": {
                "Arch": "64"
            },
            "m2.2xlarge": {
                "Arch": "64"
            },
            "m2.4xlarge": {
                "Arch": "64"
            },
            "c1.medium": {
                "Arch": "64"
            },
            "c1.xlarge": {
                "Arch": "64"
            },
            "cc1.4xlarge": {
                "Arch": "64HVM"
            },
            "cc2.8xlarge": {
                "Arch": "64HVM"
            },
            "cg1.4xlarge": {
                "Arch": "64HVM"
            }
        },
        "AWSRegionArch2AMI": {
            "us-east-1": {
                "32": "ami-899d49e0",
                "64": "ami-999d49f0",
                "64HVM": "ami-4583572c"
            }
        }
    },
    "Resources": {
        "ClusterUser": {
            "Type": "AWS::IAM::User"
        },
        "ClusterGroup": {
            "Type": "AWS::IAM::Group"
        },
        "ClusterUsers": {
            "Type": "AWS::IAM::UserToGroupAddition",
            "Properties": {
                "GroupName": {
                    "Ref": "ClusterGroup"
                },
                "Users": [
                    {
                        "Ref": "ClusterUser"
                    }
                ]
            }
        },
        "CFNUserPolicies": {
            "Type": "AWS::IAM::Policy",
            "Properties": {
                "PolicyName": "ClusterUsers",
                "PolicyDocument": {
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": [
                                "ec2:*",
                                "s3:*",
                                "cloudformation:DescribeStackResource"
                            ],
                            "Resource": "*"
                        }
                    ]
                },
                "Groups": [
                    {
                        "Ref": "ClusterGroup"
                    }
                ]
            }
        },
        "ClusterUserKeys": {
            "Type": "AWS::IAM::AccessKey",
            "Properties": {
                "UserName": {
                    "Ref": "ClusterUser"
                }
            }
        },
        "Ec2Instance": {
            "Type": "AWS::EC2::Instance",
            "Properties": {
                "SecurityGroups": [
                    {
                        "Ref": "InstanceSecurityGroup"
                    }
                ],
                "InstanceType": "t1.micro",
                "ImageId": "ami-e565ba8c",
                "KeyName": {
                    "Ref": "KeyName"
                },
                "Tags": [
                    {
                        "Key": "Role",
                        "Value": "Controller"
                    }
                ],
                "UserData": {
                    "Fn::Base64": {
                        "Fn::Join": [
                            "",
                            [
                                "#!/bin/sh\n",
                                "/opt/aws/bin/cfn-init ",
                                " -s ",
                                {
                                    "Ref": "AWS::StackId"
                                },
                                " -r Ec2Instance ",
                                "\n",
                                "cd /usr/src/pycrypto/pycrypto-2.4; /usr/bin/python setup.py build\n",
                                "cd /usr/src/pycrypto/pycrypto-2.4; /usr/bin/python setup.py install\n",
                                "cd /home/ec2-user/starcluster; /usr/bin/python distribute_setup.py\n",
                                "cd /home/ec2-user/starcluster; /usr/bin/python setup.py install\n",
                                "/bin/mkdir /home/ec2-user/.starcluster\n",
                                "/bin/chown ec2-user:ec2-user -R /home/ec2-user/.starcluster\n",
                                "/usr/bin/ruby /home/ec2-user/parser.rb /home/ec2-user/cc2-spot-template.erb /home/ec2-user/values.yml > /home/ec2-user/.starcluster/config\n",
                                "/usr/bin/starcluster -c /home/ec2-user/.starcluster/config createkey ",
                                {
                                    "Ref": "ClusterKeypair"
                                },
                                " -o /home/ec2-user/.ssh/rsa-",
                                {
                                    "Ref": "ClusterKeypair"
                                },
                                "\n",
                                "/bin/chown ec2-user:ec2-user -R /home/ec2-user/.ssh/rsa-",
                                {
                                    "Ref": "ClusterKeypair"
                                },
                                "\n",
                                "cd /home/ec2-user/; /usr/bin/starcluster -c /home/ec2-user/.starcluster/config start -b ",
                                {
                                    "Ref": "SpotPrice"
                                },
                                " ec2-cluster\n"
                            ]
                        ]
                    }
                }
            },
            "Metadata": {
                "AWS::CloudFormation::Init": {
                    "config": {
                        "packages": {
                            "yum": {
                                "python-devel": [ ],
                                "gcc": [ ],
                                "make": [ ]
                            }
                        },
                        "sources": {
                            "/usr/src/pycrypto": "https://ftp.dlitz.net/pub/dlitz/crypto/pycrypto/pycrypto-2.4.tar.gz",
                            "/home/ec2-user/starcluster": "https://github.com/jtriley/StarCluster/tarball/master"
                        },
                        "files": {
                            "/home/ec2-user/parser.rb": {
                                "mode": "000644",
                                "owner": "ec2-user",
                                "group": "ec2-user",
                                "source": "http://cfn-cc.s3.amazonaws.com/parser.rb"
                            },
                            "/home/ec2-user/cc2-spot-template.erb": {
                                "mode": "000644",
                                "owner": "ec2-user",
                                "group": "ec2-user",
                                "source": "http://cfn-cc.s3.amazonaws.com/cc2-spot-template.erb"
                            },
                            "/home/ec2-user/values.yml": {
                                "mode": "000644",
                                "owner": "ec2-user",
                                "group": "ec2-user",
                                "content": {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "values:\n",
                                            " access_key_id: ",
                                            {
                                                "Ref": "ClusterUserKeys"
                                            },
                                            "\n",
                                            " secret_access_key: ",
                                            {
                                                "Fn::GetAtt": [
                                                    "ClusterUserKeys",
                                                    "SecretAccessKey"
                                                ]
                                            },
                                            "\n",
                                            " account_number: ",
                                            {
                                                "Ref": "AccountNumber"
                                            },
                                            "\n",
                                            " instance_type: ",
                                            {
                                                "Ref": "InstanceType"
                                            },
                                            "\n",
                                            " cluster_size: ",
                                            {
                                                "Ref": "ClusterSize"
                                            },
                                            "\n",
                                            " image_id: ",
                                            {
                                                "Fn::FindInMap": [
                                                    "AWSRegionArch2AMI",
                                                    {
                                                        "Ref": "AWS::Region"
                                                    },
                                                    {
                                                        "Fn::FindInMap": [
                                                            "AWSInstanceType2Arch",
                                                            {
                                                                "Ref": "InstanceType"
                                                            },
                                                            "Arch"
                                                        ]
                                                    }
                                                ]
                                            },
                                            "\n",
                                            " cluster_keypair: ",
                                            {
                                                "Ref": "ClusterKeypair"
                                            },
                                            "\n"
                                        ]
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "InstanceSecurityGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "Enable SSH access via port 22",
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "FromPort": "22",
                        "ToPort": "22",
                        "CidrIp": { "Ref" : "SSHLocation"}
                    }
                ]
            }
        }
    },
    "Outputs": {
        "InstancePublicDNS": {
            "Description": "Public DNS for the cluster controller instance",
            "Value": {
                "Fn::GetAtt": [
                    "Ec2Instance",
                    "PublicDnsName"
                ]
            }
        },
        "AvailabilityZone": {
            "Description": "The Availability Zone in which the newly created EC2 instance was launched",
            "Value": {
                "Fn::GetAtt": [
                    "Ec2Instance",
                    "AvailabilityZone"
                ]
            }
        }
    }

}