def create_autoscaling_resource(name, launchConfig):
    """[ create simple autoscaling resource ]
    
    Arguments:
        name {[String]} -- [ name ]
        launchConfig {[LaunchConfiguration]} -- [description]
    
    Returns:
        [ troposphere.resource ] -- [ AutoScalingGroup ]
    """
    return AutoScalingGroup(
        name + "AutoScalingGroup",
        DesiredCapacity=10,
        AutoScalingGroupName=name,
        LaunchConfigurationName=Ref(launchConfig),
        MinSize=9,
        MaxSize=10,
        AvailabilityZones=[Ref(zone1), Ref(zone2)],
        HealthCheckType="EC2",
        UpdatePolicy=UpdatePolicy(
            AutoScalingReplacingUpdate=AutoScalingReplacingUpdate(
                WillReplace=True, ),
            AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                PauseTime='PT5M',
                MinInstancesInService="1",
                MaxBatchSize='1',
                WaitOnResourceSignals=True)),
        Tags=Tags(Application=Ref('AWS::StackId')))
Beispiel #2
0
    def _get_autoscaling_group_parameters(self, chain_context, launch_config_name):

        config = {
            'AvailabilityZones': Ref("AvailabilityZones"),  # Not really required in this case (yet)
            'LaunchConfigurationName': Ref(launch_config_name),
            'MinSize': Ref("MinSize"),
            'MaxSize': Ref("MaxSize"),
            'VPCZoneIdentifier': Ref("PrivateSubnets"),
            'Tags': [ASTag('Name', self.name, True)],
        }

        if META_TARGET_GROUP_NAME in chain_context.metadata:
            config['TargetGroupARNs'] = [Ref(chain_context.metadata[META_TARGET_GROUP_NAME])]

        if self.use_update_policy:
            update_policy = UpdatePolicy(
                AutoScalingReplacingUpdate=AutoScalingReplacingUpdate(
                    WillReplace=True,
                ),
                AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                    PauseTime='PT5M',
                    MinInstancesInService="1",
                    MaxBatchSize='1',
                    WaitOnResourceSignals=True
                )
            )
            config['UpdatePolicy'] = update_policy

        return config
Beispiel #3
0
def elb_asg_lc_template(app, env, nameSGRDS, rdsPort, instanceType, ami,
                        subnets, elbPort, elbCidrBlock, ec2Port,
                        desiredCapacity, minSize, maxSize, region, nameBucket,
                        officeIP):

    template = Template()

    sgELB = template.add_resource(
        SecurityGroup(
            "SecurityGroupELB" + app + env,
            GroupDescription="Security group for " + app + "-" + env,
            VpcId=ImportValue("VPC" + env),
            SecurityGroupIngress=[
                SecurityGroupRule(
                    IpProtocol="tcp",
                    FromPort=elbPort,
                    ToPort=elbPort,
                    CidrIp=elbCidrBlock,
                )
            ],
            SecurityGroupEgress=[
                SecurityGroupRule(IpProtocol="-1",
                                  ToPort=0,
                                  FromPort=65535,
                                  CidrIp="0.0.0.0/0")
            ],
            Tags=Tags(
                env=env,
                Name="sg-ELB" + app + "-" + env,
                app=app,
            ),
        ))
    sgEC2 = template.add_resource(
        SecurityGroup(
            "SecurityGroupEC2" + app + env,
            GroupDescription="Security group for EC2 " + app + "-" + env,
            VpcId=ImportValue("VPC" + env),
            DependsOn="SecurityGroupELB" + app + env,
            SecurityGroupIngress=[
                SecurityGroupRule(
                    IpProtocol="tcp",
                    FromPort=ec2Port,
                    ToPort=ec2Port,
                    SourceSecurityGroupId=Ref(sgELB),
                ),
                SecurityGroupRule(
                    IpProtocol="tcp",
                    FromPort=22,
                    ToPort=22,
                    CidrIp=officeIP,
                ),
            ],
            SecurityGroupEgress=[
                SecurityGroupRule(IpProtocol="-1",
                                  ToPort=0,
                                  FromPort=65535,
                                  CidrIp="0.0.0.0/0")
            ],
            Tags=Tags(
                env=env,
                Name="sg-EC2-" + app + "-" + env,
                app=app,
            ),
        ))
    addIngressRDS = template.add_resource(
        SecurityGroupIngress(
            "ingressSGRDS" + app + env,
            SourceSecurityGroupId=Ref(sgEC2),
            Description="From EC2 instances",
            GroupId=ImportValue("SG-" + nameSGRDS + "-" + app + "-" + env),
            IpProtocol="tcp",
            FromPort=rdsPort,
            ToPort=rdsPort,
            DependsOn="SecurityGroupEC2" + app + env,
        ))

    launchConfig = template.add_resource(
        LaunchConfiguration("LaunchConfiguration" + app + env,
                            InstanceType=instanceType,
                            ImageId=ami,
                            SecurityGroups=[Ref(sgEC2)],
                            IamInstanceProfile=ImportValue("Role-" + app +
                                                           "-" + env)))

    bucketPolicy = template.add_resource(
        BucketPolicy("BucketPolicy" + nameBucket + app + env,
                     Bucket=ImportValue("Bucket" + nameBucket + app + env),
                     PolicyDocument={
                         "Version":
                         "2012-10-17",
                         "Statement": [{
                             "Action": ["s3:PutObject"],
                             "Effect":
                             "Allow",
                             "Resource":
                             Join("", [
                                 "arn:aws:s3:::",
                                 ImportValue("Bucket" + nameBucket + app +
                                             env), "/AWSLogs/",
                                 Ref("AWS::AccountId"), "/*"
                             ]),
                             "Principal": {
                                 "AWS": ["156460612806"]
                             }
                         }]
                     }))

    lb = template.add_resource(
        LoadBalancer("LoadBalancer" + app + env,
                     ConnectionDrainingPolicy=elb.ConnectionDrainingPolicy(
                         Enabled=True,
                         Timeout=120,
                     ),
                     Subnets=subnets,
                     HealthCheck=elb.HealthCheck(
                         "HealthCheck",
                         Target="TCP:" + str(ec2Port),
                         HealthyThreshold="5",
                         UnhealthyThreshold="5",
                         Interval="30",
                         Timeout="15",
                     ),
                     Listeners=[
                         elb.Listener(
                             LoadBalancerPort=elbPort,
                             InstancePort=ec2Port,
                             Protocol="HTTP",
                             InstanceProtocol="HTTP",
                         ),
                     ],
                     CrossZone=True,
                     SecurityGroups=[Ref(sgELB)],
                     LoadBalancerName="lb-" + app + "-" + env,
                     Scheme="internet-facing",
                     AccessLoggingPolicy=AccessLoggingPolicy(
                         "LoggingELB" + app + env,
                         EmitInterval=5,
                         Enabled=True,
                         S3BucketName=ImportValue("Bucket" + nameBucket + app +
                                                  env),
                     )))

    asg = template.add_resource(
        AutoScalingGroup(
            "AutoscalingGroup" + app + env,
            DesiredCapacity=desiredCapacity,
            Tags=[Tag("Environment", env, True)],
            LaunchConfigurationName=Ref(launchConfig),
            MinSize=minSize,
            MaxSize=maxSize,
            LoadBalancerNames=[Ref(lb)],
            AvailabilityZones=GetAZs(region),
            VPCZoneIdentifier=subnets,
            HealthCheckType="ELB",
            HealthCheckGracePeriod=300,
            UpdatePolicy=UpdatePolicy(
                AutoScalingReplacingUpdate=AutoScalingReplacingUpdate(
                    WillReplace=True, ),
                AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                    PauseTime='PT5M',
                    MinInstancesInService="1",
                    MaxBatchSize='1',
                    WaitOnResourceSignals=True,
                ))))

    return (template.to_json())
            "AutoscalingGroup" + f,
            Cooldown=300,
            HealthCheckGracePeriod=300,
            DesiredCapacity=DesiredCapacity,
            MinSize=MinSize,
            MaxSize=MaxSize,
            Tags=[
                Tag("Name", environmentString + "AutoscalingGroup" + f, True)
            ],
            LaunchConfigurationName=Ref(LaunchConfig),
            VPCZoneIdentifier=subnetsList,
            # 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,
Beispiel #5
0
 def autoscaling_adder(self,
                       common_tags,
                       min_size,
                       max_size,
                       min_in_service,
                       image_id,
                       instance_size,
                       sec_groups,
                       health_check_type='EC2',
                       loadbalancer=False,
                       keyname=None,
                       targetgroup=False,
                       user_data_file=False):
     lc_name = "LaunchConfiguration" + str(random.randint(1, 999))
     as_name = "AutoScalingGroup" + str(random.randint(1, 999))
     if keyname is None:
         keyname = self.config['keyname']
     if user_data_file:
         userdata = self.__loaduserdata(user_data_file, as_name)
     else:
         userdata = self.__loaduserdata("default_userdata.txt", as_name)
     as_group_tags = self.__tag_as_role_generator(common_tags)
     blockmap = self.__generate_blockmap()
     lc_groups = copy.copy(self.sec_groups)
     lc_groups.append(Ref(sec_groups))
     launch_config = self.template.add_resource(
         LaunchConfiguration(lc_name,
                             ImageId=image_id,
                             KeyName=keyname,
                             InstanceType=instance_size,
                             SecurityGroups=lc_groups,
                             IamInstanceProfile=self.config['iam_role'],
                             UserData=userdata,
                             BlockDeviceMappings=blockmap))
     as_group = autoscalinggroup = AutoScalingGroup(
         as_name,
         Tags=as_group_tags,
         LaunchConfigurationName=Ref(lc_name),
         MinSize=Ref(min_size),
         MaxSize=Ref(max_size),
         VPCZoneIdentifier=self.config['subnets'],
         HealthCheckType=health_check_type,
         DependsOn=lc_name,
         CreationPolicy=CreationPolicy(
             AutoScalingCreationPolicy=AutoScalingCreationPolicy(
                 MinSuccessfulInstancesPercent=80),
             ResourceSignal=ResourceSignal(Count=1, Timeout='PT10M')),
         UpdatePolicy=UpdatePolicy(
             AutoScalingReplacingUpdate=AutoScalingReplacingUpdate(
                 WillReplace=False, ),
             AutoScalingScheduledAction=AutoScalingScheduledAction(
                 IgnoreUnmodifiedGroupSizeProperties=True, ),
             AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                 MaxBatchSize="2",
                 MinInstancesInService=Ref(min_in_service),
                 MinSuccessfulInstancesPercent=80,
                 PauseTime='PT10M',
                 WaitOnResourceSignals=True,
                 SuspendProcesses=[
                     "ReplaceUnHealthy, AZRebalance, AlarmNotifications, "
                     "ScheduledActions, HealthCheck"
                 ])))
     if loadbalancer:
         autoscalinggroup.LoadBalancerNames = loadbalancer
     if targetgroup:
         autoscalinggroup.TargetGroupARNs = [targetgroup]
     self.template.add_resource(autoscalinggroup)
     # getting a litte funky below. Only reason is to be able to do overrides for k8s. Probably will need to be
     # revisited
     as_lc = collections.namedtuple('aslc',
                                    'as_group,launch_config')(as_group,
                                                              launch_config)
     return as_lc
Beispiel #6
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())
Beispiel #7
0
def buildStack(bootstrap, env):
    t = Template()

    t.add_description("""\
    Configures autoscaling group for hello world app""")

    vpcCidr = t.add_parameter(
        Parameter(
            "VPCCidr",
            Type="String",
            Description="VPC cidr (x.x.x.x/xx)",
        ))

    publicSubnet1 = t.add_parameter(
        Parameter(
            "PublicSubnet1",
            Type="String",
            Description="A public VPC subnet ID for the api app load balancer.",
        ))

    publicSubnet2 = t.add_parameter(
        Parameter(
            "PublicSubnet2",
            Type="String",
            Description="A public VPC subnet ID for the api load balancer.",
        ))

    dbName = t.add_parameter(
        Parameter(
            "DBName",
            Default="HelloWorldApp",
            Description="The database name",
            Type="String",
            MinLength="1",
            MaxLength="64",
            AllowedPattern="[a-zA-Z][a-zA-Z0-9]*",
            ConstraintDescription=("must begin with a letter and contain only"
                                   " alphanumeric characters.")))

    dbUser = t.add_parameter(
        Parameter(
            "DBUser",
            NoEcho=True,
            Description="The database admin account username",
            Type="String",
            MinLength="1",
            MaxLength="16",
            AllowedPattern="[a-zA-Z][a-zA-Z0-9]*",
            ConstraintDescription=("must begin with a letter and contain only"
                                   " alphanumeric characters.")))

    dbPassword = t.add_parameter(
        Parameter(
            "DBPassword",
            NoEcho=True,
            Description="The database admin account password",
            Type="String",
            MinLength="8",
            MaxLength="41",
            AllowedPattern="[a-zA-Z0-9]*",
            ConstraintDescription="must contain only alphanumeric characters.")
    )

    dbType = t.add_parameter(
        Parameter(
            "DBType",
            Default="db.t2.medium",
            Description="Database instance class",
            Type="String",
            AllowedValues=[
                "db.m5.large", "db.m5.xlarge", "db.m5.2xlarge",
                "db.m5.4xlarge", "db.m5.12xlarge", "db.m5.24xlarge",
                "db.m4.large", "db.m4.xlarge", "db.m4.2xlarge",
                "db.m4.4xlarge", "db.m4.10xlarge", "db.m4.16xlarge",
                "db.r4.large", "db.r4.xlarge", "db.r4.2xlarge",
                "db.r4.4xlarge", "db.r4.8xlarge", "db.r4.16xlarge",
                "db.x1e.xlarge", "db.x1e.2xlarge", "db.x1e.4xlarge",
                "db.x1e.8xlarge", "db.x1e.16xlarge", "db.x1e.32xlarge",
                "db.x1.16xlarge", "db.x1.32xlarge", "db.r3.large",
                "db.r3.xlarge", "db.r3.2xlarge", "db.r3.4xlarge",
                "db.r3.8xlarge", "db.t2.micro", "db.t2.small", "db.t2.medium",
                "db.t2.large", "db.t2.xlarge", "db.t2.2xlarge"
            ],
            ConstraintDescription="must select a valid database instance type.",
        ))

    dbAllocatedStorage = t.add_parameter(
        Parameter(
            "DBAllocatedStorage",
            Default="5",
            Description="The size of the database (Gb)",
            Type="Number",
            MinValue="5",
            MaxValue="1024",
            ConstraintDescription="must be between 5 and 1024Gb.",
        ))

    whitelistedCIDR = t.add_parameter(
        Parameter(
            "WhitelistedCIDR",
            Description="CIDR whitelisted to be open on public instances",
            Type="String",
        ))

    #### NETWORK SECTION ####
    vpc = t.add_resource(
        VPC("VPC", CidrBlock=Ref(vpcCidr), EnableDnsHostnames=True))

    subnet1 = t.add_resource(
        Subnet("Subnet1",
               CidrBlock=Ref(publicSubnet1),
               AvailabilityZone="eu-west-1a",
               VpcId=Ref(vpc)))
    subnet2 = t.add_resource(
        Subnet("Subnet2",
               CidrBlock=Ref(publicSubnet2),
               AvailabilityZone="eu-west-1b",
               VpcId=Ref(vpc)))

    internetGateway = t.add_resource(InternetGateway('InternetGateway'))

    gatewayAttachment = t.add_resource(
        VPCGatewayAttachment('AttachGateway',
                             VpcId=Ref(vpc),
                             InternetGatewayId=Ref(internetGateway)))

    routeTable = t.add_resource(RouteTable('RouteTable', VpcId=Ref(vpc)))

    route = t.add_resource(
        Route(
            'Route',
            DependsOn='AttachGateway',
            GatewayId=Ref('InternetGateway'),
            DestinationCidrBlock='0.0.0.0/0',
            RouteTableId=Ref(routeTable),
        ))

    subnetRouteTableAssociation = t.add_resource(
        SubnetRouteTableAssociation(
            'SubnetRouteTableAssociation',
            SubnetId=Ref(subnet1),
            RouteTableId=Ref(routeTable),
        ))

    subnetRouteTableAssociation2 = t.add_resource(
        SubnetRouteTableAssociation(
            'SubnetRouteTableAssociation2',
            SubnetId=Ref(subnet2),
            RouteTableId=Ref(routeTable),
        ))

    #### SECURITY GROUP ####
    loadBalancerSg = t.add_resource(
        ec2.SecurityGroup(
            "LoadBalancerSecurityGroup",
            VpcId=Ref(vpc),
            GroupDescription="Enable SSH access via port 22",
            SecurityGroupIngress=[
                ec2.SecurityGroupRule(
                    IpProtocol="tcp",
                    FromPort="80",
                    ToPort="80",
                    CidrIp="0.0.0.0/0",
                ),
            ],
        ))

    instanceSg = t.add_resource(
        ec2.SecurityGroup(
            "InstanceSecurityGroup",
            VpcId=Ref(vpc),
            GroupDescription="Enable SSH access via port 22",
            SecurityGroupIngress=[
                ec2.SecurityGroupRule(
                    IpProtocol="tcp",
                    FromPort="22",
                    ToPort="22",
                    CidrIp=Ref(whitelistedCIDR),
                ),
                ec2.SecurityGroupRule(
                    IpProtocol="tcp",
                    FromPort="8000",
                    ToPort="8000",
                    SourceSecurityGroupId=Ref(loadBalancerSg),
                ),
            ],
        ))

    rdsSg = t.add_resource(
        SecurityGroup("RDSSecurityGroup",
                      GroupDescription="Security group for RDS DB Instance.",
                      VpcId=Ref(vpc),
                      SecurityGroupIngress=[
                          ec2.SecurityGroupRule(
                              IpProtocol="tcp",
                              FromPort="5432",
                              ToPort="5432",
                              SourceSecurityGroupId=Ref(instanceSg),
                          ),
                          ec2.SecurityGroupRule(
                              IpProtocol="tcp",
                              FromPort="5432",
                              ToPort="5432",
                              CidrIp=Ref(whitelistedCIDR),
                          ),
                      ]))

    #### DATABASE SECTION ####
    subnetGroup = t.add_resource(
        DBSubnetGroup(
            "SubnetGroup",
            DBSubnetGroupDescription=
            "Subnets available for the RDS DB Instance",
            SubnetIds=[Ref(subnet1), Ref(subnet2)],
        ))

    db = t.add_resource(
        DBInstance(
            "RDSHelloWorldApp",
            DBName=Join("", [Ref(dbName), env]),
            DBInstanceIdentifier=Join("", [Ref(dbName), env]),
            EnableIAMDatabaseAuthentication=True,
            PubliclyAccessible=True,
            AllocatedStorage=Ref(dbAllocatedStorage),
            DBInstanceClass=Ref(dbType),
            Engine="postgres",
            EngineVersion="10.4",
            MasterUsername=Ref(dbUser),
            MasterUserPassword=Ref(dbPassword),
            DBSubnetGroupName=Ref(subnetGroup),
            VPCSecurityGroups=[Ref(rdsSg)],
        ))

    t.add_output(
        Output("RDSConnectionString",
               Description="Connection string for database",
               Value=GetAtt("RDSHelloWorldApp", "Endpoint.Address")))

    if (bootstrap):
        return t

    #### INSTANCE SECTION ####
    keyName = t.add_parameter(
        Parameter(
            "KeyName",
            Type="String",
            Description="Name of an existing EC2 KeyPair to enable SSH access",
            MinLength="1",
            AllowedPattern="[\x20-\x7E]*",
            MaxLength="255",
            ConstraintDescription="can contain only ASCII characters.",
        ))

    scaleCapacityMin = t.add_parameter(
        Parameter(
            "ScaleCapacityMin",
            Default="1",
            Type="String",
            Description="Number of api servers to run",
        ))

    scaleCapacityMax = t.add_parameter(
        Parameter(
            "ScaleCapacityMax",
            Default="1",
            Type="String",
            Description="Number of api servers to run",
        ))

    scaleCapacityDesired = t.add_parameter(
        Parameter(
            "ScaleCapacityDesired",
            Default="1",
            Type="String",
            Description="Number of api servers to run",
        ))

    amiId = t.add_parameter(
        Parameter(
            "AmiId",
            Type="String",
            Default="ami-09693313102a30b2c",
            Description="The AMI id for the api instances",
        ))

    instanceType = t.add_parameter(
        Parameter("InstanceType",
                  Description="WebServer EC2 instance type",
                  Type="String",
                  Default="t2.medium",
                  AllowedValues=[
                      "t2.nano", "t2.micro", "t2.small", "t2.medium",
                      "t2.large", "m3.medium", "m3.large", "m3.xlarge",
                      "m3.2xlarge", "m4.large", "m4.xlarge", "m4.2xlarge",
                      "m4.4xlarge", "m4.10xlarge", "c4.large", "c4.xlarge",
                      "c4.2xlarge", "c4.4xlarge", "c4.8xlarge"
                  ],
                  ConstraintDescription="must be a valid EC2 instance type."))

    assumeRole = t.add_resource(
        Role("AssumeRole",
             AssumeRolePolicyDocument=json.loads("""\
{
  "Version": "2012-10-17",
  "Statement": [
    {
    "Action": "sts:AssumeRole",
    "Principal": {
      "Service": "ec2.amazonaws.com"
    },
    "Effect": "Allow",
    "Sid": ""
    }
  ]
}\
""")))

    instanceProfile = t.add_resource(
        InstanceProfile("InstanceProfile", Roles=[Ref(assumeRole)]))

    rolePolicyType = t.add_resource(
        PolicyType("RolePolicyType",
                   Roles=[Ref(assumeRole)],
                   PolicyName=Join("", ["CloudWatchHelloWorld", "-", env]),
                   PolicyDocument=json.loads("""\
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:DescribeLogStreams",
        "logs:PutLogEvents"
      ],
    "Effect": "Allow",
    "Resource": [
        "arn:aws:logs:*:*:*"
      ]
    }
  ]
}\
""")))

    appPassword = t.add_parameter(
        Parameter(
            "AppPassword",
            NoEcho=True,
            Description="The Password for the app user",
            Type="String",
            MinLength="8",
            MaxLength="41",
            AllowedPattern="[a-zA-Z0-9]*",
            ConstraintDescription="must contain only alphanumeric characters.")
    )

    launchConfig = t.add_resource(
        LaunchConfiguration(
            "LaunchConfiguration",
            Metadata=autoscaling.Metadata(
                cloudformation.Init({
                    "config":
                    cloudformation.InitConfig(files=cloudformation.InitFiles({
                        "/home/app/environment":
                        cloudformation.InitFile(content=Join(
                            "", [
                                "SPRING_DATASOURCE_URL=", "jdbc:postgresql://",
                                GetAtt("RDSHelloWorldApp", "Endpoint.Address"),
                                ":5432/HelloWorldApp" + env +
                                "?currentSchema=hello_world", "\n",
                                "SPRING_DATASOURCE_USERNAME=app", "\n",
                                "SPRING_DATASOURCE_PASSWORD="******"\n",
                                "SPRING_PROFILES_ACTIVE=", env, "\n"
                            ]),
                                                mode="000600",
                                                owner="app",
                                                group="app")
                    }), )
                }), ),
            UserData=Base64(
                Join('', [
                    "#!/bin/bash\n", "/opt/aws/bin/cfn-init",
                    "    --resource LaunchConfiguration", "    --stack ",
                    Ref("AWS::StackName"), "    --region ",
                    Ref("AWS::Region"), "\n", "/opt/aws/bin/cfn-signal -e $? ",
                    "         --stack ", {
                        "Ref": "AWS::StackName"
                    }, "         --resource AutoscalingGroup ",
                    "         --region ", {
                        "Ref": "AWS::Region"
                    }, "\n"
                ])),
            ImageId=Ref(amiId),
            KeyName=Ref(keyName),
            IamInstanceProfile=Ref(instanceProfile),
            BlockDeviceMappings=[
                ec2.BlockDeviceMapping(DeviceName="/dev/xvda",
                                       Ebs=ec2.EBSBlockDevice(VolumeSize="8")),
            ],
            SecurityGroups=[Ref(instanceSg)],
            InstanceType=Ref(instanceType),
            AssociatePublicIpAddress='True',
        ))

    applicationElasticLB = t.add_resource(
        elb.LoadBalancer("ApplicationElasticLB",
                         Name="ApplicationElasticLB-" + env,
                         Scheme="internet-facing",
                         Type="application",
                         SecurityGroups=[Ref(loadBalancerSg)],
                         Subnets=[Ref(subnet1), Ref(subnet2)]))

    targetGroup = t.add_resource(
        elb.TargetGroup("TargetGroupHelloWorld",
                        HealthCheckProtocol="HTTP",
                        HealthCheckTimeoutSeconds="15",
                        HealthyThresholdCount="5",
                        Matcher=elb.Matcher(HttpCode="200,404"),
                        Port="8000",
                        Protocol="HTTP",
                        UnhealthyThresholdCount="3",
                        TargetGroupAttributes=[
                            elb.TargetGroupAttribute(
                                Key="deregistration_delay.timeout_seconds",
                                Value="120",
                            )
                        ],
                        VpcId=Ref(vpc)))

    listener = t.add_resource(
        elb.Listener("Listener",
                     Port="80",
                     Protocol="HTTP",
                     LoadBalancerArn=Ref(applicationElasticLB),
                     DefaultActions=[
                         elb.Action(Type="forward",
                                    TargetGroupArn=Ref(targetGroup))
                     ]))

    t.add_output(
        Output("URL",
               Description="URL of the sample website",
               Value=Join("",
                          ["http://",
                           GetAtt(applicationElasticLB, "DNSName")])))

    autoScalingGroup = t.add_resource(
        AutoScalingGroup(
            "AutoscalingGroup",
            DesiredCapacity=Ref(scaleCapacityDesired),
            LaunchConfigurationName=Ref(launchConfig),
            MinSize=Ref(scaleCapacityMin),
            MaxSize=Ref(scaleCapacityMax),
            VPCZoneIdentifier=[Ref(subnet1), Ref(subnet2)],
            TargetGroupARNs=[Ref(targetGroup)],
            HealthCheckType="ELB",
            HealthCheckGracePeriod=360,
            UpdatePolicy=UpdatePolicy(
                AutoScalingReplacingUpdate=AutoScalingReplacingUpdate(
                    WillReplace=True, ),
                AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                    PauseTime='PT5M',
                    MinInstancesInService="1",
                    MaxBatchSize='1',
                    WaitOnResourceSignals=True)),
            CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal(
                Timeout="PT15M", Count=Ref(scaleCapacityDesired)))))

    # print(t.to_json())
    return t
Beispiel #8
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
def template():

    t = Template()

    keyname_param = t.add_parameter(
        Parameter(
            "KeyName",
            Description=
            "Name of an existing EC2 KeyPair to enable SSH access to the instance",
            Type="String"))

    image_id_param = t.add_parameter(
        Parameter("ImageId",
                  Description="ImageId of the EC2 instance",
                  Type="String"))

    instance_type_param = t.add_parameter(
        Parameter("InstanceType",
                  Description="Type of the EC2 instance",
                  Type="String"))

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

    VPCAvailabilityZone2 = t.add_parameter(
        Parameter(
            "VPCAvailabilityZone2",
            MinLength="1",
            Type="String",
            Description="Second availability zone",
            MaxLength="255",
        ))

    VPCAvailabilityZone1 = t.add_parameter(
        Parameter(
            "VPCAvailabilityZone1",
            MinLength="1",
            Type="String",
            Description="First availability zone",
            MaxLength="255",
        ))

    SecurityGroup = t.add_parameter(
        Parameter(
            "SecurityGroup",
            Type="String",
            Description="Security group.",
        ))

    RootStackName = t.add_parameter(
        Parameter(
            "RootStackName",
            Type="String",
            Description="The root stack name",
        ))

    ApiSubnet2 = t.add_parameter(
        Parameter(
            "ApiSubnet2",
            Type="String",
            Description="Second private VPC subnet ID for the api app.",
        ))

    ApiSubnet1 = t.add_parameter(
        Parameter(
            "ApiSubnet1",
            Type="String",
            Description="First private VPC subnet ID for the api app.",
        ))

    #####################################################
    # Launch Configuration
    #####################################################
    LaunchConfig = t.add_resource(
        LaunchConfiguration(
            "LaunchConfiguration",
            Metadata=autoscaling.Metadata(
                cloudformation.Init(
                    cloudformation.InitConfigSets(InstallAndRun=['Install']),
                    Install=cloudformation.InitConfig(
                        packages={
                            "apt": {
                                "curl": [],
                                "zip": [],
                                "unzip": [],
                                "git": [],
                                "supervisor": [],
                                "sqlite3": [],
                                "nginx": [],
                                "php7.2-fpm": [],
                                "php7.2-cli": [],
                                "php7.2-pgsql": [],
                                "php7.2-sqlite3": [],
                                "php7.2-gd": [],
                                "php7.2-curl": [],
                                "php7.2-memcached": [],
                                "php7.2-imap": [],
                                "php7.2-mysql": [],
                                "php7.2-mbstring": [],
                                "php7.2-xml": [],
                                "php7.2-zip": [],
                                "php7.2-bcmath": [],
                                "php7.2-soap": [],
                                "php7.2-intl": [],
                                "php7.2-readline": [],
                                "php-msgpack": [],
                                "php-igbinary": []
                            }
                        },
                        files=cloudformation.InitFiles({
                            "/etc/nginx/sites-available/default":
                            cloudformation.
                            InitFile(content=Join('', [
                                "server {\n", "   listen 80 default_server;\n",
                                "   root /var/www/html/public;\n",
                                "   index index.html index.htm index.php;\n",
                                "   server_name _;\n", "   charset utf-8;\n",
                                "   location = /favicon.ico { log_not_found off; access_log off; }\n",
                                "   location = /robots.txt  { log_not_found off; access_log off; }\n",
                                "   location / {\n",
                                "       try_files $uri $uri/ /index.php$is_args$args;\n",
                                "   }\n", "   location ~ \.php$ {\n",
                                "       include snippets/fastcgi-php.conf;\n",
                                "       fastcgi_pass unix:/run/php/php7.2-fpm.sock;\n",
                                "   }\n", "   error_page 404 /index.php;\n",
                                "}\n"
                            ])),
                            "/etc/supervisor/conf.d/supervisord.conf":
                            cloudformation.
                            InitFile(content=Join('', [
                                "[supervisord]\n",
                                "nodaemon=true\n",
                                "[program:nginx]\n",
                                "command=nginx\n",
                                "stdout_logfile=/dev/stdout\n",
                                "stdout_logfile_maxbytes=0\n",
                                "stderr_logfile=/dev/stderr\n",
                                "stderr_logfile_maxbytes=0\n",
                                "[program:php-fpm]\n",
                                "command=php-fpm7.2\n",
                                "stdout_logfile=/dev/stdout\n",
                                "stdout_logfile_maxbytes=0\n",
                                "stderr_logfile=/dev/stderr\n",
                                "stderr_logfile_maxbytes=0\n",
                                "[program:horizon]\n",
                                "process_name=%(program_name)s\n",
                                "command=php /var/www/html/artisan horizon\n",
                                "autostart=true\n",
                                "autorestart=true\n",
                                "user=root\n",
                                "redirect_stderr=true\n",
                                "stdout_logfile=/var/www/html/storage/logs/horizon.log\n",
                            ])),
                            "/etc/php/7.2/fpm/php-fpm.conf":
                            cloudformation.InitFile(
                                content=Join('', [
                                    "[global]\n",
                                    "pid = /run/php/php7.2-fpm.pid\n",
                                    "error_log = /proc/self/fd/2\n",
                                    "include=/etc/php/7.2/fpm/pool.d/*.conf\n"
                                ]))
                        }))), ),
            UserData=Base64(
                Join('', [
                    "#!/bin/bash -xe\n", "apt-get update -y\n",
                    "apt-get install -y language-pack-en-base\n",
                    "export LC_ALL=en_US.UTF-8\n", "export LANG=en_US.UTF-8\n",
                    "apt-get install -y ruby\n",
                    "wget https://aws-codedeploy-ap-south-1.s3.amazonaws.com/latest/install\n",
                    "chmod +x ./install\n", "./install auto\n",
                    "service codedeploy-agent start\n",
                    "apt-get install -y software-properties-common python-software-properties\n",
                    "add-apt-repository -y ppa:ondrej/php\n",
                    "apt-get update -y\n",
                    "apt-get install -y python-setuptools\n",
                    "mkdir -p /opt/aws/bin\n",
                    "wget https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
                    "easy_install --script-dir /opt/aws/bin aws-cfn-bootstrap-latest.tar.gz\n",
                    "# Install the files and packages from the metadata\n",
                    "/opt/aws/bin/cfn-init -v ", " --stack ",
                    Ref("AWS::StackName"), " --resource LaunchConfiguration",
                    " --configsets InstallAndRun ", " --region ",
                    Ref("AWS::Region"), "\n"
                ])),
            ImageId=Ref("ImageId"),
            KeyName=Ref(keyname_param),
            BlockDeviceMappings=[
                ec2.BlockDeviceMapping(DeviceName="/dev/sda1",
                                       Ebs=ec2.EBSBlockDevice(VolumeSize="8")),
            ],
            InstanceType=Ref("InstanceType"),
            IamInstanceProfile="CodeDeployDemo-EC2-Instance-Profile",
            SecurityGroups=[Ref(SecurityGroup)]))

    #####################################################
    # AutoScaling Groups
    #####################################################
    AutoscalingGroup = t.add_resource(
        AutoScalingGroup(
            "AutoscalingGroup",
            DesiredCapacity=Ref(ScaleCapacity),
            Tags=[
                Tag("App", "cc-worker", True),
                Tag("Name", "cc-worker", True)
            ],
            LaunchConfigurationName=Ref(LaunchConfig),
            MinSize=Ref(ScaleCapacity),
            MaxSize=Ref(ScaleCapacity),
            VPCZoneIdentifier=[Ref(ApiSubnet1),
                               Ref(ApiSubnet2)],
            AvailabilityZones=[
                Ref(VPCAvailabilityZone1),
                Ref(VPCAvailabilityZone2)
            ],
            HealthCheckType="EC2",
            UpdatePolicy=UpdatePolicy(
                AutoScalingReplacingUpdate=AutoScalingReplacingUpdate(
                    WillReplace=True, ),
                AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                    PauseTime='PT5M',
                    MinInstancesInService="1",
                    MaxBatchSize='1',
                    WaitOnResourceSignals=True))))

    return t.to_json()