{ "Description": "Launch an Alces HPC environment with a single SGE master node together with compute nodes using EC2 spot.", "Parameters": { "KeyPair": { "Description": "Choose an existing AWS key for administrator access", "Type": "AWS::EC2::KeyPair::KeyName" }, "ComputeNumber": { "Description": "Enter the number of compute nodes you wish to deploy", "Type": "String", "AllowedPattern": "[0-9]", "Default": "3" }, "SubnetId": { "Description": "Enter the ID of your existing subnet. If you wish to have one created for you, select None. The SecurityGroup field must also be set to None.", "Type": "String", "Default": "None" }, "SecurityGroup": { "Description": "Enter the ID of your existing security group. If you wish to have one created for you, select None. The Subnet ID field must also be set to None.", "Type": "String", "Default": "None" }, "InstanceFlavour": { "Description": "Select the compute node instance flavour", "Type": "String", "Default": "small", "AllowedValues": [ "small", "large" ] }, "SpotPrice": { "Description": "Enter your maximum bid per hour for each compute instance. View the Spot Request calculator for information on spot pricing.", "Type": "String", "Default": "0.50" }, "NetworkCIDR": { "Description": "Enter an address range that is permitted to access the Clusterware master node. Leave blank if unknown", "Type": "String", "Default": "0.0.0.0/0", "AllowedPattern": "[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/[0-9]{1,2}", "ConstraintDescription": "Please specify a valid IP range, e.g. 101.21.2.0/16" } }, "Mappings": { "InstanceType2Flavour": { "small": { "instanceflavour": "c4.large" }, "large": { "instanceflavour": "c4.4xlarge" } }, "AWSRegionArch2AMI": { "eu-west-1": { "centos7": "ami-3758e244" } } }, "Conditions": { "CreateNetwork": { "Fn::Equals": [ { "Ref": "SubnetId" }, "None" ] } }, "Resources": { "ClusterwareVPC": { "Type": "AWS::EC2::VPC", "Properties": { "Tags": [ { "Key": "Name", "Value": { "Ref": "AWS::StackName" } } ], "CidrBlock": "10.75.0.0/16", "EnableDnsSupport": "true", "EnableDnsHostnames": "true" }, "Condition": "CreateNetwork" }, "ClusterwareRouteTable": { "Type": "AWS::EC2::RouteTable", "DependsOn": "ClusterwareVPC", "Properties": { "VpcId": { "Ref": "ClusterwareVPC" }, "Tags": [ { "Key": "Application", "Value": { "Ref": "AWS::StackId" } } ] }, "Condition": "CreateNetwork" }, "ClusterwarePublicNet": { "Type": "AWS::EC2::Subnet", "Properties": { "VpcId": { "Ref": "ClusterwareVPC" }, "CidrBlock": "10.75.0.0/24" }, "Condition": "CreateNetwork" }, "ClusterwareGateway": { "Type": "AWS::EC2::InternetGateway", "DependsOn": "ClusterwareVPC", "Condition": "CreateNetwork" }, "ClusterwareAttachGW": { "Type": "AWS::EC2::VPCGatewayAttachment", "DependsOn": "ClusterwareVPC", "Properties": { "VpcId": { "Ref": "ClusterwareVPC" }, "InternetGatewayId": { "Ref": "ClusterwareGateway" } }, "Condition": "CreateNetwork" }, "ClusterwareRoute": { "Type": "AWS::EC2::Route", "DependsOn": "ClusterwareAttachGW", "Properties": { "RouteTableId": { "Ref": "ClusterwareRouteTable" }, "DestinationCidrBlock": "0.0.0.0/0", "GatewayId": { "Ref": "ClusterwareGateway" } }, "Condition": "CreateNetwork" }, "SubnetToRouteTable": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "DependsOn": "ClusterwareRouteTable", "Properties": { "SubnetId": { "Ref": "ClusterwarePublicNet" }, "RouteTableId": { "Ref": "ClusterwareRouteTable" } }, "Condition": "CreateNetwork" }, "AlcesClusterwareSecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "Tags": [ { "Key": "Name", "Value": { "Ref": "AWS::StackName" } } ], "GroupDescription": "Open communication between cluster hosts", "VpcId": { "Ref": "ClusterwareVPC" }, "SecurityGroupIngress": [ { "IpProtocol": "-1", "FromPort": "0", "ToPort": "65535", "CidrIp": "10.75.0.0/24" }, { "IpProtocol": "6", "FromPort": "5900", "ToPort": "5920", "CidrIp": { "Ref": "NetworkCIDR" } }, { "IpProtocol": "6", "FromPort": "22", "ToPort": "22", "CidrIp": { "Ref": "NetworkCIDR" } } ], "SecurityGroupEgress": [ { "IpProtocol": "-1", "FromPort": "0", "ToPort": "65535", "CidrIp": "0.0.0.0/0" } ] }, "Condition": "CreateNetwork" }, "AlcesClusterwareMasterNode": { "Type": "AWS::EC2::Instance", "Properties": { "Tags": [ { "Key": "Name", "Value": "Alces Clusterware Master" } ], "ImageId": { "Fn::FindInMap": [ "AWSRegionArch2AMI", { "Ref": "AWS::Region" }, "centos7" ] }, "NetworkInterfaces": [ { "AssociatePublicIpAddress": "True", "DeviceIndex": "0", "GroupSet": [ { "Fn::If": [ "CreateNetwork", { "Ref": "AlcesClusterwareSecurityGroup" }, { "Ref": "SecurityGroup" } ] } ], "SubnetId": { "Fn::If": [ "CreateNetwork", { "Ref": "ClusterwarePublicNet" }, { "Ref": "SubnetId" } ] } } ], "BlockDeviceMappings": [ { "DeviceName": "/dev/sda1", "Ebs": { "VolumeSize": "500" } } ], "InstanceType": { "Fn::FindInMap": [ "InstanceType2Flavour", { "Ref": "InstanceFlavour" }, "instanceflavour" ] }, "KeyName": { "Ref": "KeyPair" }, "UserData": { "Fn::Base64": { "Fn::Join": [ "", [ "#cloud-config", "\n", "hostname: login1", "\n", "write_files:", "\n", "- content: |", "\n", " cluster:", "\n", " uuid: '11111111-2222-3333-444444444444'", "\n", " token: '1A0a1aaAA1aAAA/aaa1aAA=='", "\n", " name: ", { "Ref": "AWS::StackName" }, "\n", " role: 'master'", "\n", " tags:", "\n", " scheduler_roles: ':master:'", "\n", " owner: root:root", "\n", " path: /opt/clusterware/etc/config.yml", "\n", " permissions: '0640'", "\n" ] ] } } } }, "ComputeConfig": { "Type": "AWS::AutoScaling::LaunchConfiguration", "Properties": { "AssociatePublicIpAddress": "True", "KeyName": { "Ref": "KeyPair" }, "ImageId": { "Fn::FindInMap": [ "AWSRegionArch2AMI", { "Ref": "AWS::Region" }, "centos7" ] }, "InstanceType": { "Fn::FindInMap": [ "InstanceType2Flavour", { "Ref": "InstanceFlavour" }, "instanceflavour" ] }, "BlockDeviceMappings": [ { "DeviceName": "/dev/sda1", "Ebs": { "VolumeSize": "500" } } ], "SpotPrice": { "Ref": "SpotPrice" }, "SecurityGroups": [ { "Fn::If": [ "CreateNetwork", { "Ref": "AlcesClusterwareSecurityGroup" }, { "Ref": "SecurityGroup" } ] } ], "UserData": { "Fn::Base64": { "Fn::Join": [ "", [ "#cloud-config", "\n", "write_files:", "\n", "- content: |", "\n", " cluster:", "\n", " uuid: '11111111-2222-3333-444444444444'", "\n", " token: '1A0a1aaAA1aAAA/aaa1aAA=='", "\n", " name: ", { "Ref": "AWS::StackName" }, "\n", " role: 'slave'", "\n", " master: ", { "Fn::GetAtt": [ "AlcesClusterwareMasterNode", "PrivateIp" ] }, "\n", " tags:", "\n", " scheduler_roles: ':compute:'", "\n", " quorum: 3", "\n", " owner: root:root", "\n", " path: /opt/clusterware/etc/config.yml", "\n", " permissions: '0640'", "\n" ] ] } } } }, "ComputeGroup": { "Type": "AWS::AutoScaling::AutoScalingGroup", "DependsOn": "AlcesClusterwareMasterNode", "Properties": { "DesiredCapacity": { "Ref": "ComputeNumber" }, "LaunchConfigurationName": { "Ref": "ComputeConfig" }, "MinSize": "1", "MaxSize": "100", "VPCZoneIdentifier": [ { "Fn::If": [ "CreateNetwork", { "Ref": "ClusterwarePublicNet" }, { "Ref": "SubnetId" } ] } ] } }, "ScaleUp": { "Type": "AWS::AutoScaling::ScalingPolicy", "Properties": { "AdjustmentType": "ChangeInCapacity", "AutoScalingGroupName": { "Ref": "ComputeGroup" }, "Cooldown": "3300", "ScalingAdjustment": "1" } }, "ScaleDown": { "Type": "AWS::AutoScaling::ScalingPolicy", "Properties": { "AdjustmentType": "ChangeInCapacity", "AutoScalingGroupName": { "Ref": "ComputeGroup" }, "Cooldown": "3300", "ScalingAdjustment": "-1" } }, "CPUAlarmHigh": { "Type": "AWS::CloudWatch::Alarm", "Properties": { "AlarmDescription": "Scale-up if CPU > 90% for 20 minutes", "MetricName": "CPUUtilization", "Namespace": "AWS/EC2", "Statistic": "Average", "Period": "60", "EvaluationPeriods": "20", "Threshold": "90", "AlarmActions": [ { "Ref": "ScaleUp" } ], "Dimensions": [ { "Name": "AutoScalingGroupName", "Value": { "Ref": "ComputeGroup" } } ], "ComparisonOperator": "GreaterThanThreshold" } }, "CPUAlarmLow": { "Type": "AWS::CloudWatch::Alarm", "Properties": { "AlarmDescription": "Scale-down if CPU < 10% for 55 minutes", "MetricName": "CPUUtilization", "Namespace": "AWS/EC2", "Statistic": "Average", "Period": "60", "EvaluationPeriods": "55", "Threshold": "10", "AlarmActions": [ { "Ref": "ScaleDown" } ], "Dimensions": [ { "Name": "AutoScalingGroupName", "Value": { "Ref": "ComputeGroup" } } ], "ComparisonOperator": "LessThanThreshold" } } }, "Outputs": { "AccessIP": { "Value": { "Fn::GetAtt": [ "AlcesClusterwareMasterNode", "PublicIp" ] } } } }