コード例 #1
0
 def test_works(self):
     p = UpdatePolicy(AutoScalingRollingUpdate=AutoScalingRollingUpdate(
         MaxBatchSize=2,
         MinInstancesInService=1,
         PauseTime="PT90S",
         WaitOnResourceSignals=True,
     ))
     self.assertEqual(p.AutoScalingRollingUpdate.MaxBatchSize, 2)
     self.assertEqual(p.AutoScalingRollingUpdate.MinInstancesInService, 1)
     self.assertEqual(p.AutoScalingRollingUpdate.PauseTime, "PT90S")
     self.assertTrue(p.AutoScalingRollingUpdate.WaitOnResourceSignals)
コード例 #2
0
ファイル: test_policies.py プロジェクト: yasra002/troposphere
 def test_json(self):
     p = UpdatePolicy(AutoScalingRollingUpdate=AutoScalingRollingUpdate(
         MaxBatchSize=2,
         MinInstancesInService=1,
         PauseTime='PT90S',
         WaitOnResourceSignals=True))
     p = json.loads(json.dumps(p, cls=awsencode))
     self.assertEqual(p['AutoScalingRollingUpdate']['MaxBatchSize'], 2)
     self.assertEqual(
         p['AutoScalingRollingUpdate']['MinInstancesInService'], 1)
     self.assertEqual(p['AutoScalingRollingUpdate']['PauseTime'], 'PT90S')
     self.assertTrue(p['AutoScalingRollingUpdate']['WaitOnResourceSignals'])
コード例 #3
0
ファイル: test_policies.py プロジェクト: gsoyka/troposphere
 def test_json(self):
     p = UpdatePolicy(AutoScalingRollingUpdate=AutoScalingRollingUpdate(
         MaxBatchSize=2,
         MinInstancesInService=1,
         PauseTime="PT90S",
         WaitOnResourceSignals=True,
     ))
     p = p.to_dict()
     self.assertEqual(p["AutoScalingRollingUpdate"]["MaxBatchSize"], 2)
     self.assertEqual(
         p["AutoScalingRollingUpdate"]["MinInstancesInService"], 1)
     self.assertEqual(p["AutoScalingRollingUpdate"]["PauseTime"], "PT90S")
     self.assertTrue(p["AutoScalingRollingUpdate"]["WaitOnResourceSignals"])
コード例 #4
0
ファイル: test_policies.py プロジェクト: yasra002/troposphere
 def test_mininstances(self):
     group = AutoScalingGroup(
         'mygroup',
         LaunchConfigurationName="I'm a test",
         MaxSize=1,
         MinSize=1,
         UpdatePolicy=UpdatePolicy(
             AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                 PauseTime='PT1M5S',
                 MinInstancesInService='1',
                 MaxBatchSize='1')))
     with self.assertRaises(ValueError):
         self.assertTrue(group.validate())
コード例 #5
0
    def test_AutoScalingRollingUpdate_validation(self):
        update_policy = UpdatePolicy(
            AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                MinInstancesInService="2", MaxBatchSize='1'))
        group = AutoScalingGroup(
            'mygroup',
            AvailabilityZones=['eu-west-1a', 'eu-west-1b'],
            LaunchConfigurationName="I'm a test",
            MaxSize="2",
            MinSize="1",
            UpdatePolicy=update_policy)

        with self.assertRaises(ValueError):
            self.assertTrue(group.validate())
コード例 #6
0
ファイル: test_policies.py プロジェクト: yasra002/troposphere
 def test_mininstances_maxsize_is_ref(self):
     paramMaxSize = Parameter("ParamMaxSize", Type="String")
     group = AutoScalingGroup(
         'mygroup',
         AvailabilityZones=['eu-west-1a', 'eu-west-1b'],
         LaunchConfigurationName="I'm a test",
         MaxSize=Ref(paramMaxSize),
         MinSize="2",
         UpdatePolicy=UpdatePolicy(
             AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                 PauseTime='PT1M5S',
                 MinInstancesInService='2',
                 MaxBatchSize="1")))
     self.assertTrue(group.validate())
コード例 #7
0
 def test_size_if(self):
     group = AutoScalingGroup(
         'mygroup',
         AvailabilityZones=['eu-west-1a', 'eu-west-1b'],
         LaunchConfigurationName="I'm a test",
         MaxSize=If("isstage", "1", "5"),
         MinSize="1",
         UpdatePolicy=UpdatePolicy(
             AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                 PauseTime='PT5M',
                 MinInstancesInService="1",
                 MaxBatchSize='1',
                 WaitOnResourceSignals=True)))
     self.assertTrue(group.validate())
コード例 #8
0
    def test_AutoScalingRollingUpdate_validation(self):
        update_policy = UpdatePolicy(
            AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                MinInstancesInService="2", MaxBatchSize="1"))
        group = AutoScalingGroup(
            "mygroup",
            AvailabilityZones=["eu-west-1a", "eu-west-1b"],
            LaunchConfigurationName="I'm a test",
            MaxSize="2",
            MinSize="1",
            UpdatePolicy=update_policy,
        )

        with self.assertRaises(ValueError):
            group.validate()
コード例 #9
0
 def test_size_if(self):
     group = AutoScalingGroup(
         "mygroup",
         AvailabilityZones=["eu-west-1a", "eu-west-1b"],
         LaunchConfigurationName="I'm a test",
         MaxSize=If("isstage", "1", "5"),
         MinSize="1",
         UpdatePolicy=UpdatePolicy(
             AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                 PauseTime="PT5M",
                 MinInstancesInService="1",
                 MaxBatchSize="1",
                 WaitOnResourceSignals=True,
             )),
     )
     self.assertIsNone(group.validate())
コード例 #10
0
ファイル: test_policies.py プロジェクト: gsoyka/troposphere
 def test_mininstances_mininstancesinservice_is_ref(self):
     paramMinInstancesInService = Parameter("ParamMinInstancesInService",
                                            Type="String")
     group = AutoScalingGroup(
         "mygroup",
         AvailabilityZones=["eu-west-1a", "eu-west-1b"],
         LaunchConfigurationName="I'm a test",
         MaxSize="4",
         MinSize="2",
         UpdatePolicy=UpdatePolicy(
             AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                 PauseTime="PT1M5S",
                 MinInstancesInService=Ref(paramMinInstancesInService),
                 MaxBatchSize="2",
             )),
     )
     self.assertIsNone(group.validate())
コード例 #11
0
 def test_helperfn_as_AutoScalingRollingUpdate(self):
     update_policy = UpdatePolicy(AutoScalingRollingUpdate=If(
         'RollingUpdate',
         AutoScalingRollingUpdate(PauseTime='PT5M',
                                  MinInstancesInService="1",
                                  MaxBatchSize='1',
                                  WaitOnResourceSignals=True),
         Ref("AWS::NoValue"),
     ), )
     group = AutoScalingGroup(
         'mygroup',
         AvailabilityZones=['eu-west-1a', 'eu-west-1b'],
         LaunchConfigurationName="I'm a test",
         MaxSize=If("isstage", "1", "5"),
         MinSize="1",
         UpdatePolicy=If("UseUpdatePolicy", update_policy,
                         Ref("AWS::NoValue")))
     self.assertTrue(group.validate())
コード例 #12
0
 def test_helperfn_as_updatepolicy(self):
     update_policy = UpdatePolicy(
         AutoScalingRollingUpdate=AutoScalingRollingUpdate(
             PauseTime="PT5M",
             MinInstancesInService="1",
             MaxBatchSize="1",
             WaitOnResourceSignals=True,
         ))
     group = AutoScalingGroup(
         "mygroup",
         AvailabilityZones=["eu-west-1a", "eu-west-1b"],
         LaunchConfigurationName="I'm a test",
         MaxSize=If("isstage", "1", "5"),
         MinSize="1",
         UpdatePolicy=If("UseUpdatePolicy", update_policy,
                         Ref("AWS::NoValue")),
     )
     self.assertTrue(group.validate())
コード例 #13
0
 def test_mininstances_mininstancesinservice_is_ref(self):
     paramMinInstancesInService = Parameter(
         "ParamMinInstancesInService",
         Type="String"
     )
     group = AutoScalingGroup(
         'mygroup',
         LaunchConfigurationName="I'm a test",
         MaxSize="4",
         MinSize="2",
         UpdatePolicy=UpdatePolicy(
             AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                 PauseTime='PT1M5S',
                 MinInstancesInService=Ref(paramMinInstancesInService),
                 MaxBatchSize="2",
             )
         )
     )
     self.assertTrue(group.validate())
コード例 #14
0
ファイル: EC2.py プロジェクト: joewcarpenter/simple-web-app
    def add_autoscaling_group(self,
                              name,
                              launch_configuration_name,
                              subnets,
                              desired_size=2,
                              min_size=1,
                              max_size=2,
                              health_check_type='EC2',
                              target_group_arns=[]):
        """
        Create Autoscaling Group

        :param name: Name of the ASG
        :param launch_configuration_name: Which launch configuration to use to create instances
        :param subnets: Subnet to spin up instances in
        :param desired_size: Desired number of instances
        :param min_size: Minimum number of instances
        :param max_size: Maximum number of instances
        :param health_check_type: Health check type
        :param target_group_arns: ARN of the target group(s), if any
        """
        auto_scaling_group = AutoScalingGroup(
            name,
            DesiredCapacity=desired_size,
            Tags=[{
                'Key': 'Name',
                'Value': name,
                'PropagateAtLaunch': True
            }],
            LaunchConfigurationName=Ref(launch_configuration_name),
            MinSize=min_size,
            MaxSize=max_size,
            VPCZoneIdentifier=subnets,
            HealthCheckType=health_check_type,
            HealthCheckGracePeriod=60,
            TargetGroupARNs=target_group_arns,
            UpdatePolicy=UpdatePolicy(
                AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                    PauseTime='PT1H',
                    MinInstancesInService=min_size,
                    MaxBatchSize='1',
                    WaitOnResourceSignals=True)))
        self.template.add_resource(auto_scaling_group)
コード例 #15
0
ファイル: cf_generator.py プロジェクト: duy156/houston
 def _auto_scaling_group(self):
     return AutoScalingGroup(
         "duy%sAutoscalingGroup" % self.config['env'],
         DesiredCapacity=self.config['scale_desire'],
         Tags=[
             Tag("Name", "duy-%s" % self.config['env'], True),
             Tag("Environment", self.config['env'], True),
             Tag("PropagateAtLaunch", "true", True)
         ],
         LaunchConfigurationName=Ref(self.launchConfiguration),
         MinSize=self.config['scale_min'],
         MaxSize=self.config['scale_max'],
         VPCZoneIdentifier=self.config['private_subnet'],
         LoadBalancerNames=[Ref(self.loadBalancer)],
         HealthCheckType="EC2",
         HealthCheckGracePeriod="300",
         TerminationPolicies=["OldestInstance", "Default"],
         UpdatePolicy=UpdatePolicy(
             AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                 PauseTime='PT5M',
                 MinInstancesInService="1",
                 MaxBatchSize='1',
                 WaitOnResourceSignals=True)))
コード例 #16
0
 def add_auto_scaling_group(self):
     '''
     Add Instance AutoScalingGroup
     '''
     self.cfn_template.add_resource(
         AutoScalingGroup(
             title=constants.INST_ASG,
             AvailabilityZones=[
                 ImportValue(Sub('${Environment}-PRIVATE-SUBNET-1-AZ')),
                 ImportValue(Sub('${Environment}-PRIVATE-SUBNET-2-AZ')),
             ],
             HealthCheckGracePeriod=int('150'),
             LaunchConfigurationName=Ref(constants.INST_LC),
             MaxSize='4',
             MinSize='2',
             VPCZoneIdentifier=[
                 ImportValue(Sub('${Environment}-PRIVATE-SUBNET-1')),
                 ImportValue(Sub('${Environment}-PRIVATE-SUBNET-2')),
             ],
             CreationPolicy=CreationPolicy(
                 ResourceSignal=ResourceSignal(
                     Count='2',
                     Timeout='PT30M'
                 )
             ),
             UpdatePolicy=UpdatePolicy(
                 AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                     MaxBatchSize=int('1'),
                     MinInstancesInService=int('1'),
                     PauseTime='PT10M',
                     WaitOnResourceSignals='true'
                 )
             )
         )
     )
     return self.cfn_template
コード例 #17
0
 def create_auto_scaling_group(self, asg_args):
     '''
     Method creates an auto scaling group and adds it to the resources list
     @param asg_args [dict] collection of keyword arguments for the asg
     '''
     autoscaling_group = self.add_resource(
         AutoScalingGroup(
             "AutoscalingGroup",
             DesiredCapacity=asg_args['desired_capacity'],
             Tags=[Tag("Name", "CloudformationLab", True)],
             LaunchConfigurationName=Ref(self.launch_configuration),
             MinSize=asg_args['min_capacity'],
             MaxSize=asg_args['max_capacity'],
             VPCZoneIdentifier=self.subnets,
             LoadBalancerNames=[Ref(self.load_balancer)],
             AvailabilityZones=self.availability_zones,
             HealthCheckType="ELB",
             HealthCheckGracePeriod=60,
             UpdatePolicy=UpdatePolicy(
                 AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                     PauseTime='PT5M',
                     MinInstancesInService=asg_args['min_capacity'],
                     MaxBatchSize='1',
                     WaitOnResourceSignals=True))))
コード例 #18
0
    def create_template(self):
        """Create template (main function called by Stacker)."""
        template = self.template
        variables = self.get_variables()
        template.add_version('2010-09-09')
        template.add_description('Kubernetes workers via EKS - V1.0.0 '
                                 '- compatible with amazon-eks-node-v23+')

        # Metadata
        template.add_metadata({
            'AWS::CloudFormation::Interface': {
                'ParameterGroups': [
                    {'Label': {'default': 'EKS Cluster'},
                     'Parameters': [variables[i].name
                                    for i
                                    in ['ClusterName',
                                        'ClusterControlPlaneSecurityGroup']]},
                    {'Label': {'default': 'Worker Node Configuration'},
                     'Parameters': [variables[i].name
                                    for i
                                    in ['NodeGroupName',
                                        'NodeAutoScalingGroupMinSize',
                                        'NodeAutoScalingGroupMaxSize',
                                        'UseDesiredInstanceCount',
                                        'NodeInstanceType',
                                        'NodeInstanceProfile',
                                        'NodeImageId',
                                        'NodeVolumeSize',
                                        'KeyName',
                                        'UseSpotInstances',
                                        'SpotBidPrice',
                                        'BootstrapArguments']]},
                    {'Label': {'default': 'Worker Network Configuration'},
                     'Parameters': [variables[i].name
                                    for i
                                    in ['VpcId', 'Subnets']]}
                ]
            }
        })

        # Conditions
        template.add_condition(
            'SetSpotPrice',
            Equals(variables['UseSpotInstances'].ref, 'yes')
        )
        template.add_condition(
            'DesiredInstanceCountSpecified',
            Equals(variables['UseDesiredInstanceCount'].ref, 'true')
        )
        template.add_condition(
            'KeyNameSpecified',
            Not(Equals(variables['KeyName'].ref, ''))
        )

        # Resources
        nodesecuritygroup = template.add_resource(
            ec2.SecurityGroup(
                'NodeSecurityGroup',
                GroupDescription='Security group for all nodes in the cluster',
                Tags=[
                    {'Key': Sub('kubernetes.io/cluster/${ClusterName}'),
                     'Value': 'owned'},
                ],
                VpcId=variables['VpcId'].ref
            )
        )
        template.add_output(
            Output(
                'NodeSecurityGroup',
                Description='Security group for all nodes in the cluster',
                Value=nodesecuritygroup.ref()
            )
        )
        template.add_resource(
            ec2.SecurityGroupIngress(
                'NodeSecurityGroupIngress',
                Description='Allow node to communicate with each other',
                GroupId=nodesecuritygroup.ref(),
                SourceSecurityGroupId=nodesecuritygroup.ref(),
                IpProtocol='-1',
                FromPort=0,
                ToPort=65535
            )
        )
        template.add_resource(
            ec2.SecurityGroupIngress(
                'NodeSecurityGroupFromControlPlaneIngress',
                Description='Allow worker Kubelets and pods to receive '
                            'communication from the cluster control plane',
                GroupId=nodesecuritygroup.ref(),
                SourceSecurityGroupId=variables['ClusterControlPlaneSecurityGroup'].ref,  # noqa
                IpProtocol='tcp',
                FromPort=1025,
                ToPort=65535
            )
        )
        template.add_resource(
            ec2.SecurityGroupEgress(
                'ControlPlaneEgressToNodeSecurityGroup',
                Description='Allow the cluster control plane to communicate '
                            'with worker Kubelet and pods',
                GroupId=variables['ClusterControlPlaneSecurityGroup'].ref,
                DestinationSecurityGroupId=nodesecuritygroup.ref(),
                IpProtocol='tcp',
                FromPort=1025,
                ToPort=65535
            )
        )
        template.add_resource(
            ec2.SecurityGroupIngress(
                'NodeSecurityGroupFromControlPlaneOn443Ingress',
                Description='Allow pods running extension API servers on port '
                            '443 to receive communication from cluster '
                            'control plane',
                GroupId=nodesecuritygroup.ref(),
                SourceSecurityGroupId=variables['ClusterControlPlaneSecurityGroup'].ref,  # noqa
                IpProtocol='tcp',
                FromPort=443,
                ToPort=443
            )
        )
        template.add_resource(
            ec2.SecurityGroupEgress(
                'ControlPlaneEgressToNodeSecurityGroupOn443',
                Description='Allow the cluster control plane to communicate '
                            'with pods running extension API servers on port '
                            '443',
                GroupId=variables['ClusterControlPlaneSecurityGroup'].ref,
                DestinationSecurityGroupId=nodesecuritygroup.ref(),
                IpProtocol='tcp',
                FromPort=443,
                ToPort=443
            )
        )
        template.add_resource(
            ec2.SecurityGroupIngress(
                'ClusterControlPlaneSecurityGroupIngress',
                Description='Allow pods to communicate with the cluster API '
                            'Server',
                GroupId=variables['ClusterControlPlaneSecurityGroup'].ref,
                SourceSecurityGroupId=nodesecuritygroup.ref(),
                IpProtocol='tcp',
                FromPort=443,
                ToPort=443
            )
        )

        nodelaunchconfig = template.add_resource(
            autoscaling.LaunchConfiguration(
                'NodeLaunchConfig',
                AssociatePublicIpAddress=True,
                IamInstanceProfile=variables['NodeInstanceProfile'].ref,
                ImageId=variables['NodeImageId'].ref,
                InstanceType=variables['NodeInstanceType'].ref,
                KeyName=If(
                    'KeyNameSpecified',
                    variables['KeyName'].ref,
                    NoValue
                ),
                SecurityGroups=[nodesecuritygroup.ref()],
                SpotPrice=If('SetSpotPrice',
                             variables['SpotBidPrice'].ref,
                             NoValue),
                BlockDeviceMappings=[autoscaling.BlockDeviceMapping(
                    DeviceName='/dev/xvda',
                    Ebs=autoscaling.EBSBlockDevice(
                        VolumeSize=variables['NodeVolumeSize'].ref,
                        VolumeType='gp2',
                        DeleteOnTermination=True
                    )
                )],
                UserData=Base64(
                    Sub('\n'.join([
                        '#!/bin/bash',
                        'set -o xtrace',
                        '/etc/eks/bootstrap.sh ${ClusterName} ${BootstrapArguments}',  # noqa
                        '/opt/aws/bin/cfn-signal --exit-code $? \\',
                        '--stack ${AWS::StackName} \\',
                        '--resource NodeGroup \\',
                        '--region ${AWS::Region}'
                    ]))
                )
            )
        )

        template.add_resource(
            autoscaling.AutoScalingGroup(
                'NodeGroup',
                DesiredCapacity=If(
                    'DesiredInstanceCountSpecified',
                    variables['NodeAutoScalingGroupMaxSize'].ref,
                    NoValue
                ),
                LaunchConfigurationName=nodelaunchconfig.ref(),
                MinSize=variables['NodeAutoScalingGroupMinSize'].ref,
                MaxSize=variables['NodeAutoScalingGroupMaxSize'].ref,
                VPCZoneIdentifier=variables['Subnets'].ref,
                Tags=[
                    autoscaling.Tag(
                        'Name',
                        Sub('${ClusterName}-${NodeGroupName}-Node'),
                        True),
                    autoscaling.Tag(
                        Sub('kubernetes.io/cluster/${ClusterName}'),
                        'owned',
                        True)
                ],
                UpdatePolicy=UpdatePolicy(
                    AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                        MinInstancesInService='1',
                        MaxBatchSize='1'
                    )
                )
            )
        )
コード例 #19
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())
コード例 #20
0
            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,
                      AutoScalingGroupName=Ref(AutoscalingGroupX),
                      AdjustmentType="ChangeInCapacity",
                      Cooldown="300",
コード例 #21
0
ファイル: k8s_workers.py プロジェクト: onicagroup/runway
    def create_template(self) -> None:
        """Create template (main function called by Stacker)."""
        template = self.template
        template.add_version("2010-09-09")
        template.add_description(
            "Kubernetes workers via EKS - V1.0.0 "
            "- compatible with amazon-eks-node-v23+"
        )

        # Metadata
        template.add_metadata(
            {
                "AWS::CloudFormation::Interface": {
                    "ParameterGroups": [
                        {
                            "Label": {"default": "EKS Cluster"},
                            "Parameters": [
                                self.variables[i].name
                                for i in [
                                    "ClusterName",
                                    "ClusterControlPlaneSecurityGroup",
                                ]
                            ],
                        },
                        {
                            "Label": {"default": "Worker Node Configuration"},
                            "Parameters": [
                                self.variables[i].name
                                for i in [
                                    "NodeGroupName",
                                    "NodeAutoScalingGroupMinSize",
                                    "NodeAutoScalingGroupMaxSize",
                                    "UseDesiredInstanceCount",
                                    "NodeInstanceType",
                                    "NodeInstanceProfile",
                                    "NodeImageId",
                                    "NodeVolumeSize",
                                    "KeyName",
                                    "UseSpotInstances",
                                    "SpotBidPrice",
                                    "BootstrapArguments",
                                ]
                            ],
                        },
                        {
                            "Label": {"default": "Worker Network Configuration"},
                            "Parameters": [
                                self.variables[i].name for i in ["VpcId", "Subnets"]
                            ],
                        },
                    ]
                }
            }
        )

        # Conditions
        template.add_condition(
            "SetSpotPrice", Equals(self.variables["UseSpotInstances"].ref, "yes")
        )
        template.add_condition(
            "DesiredInstanceCountSpecified",
            Equals(self.variables["UseDesiredInstanceCount"].ref, "true"),
        )
        template.add_condition(
            "KeyNameSpecified", Not(Equals(self.variables["KeyName"].ref, ""))
        )

        # Resources
        nodesecuritygroup = template.add_resource(
            ec2.SecurityGroup(
                "NodeSecurityGroup",
                GroupDescription="Security group for all nodes in the cluster",
                Tags=[
                    {
                        "Key": Sub("kubernetes.io/cluster/${ClusterName}"),
                        "Value": "owned",
                    },
                ],
                VpcId=self.variables["VpcId"].ref,
            )
        )
        template.add_output(
            Output(
                "NodeSecurityGroup",
                Description="Security group for all nodes in the cluster",
                Value=nodesecuritygroup.ref(),
            )
        )
        template.add_resource(
            ec2.SecurityGroupIngress(
                "NodeSecurityGroupIngress",
                Description="Allow node to communicate with each other",
                GroupId=nodesecuritygroup.ref(),
                SourceSecurityGroupId=nodesecuritygroup.ref(),
                IpProtocol="-1",
                FromPort=0,
                ToPort=65535,
            )
        )
        template.add_resource(
            ec2.SecurityGroupIngress(
                "NodeSecurityGroupFromControlPlaneIngress",
                Description="Allow worker Kubelets and pods to receive "
                "communication from the cluster control plane",
                GroupId=nodesecuritygroup.ref(),
                SourceSecurityGroupId=self.variables[
                    "ClusterControlPlaneSecurityGroup"
                ].ref,  # noqa
                IpProtocol="tcp",
                FromPort=1025,
                ToPort=65535,
            )
        )
        template.add_resource(
            ec2.SecurityGroupEgress(
                "ControlPlaneEgressToNodeSecurityGroup",
                Description="Allow the cluster control plane to communicate "
                "with worker Kubelet and pods",
                GroupId=self.variables["ClusterControlPlaneSecurityGroup"].ref,
                DestinationSecurityGroupId=nodesecuritygroup.ref(),
                IpProtocol="tcp",
                FromPort=1025,
                ToPort=65535,
            )
        )
        template.add_resource(
            ec2.SecurityGroupIngress(
                "NodeSecurityGroupFromControlPlaneOn443Ingress",
                Description="Allow pods running extension API servers on port "
                "443 to receive communication from cluster "
                "control plane",
                GroupId=nodesecuritygroup.ref(),
                SourceSecurityGroupId=self.variables[
                    "ClusterControlPlaneSecurityGroup"
                ].ref,  # noqa
                IpProtocol="tcp",
                FromPort=443,
                ToPort=443,
            )
        )
        template.add_resource(
            ec2.SecurityGroupEgress(
                "ControlPlaneEgressToNodeSecurityGroupOn443",
                Description="Allow the cluster control plane to communicate "
                "with pods running extension API servers on port "
                "443",
                GroupId=self.variables["ClusterControlPlaneSecurityGroup"].ref,
                DestinationSecurityGroupId=nodesecuritygroup.ref(),
                IpProtocol="tcp",
                FromPort=443,
                ToPort=443,
            )
        )
        template.add_resource(
            ec2.SecurityGroupIngress(
                "ClusterControlPlaneSecurityGroupIngress",
                Description="Allow pods to communicate with the cluster API " "Server",
                GroupId=self.variables["ClusterControlPlaneSecurityGroup"].ref,
                SourceSecurityGroupId=nodesecuritygroup.ref(),
                IpProtocol="tcp",
                FromPort=443,
                ToPort=443,
            )
        )

        nodelaunchconfig = template.add_resource(
            autoscaling.LaunchConfiguration(
                "NodeLaunchConfig",
                AssociatePublicIpAddress=True,
                IamInstanceProfile=self.variables["NodeInstanceProfile"].ref,
                ImageId=self.variables["NodeImageId"].ref,
                InstanceType=self.variables["NodeInstanceType"].ref,
                KeyName=If("KeyNameSpecified", self.variables["KeyName"].ref, NoValue),
                SecurityGroups=[nodesecuritygroup.ref()],
                SpotPrice=If(
                    "SetSpotPrice", self.variables["SpotBidPrice"].ref, NoValue
                ),
                BlockDeviceMappings=[
                    autoscaling.BlockDeviceMapping(
                        DeviceName="/dev/xvda",
                        Ebs=autoscaling.EBSBlockDevice(
                            VolumeSize=self.variables["NodeVolumeSize"].ref,
                            VolumeType="gp2",
                            DeleteOnTermination=True,
                        ),
                    )
                ],
                UserData=Base64(
                    Sub(
                        "\n".join(
                            [
                                "#!/bin/bash",
                                "set -o xtrace",
                                "/etc/eks/bootstrap.sh ${ClusterName} ${BootstrapArguments}",
                                "/opt/aws/bin/cfn-signal --exit-code $? \\",
                                "--stack ${AWS::StackName} \\",
                                "--resource NodeGroup \\",
                                "--region ${AWS::Region}",
                            ]
                        )
                    )
                ),
            )
        )

        template.add_resource(
            autoscaling.AutoScalingGroup(
                "NodeGroup",
                DesiredCapacity=If(
                    "DesiredInstanceCountSpecified",
                    self.variables["NodeAutoScalingGroupMaxSize"].ref,
                    NoValue,
                ),
                LaunchConfigurationName=nodelaunchconfig.ref(),
                MinSize=self.variables["NodeAutoScalingGroupMinSize"].ref,
                MaxSize=self.variables["NodeAutoScalingGroupMaxSize"].ref,
                VPCZoneIdentifier=self.variables["Subnets"].ref,
                Tags=[
                    autoscaling.Tag(
                        "Name", Sub("${ClusterName}-${NodeGroupName}-Node"), True
                    ),
                    autoscaling.Tag(
                        Sub("kubernetes.io/cluster/${ClusterName}"), "owned", True
                    ),
                ],
                UpdatePolicy=UpdatePolicy(
                    AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                        MinInstancesInService="1", MaxBatchSize="1"
                    )
                ),
            )
        )
コード例 #22
0
def generate_cloudformation_template():
    enable_elb = sys.argv[1]
    input_scaling_policies = ast.literal_eval(sys.argv[2])
    input_alarms = ast.literal_eval(sys.argv[3])

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

    template = Template()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    return template
コード例 #23
0
ファイル: test_policies.py プロジェクト: yasra002/troposphere
 def test_pausetime(self):
     with self.assertRaises(ValueError):
         UpdatePolicy(AutoScalingRollingUpdate=AutoScalingRollingUpdate(
             PauseTime='90'))
コード例 #24
0
def build_template(sierrafile):
    template = Template()

    template.add_version('2010-09-09')

    template.add_metadata(build_interface(sierrafile.extra_params))

    parameters = AttrDict(

        # Network Parameters

        vpc_cidr=template.add_parameter(Parameter(
            'VpcCidr',
            Type='String',
            Default='192.172.0.0/16',
        )),
        subnet1_cidr=template.add_parameter(Parameter(
            'Subnet1Cidr',
            Type='String',
            Default='192.172.1.0/24',
        )),
        subnet2_cidr=template.add_parameter(Parameter(
            'Subnet2Cidr',
            Type='String',
            Default='192.172.2.0/24',
        )),

        # ECS Parameters

        cluster_size=template.add_parameter(Parameter(
            'ClusterSize',
            Type='Number',
            Default=2,
        )),
        instance_type=template.add_parameter(Parameter(
            'InstanceType',
            Type='String',
            Default='t2.medium'
        )),
        key_name=template.add_parameter(Parameter(
            'KeyName',
            Type='AWS::EC2::KeyPair::KeyName',
        )),
        image_id=template.add_parameter(Parameter(
            'ImageId',
            Type='AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>',
            Default=(
                '/aws/service/ecs/optimized-ami'
                '/amazon-linux/recommended/image_id'
            ),
            Description=(
              'An SSM parameter that resolves to a valid AMI ID.'
              ' This is the AMI that will be used to create ECS hosts.'
              ' The default is the current recommended ECS-optimized AMI.'
            )
        )),

        # Other Parameters

        github_token=template.add_parameter(Parameter(
            'GitHubToken',
            Type='String',
            NoEcho=True,
        )),
    )

    # Environment Variable Parameters

    for env_var_param, env_var_name in sierrafile.extra_params:
        template.add_parameter(Parameter(
            env_var_param,
            Type='String',
            NoEcho=True,
        ))

    # Resource Declarations

    # # Network

    network_vpc = template.add_resource(VPC(
        'NetworkVpc',
        CidrBlock=Ref(parameters.vpc_cidr),
        Tags=Tags(Name=Ref('AWS::StackName')),
    ))

    network_ig = template.add_resource(InternetGateway(
        'NetworkInternetGateway',
        Tags=Tags(Name=Ref('AWS::StackName')),
    ))

    vpc_attach = template.add_resource(VPCGatewayAttachment(
        'NetworkInternetGatewayAttachment',
        InternetGatewayId=Ref(network_ig),
        VpcId=Ref(network_vpc),
    ))

    route_table = template.add_resource(RouteTable(
        'NetworkRouteTable',
        VpcId=Ref(network_vpc),
        Tags=Tags(Name=Ref('AWS::StackName')),
    ))

    template.add_resource(Route(
        'NetworkDefaultRoute',
        DependsOn=[vpc_attach.title],
        RouteTableId=Ref(route_table),
        DestinationCidrBlock='0.0.0.0/0',
        GatewayId=Ref(network_ig),
    ))

    subnet1 = template.add_resource(Subnet(
        'NetworkSubnet1',
        VpcId=Ref(network_vpc),
        AvailabilityZone=Select(0, GetAZs()),
        MapPublicIpOnLaunch=True,
        CidrBlock=Ref(parameters.subnet1_cidr),
        Tags=Tags(Name=Sub('${AWS::StackName} (Public)')),
    ))

    subnet2 = template.add_resource(Subnet(
        'NetworkSubnet2',
        VpcId=Ref(network_vpc),
        AvailabilityZone=Select(1, GetAZs()),
        MapPublicIpOnLaunch=True,
        CidrBlock=Ref(parameters.subnet2_cidr),
        Tags=Tags(Name=Sub('${AWS::StackName} (Public)')),
    ))

    template.add_resource(SubnetRouteTableAssociation(
        'NetworkSubnet1RouteTableAssociation',
        RouteTableId=Ref(route_table),
        SubnetId=Ref(subnet1),
    ))

    template.add_resource(SubnetRouteTableAssociation(
        'NetworkSubnet2RouteTableAssociation',
        RouteTableId=Ref(route_table),
        SubnetId=Ref(subnet2),
    ))

    elb = template.add_resource(LoadBalancer(
        ELB_NAME,
        Name=Sub('${AWS::StackName}-elb'),
        Type='network',
        Subnets=[Ref(subnet1), Ref(subnet2)],
    ))

    # # Cluster

    ecs_host_role = template.add_resource(Role(
        'EcsHostRole',
        AssumeRolePolicyDocument=PolicyDocument(
            Statement=[Statement(
                Effect=Allow,
                Principal=Principal('Service', 'ec2.amazonaws.com'),
                Action=[awacs.sts.AssumeRole]
            )],
        ),
        ManagedPolicyArns=[
            'arn:aws:iam::aws:policy/'
            'service-role/AmazonEC2ContainerServiceforEC2Role'
        ]
    ))

    ecs_host_profile = template.add_resource(InstanceProfile(
        'EcsHostInstanceProfile',
        Roles=[Ref(ecs_host_role)]
    ))

    ecs_host_sg = template.add_resource(SecurityGroup(
        'EcsHostSecurityGroup',
        GroupDescription=Sub('${AWS::StackName}-hosts'),
        VpcId=Ref(network_vpc),
        SecurityGroupIngress=[SecurityGroupRule(
            CidrIp='0.0.0.0/0',
            IpProtocol='-1'
        )]
    ))

    cluster = template.add_resource(Cluster(
        'EcsCluster',
        ClusterName=Ref('AWS::StackName')
    ))

    autoscaling_name = 'EcsHostAutoScalingGroup'
    launch_conf_name = 'EcsHostLaunchConfiguration'

    launch_conf = template.add_resource(LaunchConfiguration(
        launch_conf_name,
        ImageId=Ref(parameters.image_id),
        InstanceType=Ref(parameters.instance_type),
        IamInstanceProfile=Ref(ecs_host_profile),
        KeyName=Ref(parameters.key_name),
        SecurityGroups=[Ref(ecs_host_sg)],
        UserData=Base64(Sub(
            '#!/bin/bash\n'
            'yum install -y aws-cfn-bootstrap\n'
            '/opt/aws/bin/cfn-init -v'
            ' --region ${AWS::Region}'
            ' --stack ${AWS::StackName}'
            f' --resource {launch_conf_name}\n'
            '/opt/aws/bin/cfn-signal -e $?'
            ' --region ${AWS::Region}'
            ' --stack ${AWS::StackName}'
            f' --resource {autoscaling_name}\n'
        )),
        Metadata={
            'AWS::CloudFormation::Init': {
                'config': {
                    'commands': {
                        '01_add_instance_to_cluster': {
                            'command': Sub(
                                f'echo ECS_CLUSTER=${{{cluster.title}}}'
                                f' > /etc/ecs/ecs.config'
                            ),
                        }
                    },
                    'files': {
                        '/etc/cfn/cfn-hup.conf': {
                            'mode': 0o400,
                            'owner': 'root',
                            'group': 'root',
                            'content': Sub(
                                '[main]\n'
                                'stack=${AWS::StackId}\n'
                                'region=${AWS::Region}\n'
                            ),
                        },
                        '/etc/cfn/hooks.d/cfn-auto-reloader.conf': {
                            'content': Sub(
                                '[cfn-auto-reloader-hook]\n'
                                'triggers=post.update\n'
                                'path=Resources.ContainerInstances.Metadata'
                                '.AWS::CloudFormation::Init\n'
                                'action=/opt/aws/bin/cfn-init -v'
                                ' --region ${AWS::Region}'
                                ' --stack ${AWS::StackName}'
                                f' --resource {launch_conf_name}\n'
                            ),
                        },
                    },
                    'services': {
                        'sysvinit': {
                            'cfn-hup': {
                                'enabled': True,
                                'ensureRunning': True,
                                'files': [
                                    '/etc/cfn/cfn-hup.conf',
                                    '/etc/cfn/hooks.d/cfn-auto-reloader.conf'
                                ]
                            }
                        }
                    }
                }
            }
        }
    ))

    autoscaling_group = template.add_resource(AutoScalingGroup(
        autoscaling_name,
        VPCZoneIdentifier=[Ref(subnet1), Ref(subnet2)],
        LaunchConfigurationName=Ref(launch_conf),
        DesiredCapacity=Ref(parameters.cluster_size),
        MinSize=Ref(parameters.cluster_size),
        MaxSize=Ref(parameters.cluster_size),
        Tags=[{
            'Key': 'Name',
            'Value': Sub('${AWS::StackName} - ECS Host'),
            'PropagateAtLaunch': True,
        }],
        CreationPolicy=CreationPolicy(
            ResourceSignal=ResourceSignal(Timeout='PT15M'),
        ),
        UpdatePolicy=UpdatePolicy(
            AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                MinInstancesInService=1,
                MaxBatchSize=1,
                PauseTime='PT5M',
                WaitOnResourceSignals=True,
            ),
        ),
    ))

    # # Services

    task_role = template.add_resource(Role(
        'TaskExecutionRole',
        AssumeRolePolicyDocument=PolicyDocument(
            Statement=[Statement(
                Effect=Allow,
                Principal=Principal('Service', 'ecs-tasks.amazonaws.com'),
                Action=[awacs.sts.AssumeRole],
            )],
        ),
        ManagedPolicyArns=[
            'arn:aws:iam::aws:policy/'
            'service-role/AmazonECSTaskExecutionRolePolicy'
        ],
    ))

    artifact_bucket = template.add_resource(Bucket(
        'ArtifactBucket',
        DeletionPolicy='Retain',
    ))

    codebuild_role = template.add_resource(Role(
        'CodeBuildServiceRole',
        Path='/',
        AssumeRolePolicyDocument=PolicyDocument(
            Version='2012-10-17',
            Statement=[
                Statement(
                    Effect=Allow,
                    Principal=Principal(
                        'Service', 'codebuild.amazonaws.com'
                    ),
                    Action=[
                        awacs.sts.AssumeRole,
                    ],
                ),
            ],
        ),
        Policies=[Policy(
            PolicyName='root',
            PolicyDocument=PolicyDocument(
                Version='2012-10-17',
                Statement=[
                    Statement(
                        Resource=['*'],
                        Effect=Allow,
                        Action=[
                            awacs.ssm.GetParameters,
                        ],
                    ),
                    Statement(
                        Resource=['*'],
                        Effect=Allow,
                        Action=[
                            awacs.s3.GetObject,
                            awacs.s3.PutObject,
                            awacs.s3.GetObjectVersion,
                        ],
                    ),
                    Statement(
                        Resource=['*'],
                        Effect=Allow,
                        Action=[
                            awacs.logs.CreateLogGroup,
                            awacs.logs.CreateLogStream,
                            awacs.logs.PutLogEvents,
                        ],
                    ),
                ],
            ),
        )],
    ))

    codepipeline_role = template.add_resource(Role(
        'CodePipelineServiceRole',
        Path='/',
        AssumeRolePolicyDocument=PolicyDocument(
            Version='2012-10-17',
            Statement=[
                Statement(
                    Effect=Allow,
                    Principal=Principal(
                        'Service', 'codepipeline.amazonaws.com'
                    ),
                    Action=[
                        awacs.sts.AssumeRole,
                    ],
                ),
            ],
        ),
        Policies=[Policy(
            PolicyName='root',
            PolicyDocument=PolicyDocument(
                Version='2012-10-17',
                Statement=[
                    Statement(
                        Resource=[
                            Sub(f'${{{artifact_bucket.title}.Arn}}/*')
                        ],
                        Effect=Allow,
                        Action=[
                            awacs.s3.GetBucketVersioning,
                            awacs.s3.GetObject,
                            awacs.s3.GetObjectVersion,
                            awacs.s3.PutObject,
                        ],
                    ),
                    Statement(
                        Resource=['*'],
                        Effect=Allow,
                        Action=[
                            awacs.ecs.DescribeServices,
                            awacs.ecs.DescribeTaskDefinition,
                            awacs.ecs.DescribeTasks,
                            awacs.ecs.ListTasks,
                            awacs.ecs.RegisterTaskDefinition,
                            awacs.ecs.UpdateService,
                            awacs.codebuild.StartBuild,
                            awacs.codebuild.BatchGetBuilds,
                            awacs.iam.PassRole,
                        ],
                    ),
                ],
            ),
        )],
    ))

    log_group = template.add_resource(LogGroup(
        'LogGroup',
        LogGroupName=Sub('/ecs/${AWS::StackName}'),
    ))

    if any(conf.pipeline.enable for conf in sierrafile.services.values()):
        project = template.add_resource(Project(
            'CodeBuildProject',
            Name=Sub('${AWS::StackName}-build'),
            ServiceRole=Ref(codebuild_role),
            Artifacts=Artifacts(Type='CODEPIPELINE'),
            Source=Source(Type='CODEPIPELINE'),
            Environment=Environment(
                ComputeType='BUILD_GENERAL1_SMALL',
                Image='aws/codebuild/docker:17.09.0',
                Type='LINUX_CONTAINER',
            ),
        ))

    for name, settings in sierrafile.services.items():
        task_definition = template.add_resource(TaskDefinition(
            f'{name}TaskDefinition',
            RequiresCompatibilities=['EC2'],
            Cpu=str(settings.container.cpu),
            Memory=str(settings.container.memory),
            NetworkMode='bridge',
            ExecutionRoleArn=Ref(task_role.title),
            ContainerDefinitions=[
                ContainerDefinition(
                    Name=f'{name}',
                    Image=settings.container.image,
                    Memory=str(settings.container.memory),
                    Essential=True,
                    PortMappings=[
                        PortMapping(
                            ContainerPort=settings.container.port,
                            Protocol='tcp',
                        ),
                    ],
                    Environment=[
                        troposphere.ecs.Environment(Name=k, Value=v)
                        for k, v in sierrafile.env_vars.items()
                        if k in settings.get('environment', [])
                    ],
                    LogConfiguration=LogConfiguration(
                        LogDriver='awslogs',
                        Options={
                            'awslogs-region': Ref('AWS::Region'),
                            'awslogs-group': Ref(log_group.title),
                            'awslogs-stream-prefix': Ref('AWS::StackName'),
                        },
                    ),
                ),
            ],
        ))

        target_group = template.add_resource(TargetGroup(
            f'{name}TargetGroup',
            Port=settings.container.port,
            Protocol='TCP',
            VpcId=Ref(network_vpc),
            Tags=Tags(Name=Sub(f'${{AWS::StackName}}-{name}')),
        ))

        listener = template.add_resource(Listener(
            f'{name}ElbListener',
            LoadBalancerArn=Ref(elb),
            Port=settings.container.port,
            Protocol='TCP',
            DefaultActions=[
                Action(TargetGroupArn=Ref(target_group), Type='forward')
            ],
        ))

        service = template.add_resource(Service(
            f'{name}Service',
            Cluster=Ref(cluster),
            ServiceName=f'{name}-service',
            DependsOn=[autoscaling_group.title, listener.title],
            DesiredCount=settings.container.count,
            TaskDefinition=Ref(task_definition),
            LaunchType='EC2',
            LoadBalancers=[
                troposphere.ecs.LoadBalancer(
                    ContainerName=f'{name}',
                    ContainerPort=settings.container.port,
                    TargetGroupArn=Ref(target_group),
                ),
            ],
        ))

        if settings.pipeline.enable:
            pipeline = template.add_resource(Pipeline(
                f'{name}Pipeline',
                RoleArn=GetAtt(codepipeline_role, 'Arn'),
                ArtifactStore=ArtifactStore(
                    Type='S3',
                    Location=Ref(artifact_bucket),
                ),
                Stages=[
                    Stages(
                        Name='Source',
                        Actions=[Actions(
                            Name='Source',
                            ActionTypeId=ActionTypeId(
                                Category='Source',
                                Owner='ThirdParty',
                                Version='1',
                                Provider='GitHub',
                            ),
                            OutputArtifacts=[
                                OutputArtifacts(Name=f'{name}Source'),
                            ],
                            RunOrder='1',
                            Configuration={
                                'Owner': settings.pipeline.user,
                                'Repo': settings.pipeline.repo,
                                'Branch': settings.pipeline.branch,
                                'OAuthToken': Ref(parameters.github_token),
                            },
                        )],
                    ),
                    Stages(
                        Name='Build',
                        Actions=[Actions(
                            Name='Build',
                            ActionTypeId=ActionTypeId(
                                Category='Build',
                                Owner='AWS',
                                Version='1',
                                Provider='CodeBuild',
                            ),
                            InputArtifacts=[
                                InputArtifacts(Name=f'{name}Source'),
                            ],
                            OutputArtifacts=[
                                OutputArtifacts(Name=f'{name}Build'),
                            ],
                            RunOrder='1',
                            Configuration={
                                'ProjectName': Ref(project),
                            },
                        )],
                    ),
                    Stages(
                        Name='Deploy',
                        Actions=[Actions(
                            Name='Deploy',
                            ActionTypeId=ActionTypeId(
                                Category='Deploy',
                                Owner='AWS',
                                Version='1',
                                Provider='ECS',
                            ),
                            InputArtifacts=[
                                InputArtifacts(Name=f'{name}Build')
                            ],
                            RunOrder='1',
                            Configuration={
                                'ClusterName': Ref(cluster),
                                'ServiceName': Ref(service),
                                'FileName': 'image.json',
                            },
                        )],
                    ),
                ],
            ))

            template.add_resource(Webhook(
                f'{name}CodePipelineWebhook',
                Name=Sub(f'${{AWS::StackName}}-{name}-webhook'),
                Authentication='GITHUB_HMAC',
                AuthenticationConfiguration=AuthenticationConfiguration(
                    SecretToken=Ref(parameters.github_token),
                ),
                Filters=[FilterRule(
                    JsonPath='$.ref',
                    MatchEquals=f'refs/heads/{settings.pipeline.branch}'
                )],
                TargetAction='Source',
                TargetPipeline=Ref(pipeline),
                TargetPipelineVersion=1,
                RegisterWithThirdParty=True,
            ))

    return template
コード例 #25
0
ファイル: stack.py プロジェクト: jpza/ekscli
    def _create_cfn_template(self):
        self.tpl = Template()
        self.tpl.add_version('2010-09-09')
        self.tpl.add_description('CFN template to create an EKS node group and affiliated resources.')

        eks_tag = 'kubernetes.io/cluster/{}'.format(self.cluster.name)

        r = self.resources.get(self.RESOURCE_NG_ROLE.name)
        if self.role:
            profile = InstanceProfile(
                self.RESOURCE_NG_PROFILE.name, InstanceProfileName=self.tag_name, Path='/', Roles=[self.role])
            account_id = boto3.session.Session().client('sts').get_caller_identity().get('Account')
            role_arn = 'arn:aws:iam::{}:role/{}'.format(account_id, self.role)
            self.tpl.add_output(
                Output(self.RESOURCE_NG_ROLE.name, Value=role_arn, Description='Node group role'))
            r.status = Status.provided
            r.resource_id = role_arn
        else:
            role = Role(
                self.RESOURCE_NG_ROLE.name, RoleName=self.tag_name,
                AssumeRolePolicyDocument=Policy(Statement=[
                    Statement(Effect=Allow, Action=[AssumeRole],
                              Principal=Principal('Service', ['ec2.amazonaws.com'])), ], ),
                ManagedPolicyArns=['arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy',
                                   'arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy',
                                   'arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly']
            )
            self.tpl.add_resource(role)
            profile = InstanceProfile(
                self.RESOURCE_NG_PROFILE.name, InstanceProfileName=self.tag_name, Path='/', Roles=[Ref(role)])
            self.tpl.add_output(
                Output(self.RESOURCE_NG_ROLE.name, Value=GetAtt(role, 'Arn'), Description='Node group role'))

        self.tpl.add_resource(profile)

        if self.sg_igresses:
            sg = SecurityGroup(
                self.RESOURCE_NG_SG.name, VpcId=self.cluster.vpc, Tags=Tags({'Name': self.tag_name, eks_tag: 'owned'}),
                GroupDescription='Security Group applied to the EKS node group',
                SecurityGroupIngress=[SecurityGroupRule(IpProtocol=r.protocol, FromPort=r.from_port, ToPort=r.to_port,
                                                        CidrIp=r.cidr) for r in self.sg_igresses]
            )
        else:
            sg = SecurityGroup(
                self.RESOURCE_NG_SG.name, VpcId=self.cluster.vpc, Tags=Tags({'Name': self.tag_name, eks_tag: 'owned'}),
                GroupDescription='Security Group applied to the EKS node group',
            )
        self.tpl.add_resource(sg)

        self.tpl.add_resource(SecurityGroupIngress(
            self.RESOURCE_NG_SG_INGRESS.name, DependsOn=sg, Description='Allow node to communicate with each other',
            GroupId=Ref(sg), SourceSecurityGroupId=Ref(sg), IpProtocol='-1', FromPort=0, ToPort=65535
        ))

        self.tpl.add_resource(SecurityGroupIngress(
            self.RESOURCE_NG_SG_CP_INGRESS.name, DependsOn=sg,
            Description='Allow kubelet and pods on the nodes to receive communication from the cluster control plane',
            GroupId=Ref(sg), SourceSecurityGroupId=self.cluster.sg, IpProtocol='tcp', FromPort=1025, ToPort=65535
        ))

        self.tpl.add_resource(SecurityGroupEgress(
            self.RESOURCE_CP_EGRESS_TO_NG.name, DependsOn=sg,
            Description='Allow the cluster control plane to communicate with nodes kubelet and pods',
            GroupId=self.cluster.sg, DestinationSecurityGroupId=Ref(sg), IpProtocol='tcp', FromPort=1025, ToPort=65535
        ))

        self.tpl.add_resource(SecurityGroupIngress(
            self.RESOURCE_CP_SG_INGRESS.name, DependsOn=sg,
            Description='Allow pods to communicate with the cluster API Server',
            GroupId=self.cluster.sg, SourceSecurityGroupId=Ref(sg), IpProtocol='tcp', FromPort=443, ToPort=443
        ))

        # keypair
        ec2 = boto3.session.Session().resource('ec2')
        r = self.resources.get(self.RESOURCE_NG_KEYPAIR.name)
        if not self.keypair:
            keyname = 'eks{}'.format(''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(5)))
            with open(self.ssh_public_key, 'rb') as f:
                ec2.import_key_pair(KeyName=keyname, PublicKeyMaterial=f.read())
            self.keypair = keyname
            self.keypair_imported = True
            self.tpl.add_output(Output(self.OUTPUT_KEYNAME, Value=self.keypair, Description='Imported kaypair name'))
            r.status = Status.created
        else:
            r.status = Status.provided

        r.resource_id = self.keypair

        # auto-scaling group and launch configuration
        if self.no_user_data:
            lc = LaunchConfiguration(
                self.RESOURCE_NG_ASG_LC.name, AssociatePublicIpAddress=self.use_public_ip,
                IamInstanceProfile=Ref(profile),
                ImageId=self.ami, InstanceType=self.instance, KeyName=self.keypair, SecurityGroups=[Ref(sg)])
        else:
            user_data = Base64(
                Join('', [line + '\n' for line in
                          Environment().from_string(self.USER_DATA).render(
                              ci=self.cluster, ng_asg=self.RESOURCE_NG_ASG.name, stack_name=self.stack_name,
                              max_pods=self.MAX_PODS.get(self.instance), region=self.region).split('\n')]))
            lc = LaunchConfiguration(
                self.RESOURCE_NG_ASG_LC.name, AssociatePublicIpAddress=self.use_public_ip,
                IamInstanceProfile=Ref(profile),
                ImageId=self.ami, InstanceType=self.instance, KeyName=self.keypair, SecurityGroups=[Ref(sg)],
                UserData=user_data)

        self.tpl.add_resource(lc)
        self.tpl.add_resource(AutoScalingGroup(
            self.RESOURCE_NG_ASG.name, DesiredCapacity=self.desired, MinSize=self.min, MaxSize=self.max,
            LaunchConfigurationName=Ref(lc), VPCZoneIdentifier=self.subnets,
            Tags=[Tag('Name', self.tag_name, True), Tag(eks_tag, 'owned', True)],
            UpdatePolicy=UpdatePolicy(
                AutoScalingRollingUpdate=AutoScalingRollingUpdate(MinInstancesInService=1, MaxBatchSize=1))))
コード例 #26
0
    def _add_ec2_auto_scaling(self):
        instance_profile = self._add_instance_profile()
        self.sg_alb = SecurityGroup(
            "SecurityGroupAlb",
            VpcId=Ref(self.vpc),
            GroupDescription=Sub("${AWS::StackName}-alb"))
        self.template.add_resource(self.sg_alb)
        self.sg_hosts = SecurityGroup(
            "SecurityGroupEc2Hosts",
            SecurityGroupIngress=[{
                'SourceSecurityGroupId': Ref(self.sg_alb),
                'IpProtocol': -1
            }],
            VpcId=Ref(self.vpc),
            GroupDescription=Sub("${AWS::StackName}-hosts"))
        self.template.add_resource(self.sg_hosts)

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

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

        # This will be the name used in resource names and descriptions
        self.name = name

        # This is the name used to identify the AMI from the ami_cache.json file
        self.ami_name = ami_name

        # This is the contents of the userdata script as a string
        self.user_data = user_data

        # This is a dictionary of environment variables to inject into the instances
        self.env_vars = env_vars

        # These define the lower and upper boundaries of the autoscaling group
        self.min_size = min_size
        self.max_size = max_size
        self.desired_capacity = desired_capacity

        # The type of instance for the autoscaling group
        self.instance_type = instance_type

        # This is the subnet layer that the ASG is in (public, private, ...)
        self.subnet_layer = subnet_layer

        # This is the type of ELB: internet-facing gets a publicly accessible DNS, while internal is only accessible to the VPC
        self.elb_scheme = elb_scheme

        # This should be a list of dictionaries defining each listener for the ELB
        # Each dictionary can contain elb_port [required], elb_protocol, instance_port, instance_protocol, ssl_cert_name
        self.elb_listeners = elb_listeners

        # This is the health check port for the cluster
        self.elb_health_check_port = elb_health_check_port

        # The ELB health check protocol for the cluster (HTTP, HTTPS, TCP, SSL)
        self.elb_health_check_protocol = elb_health_check_protocol

        # The ELB health check path for the cluster (Only for HTTP and HTTPS)
        self.elb_health_check_path = elb_health_check_path

        # Add a creation policy with a custom timeout if one was specified
        if creation_policy_timeout:
            self.creation_policy = CreationPolicy(
                ResourceSignal=ResourceSignal(
                    Timeout='PT' + str(creation_policy_timeout) + 'M'))
        else:
            self.creation_policy = None

        # Add update policy
        self.update_policy = UpdatePolicy(
            AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                PauseTime=update_policy_PauseTime,
                MinInstancesInService=update_policy_MinInstancesInService,
                MaxBatchSize=update_policy_MaxBatchSize,
                # WaitOnResourceSignals=True
            ))

        # The Idle Timeout for the ELB (how long your connection can stay idle before being terminated)
        self.elb_idle_timeout = elb_idle_timeout

        # This is an optional fully qualified DNS name to create a CNAME in a private hosted zone
        self.cname = cname

        # Translate the custom_tags dict to a list of autoscaling Tags
        self.custom_tags = []
        for key, value in custom_tags.iteritems():
            self.custom_tags.append(autoscaling.Tag(key, value, True))

        ## Save ELB tags for add_cluster_elb
        self.elb_custom_tags = elb_custom_tags

        # A list of dictionaries describing scaling policies to be passed to add_asg
        self.scaling_policies = scaling_policies

        # Indicates whether ingress rules should be added to the ELB for type-appropriate CIDR ranges
        # Internet facing ELBs would allow ingress from PUBLIC_ACCESS_CIDR and private ELBs will allow ingress from the VPC CIDR
        self.allow_default_ingress = allow_default_ingress

        super(HaCluster, self).__init__(template_name=self.name)
コード例 #28
0
ファイル: asg-elb-dns.py プロジェクト: ismferd/wimpy
def generate_cloudformation_template():
    template = Template()

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

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

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

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

    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",
        ))

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

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

    loadbalancername = template.add_parameter(
        Parameter(
            "LoadBalancerName",
            Type="String",
        ))

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

    healthCheckTarget = template.add_parameter(
        Parameter(
            "LoadBalancerHealthCheckTarget",
            Type="String",
        ))

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

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

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

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

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

    loadbalancer = template.add_resource(
        elb.LoadBalancer(
            "LoadBalancer",
            ConnectionDrainingPolicy=elb.ConnectionDrainingPolicy(
                Enabled=True,
                Timeout=30,
            ),
            Subnets=Ref(subnet),
            HealthCheck=elb.HealthCheck(
                Target=Ref(healthCheckTarget),
                HealthyThreshold=Ref(healthyThreshold),
                UnhealthyThreshold=Ref(unhealthyThreshold),
                Interval=Ref(healthCheckInterval),
                Timeout=Ref(healthCheckTimeout),
            ),
            Listeners=[
                elb.Listener(
                    LoadBalancerPort="80",
                    InstancePort="80",
                    Protocol="HTTP",
                    InstanceProtocol="HTTP",
                ),
            ],
            CrossZone=True,
            SecurityGroups=[Ref(loadbalancersecuritygroup)],
            LoadBalancerName=Ref(loadbalancername),
            Scheme=Ref(elbSchema),
        ))

    autoscalinggroup = template.add_resource(
        AutoScalingGroup("AutoscalingGroup",
                         Tags=[Tag("Environment", Ref(environment), True)],
                         LaunchConfigurationName=Ref(launchconfigurationname),
                         MinSize=Ref(minsize),
                         MaxSize=Ref(maxsize),
                         DesiredCapacity=Ref(scalecapacity),
                         LoadBalancerNames=[Ref(loadbalancer)],
                         VPCZoneIdentifier=Ref(subnet),
                         HealthCheckType='ELB',
                         HealthCheckGracePeriod=30,
                         UpdatePolicy=UpdatePolicy(
                             AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                                 PauseTime='PT1M',
                                 MinInstancesInService="1",
                                 MaxBatchSize='1'))))

    route53record = template.add_resource(
        RecordSetType(
            "myDNSRecord",
            HostedZoneName=Join("", [Ref(hostedzone), "."]),
            Name=Join("", [Ref(dnsRecord), ".",
                           Ref(hostedzone), "."]),
            Type="CNAME",
            TTL="300",
            ResourceRecords=[GetAtt(loadbalancer, "DNSName")],
        ))

    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="Created Auto Scaling Group"))
    template.add_output(
        Output("LaunchConfiguration",
               Value=Ref(launchconfigurationname),
               Description="LaunchConfiguration for this deploy"))

    return template
コード例 #29
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
コード例 #30
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())