Created
July 20, 2018 04:34
-
-
Save levivm/ebf34d0089e8f1f52f7950ec17d1739e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from troposphere import ( | |
| Template, | |
| Parameter, | |
| FindInMap, | |
| Ref, | |
| Output, | |
| GetAtt, | |
| Base64, | |
| Tags, | |
| Join | |
| ) | |
| from troposphere.s3 import Bucket, BucketPolicy | |
| from troposphere.iam import Role, InstanceProfile, Policy | |
| from troposphere.elasticloadbalancing import ( | |
| LoadBalancer, | |
| HealthCheck, | |
| Listener, | |
| Policy as ELBPolicy, | |
| AccessLoggingPolicy, | |
| ConnectionSettings | |
| ) | |
| from troposphere.ec2 import ( | |
| BlockDeviceMapping, | |
| EBSBlockDevice, | |
| SecurityGroup, | |
| SecurityGroupRule, | |
| ) | |
| from troposphere.autoscaling import ( | |
| AutoScalingGroup, | |
| LaunchConfiguration, | |
| ScalingPolicy, | |
| ScheduledAction, | |
| ) | |
| from troposphere.cloudwatch import Alarm, MetricDimension | |
| from troposphere.policies import UpdatePolicy, AutoScalingRollingUpdate | |
| from cloudwhale.utils import ( | |
| EC2_INSTANCE_TYPES, | |
| AMIS_BY_INSTANCE, | |
| WILDCARD_CIDR, | |
| INTERNAL_CIDR, | |
| get_user_data, | |
| INTERNAL_IPS, ELB_ACCOUNTS | |
| ) | |
| def get_template( | |
| AvailabilityZones="b,d,e", | |
| internal_ips_extra=(), | |
| elb_logging="", | |
| tls_standards="", | |
| MediaBucketName=None, | |
| RecuringBump=None, | |
| scheduled_actions=None, | |
| **kwargs): | |
| t = Template() | |
| t.add_version() | |
| t.add_description("Web instances with autoscaling group and loadbalancer") | |
| t.add_mapping('UBUNTUAMI', AMIS_BY_INSTANCE) | |
| t.add_mapping('ELBACCOUNTS', ELB_ACCOUNTS) | |
| target_group_arns_param = t.add_parameter(Parameter( | |
| 'TargetGroupARNs', | |
| Type="CommaDelimitedList", | |
| Default="", | |
| Description="Target group ARNs to associate with ALB" | |
| )) | |
| scale_up_number_param = t.add_parameter(Parameter( | |
| "ScalingUpNumber", | |
| Type="Number", | |
| Default="3", | |
| Description="Number of instances to add when scaling up" | |
| )) | |
| scale_down_number_param = t.add_parameter(Parameter( | |
| "ScalingDownNumber", | |
| Type="Number", | |
| Default="-1", | |
| Description="Number of instances to remove when scaling down" | |
| )) | |
| cpu_alarm_period_param = t.add_parameter(Parameter( | |
| "CPUAlarmPeriod", | |
| Type="Number", | |
| Default="2", | |
| Description="Amount of periods to trigger scale up" | |
| )) | |
| scale_up_cpu_param = t.add_parameter(Parameter( | |
| "ScalingUpCPU", | |
| Type="Number", | |
| Default="60", | |
| Description="CPU in percents when we need to scale up" | |
| )) | |
| scale_down_cpu_param = t.add_parameter(Parameter( | |
| "ScalingDownCPU", | |
| Type="Number", | |
| Default="10", | |
| Description="CPU in percents when we need to scale down" | |
| )) | |
| scale_up_cooldown_param = t.add_parameter(Parameter( | |
| "ScalingUpCooldown", | |
| Type="Number", | |
| Default="120", | |
| Description="Number of seconds to wait before another scaling up action" | |
| )) | |
| scale_down_cooldown_param = t.add_parameter(Parameter( | |
| "ScalingDownCooldown", | |
| Type="Number", | |
| Default="120", | |
| Description="Number of seconds to waint before another scaling down action" | |
| )) | |
| t.add_parameter(Parameter( | |
| "MediaBucketName", | |
| Type='String', | |
| Default="", | |
| Description="Name of the S3 bucket for media" | |
| )) | |
| t.add_parameter(Parameter( | |
| "DistilleryBucketName", | |
| Type='String', | |
| Default="", | |
| Description="Name of the S3 bucket for distillery" | |
| )) | |
| t.add_parameter(Parameter( | |
| "DistilleryAccessKeyId", | |
| Type='String', | |
| Default="", | |
| Description="Access key id for distillery" | |
| )) | |
| t.add_parameter(Parameter( | |
| "DistillerySecretAccessKey", | |
| Type='String', | |
| Default="", | |
| Description="Secret access key for distillery" | |
| )) | |
| cloudfront_domain_param = t.add_parameter(Parameter( | |
| "CloudFrontDomainName", | |
| Default="", | |
| Type='String', | |
| Description="Domain of the CloudFront distribution" | |
| )) | |
| secure_cloudfront_domain_param = t.add_parameter(Parameter( | |
| "SecureCloudFrontDomainName", | |
| Type='String', | |
| Default="", | |
| Description="Domain of the CloudFront private distribution" | |
| )) | |
| cloudfront_distribution_param = t.add_parameter(Parameter( | |
| "CloudFrontDistribution", | |
| Default="", | |
| Type='String', | |
| Description="ID of CloudFront distribution" | |
| )) | |
| public_subnets_param = t.add_parameter(Parameter( | |
| "PublicSubnets", | |
| Type='CommaDelimitedList', | |
| Description="Private subnets separate by commas" | |
| )) | |
| ssl_certificate_id_param = t.add_parameter(Parameter( | |
| "SSLCertificateId", | |
| Type="String", | |
| Default="", | |
| Description="SSL certificate ID" | |
| )) | |
| max_size_param = t.add_parameter(Parameter( | |
| "MaxSize", | |
| Type='Number', | |
| Description="Max number of instances in ASG", | |
| Default="3" | |
| )) | |
| min_size_param = t.add_parameter(Parameter( | |
| "MinSize", | |
| Type='Number', | |
| Description="Min number of instances in ASG", | |
| Default="3" | |
| )) | |
| update_pause_param = t.add_parameter(Parameter( | |
| "UpdatePauseTime", | |
| Type="String", | |
| Description="Pause between instance update", | |
| Default="PT8M" | |
| )) | |
| max_batch_size = t.add_parameter(Parameter( | |
| "MaxBatchSize", | |
| Type='Number', | |
| Description="Max number of instances to update during rolling update", | |
| Default="2" | |
| )) | |
| min_instances_in_service = t.add_parameter(Parameter( | |
| "MinInstancesInService", | |
| Type='Number', | |
| Description="Minimum number of instances in service", | |
| Default="1" | |
| )) | |
| t.add_parameter(Parameter( | |
| "AvailabilityZones", | |
| Type='String', | |
| Description="Availability zones separate by commas" | |
| )) | |
| role_param = t.add_parameter(Parameter( | |
| "Role", | |
| Type="String", | |
| Default="web", | |
| Description="Role of your instances" | |
| )) | |
| project_param = t.add_parameter(Parameter( | |
| "Project", | |
| Type="String", | |
| Description="Name of the project" | |
| )) | |
| env_param = t.add_parameter(Parameter( | |
| "Environment", | |
| Type="String", | |
| Description="Name of the project environment, i.e. prod, qa, alpha" | |
| )) | |
| vpc_id_param = t.add_parameter(Parameter( | |
| "VPCId", | |
| Type="String", | |
| Description="An ID of your VPC" | |
| )) | |
| key_name_param = t.add_parameter(Parameter( | |
| "KeyName", | |
| Type="String", | |
| Default="wr-master", | |
| Description="Name of the existing EC2 KeyPair to enable SSH access" | |
| )) | |
| instance_type_param = t.add_parameter(Parameter( | |
| "InstanceType", | |
| Type='String', | |
| Default='t2.micro', | |
| Description='EC2 instance type', | |
| AllowedValues=EC2_INSTANCE_TYPES | |
| )) | |
| alb_security_group_param = t.add_parameter(Parameter( | |
| "AlbSecurityGroup", | |
| Type='String', | |
| Default='', | |
| Description='ALB Security Group' | |
| )) | |
| elb_enabled = False | |
| alb_enabled = False | |
| if kwargs.get('lb_type') == 'alb': | |
| alb_enabled = True | |
| elif kwargs.get('lb_type') == 'both': | |
| elb_enabled = True | |
| alb_enabled = True | |
| else: | |
| elb_enabled = True | |
| # -------------- Instance ------------------- | |
| instance_security_group = t.add_resource(SecurityGroup( | |
| "InstanceSearchSecurityGroup", | |
| VpcId=Ref(vpc_id_param), | |
| GroupDescription="Open web and SSH ports", | |
| SecurityGroupIngress=[ | |
| SecurityGroupRule( | |
| IpProtocol="tcp", | |
| FromPort=22, | |
| ToPort=22, | |
| CidrIp=internal_ip | |
| ) for internal_ip in INTERNAL_IPS + list(internal_ips_extra)] + [ | |
| SecurityGroupRule( | |
| IpProtocol="icmp", | |
| FromPort=-1, | |
| ToPort=-1, | |
| CidrIp=INTERNAL_CIDR | |
| ) | |
| ] | |
| )) | |
| instance_role = t.add_resource(Role( | |
| "WebInstanceRole", | |
| ManagedPolicyArns=kwargs.get("AdditionalIAMRolePolicies", []), | |
| AssumeRolePolicyDocument={ | |
| "Version": "2012-10-17", | |
| "Statement": [{ | |
| "Effect": "Allow", | |
| "Principal": { | |
| "Service": ["ec2.amazonaws.com"] | |
| }, | |
| "Action": ["sts:AssumeRole"] | |
| }] | |
| }, | |
| Path="/", | |
| Policies=[Policy( | |
| "WebInstancePolicy", | |
| PolicyName="root", | |
| PolicyDocument={ | |
| "Version": "2012-10-17", | |
| "Statement": [{ | |
| "Effect": "Allow", | |
| "Action": [ | |
| "ec2:Describe*", | |
| "ec2:CreateTags", | |
| "ec2:DescribeTags", | |
| "cloudformation:Describe*", | |
| "cloudfront:CreateInvalidation", | |
| "cloudfront:GetDistribution", | |
| ], | |
| "Resource": "*" | |
| }, { | |
| "Action": [ | |
| "s3:*" | |
| ], | |
| "Effect": "Allow", | |
| "Resource": [ | |
| "arn:aws:s3:::whalerock-releases", | |
| "arn:aws:s3:::whalerock-releases/*", | |
| "arn:aws:s3:::bootstrapcheck", | |
| "arn:aws:s3:::bootstrapcheck/*", | |
| ] + ([ | |
| {"Fn::Join": ["", ["arn:aws:s3:::", {"Ref": "MediaBucketName"}]]}, | |
| {"Fn::Join": ["", ["arn:aws:s3:::", {"Ref": "MediaBucketName"}, "/*"]]} | |
| ] if MediaBucketName else []) | |
| }] + kwargs.get('AdditionalIAMRoleStatements', []) + | |
| ([{ | |
| "Effect": "Allow", | |
| "Action": [ | |
| "logs:CreateLogGroup", | |
| "logs:CreateLogStream", | |
| "logs:PutLogEvents", | |
| "logs:DescribeLogStreams" | |
| ], | |
| "Resource": [ | |
| "arn:aws:logs:*:*:*" | |
| ] | |
| }] if kwargs.get('AwslogEnabled') else []) | |
| } | |
| )] | |
| )) | |
| instance_role.ManagedPolicyArns.append("arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM") | |
| instance_profile = t.add_resource(InstanceProfile( | |
| "WebInstanceProfile", | |
| Path="/", | |
| Roles=[Ref(instance_role)] | |
| )) | |
| launch_configuration = t.add_resource(LaunchConfiguration( | |
| "WebLaunchConfiguration", | |
| AssociatePublicIpAddress=True, | |
| ImageId=FindInMap('UBUNTUAMI', Ref(instance_type_param), 'AMI'), | |
| InstanceType=Ref(instance_type_param), | |
| KeyName=Ref(key_name_param), | |
| SecurityGroups=[Ref(instance_security_group)], | |
| IamInstanceProfile=Ref(instance_profile), | |
| UserData=Base64(get_user_data("ansible.yml")) | |
| )) | |
| if kwargs.get("volume_size"): | |
| launch_configuration.BlockDeviceMappings = [ | |
| BlockDeviceMapping( | |
| DeviceName="/dev/sda1", | |
| Ebs=EBSBlockDevice( | |
| VolumeSize=str(kwargs["volume_size"]) | |
| ) | |
| ) | |
| ] | |
| # -------------- ELB ASG ---------------------- | |
| if elb_enabled: | |
| elb_security_group = t.add_resource(SecurityGroup( | |
| "ELBSecurityGroup", | |
| VpcId=Ref(vpc_id_param), | |
| GroupDescription="Open ELB ports", | |
| SecurityGroupIngress=[ | |
| SecurityGroupRule( | |
| IpProtocol="tcp", | |
| FromPort=port, | |
| ToPort=port, | |
| CidrIp=WILDCARD_CIDR | |
| ) for port in [80, 443] | |
| ] + [ | |
| SecurityGroupRule( | |
| IpProtocol="icmp", | |
| FromPort=-1, | |
| ToPort=-1, | |
| CidrIp=INTERNAL_CIDR | |
| ) | |
| ] | |
| )) | |
| certificate_id = kwargs.get("SSLCertificateId", None) | |
| ssl_listeners = [] | |
| policies = [] | |
| access_logging_policy = AccessLoggingPolicy( | |
| Enabled=False | |
| ) | |
| if certificate_id: | |
| ssl_listeners = [ | |
| Listener( | |
| LoadBalancerPort=443, | |
| Protocol="HTTPS", | |
| InstancePort=80, | |
| InstanceProtocol="HTTP", | |
| SSLCertificateId=Ref(ssl_certificate_id_param) | |
| ) | |
| ] | |
| if tls_standards: | |
| policies = [ELBPolicy( | |
| PolicyName="SSLNegotiationPolicy", | |
| PolicyType="SSLNegotiationPolicyType", | |
| Attributes=[ | |
| {"Name": "Protocol-TLSv1", "Value": "true"}, | |
| {"Name": "Protocol-TLSv1.1", "Value": "true"}, | |
| {"Name": "Protocol-TLSv1.2", "Value": "true"}, | |
| {"Name": "Protocol-SSLv2", "Value": "false"}, | |
| {"Name": "Protocol-SSLv3", "Value": "false"}, | |
| {"Name": "Server-Defined-Cipher-Order", "Value": "true"}, | |
| {"Name": "ECDHE-ECDSA-AES128-GCM-SHA256", "Value": "true"}, | |
| {"Name": "ECDHE-RSA-AES128-GCM-SHA256", "Value": "true"}, # | |
| {"Name": "ECDHE-ECDSA-AES128-SHA256", "Value": "true"}, | |
| {"Name": "ECDHE-RSA-AES128-SHA256", "Value": "true"}, # | |
| {"Name": "ECDHE-ECDSA-AES128-SHA", "Value": "true"}, | |
| {"Name": "ECDHE-RSA-AES128-SHA", "Value": "true"}, # | |
| {"Name": "DHE-DSS-AES128-SHA", "Value": "true"}, | |
| {"Name": "ECDHE-ECDSA-AES256-GCM-SHA384", "Value": "true"}, | |
| {"Name": "ECDHE-RSA-AES256-GCM-SHA384", "Value": "true"}, # | |
| {"Name": "ECDHE-ECDSA-AES256-SHA384", "Value": "true"}, | |
| {"Name": "ECDHE-RSA-AES256-SHA384", "Value": "true"}, # | |
| {"Name": "ECDHE-RSA-AES256-SHA", "Value": "true"}, # | |
| {"Name": "ECDHE-ECDSA-AES256-SHA", "Value": "true"}, | |
| {"Name": "AES128-GCM-SHA256", "Value": "false"}, | |
| {"Name": "AES128-SHA256", "Value": "false"}, | |
| {"Name": "AES128-SHA", "Value": "false"}, | |
| {"Name": "AES256-GCM-SHA384", "Value": "false"}, | |
| {"Name": "AES256-SHA256", "Value": "false"}, | |
| {"Name": "AES256-SHA", "Value": "false"}, | |
| {"Name": "DHE-RSA-AES128-SHA", "Value": "true"}, # | |
| {"Name": "CAMELLIA128-SHA", "Value": "false"}, | |
| {"Name": "EDH-RSA-DES-CBC3-SHA", "Value": "false"}, | |
| {"Name": "DES-CBC3-SHA", "Value": "true"}, # | |
| {"Name": "DHE-RSA-AES256-SHA", "Value": "true"}, # | |
| ], | |
| LoadBalancerPorts=["443"]) | |
| ] | |
| elb_load_balancer = t.add_resource(LoadBalancer( | |
| "ELB", | |
| AccessLoggingPolicy=access_logging_policy, | |
| CrossZone=True, | |
| HealthCheck=HealthCheck( | |
| HealthyThreshold=3, | |
| Interval=10, | |
| Target="HTTP:80/ping", | |
| Timeout=5, | |
| UnhealthyThreshold=2 | |
| ), | |
| Listeners=[ | |
| Listener( | |
| InstancePort=80, | |
| InstanceProtocol="HTTP", | |
| LoadBalancerPort=80, | |
| Protocol="HTTP" | |
| ) | |
| ] + ssl_listeners, | |
| Policies=policies, | |
| Scheme="internet-facing", | |
| SecurityGroups=[ | |
| Ref(elb_security_group) | |
| ], | |
| Subnets=Ref(public_subnets_param), | |
| Tags=[{ | |
| "Key": "Name", | |
| "Value": Join("-", [ | |
| Ref(role_param), | |
| "elb", | |
| Ref(project_param), | |
| Ref(env_param) | |
| ]) | |
| }, { | |
| "Key": "Project", | |
| "Value": Ref(project_param) | |
| }, { | |
| "Key": "Environment", | |
| "Value": Ref(env_param) | |
| }, { | |
| "Key": "Role", | |
| "Value": Ref(role_param) | |
| }] | |
| )) | |
| if elb_logging: | |
| s3_bucket = t.add_resource(Bucket( | |
| "ELBLogsBucket", | |
| Tags=Tags( | |
| Role="ELBLogs", | |
| Environment=Ref(env_param), | |
| Project=Ref(project_param) | |
| ), | |
| DeletionPolicy="Retain" | |
| )) | |
| access_logging_policy = AccessLoggingPolicy( | |
| EmitInterval=5, | |
| Enabled=True, | |
| S3BucketName=Ref(s3_bucket) | |
| ) | |
| bucket_policy = t.add_resource(BucketPolicy( | |
| "ELBLogsBucketPolicy", | |
| PolicyDocument={ | |
| "Id": "ELBPermissionsEnabled", | |
| "Statement": [{ | |
| "Sid": "Grant a ELB access to the bucket", | |
| "Action": ["s3:PutObject"], | |
| "Effect": "Allow", | |
| "Resource": {"Fn::Join": [ | |
| "", ["arn:aws:s3:::", {"Ref": "ELBLogsBucket"}, "/*"] | |
| ]}, | |
| "Principal": { | |
| "AWS": [{"Fn::FindInMap": ['ELBACCOUNTS', {"Ref": "AWS::Region"}, 'ACCOUNTID']}] | |
| } | |
| }] | |
| }, | |
| Bucket=Ref(s3_bucket) | |
| )) | |
| elb_load_balancer.DependsOn = bucket_policy.name | |
| elb_load_balancer.AccessLoggingPolicy = access_logging_policy | |
| elb_autoscaling_group = t.add_resource(AutoScalingGroup( | |
| "WebAutoScalingGroup", | |
| VPCZoneIdentifier=Ref(public_subnets_param), | |
| HealthCheckGracePeriod=60 * 20, | |
| HealthCheckType="ELB", | |
| AvailabilityZones=[ | |
| Join("", [Ref("AWS::Region"), zone]) for zone in AvailabilityZones.split(',') | |
| ], | |
| Cooldown=120, | |
| UpdatePolicy=UpdatePolicy( | |
| AutoScalingRollingUpdate=AutoScalingRollingUpdate( | |
| MaxBatchSize=Ref(max_batch_size), | |
| MinInstancesInService=Ref(min_instances_in_service), | |
| PauseTime=Ref(update_pause_param) | |
| ) | |
| ), | |
| MaxSize=Ref(max_size_param), | |
| MinSize=Ref(min_size_param), | |
| LaunchConfigurationName=Ref(launch_configuration), | |
| LoadBalancerNames=[Ref(elb_load_balancer)], | |
| Tags=[{ | |
| "Key": "Name", | |
| "Value": Join("-", [ | |
| Ref(role_param), | |
| Ref(project_param), | |
| Ref(env_param) | |
| ]), | |
| "PropagateAtLaunch": True | |
| }, { | |
| "Key": "Project", | |
| "Value": Ref(project_param), | |
| "PropagateAtLaunch": True | |
| }, { | |
| "Key": "Environment", | |
| "Value": Ref(env_param), | |
| "PropagateAtLaunch": True | |
| }, { | |
| "Key": "Role", | |
| "Value": Ref(role_param), | |
| "PropagateAtLaunch": True | |
| }, { | |
| "Key": "CloudFrontDomain", | |
| "Value": Ref(cloudfront_domain_param), | |
| "PropagateAtLaunch": False, | |
| }, { | |
| "Key": "SecureCloudFrontDomain", | |
| "Value": Ref(secure_cloudfront_domain_param), | |
| "PropagateAtLaunch": False, | |
| }, { | |
| "Key": "CloudFrontDistribution", | |
| "Value": Ref(cloudfront_distribution_param), | |
| "PropagateAtLaunch": False, | |
| }] | |
| )) | |
| elb_scale_up_policy = t.add_resource(ScalingPolicy( | |
| "ScalingUp", | |
| AdjustmentType="ChangeInCapacity", | |
| AutoScalingGroupName=Ref(elb_autoscaling_group), | |
| Cooldown=Ref(scale_up_cooldown_param), | |
| ScalingAdjustment=Ref(scale_up_number_param) | |
| )) | |
| elb_scale_down_policy = t.add_resource(ScalingPolicy( | |
| "ScalingDown", | |
| AdjustmentType="ChangeInCapacity", | |
| AutoScalingGroupName=Ref(elb_autoscaling_group), | |
| Cooldown=Ref(scale_down_cooldown_param), | |
| ScalingAdjustment=Ref(scale_down_number_param) | |
| )) | |
| t.add_resource(Alarm( | |
| "CPUAlarmHigh", | |
| AlarmDescription="Scale up if CPU is more than specified threshold", | |
| MetricName="CPUUtilization", | |
| Namespace="AWS/EC2", | |
| Statistic="Average", | |
| Period="120", | |
| EvaluationPeriods=Ref(cpu_alarm_period_param), | |
| Threshold=Ref(scale_up_cpu_param), | |
| AlarmActions=[Ref(elb_scale_up_policy)], | |
| Dimensions=[ | |
| MetricDimension( | |
| Name="AutoScalingGroupName", | |
| Value=Ref(elb_autoscaling_group) | |
| ), | |
| ], | |
| ComparisonOperator="GreaterThanThreshold" | |
| )) | |
| t.add_resource(Alarm( | |
| "CPUAlarmLow", | |
| AlarmDescription="Scale down if CPU is less than specified threshold", | |
| MetricName="CPUUtilization", | |
| Namespace="AWS/EC2", | |
| Statistic="Average", | |
| Period="300", | |
| EvaluationPeriods="2", | |
| Threshold=Ref(scale_down_cpu_param), | |
| AlarmActions=[Ref(elb_scale_down_policy)], | |
| Dimensions=[ | |
| MetricDimension( | |
| Name="AutoScalingGroupName", | |
| Value=Ref(elb_autoscaling_group) | |
| ), | |
| ], | |
| ComparisonOperator="LessThanThreshold" | |
| )) | |
| instance_security_group.SecurityGroupIngress.append(SecurityGroupRule( | |
| IpProtocol="tcp", | |
| FromPort=80, | |
| ToPort=80, | |
| SourceSecurityGroupId=Ref(elb_security_group) | |
| )) | |
| instance_security_group.SecurityGroupIngress.append(SecurityGroupRule( | |
| IpProtocol="tcp", | |
| FromPort=443, | |
| ToPort=443, | |
| SourceSecurityGroupId=Ref(elb_security_group) | |
| )) | |
| if kwargs.get('idle_timeout'): | |
| elb_load_balancer.ConnectionSettings = ConnectionSettings(IdleTimeout=kwargs.get('idle_timeout')) | |
| t.add_output(Output( | |
| "WebELBDomain", | |
| Description="Your ELB address", | |
| Value=GetAtt(elb_load_balancer, "DNSName") | |
| )) | |
| # -------------- ALB ASG ---------------------- | |
| if alb_enabled: | |
| alb_autoscaling_group = t.add_resource(AutoScalingGroup( | |
| "AlbWebAutoScalingGroup", | |
| VPCZoneIdentifier=Ref(public_subnets_param), | |
| HealthCheckGracePeriod=60 * 20, | |
| HealthCheckType="ELB", | |
| AvailabilityZones=[ | |
| Join("", [Ref("AWS::Region"), zone]) for zone in AvailabilityZones.split(',') | |
| ], | |
| Cooldown=120, | |
| UpdatePolicy=UpdatePolicy( | |
| AutoScalingRollingUpdate=AutoScalingRollingUpdate( | |
| MaxBatchSize=Ref(max_batch_size), | |
| MinInstancesInService=Ref(min_instances_in_service), | |
| PauseTime=Ref(update_pause_param) | |
| ) | |
| ), | |
| MaxSize=Ref(max_size_param), | |
| MinSize=Ref(min_size_param), | |
| LaunchConfigurationName=Ref(launch_configuration), | |
| TargetGroupARNs=Ref(target_group_arns_param), | |
| Tags=[{ | |
| "Key": "Name", | |
| "Value": Join("-", [ | |
| Ref(role_param), | |
| Ref(project_param), | |
| Ref(env_param) | |
| ]), | |
| "PropagateAtLaunch": True | |
| }, { | |
| "Key": "Project", | |
| "Value": Ref(project_param), | |
| "PropagateAtLaunch": True | |
| }, { | |
| "Key": "Environment", | |
| "Value": Ref(env_param), | |
| "PropagateAtLaunch": True | |
| }, { | |
| "Key": "Role", | |
| "Value": Ref(role_param), | |
| "PropagateAtLaunch": True | |
| }, { | |
| "Key": "CloudFrontDomain", | |
| "Value": Ref(cloudfront_domain_param), | |
| "PropagateAtLaunch": False, | |
| }, { | |
| "Key": "SecureCloudFrontDomain", | |
| "Value": Ref(secure_cloudfront_domain_param), | |
| "PropagateAtLaunch": False, | |
| }, { | |
| "Key": "CloudFrontDistribution", | |
| "Value": Ref(cloudfront_distribution_param), | |
| "PropagateAtLaunch": False, | |
| }] | |
| )) | |
| alb_scale_up_policy = t.add_resource(ScalingPolicy( | |
| "AlbScalingUp", | |
| AdjustmentType="ChangeInCapacity", | |
| AutoScalingGroupName=Ref(alb_autoscaling_group), | |
| Cooldown=Ref(scale_up_cooldown_param), | |
| ScalingAdjustment=Ref(scale_up_number_param) | |
| )) | |
| alb_scale_down_policy = t.add_resource(ScalingPolicy( | |
| "AlbScalingDown", | |
| AdjustmentType="ChangeInCapacity", | |
| AutoScalingGroupName=Ref(alb_autoscaling_group), | |
| Cooldown=Ref(scale_down_cooldown_param), | |
| ScalingAdjustment=Ref(scale_down_number_param) | |
| )) | |
| t.add_resource(Alarm( | |
| "AlbCPUAlarmHigh", | |
| AlarmDescription="Scale up if CPU is more than specified threshold", | |
| MetricName="CPUUtilization", | |
| Namespace="AWS/EC2", | |
| Statistic="Average", | |
| Period="120", | |
| EvaluationPeriods=Ref(cpu_alarm_period_param), | |
| Threshold=Ref(scale_up_cpu_param), | |
| AlarmActions=[Ref(alb_scale_up_policy)], | |
| Dimensions=[ | |
| MetricDimension( | |
| Name="AutoScalingGroupName", | |
| Value=Ref(alb_autoscaling_group) | |
| ), | |
| ], | |
| ComparisonOperator="GreaterThanThreshold" | |
| )) | |
| t.add_resource(Alarm( | |
| "AlbCPUAlarmLow", | |
| AlarmDescription="Scale down if CPU is less than specified threshold", | |
| MetricName="CPUUtilization", | |
| Namespace="AWS/EC2", | |
| Statistic="Average", | |
| Period="300", | |
| EvaluationPeriods="2", | |
| Threshold=Ref(scale_down_cpu_param), | |
| AlarmActions=[Ref(alb_scale_down_policy)], | |
| Dimensions=[ | |
| MetricDimension( | |
| Name="AutoScalingGroupName", | |
| Value=Ref(alb_autoscaling_group) | |
| ), | |
| ], | |
| ComparisonOperator="LessThanThreshold" | |
| )) | |
| instance_security_group.SecurityGroupIngress.append(SecurityGroupRule( | |
| IpProtocol="tcp", | |
| FromPort=80, | |
| ToPort=80, | |
| SourceSecurityGroupId=Ref(alb_security_group_param) | |
| )) | |
| instance_security_group.SecurityGroupIngress.append(SecurityGroupRule( | |
| IpProtocol="tcp", | |
| FromPort=443, | |
| ToPort=443, | |
| SourceSecurityGroupId=Ref(alb_security_group_param) | |
| )) | |
| if RecuringBump: | |
| t.add_resource(ScheduledAction( | |
| "ScheduledActionUp", | |
| AutoScalingGroupName = Ref(alb_autoscaling_group), | |
| Recurrence = RecuringBump["Up"], | |
| MinSize = RecuringBump["MinSize"], | |
| MaxSize = RecuringBump["MaxSize"], | |
| DesiredCapacity = RecuringBump["DesiredCapacity"], | |
| )) | |
| t.add_resource(ScheduledAction( | |
| "ScheduledActionDown", | |
| AutoScalingGroupName = Ref(alb_autoscaling_group), | |
| DesiredCapacity = Ref(min_size_param), | |
| MaxSize = Ref(max_size_param), | |
| MinSize = Ref(min_size_param), | |
| Recurrence = RecuringBump["Down"], | |
| )) | |
| if scheduled_actions: | |
| for action in scheduled_actions: | |
| for k,v in action.iteritems(): | |
| scheduled_action = t.add_resource(ScheduledAction( | |
| k, | |
| AutoScalingGroupName=Ref(alb_autoscaling_group), | |
| )) | |
| if 'DesiredCapacity' in v: | |
| scheduled_action.DesiredCapacity = v["DesiredCapacity"] | |
| if 'EndTime' in v: | |
| scheduled_action.EndTime = v["EndTime"] | |
| if 'MaxSize' in v: | |
| scheduled_action.MaxSize = v["MaxSize"] | |
| if 'MinSize' in v: | |
| scheduled_action.MinSize = v["MinSize"] | |
| if 'Recurrence' in v: | |
| scheduled_action.Recurrence = v["Recurrence"] | |
| if 'StartTime' in v: | |
| scheduled_action.StartTime = v["StartTime"] | |
| return t | |
| if __name__ == "__main__": | |
| print(get_template().to_json()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment