Пример #1
0
    def add_resources(self):
        self.scaleout_policy = self.template.add_resource(
            ScalingPolicy(
                "RunnerScaleoutPolicy",
                AdjustmentType="ChangeInCapacity",
                AutoScalingGroupName=Ref(self.runner_autoscaling_group),
                Cooldown=Ref(self.runner_scaleout_cooldown),
                ScalingAdjustment="1",
            ))

        self.runner_cpu_alarm_high = self.template.add_resource(
            Alarm(
                "RunnerCPUAlarmHigh",
                EvaluationPeriods="1",
                Statistic="Average",
                Threshold=Ref(self.runner_scaleout_threshold),
                AlarmDescription="Alarm if CPU utilization too high",
                Period="60",
                AlarmActions=[Ref(self.scaleout_policy)],
                Namespace="AWS/EC2",
                Dimensions=[
                    MetricDimension(
                        Name="AutoScalingGroupName",
                        Value=Ref(self.runner_autoscaling_group),
                    )
                ],
                ComparisonOperator="GreaterThanThreshold",
                MetricName="CPUUtilization",
            ))

        self.scalein_policy = self.template.add_resource(
            ScalingPolicy(
                "RunnerScaleinPolicy",
                AdjustmentType="ChangeInCapacity",
                AutoScalingGroupName=Ref(self.runner_autoscaling_group),
                Cooldown=Ref(self.runner_scalein_cooldown),
                ScalingAdjustment="-1",
            ))

        self.runner_cpu_alarm_low = self.template.add_resource(
            Alarm(
                "RunnerCPUAlarmLow",
                EvaluationPeriods="1",
                Statistic="Average",
                Threshold=Ref(self.runner_scalein_threshold),
                AlarmDescription="Alarm if CPU utilization too low",
                Period="60",
                AlarmActions=[Ref(self.scalein_policy)],
                Namespace="AWS/EC2",
                Dimensions=[
                    MetricDimension(
                        Name="AutoScalingGroupName",
                        Value=Ref(self.runner_autoscaling_group),
                    )
                ],
                ComparisonOperator="LessThanThreshold",
                MetricName="CPUUtilization",
            ))
Пример #2
0
    def create_autoscaling_policies(self):
        t = self.template
        asg_name = "%sASG" % self.name
        ScaleUpPolicy = t.add_resource(ScalingPolicy(
            "ScaleUpPolicy",
            AdjustmentType="ChangeInCapacity",
            AutoScalingGroupName=Ref(asg_name),
            Cooldown="5",
            ScalingAdjustment="1",
        ))

        CPUAlarmHigh = t.add_resource(Alarm(
            "CPUAlarmHigh",
            EvaluationPeriods="10",
            Statistic="Average",
            Threshold="50",
            AlarmDescription="Alarm if CPU too high or metric disappears indicating instance is down",
            Period="60",
            AlarmActions=[Ref(ScaleUpPolicy)],
            Namespace="AWS/EC2",
            Dimensions=[
                MetricDimension(Name="AutoScalingGroupName", Value=Ref(asg_name))],
            ComparisonOperator="GreaterThanThreshold",
            MetricName="CPUUtilization",
        ))

        ScaleDownPolicy = t.add_resource(ScalingPolicy(
            "ScaleDownPolicy",
            AdjustmentType="ChangeInCapacity",
            AutoScalingGroupName=Ref(asg_name),
            Cooldown="5",
            ScalingAdjustment="-1",
        ))

        CPUAlarmLow = t.add_resource(Alarm(
            "CPUAlarmLow",
            EvaluationPeriods="10",
            Statistic="Average",
            Threshold="10",
            AlarmDescription="Alarm if CPU is not high anymore, scale down instances",
            Period="60",
            AlarmActions=[Ref(ScaleDownPolicy)],
            Namespace="AWS/EC2",
            Dimensions=[
                MetricDimension(Name="AutoScalingGroupName", Value=Ref(asg_name))],
            ComparisonOperator="LessThanThreshold",
            MetricName="CPUUtilization",
        ))
Пример #3
0
 def _scaling_policy(self):
     return ScalingPolicy(
         "duy%sScalingPolicy" % self.config['env'],
         AdjustmentType="ExactCapacity",
         PolicyType="SimpleScaling",
         Cooldown="60",
         AutoScalingGroupName=Ref(self.auto_scaling_group),
         ScalingAdjustment="1",
     )
Пример #4
0
    def create_simple_scaling_policy(self, scaling_policy_config):
        """
        Simple scaling policy based upon ec2 metrics

        heavy-load
        cpu > 45 for 1 period of 300 seconds add two instances, 45 second cooldown

        light-load
        cpu <= 15 for 6 periods of 300 seconds remove one instance, 120 second cooldown

        medium-load
        cpu >= 25 for 1 period of 300 seconds add one instance, 45 second cooldown

        [name]
        [metric_name] [comparison_operator] [threshold] [evaluation_periods] [period] [scaling_adjustment] [cooldown]

        https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cw-alarm.html
        https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-policy.html
        :param scaling_policy_config: simple scaling policy config object
        """

        cf_name = self.trop_asg.title + get_cf_friendly_name(scaling_policy_config.name)

        scaling_policy = self.template.add_resource(ScalingPolicy(
            title=cf_name + 'Sp',
            AdjustmentType='ChangeInCapacity',
            AutoScalingGroupName=Ref(self.trop_asg),
            Cooldown=scaling_policy_config.cooldown,
            ScalingAdjustment=scaling_policy_config.scaling_adjustment,
        ))

        self.scaling_polices.append(scaling_policy)

        self.cw_alarms.append(self.template.add_resource(Alarm(
            title=cf_name + 'Cwa',
            AlarmActions=[Ref(scaling_policy), self.network_config.sns_topic],
            AlarmDescription=scaling_policy_config.description,
            AlarmName=cf_name,
            ComparisonOperator=scaling_policy_config.comparison_operator,
            Dimensions=[MetricDimension(
                Name='AutoScalingGroupName',
                Value=Ref(self.trop_asg)
            )],
            EvaluationPeriods=scaling_policy_config.evaluation_periods,
            MetricName=scaling_policy_config.metric_name,
            Namespace='AWS/EC2',
            Period=scaling_policy_config.period,
            Statistic='Average',
            Threshold=scaling_policy_config.threshold,
            OKActions=[self.network_config.sns_topic]
        )))
 def add_scaling_policy(self, title, cd_number, adjustment):
     '''
     Add autoscaling policy
     '''
     self.cfn_template.add_resource(
         ScalingPolicy(
             title=title,
             AdjustmentType='ChangeInCapacity',
             AutoScalingGroupName=Ref(constants.INST_ASG),
             Cooldown=cd_number,
             ScalingAdjustment=adjustment
         )
     )
     return self.cfn_template
        MinSize=0,
        MaxSize=Ref(max_instances),
        VPCZoneIdentifier=[Ref(subnet) for subnet in get_public_subnets()],
        HealthCheckType="EC2",
        Tags=Tags(Maturity=environment.maturity,
                  Project="hyp3-in-a-box",
                  StackName=Ref('AWS::StackName'),
                  Name="HyP3-Worker")))

target_tracking_scaling_policy = t.add_resource(
    ScalingPolicy(
        "HyP3ScaleByBackloggedMessages",
        AutoScalingGroupName=Ref(processing_group),
        PolicyType="TargetTrackingScaling",
        TargetTrackingConfiguration=TargetTrackingConfiguration(
            CustomizedMetricSpecification=CustomizedMetricSpecification(
                MetricName=custom_metric_name,
                Namespace=Ref('AWS::StackName'),
                Statistic="Average"),
            DisableScaleIn=True,
            TargetValue=1.0  # Keep a ratio of 1 message per instance
        )))

terminate_instance = t.add_resource(
    PolicyType(
        "HyP3InstanceTerminateSelf",
        PolicyName="TerminateSelf",
        PolicyDocument=Policy(Statement=[
            Statement(Effect=Allow,
                      Action=[TerminateInstanceInAutoScalingGroup],
                      Resource=[
                          Join(":", [
Пример #7
0
                                                 "ELBName"),
                     AvailabilityZones=availability_zones,
                     LaunchConfigurationName=Ref(launchconfig_resource),
                     VPCZoneIdentifier=FindInMap("RegionMap",
                                                 {"Ref": "AWS::Region"},
                                                 "SNETid"),
                     Tags=[
                         Tag("Name", "MyInstance", True),
                         Tag("Project", "MyProject", True),
                         Tag("Team", "MyTeam", True)
                     ]))

autoscaling_up_resource = t.add_resource(
    ScalingPolicy("myScalingUp",
                  AdjustmentType="ChangeInCapacity",
                  ScalingAdjustment="1",
                  Cooldown="300",
                  AutoScalingGroupName=Ref(autoscaling_group_resource)))

autoscaling_down_resource = t.add_resource(
    ScalingPolicy("myScalingDown",
                  AdjustmentType="ChangeInCapacity",
                  ScalingAdjustment="-1",
                  Cooldown="300",
                  AutoScalingGroupName=Ref(autoscaling_group_resource)))

# Printing json template
filename = inspect.getfile(inspect.currentframe(0))
t_json = t.to_json()
file = open('./' + filename + '.json', 'w')
file.write(t_json)
Пример #8
0
            ),
            AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                PauseTime="PT5M",
                MinInstancesInService="1",
                MaxBatchSize="1",
                WaitOnResourceSignals=True,
            ),
        ),
    )
)

ScalePolicy = t.add_resource(
    ScalingPolicy(
        "HTTPRequestScalingPolicy",
        AdjustmentType="ChangeInCapacity",
        AutoScalingGroupName=Ref(AutoscalingGroup),
        Cooldown="1",
        ScalingAdjustment="1",
    )
)

HTTPRequestAlarm = t.add_resource(
    Alarm(
        "HTTPRequestAlarm",
        AlarmDescription="Alarm if HTTP Requests go above a 2000",
        Namespace="AWS/SQS",
        MetricName="RequestCount",
        Dimensions=[
            MetricDimension(Name="LoadBalancerName", Value=Ref(LoadBalancerResource)),
        ],
        Statistic="Sum",
Пример #9
0
        AlarmActions=[Ref(SnsTopic),
                      Ref("CraftScaleDownPolicy")],
        AlarmDescription="Signal alarm if CPU utilization is below threshold",
        Namespace="AWS/EC2",
        Period="120",
        ComparisonOperator="LessThanOrEqualToThreshold",
        Statistic="Average",
        Threshold="40",
        MetricName="CPUUtilization",
    ))

CraftScaleUpPolicy = t.add_resource(
    ScalingPolicy(
        "CraftScaleUpPolicy",
        ScalingAdjustment="1",
        AutoScalingGroupName=Ref(CraftAsg),
        Cooldown=300,
        AdjustmentType="ChangeInCapacity",
    ))

CraftRootDiskWriteOps = t.add_resource(
    Alarm(
        "CraftRootDiskWriteOps",
        EvaluationPeriods="1",
        Dimensions=[{
            "Name": "AutoScalingGroupName",
            "Value": Ref(CraftAsg)
        }],
        AlarmActions=[Ref(SnsTopic)],
        AlarmDescription="Send alert if DiskWriteOps is greater than ~90%",
        Namespace="AWS/EC2",
Пример #10
0
))

CloudWatchEC2CPUAlarm = t.add_resource(Alarm(
    "EC2CPUAlarm",
    AlarmDescription="Alarm if CPU too high or metric disappears indicating instance is down",
    EvaluationPeriods= "5",
    Statistic= "Average",
    Threshold= "10",
    Period= "60",
    AlarmActions= [Ref('EC2CPUScalingPolicy'),],
    Namespace= "AWS/EC2",
    Dimensions= [ MetricDimension(
            Name= "AutoScalingGroupName",
            Value= Ref('ECSAutoScalingGroup')
    )],
    ComparisonOperator= "GreaterThanThreshold",
    MetricName= "CPUUtilization"
))


EC2CPUScalingPolicy = t.add_resource(ScalingPolicy(
    "EC2CPUScalingPolicy",
    AdjustmentType= "ChangeInCapacity",
    AutoScalingGroupName= Ref('ECSAutoScalingGroup'),
    Cooldown= "100",
    ScalingAdjustment= "1",
))

print(t.to_json())
#print("OK!!!")
Пример #11
0
                  Dimensions=[
                      MetricDimension(Name="ClusterName",
                                      Value=Ref("ECSCluster")),
                  ],
                  Statistic="Average",
                  Period="60",
                  EvaluationPeriods="1",
                  Threshold=value['threshold'],
                  ComparisonOperator=value['operator'],
                  AlarmActions=[
                      Ref("{}{}".format(value['alarmPrefix'], reservation))
                  ]))
        t.add_resource(
            ScalingPolicy(
                "{}{}".format(value['alarmPrefix'], reservation),
                ScalingAdjustment=value['adjustment'],
                AutoScalingGroupName=Ref("ECSAutoScalingGroup"),
                AdjustmentType="ChangeInCapacity",
            ))

t.add_output(
    Output(
        "Cluster",
        Description="ECS Cluster Name",
        Value=Ref("ECSCluster"),
        Export=Export(Sub("${AWS::StackName}-id")),
    ))

t.add_output(
    Output(
        "VpcId",
        Description="VpcId",
    def init_template(self):
        self.template.add_description(self.TEMPLATE_DESCRIPTION)

        ecs_cluster = self.template.add_resource(Cluster(self.CLUSTER_NAME))

        ecs_instance_role = self.template.add_resource(
            Role('sitInstanceRole',
                 Path='/',
                 AssumeRolePolicyDocument={
                     "Statement": [{
                         "Effect": "Allow",
                         "Principal": {
                             "Service": ["ec2.amazonaws.com"]
                         },
                         "Action": ["sts:AssumeRole"]
                     }]
                 }))

        ecs_instance_profile = self.template.add_resource(
            InstanceProfile('sitInstanceProfile',
                            Path='/',
                            Roles=[Ref(ecs_instance_role)]))

        ecs_instance_policy = self.template.add_resource(
            PolicyType('sitInstancePolicy',
                       PolicyName='ecs-policy',
                       Roles=[Ref(ecs_instance_role)],
                       PolicyDocument={
                           "Statement": [{
                               "Effect":
                               "Allow",
                               "Action": [
                                   "ecs:CreateCluster",
                                   "ecs:RegisterContainerInstance",
                                   "ecs:DeregisterContainerInstance",
                                   "ecs:DiscoverPollEndpoint", "ecs:Submit*",
                                   "ecs:Poll", "ecs:StartTelemetrySession",
                                   "ecr:GetAuthorizationToken",
                                   "ecr:BatchCheckLayerAvailability",
                                   "ecr:GetDownloadUrlForLayer",
                                   "ecr:BatchGetImage", "logs:CreateLogStream",
                                   "logs:PutLogEvents"
                               ],
                               "Resource":
                               "*"
                           }],
                       }))

        commands = {
            '01_add_instance_to_cluster': {
                'command':
                Join('', [
                    '#!/bin/bash\n', 'echo ECS_CLUSTER=',
                    Ref(ecs_cluster),
                    '$"\n"ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION=',
                    self.ECS_TASK_CLEANUP_WAIT, ' >> /etc/ecs/ecs.config'
                ])
            }
        }

        files = {
            "/etc/cfn/cfn-hup.conf": {
                "content":
                Join("", [
                    "[main]\n", "stack=",
                    Ref("AWS::StackId"), "\n", "region=",
                    Ref("AWS::Region"), "\n"
                ]),
                "mode":
                "000400",
                "owner":
                "root",
                "group":
                "root"
            },
            "/etc/cfn/hooks.d/cfn-auto-reloader.conf": {
                "content":
                Join("", [
                    "[cfn-auto-reloader-hook]\n", "triggers=post.update\n",
                    "path=Resources.{0}.Metadata.AWS::CloudFormation::Init\n".
                    format(self.LAUNCH_CONFIGURATION_NAME),
                    "action=/opt/aws/bin/cfn-init -v ", "         --stack ",
                    Ref("AWS::StackName"), "         --resource {0}".format(
                        self.LAUNCH_CONFIGURATION_NAME), "         --region ",
                    Ref("AWS::Region"), "\n", "runas=root\n"
                ])
            }
        }

        services = {
            "sysvinit": {
                "cfn-hup": {
                    "enabled":
                    "true",
                    "ensureRunning":
                    "true",
                    "files": [
                        "/etc/cfn/cfn-hup.conf",
                        "/etc/cfn/hooks.d/cfn-auto-reloader.conf"
                    ]
                }
            }
        }

        launch_configuration = self.template.add_resource(
            LaunchConfiguration(self.LAUNCH_CONFIGURATION_NAME,
                                ImageId=self.AMI_ID,
                                IamInstanceProfile=Ref(ecs_instance_profile),
                                InstanceType=self.INSTANCE_TYPE,
                                UserData=self.user_data.get_base64_data(),
                                AssociatePublicIpAddress=False,
                                SecurityGroups=self.SECURITY_GROUPS,
                                KeyName=self.KEY_NAME,
                                Metadata=autoscaling.Metadata(
                                    cloudformation.Init({
                                        "config":
                                        cloudformation.InitConfig(
                                            commands=commands,
                                            files=files,
                                            services=services)
                                    })),
                                BlockDeviceMappings=[
                                    autoscaling.BlockDeviceMapping(
                                        DeviceName=self.EBS_DEVICE_NAME,
                                        Ebs=autoscaling.EBSBlockDevice(
                                            DeleteOnTermination=True,
                                            VolumeSize=self.EBS_VOLUME_SIZE,
                                            VolumeType='gp2'))
                                ]))

        auto_scaling_group = self.template.add_resource(
            AutoScalingGroup(self.AUTOSCALING_GROUP_NAME,
                             MaxSize=self.MAX_SIZE,
                             MinSize=self.MIN_SIZE,
                             Cooldown=60,
                             LaunchConfigurationName=Ref(launch_configuration),
                             VPCZoneIdentifier=[self.SUBNET]))
        """ Scale UP Policy """
        scaling_up_policy = self.template.add_resource(
            ScalingPolicy('{0}ScaleUpPolicy'.format(
                self.AUTOSCALING_GROUP_NAME),
                          AdjustmentType='ChangeInCapacity',
                          AutoScalingGroupName=Ref(auto_scaling_group),
                          Cooldown=60,
                          ScalingAdjustment='1'))

        for alarm_name, alarm in self.AUTOSCALE_UP_ALARMS.iteritems():
            """ Cloud Watch Alarm """
            self.template.add_resource(
                Alarm('{0}ScaleUp{1}'.format(self.AUTOSCALING_GROUP_NAME,
                                             alarm_name),
                      ActionsEnabled=True,
                      Namespace='AWS/ECS',
                      MetricName=alarm['scaling_metric'],
                      ComparisonOperator='GreaterThanOrEqualToThreshold',
                      Threshold=alarm['scale_up_threshold'],
                      EvaluationPeriods=1,
                      Statistic=alarm['statistic'],
                      Period=alarm['period'],
                      AlarmActions=[Ref(scaling_up_policy)],
                      Dimensions=[
                          MetricDimension(Name='ClusterName',
                                          Value=Ref(ecs_cluster))
                      ]))
        """ Scale DOWN Policy """
        scaling_down_policy = self.template.add_resource(
            ScalingPolicy('{0}ScaleDownPolicy'.format(
                self.AUTOSCALING_GROUP_NAME),
                          AdjustmentType='ChangeInCapacity',
                          AutoScalingGroupName=Ref(auto_scaling_group),
                          Cooldown=60,
                          ScalingAdjustment='-1'))

        for alarm_name, alarm in self.AUTOSCALE_DOWN_ALARMS.iteritems():
            """ Cloud Watch Alarm """
            self.template.add_resource(
                Alarm('{0}ScaleDown{1}'.format(self.AUTOSCALING_GROUP_NAME,
                                               alarm_name),
                      ActionsEnabled=True,
                      Namespace='AWS/ECS',
                      MetricName=alarm['scaling_metric'],
                      ComparisonOperator='LessThanOrEqualToThreshold',
                      Threshold=alarm['scale_down_threshold'],
                      EvaluationPeriods=1,
                      Statistic=alarm['statistic'],
                      Period=alarm['period'],
                      AlarmActions=[Ref(scaling_down_policy)],
                      Dimensions=[
                          MetricDimension(Name='ClusterName',
                                          Value=Ref(ecs_cluster))
                      ]))
Пример #13
0
    def create_instance(self, subnet1, subnet2, load_balancer, autoscaling_sg,
                        webapp_zip):

        launch_config = self.t.add_resource(
            LaunchConfiguration(
                "LaunchConfiguration",
                UserData=Base64(
                    Join('', [
                        "#!/bin/bash\n",
                        "sudo yum install httpd mod_wsgi -y\n",
                        "sudo pip install flask\n",
                        "sudo chkconfig httpd on\n",
                        "sudo service httpd start\n",
                        "sudo service httpd restart\n",
                        "sudo aws s3 cp s3://thivan-sample-data/",
                        Ref(webapp_zip), " .\n", "sudo unzip ",
                        Ref(webapp_zip), "\n",
                        "sudo mv /home/ec2-user/app /var/www/html/\n",
                        "sudo mv app /var/www/html/\n",
                        "sudo mv /var/www/html/app/server_config/wsgi.conf /etc/httpd/conf.d/\n",
                        "sudo groupadd group1\n",
                        "sudo useradd user1 -g group1\n",
                        "sudo usermod -a -G group1 apache\n",
                        "sudo chown -vR :group1 /var/www/\n",
                        "sudo chmod -vR g+w /var/www/\n",
                        "sudo service httpd restart\n", "cfn-signal -e 0",
                        "    --resource AutoscalingGroup", "    --stack ",
                        Ref("AWS::StackName"), "    --region ",
                        Ref("AWS::Region"), "\n"
                    ])),
                IamInstanceProfile=
                "arn:aws:iam::205198152101:instance-profile/webapps3",
                ImageId="ami-b73b63a0",
                KeyName="thivancf",
                SecurityGroups=[Ref(autoscaling_sg)],
                InstanceType="t2.micro",
            ))

        asg = self.t.add_resource(
            AutoScalingGroup(
                "AutoscalingGroup",
                DesiredCapacity=2,
                LaunchConfigurationName=Ref(launch_config),
                MinSize=1,
                MaxSize=4,
                VPCZoneIdentifier=[Ref(subnet1), Ref(subnet2)],
                LoadBalancerNames=[Ref(load_balancer)],
                HealthCheckGracePeriod=300,
                HealthCheckType="EC2",
                UpdatePolicy=UpdatePolicy(
                    AutoScalingReplacingUpdate=AutoScalingReplacingUpdate(
                        WillReplace=True, ),
                    AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                        PauseTime='PT5M',
                        MinInstancesInService="1",
                        MaxBatchSize='1',
                    ))))

        scaling_policy = self.t.add_resource(
            ScalingPolicy("ScalingPolicy",
                          AdjustmentType="ChangeInCapacity",
                          AutoScalingGroupName=Ref(asg),
                          Cooldown="120",
                          ScalingAdjustment="1"))

        self.t.add_resource(
            Alarm(
                "CPUAlarm",
                EvaluationPeriods="1",
                Statistic="Maximum",
                Threshold="50",
                AlarmDescription=
                "Alarm if CPU too high or metric disappears indicating instance is down",
                Period="60",
                AlarmActions=[Ref(scaling_policy)],
                Namespace="AWS/EC2",
                Dimensions=[
                    MetricDimension(Name="AutoScalingGroupName",
                                    Value=Ref(asg)),
                ],
                ComparisonOperator="GreaterThanThreshold",
                MetricName="CPUUtilization"))
        return launch_config
Пример #14
0
    SecurityGroups=[Ref(ec2_security_group)])
auto_scale_group = AutoScalingGroup(
    "AutoscaleGroup",
    MinSize=autoscaling_min,
    MaxSize=autoscaling_max,
    DesiredCapacity=autoscaling_desired,
    LaunchConfigurationName=Ref(launch_config),
    TargetGroupARNs=[GetAtt(target_group, "LoadBalancerArns")],
    VPCZoneIdentifier=subnet_ids)
template.add_resource(launch_config)
template.add_resource(auto_scale_group)

# asg scaling policies
scale_down_policy = ScalingPolicy("ScaleDownPolicy",
                                  AdjustmentType="ChangeInCapacity",
                                  AutoScalingGroupName=Ref(auto_scale_group),
                                  Cooldown="300",
                                  ScalingAdjustment="1")
scale_up_policy = ScalingPolicy("ScaleUpPolicy",
                                AdjustmentType="ChangeInCapacity",
                                AutoScalingGroupName=Ref(auto_scale_group),
                                Cooldown="120",
                                ScalingAdjustment="1")
template.add_resource(scale_down_policy)
template.add_resource(scale_up_policy)

# cloudwatch alarms on cpu
cloudwatch_cpu_high_alarm = Alarm("CPUHighAlarm",
                                  EvaluationPeriods="2",
                                  Statistic="Average",
                                  Threshold="70",
Пример #15
0
        )
    ),
    Tags = [
        {
            "Key": "Name",
            "Value": Join("", [Ref("AWS::StackName"), "-", Ref(NATInstanceNamesParam)]), 
            "PropagateAtLaunch": True
        }
    ],
    Cooldown=Ref(ScalingActivityCoolOffParam),
))

ScaleOutPolicy = t.add_resource(ScalingPolicy(
    'ScaleOutPolicy',
    AdjustmentType="ChangeInCapacity",
    AutoScalingGroupName=Ref(AutoscalingGroup),
    Cooldown=300,
    ScalingAdjustment=1
))

ScaleInPolicy = t.add_resource(ScalingPolicy(
    'ScaleInPolicy',
    AdjustmentType="ChangeInCapacity",
    AutoScalingGroupName=Ref(AutoscalingGroup),
    Cooldown=300,
    ScalingAdjustment=-1
))

AlarmScaleOutPolicy = t.add_resource(Alarm(
    "AlarmScaleOutPolicy",
    AlarmDescription=Join("", ["Scale out if average traffic > ", Ref(ScaleOutAverageThresholdParam), " KB/s for ",
Пример #16
0
def generate_cloudformation_template():
    enable_elb = sys.argv[1]
    input_scaling_policies = ast.literal_eval(sys.argv[2])
    input_alarms = ast.literal_eval(sys.argv[3])

    enable_elb = enable_elb == 'True'
    elb_listeners = ast.literal_eval(sys.argv[4])

    template = Template()

    template.add_description("""\
    Configures Auto Scaling Group for the app""")

    project_name = template.add_parameter(
        Parameter(
            "Name",
            Type="String",
            Description="Instances will be tagged with this name",
        ))

    scalecapacity = template.add_parameter(
        Parameter(
            "ScaleCapacity",
            Default="1",
            Type="String",
            Description="Number of api servers to run",
        ))

    minsize = template.add_parameter(
        Parameter(
            "MinScale",
            Type="String",
            Description="Minimum number of servers to keep in the ASG",
        ))

    maxsize = template.add_parameter(
        Parameter(
            "MaxScale",
            Type="String",
            Description="Maximum number of servers to keep in the ASG",
        ))

    signalcount = template.add_parameter(
        Parameter(
            "SignalCount",
            Default="1",
            Type="String",
            Description=
            "No. of signals CF must receive before it sets the status as CREATE_COMPLETE",
        ))

    signaltimeout = template.add_parameter(
        Parameter(
            "SignalTimeout",
            Default="PT5M",
            Type="String",
            Description=
            "Time that CF waits for the number of signals that was specified in Count ",
        ))

    minsuccessfulinstancespercent = template.add_parameter(
        Parameter(
            "MinSuccessfulInstancesPercent",
            Default="100",
            Type="String",
            Description=
            "% instances in a rolling update that must signal success for CF to succeed",
        ))

    environment = template.add_parameter(
        Parameter(
            "Environment",
            Type="String",
            Description="The environment being deployed into",
        ))

    subnet = template.add_parameter(
        Parameter(
            "Subnets",
            Type="CommaDelimitedList",
        ))

    launchconfigurationname = template.add_parameter(
        Parameter(
            "LaunchConfigurationName",
            Type="String",
        ))

    health_check_grace_period = template.add_parameter(
        Parameter(
            "HealthCheckGracePeriod",
            Type="String",
            Default="300",
        ))

    if enable_elb:
        elb_subnets = template.add_parameter(
            Parameter(
                "LoadBalancerSubnets",
                Type="CommaDelimitedList",
            ))

        elb_bucket_name = template.add_parameter(
            Parameter("LoadBalancerBucketName",
                      Type="String",
                      Description="S3 Bucket for the ELB access logs"))

        template.add_condition("ElbLoggingCondition",
                               Not(Equals(Ref(elb_bucket_name), "")))

        elb_schema = template.add_parameter(
            Parameter(
                "LoadBalancerSchema",
                Type="String",
            ))

        health_check_interval = template.add_parameter(
            Parameter(
                "LoadBalancerHealthCheckInterval",
                Type="String",
            ))

        health_check_timeout = template.add_parameter(
            Parameter(
                "LoadBalancerHealthCheckTimeout",
                Type="String",
            ))

        healthy_threshold = template.add_parameter(
            Parameter(
                "LoadBalancerHealthyThreshold",
                Type="String",
            ))

        unhealthy_threshold = template.add_parameter(
            Parameter(
                "LoadBalancerUnHealthyThreshold",
                Type="String",
            ))

        enable_connection_draining = template.add_parameter(
            Parameter(
                "LoadBalancerEnableConnectionDraining",
                Type="String",
                Default="True",
            ))

        connection_draining_timeout = template.add_parameter(
            Parameter(
                "LoadBalancerConnectionDrainingTimeout",
                Type="String",
                Default="30",
            ))

        loadbalancersecuritygroup = template.add_parameter(
            Parameter(
                "LoadBalancerSecurityGroup",
                Type="CommaDelimitedList",
                Description="Security group for api app load balancer.",
            ))

        hostedzone = template.add_parameter(
            Parameter(
                "HostedZoneName",
                Description=
                "The DNS name of an existing Amazon Route 53 hosted zone",
                Type="String",
            ))

        dns_record = template.add_parameter(
            Parameter(
                "DNSRecord",
                Type="String",
            ))

        dns_ttl = template.add_parameter(
            Parameter(
                "DNSTTL",
                Default="300",
                Type="String",
            ))

        new_weight = template.add_parameter(
            Parameter(
                "NewDnsWeight",
                Type="String",
                Default="100",
            ))

        health_check_protocol = template.add_parameter(
            Parameter(
                "LoadBalancerHealthCheckProtocol",
                Type="String",
            ))

        template.add_condition("ElbTCPProtocolCondition",
                               Equals(Ref(health_check_protocol), "TCP"))

        health_check_port = template.add_parameter(
            Parameter(
                "LoadBalancerHealthCheckPort",
                Type="String",
            ))

        health_check_path = template.add_parameter(
            Parameter(
                "LoadBalancerHealthCheckPath",
                Type="String",
            ))

        load_balancer_listeners = []
        for listener in elb_listeners:
            load_balancer_listeners.append(
                elb.Listener(
                    LoadBalancerPort=listener['load_balancer_port'],
                    InstancePort=listener['instance_port'],
                    Protocol=listener['protocol'],
                    InstanceProtocol=Ref(health_check_protocol),
                ))

        loadbalancer = template.add_resource(
            elb.LoadBalancer(
                "LoadBalancer",
                AccessLoggingPolicy=If(
                    "ElbLoggingCondition",
                    elb.AccessLoggingPolicy(EmitInterval=60,
                                            Enabled=True,
                                            S3BucketName=Ref(elb_bucket_name),
                                            S3BucketPrefix="ELBLogs"),
                    Ref("AWS::NoValue")),
                ConnectionDrainingPolicy=elb.ConnectionDrainingPolicy(
                    Enabled=Ref(enable_connection_draining),
                    Timeout=Ref(connection_draining_timeout),
                ),
                Subnets=Ref(elb_subnets),
                HealthCheck=elb.HealthCheck(
                    Target=Join("", [
                        Ref(health_check_protocol), ":",
                        Ref(health_check_port),
                        If("ElbTCPProtocolCondition", Ref("AWS::NoValue"),
                           Ref(health_check_path))
                    ]),
                    HealthyThreshold=Ref(healthy_threshold),
                    UnhealthyThreshold=Ref(unhealthy_threshold),
                    Interval=Ref(health_check_interval),
                    Timeout=Ref(health_check_timeout),
                ),
                Listeners=load_balancer_listeners,
                CrossZone=True,
                SecurityGroups=Ref(loadbalancersecuritygroup),
                Scheme=Ref(elb_schema)))

        route53record = template.add_resource(
            RecordSetType(
                "DNS",
                HostedZoneName=Join("", [Ref(hostedzone), "."]),
                Name=Join("", [Ref(dns_record), ".",
                               Ref(hostedzone), "."]),
                ResourceRecords=[GetAtt(loadbalancer, "DNSName")],
                SetIdentifier=Ref(project_name),
                TTL=Ref(dns_ttl),
                Type="CNAME",
                Weight=Ref(new_weight),
            ))

    autoscalinggroup = template.add_resource(
        AutoScalingGroup(
            "AutoscalingGroup",
            Tags=[
                Tag("Name", Ref(project_name), True),
                Tag("Environment", Ref(environment), True)
            ],
            LaunchConfigurationName=Ref(launchconfigurationname),
            MinSize=Ref(minsize),
            MaxSize=Ref(maxsize),
            DesiredCapacity=Ref(scalecapacity),
            VPCZoneIdentifier=Ref(subnet),
            HealthCheckGracePeriod=Ref(health_check_grace_period),
            CreationPolicy=CreationPolicy(
                ResourceSignal=ResourceSignal(Count=Ref(signalcount),
                                              Timeout=Ref(signaltimeout)),
                AutoScalingCreationPolicy=AutoScalingCreationPolicy(
                    MinSuccessfulInstancesPercent=Ref(
                        minsuccessfulinstancespercent))),
            UpdatePolicy=UpdatePolicy(
                AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                    MaxBatchSize='1',
                    MinInstancesInService='1',
                    MinSuccessfulInstancesPercent=Ref(
                        minsuccessfulinstancespercent),
                    PauseTime=Ref(signaltimeout),
                    WaitOnResourceSignals=True))))

    autoscalinggroup.HealthCheckType = 'EC2'
    if enable_elb:
        autoscalinggroup.LoadBalancerNames = [Ref(loadbalancer)]
        autoscalinggroup.HealthCheckType = 'ELB'

    created_scaling_policies = dict()
    for scaling_policy in input_scaling_policies:
        policy_properties = {
            'AdjustmentType': scaling_policy['adjustment_type'],
            'AutoScalingGroupName': Ref(autoscalinggroup),
            'Cooldown': scaling_policy['cooldown'],
            'PolicyType': scaling_policy['policy_type'],
            'ScalingAdjustment': scaling_policy['scaling_adjustment'],
        }
        if scaling_policy['policy_type'] != "SimpleScaling" \
                and 'estimated_instance_warmup' in scaling_policy:
            policy_properties['EstimatedInstanceWarmup'] = \
                scaling_policy['estimated_instance_warmup']

        if scaling_policy['policy_type'] != "SimpleScaling" \
                and 'metric_aggregation_type' in scaling_policy:
            policy_properties['MetricAggregationType'] = scaling_policy[
                'metric_aggregation_type']

        if scaling_policy['adjustment_type'] == "PercentChangeInCapacity" \
                and 'min_adjustment_magnitude' in scaling_policy:
            policy_properties['MinAdjustmentMagnitude'] = scaling_policy[
                'min_adjustment_magnitude']

        if 'step_adjustments' in scaling_policy:
            policy_properties['StepAdjustments'] = scaling_policy[
                'step_adjustments']

        created_scaling_policies[
            scaling_policy['name']] = template.add_resource(
                ScalingPolicy(scaling_policy['name'], **policy_properties))

    for alarm in input_alarms:
        template.add_resource(
            Alarm(
                alarm['name'],
                ActionsEnabled=True,
                AlarmActions=[
                    Ref(created_scaling_policies[alarm['scaling_policy_name']])
                ],
                AlarmDescription=alarm['description'],
                ComparisonOperator=alarm['comparison'],
                Dimensions=[
                    MetricDimension(Name="AutoScalingGroupName",
                                    Value=Ref(autoscalinggroup)),
                ],
                EvaluationPeriods=alarm['evaluation_periods'],
                InsufficientDataActions=[],
                MetricName=alarm['metric'],
                Namespace=alarm['namespace'],
                OKActions=[],
                Period=alarm['period'],
                Statistic=alarm['statistics'],
                Threshold=str(alarm['threshold']),
                Unit=alarm['unit'],
            ))

    template.add_output(
        Output("StackName", Value=Ref(project_name), Description="Stack Name"))
    if enable_elb:
        template.add_output(
            Output("DomainName",
                   Value=Ref(route53record),
                   Description="DNS to access the service"))
        template.add_output(
            Output("LoadBalancer",
                   Value=GetAtt(loadbalancer, "DNSName"),
                   Description="ELB dns"))
    template.add_output(
        Output("AutoScalingGroup",
               Value=Ref(autoscalinggroup),
               Description="Auto Scaling Group"))
    template.add_output(
        Output("LaunchConfiguration",
               Value=Ref(launchconfigurationname),
               Description="LaunchConfiguration for this deploy"))

    return template
            # LoadBalancerNames=[Ref(LoadBalancer)],
            #AvailabilityZones=subnetsList,
            HealthCheckType="EC2",
            UpdatePolicy=UpdatePolicy(
                AutoScalingReplacingUpdate=AutoScalingReplacingUpdate(
                    WillReplace=True, ),
                AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                    PauseTime='PT5M',
                    MinInstancesInService="1",
                    MaxBatchSize='1',
                    WaitOnResourceSignals=True))))

    ScalePolicyUp = template.add_resource(
        ScalingPolicy("HTTPRequestScalingPolicyUp" + f,
                      AutoScalingGroupName=Ref(AutoscalingGroupX),
                      AdjustmentType="ChangeInCapacity",
                      Cooldown="300",
                      ScalingAdjustment="1"))

    ScalePolicyDown = template.add_resource(
        ScalingPolicy("HTTPRequestScalingPolicyDown" + f,
                      AutoScalingGroupName=Ref(AutoscalingGroupX),
                      AdjustmentType="ChangeInCapacity",
                      Cooldown="300",
                      ScalingAdjustment="-1"))

    HTTPRequestAlarmUp = template.add_resource(
        Alarm(
            "HTTPRequestAlarmUp" + f,
            AlarmDescription="Alarm if Network out is > 4.000.000",
            Namespace="AWS/EC2",
Пример #18
0
def main():
    t = Template()
    t.add_version('2010-09-09')
    t.set_description("AWS CloudFormation ECS example")

    # Add the Parameters

    AMI = t.add_parameter(Parameter(
        "AMI",
        Type="String",
    ))

    ClusterSize = t.add_parameter(Parameter(
        "ClusterSize",
        Type="String",
    ))

    ClusterType = t.add_parameter(Parameter(
        "ClusterType",
        Type="String",
    ))

    InstanceType = t.add_parameter(Parameter(
        "InstanceType",
        Type="String",
    ))

    IamInstanceProfile = t.add_parameter(
        Parameter(
            "IamInstanceProfile",
            Type="String",
        ))

    KeyName = t.add_parameter(
        Parameter(
            "KeyName",
            Type="AWS::EC2::KeyPair::KeyName",
        ))

    MaxClusterSize = t.add_parameter(
        Parameter(
            "MaxClusterSize",
            Type="String",
        ))

    RollingUpdate = t.add_parameter(Parameter(
        "RollingUpdate",
        Type="String",
    ))

    Stage = t.add_parameter(Parameter(
        "Stage",
        Type="String",
    ))

    Subnets = t.add_parameter(
        Parameter(
            "Subnets",
            Type="List<AWS::EC2::Subnet::Id>",
        ))

    VpcCidr = t.add_parameter(Parameter(
        "VpcCidr",
        Type="String",
    ))

    VpcId = t.add_parameter(Parameter(
        "VpcId",
        Type="AWS::EC2::VPC::Id",
    ))

    ContainerInstances = t.add_resource(
        LaunchConfiguration(
            'ContainerInstances',
            UserData=Base64(
                Join('', [
                    '#!/bin/bash -xe\n', 'echo ECS_CLUSTER=',
                    Ref('AWS::StackName'), '>> /etc/ecs/ecs.config\n',
                    'systemctl enable [email protected]\n',
                    'systemctl start [email protected]\n',
                    '/usr/bin/cfn-signal -e $? ', '         --stack ',
                    Ref('AWS::StackName'),
                    '         --resource ECSAutoScalingGroup ',
                    '         --region ',
                    Ref('AWS::Region'), '\n'
                ])),
            ImageId=Ref(AMI),
            KeyName=Ref(KeyName),
            SecurityGroups=[Ref('EcsSecurityGroup')],
            IamInstanceProfile=Ref(IamInstanceProfile),
            InstanceType=Ref(InstanceType)))

    ECSCluster = t.add_resource(
        Cluster('EcsCluster', ClusterName=Ref('AWS::StackName')))

    ECSAutoScalingGroup = t.add_resource(
        AutoScalingGroup(
            'ECSAutoScalingGroup',
            DesiredCapacity=Ref(ClusterSize),
            MinSize=Ref(ClusterSize),
            MaxSize=Ref(MaxClusterSize),
            VPCZoneIdentifier=Ref(Subnets),
            LaunchConfigurationName=Ref('ContainerInstances'),
            HealthCheckType="EC2",
            UpdatePolicy=UpdatePolicy(
                AutoScalingReplacingUpdate=AutoScalingReplacingUpdate(
                    WillReplace=True, ),
                AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                    PauseTime='PT5M',
                    MinInstancesInService=Ref(ClusterSize),
                    MaxBatchSize='1',
                    WaitOnResourceSignals=True)),
            Tags=[
                Tag("Project", "demo", True),
                Tag("Stage", Ref(Stage), True),
                Tag("Name", "home-ecs", True),
            ]))

    t.add_resource(
        ScalingPolicy("EcsAsgScaleDown",
                      AdjustmentType="PercentChangeInCapacity",
                      AutoScalingGroupName=Ref("ECSAutoScalingGroup"),
                      MetricAggregationType="Average",
                      MinAdjustmentMagnitude="1",
                      PolicyType="StepScaling",
                      StepAdjustments=[
                          StepAdjustments(MetricIntervalLowerBound="-10",
                                          MetricIntervalUpperBound="0",
                                          ScalingAdjustment="-10"),
                          StepAdjustments(MetricIntervalUpperBound="-10",
                                          ScalingAdjustment="-20")
                      ]))

    t.add_resource(
        ScalingPolicy('EcsScaleUp',
                      AdjustmentType="PercentChangeInCapacity",
                      AutoScalingGroupName=Ref("ECSAutoScalingGroup"),
                      EstimatedInstanceWarmup="300",
                      MetricAggregationType="Average",
                      MinAdjustmentMagnitude="1",
                      PolicyType="StepScaling",
                      StepAdjustments=[
                          StepAdjustments(MetricIntervalLowerBound="0",
                                          MetricIntervalUpperBound="10",
                                          ScalingAdjustment="10"),
                          StepAdjustments(MetricIntervalLowerBound="10",
                                          ScalingAdjustment="20")
                      ]))

    t.add_resource(
        cloudwatch.Alarm("EcsScaleDownAlarm",
                         ActionsEnabled="True",
                         MetricName="CPUUtilization",
                         AlarmActions=[Ref("EcsAsgScaleDown")],
                         AlarmDescription="Scale down ECS Instances",
                         Namespace="AWS/EC2",
                         Statistic="Average",
                         Period="60",
                         EvaluationPeriods="6",
                         Threshold="25",
                         ComparisonOperator="LessThanThreshold",
                         Dimensions=[
                             cloudwatch.MetricDimension(
                                 Name="AutoScalingGroupName",
                                 Value=Ref("ECSAutoScalingGroup"))
                         ]))

    t.add_resource(
        cloudwatch.Alarm("EcsAsgScaleUpAlarm",
                         ActionsEnabled="True",
                         MetricName="CPUUtilization",
                         AlarmActions=[Ref("EcsScaleUp")],
                         AlarmDescription="Scale up ECS Instances",
                         Namespace="AWS/EC2",
                         Statistic="Average",
                         Period="60",
                         EvaluationPeriods="3",
                         Threshold="65",
                         ComparisonOperator="GreaterThanThreshold",
                         Dimensions=[
                             cloudwatch.MetricDimension(
                                 Name="AutoScalingGroupName",
                                 Value=Ref("ECSAutoScalingGroup"))
                         ]))

    EC2SecurityGroup = t.add_resource(
        ec2.SecurityGroup('EcsSecurityGroup',
                          GroupDescription='ECS InstanceSecurityGroup',
                          SecurityGroupIngress=[
                              ec2.SecurityGroupRule(IpProtocol='tcp',
                                                    FromPort='22',
                                                    ToPort='22',
                                                    CidrIp='0.0.0.0/0'),
                              ec2.SecurityGroupRule(IpProtocol='tcp',
                                                    FromPort='31000',
                                                    ToPort='61000',
                                                    CidrIp='0.0.0.0/0')
                          ],
                          VpcId=Ref(VpcId)))

    with open("ecs-ec2-cluster-cf.yaml", "w") as yamlout:
        yamlout.write(t.to_yaml())
Пример #19
0
t.add_resource(
    AutoScalingGroup(
        "AutoscalingGroup",
        DesiredCapacity=Ref("ScaleCapacity"),
        LaunchConfigurationName=Ref("LaunchConfiguration"),
        MinSize=2,
        MaxSize=5,
        LoadBalancerNames=[Ref("LoadBalancer")],
        VPCZoneIdentifier=Ref("PublicSubnet"),
    ))

t.add_resource(
    ScalingPolicy(
        "ScaleDownPolicy",
        ScalingAdjustment="-1",
        AutoScalingGroupName=Ref("AutoscalingGroup"),
        AdjustmentType="ChangeInCapacity",
    ))

t.add_resource(
    ScalingPolicy(
        "ScaleUpPolicy",
        ScalingAdjustment="1",
        AutoScalingGroupName=Ref("AutoscalingGroup"),
        AdjustmentType="ChangeInCapacity",
    ))

t.add_resource(
    Alarm(
        "CPUTooLow",
        AlarmDescription="Alarm if CPU too low",
Пример #20
0
    def _add_ec2_auto_scaling(self):
        instance_profile = self._add_instance_profile()
        self.sg_alb = SecurityGroup(
            "SecurityGroupAlb",
            VpcId=Ref(self.vpc),
            GroupDescription=Sub("${AWS::StackName}-alb"))
        self.template.add_resource(self.sg_alb)
        self.sg_hosts = SecurityGroup(
            "SecurityGroupEc2Hosts",
            SecurityGroupIngress=[{
                'SourceSecurityGroupId': Ref(self.sg_alb),
                'IpProtocol': -1
            }],
            VpcId=Ref(self.vpc),
            GroupDescription=Sub("${AWS::StackName}-hosts"))
        self.template.add_resource(self.sg_hosts)

        sg_host_ingress = SecurityGroupIngress("SecurityEc2HostsIngress",
                                               SourceSecurityGroupId=Ref(
                                                   self.sg_hosts),
                                               IpProtocol="-1",
                                               GroupId=Ref(self.sg_hosts),
                                               FromPort="-1",
                                               ToPort="-1")
        self.template.add_resource(sg_host_ingress)

        database_security_group = SecurityGroup(
            "SecurityGroupDatabases",
            SecurityGroupIngress=[{
                'SourceSecurityGroupId': Ref(self.sg_hosts),
                'IpProtocol': -1
            }],
            VpcId=Ref(self.vpc),
            GroupDescription=Sub("${AWS::StackName}-databases"))
        self.template.add_resource(database_security_group)
        user_data = Base64(
            Sub('\n'.join([
                "#!/bin/bash", "yum update -y",
                "yum install -y aws-cfn-bootstrap",
                "/opt/aws/bin/cfn-init -v --region ${AWS::Region} --stack ${AWS::StackName} --resource LaunchConfiguration",
                "/opt/aws/bin/cfn-signal -e $? --region ${AWS::Region} --stack ${AWS::StackName} --resource AutoScalingGroup",
                "yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm",
                "systemctl enable amazon-ssm-agent",
                "systemctl start amazon-ssm-agent", ""
            ])))
        lc_metadata = cloudformation.Init({
            "config":
            cloudformation.InitConfig(
                files=cloudformation.InitFiles({
                    "/etc/cfn/cfn-hup.conf":
                    cloudformation.InitFile(
                        content=Sub('\n'.join([
                            '[main]', 'stack=${AWS::StackId}',
                            'region=${AWS::Region}', ''
                        ])),
                        mode='256',  # TODO: Why 256
                        owner="root",
                        group="root"),
                    "/etc/cfn/hooks.d/cfn-auto-reloader.conf":
                    cloudformation.InitFile(content=Sub('\n'.join([
                        '[cfn-auto-reloader-hook]', 'triggers=post.update',
                        'path=Resources.ContainerInstances.Metadata.AWS::CloudFormation::Init',
                        'action=/opt/aws/bin/cfn-init -v --region ${AWS::Region} --stack ${AWS::StackName} --resource LaunchConfiguration',
                        ''
                    ])), )
                }),
                services={
                    "sysvinit":
                    cloudformation.InitServices({
                        "cfn-hup":
                        cloudformation.InitService(
                            enabled=True,
                            ensureRunning=True,
                            files=[
                                '/etc/cfn/cfn-hup.conf',
                                '/etc/cfn/hooks.d/cfn-auto-reloader.conf'
                            ])
                    })
                },
                commands={
                    '01_add_instance_to_cluster': {
                        'command':
                        Sub('echo "ECS_CLUSTER=${Cluster}\nECS_RESERVED_MEMORY=256" > /etc/ecs/ecs.config'
                            )
                    }
                })
        })
        launch_configuration = LaunchConfiguration(
            'LaunchConfiguration',
            UserData=user_data,
            IamInstanceProfile=Ref(instance_profile),
            SecurityGroups=[Ref(self.sg_hosts)],
            InstanceType=Ref('InstanceType'),
            ImageId=FindInMap("AWSRegionToAMI", Ref("AWS::Region"), "AMI"),
            Metadata=lc_metadata,
            KeyName=Ref(self.key_pair))
        self.template.add_resource(launch_configuration)
        # , PauseTime='PT15M', WaitOnResourceSignals=True, MaxBatchSize=1, MinInstancesInService=1)
        up = AutoScalingRollingUpdate('AutoScalingRollingUpdate')
        # TODO: clean up
        subnets = list(self.private_subnets)
        self.auto_scaling_group = AutoScalingGroup(
            "AutoScalingGroup",
            UpdatePolicy=up,
            DesiredCapacity=self.desired_instances,
            Tags=[{
                'PropagateAtLaunch': True,
                'Value': Sub('${AWS::StackName} - ECS Host'),
                'Key': 'Name'
            }],
            MinSize=Ref('MinSize'),
            MaxSize=Ref('MaxSize'),
            VPCZoneIdentifier=[Ref(subnets.pop()),
                               Ref(subnets.pop())],
            LaunchConfigurationName=Ref(launch_configuration),
            CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal(
                Timeout='PT15M')))
        self.template.add_resource(self.auto_scaling_group)
        self.cluster_scaling_policy = ScalingPolicy(
            'AutoScalingPolicy',
            AdjustmentType='ChangeInCapacity',
            AutoScalingGroupName=Ref(self.auto_scaling_group),
            Cooldown=300,
            PolicyType='SimpleScaling',
            ScalingAdjustment=1)
        self.template.add_resource(self.cluster_scaling_policy)