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", ))
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", ))
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", )
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(":", [
"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)
), 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",
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",
)) 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!!!")
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)) ]))
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
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",
) ), 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 ",
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",
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())
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",
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)