コード例 #1
0
 def test_auto_scaling_creation_policy_json(self):
     policy = CreationPolicy(
         AutoScalingCreationPolicy=AutoScalingCreationPolicy(
             MinSuccessfulInstancesPercent=50, ),
         ResourceSignal=ResourceSignal(Count=2, Timeout='PT10M'))
     p = policy.to_dict()
     self.assertEqual(
         p['AutoScalingCreationPolicy']['MinSuccessfulInstancesPercent'],
         50)
コード例 #2
0
ファイル: test_policies.py プロジェクト: Arvoreen/troposphere
 def test_json(self):
     policy = CreationPolicy(
         ResourceSignal=ResourceSignal(
             Count=2,
             Timeout='PT10M'
         )
     )
     p = policy.to_dict()
     self.assertEqual(p['ResourceSignal']['Count'], 2)
     self.assertEqual(p['ResourceSignal']['Timeout'], 'PT10M')
コード例 #3
0
ファイル: test_policies.py プロジェクト: Arvoreen/troposphere
 def test_auto_scaling_creation_policy_json(self):
     policy = CreationPolicy(
         AutoScalingCreationPolicy=AutoScalingCreationPolicy(
             MinSuccessfulInstancesPercent=50,
         ),
         ResourceSignal=ResourceSignal(
             Count=2,
             Timeout='PT10M'
         )
     )
     p = policy.to_dict()
     self.assertEqual(
         p['AutoScalingCreationPolicy']['MinSuccessfulInstancesPercent'],
         50
     )
コード例 #4
0
    def add_nat_asg(self):

        user_data = [resources.get_resource('nat_takeover.sh')]

        if self.enable_ntp:
            user_data.append(resources.get_resource('ntp_takeover.sh'))
        if self.extra_user_data:
            user_data.append(open(self.extra_user_data).read())

        nat_asg_name = "Nat%sASG" % str(self.subnet_index)

        user_data.extend([
            "\n", "cfn-signal -s true", " --resource ", nat_asg_name,
            " --stack ", {
                "Ref": "AWS::StackName"
            }, " --region ", {
                "Ref": "AWS::Region"
            }
        ])

        nat_launch_config = self.add_resource(
            LaunchConfiguration("Nat%sLaunchConfig" % str(self.subnet_index),
                                UserData=Base64(Join('', user_data)),
                                ImageId=FindInMap('RegionMap',
                                                  Ref('AWS::Region'),
                                                  'natAmiId'),
                                KeyName=Ref('ec2Key'),
                                SecurityGroups=[Ref(self.sg)],
                                EbsOptimized=False,
                                IamInstanceProfile=Ref(self.instance_profile),
                                InstanceType=self.instance_type,
                                AssociatePublicIpAddress=True))

        # Create the NAT in a public subnet
        subnet_layer = self._subnets['public'].keys()[0]

        nat_asg = self.add_resource(
            AutoScalingGroup(
                nat_asg_name,
                DesiredCapacity=1,
                Tags=[
                    Tag("Name", Join("-", [
                        "NAT",
                        self.subnet_index,
                    ]), True),
                    Tag("isNat", "true", True)
                ],
                MinSize=1,
                MaxSize=1,
                Cooldown="30",
                LaunchConfigurationName=Ref(nat_launch_config),
                HealthCheckGracePeriod=30,
                HealthCheckType="EC2",
                VPCZoneIdentifier=[
                    self._subnets['public'][subnet_layer][self.subnet_index]
                ],
                CreationPolicy=CreationPolicy(
                    ResourceSignal=ResourceSignal(Count=1, Timeout='PT15M'))))

        return nat_asg
コード例 #5
0
 def test_auto_scaling_creation_policy(self):
     policy = CreationPolicy(
         AutoScalingCreationPolicy=AutoScalingCreationPolicy(
             MinSuccessfulInstancesPercent=50, ),
         ResourceSignal=ResourceSignal(Count=2, Timeout='PT10M'))
     self.assertEqual(
         policy.AutoScalingCreationPolicy.MinSuccessfulInstancesPercent, 50)
コード例 #6
0
 def test_CreationPolicy(self):
     w = WaitCondition(
         "mycondition",
         CreationPolicy=CreationPolicy(
             ResourceSignal=ResourceSignal(
                 Timeout='PT15M')),
     )
     w.validate()
コード例 #7
0
 def test_works(self):
     policy = CreationPolicy(
         ResourceSignal=ResourceSignal(
             Count=2,
             Timeout='PT10M'
         )
     )
     self.assertEqual(policy.ResourceSignal.Count, 2)
     self.assertEqual(policy.ResourceSignal.Timeout, 'PT10M')
コード例 #8
0
 def test_auto_scaling_creation_policy_json(self):
     policy = CreationPolicy(
         AutoScalingCreationPolicy=AutoScalingCreationPolicy(
             MinSuccessfulInstancesPercent=50, ),
         ResourceSignal=ResourceSignal(Count=2, Timeout='PT10M'))
     p = json.loads(json.dumps(policy, cls=awsencode))
     self.assertEqual(
         p['AutoScalingCreationPolicy']['MinSuccessfulInstancesPercent'],
         50)
コード例 #9
0
 def test_CreationPolicyWithProps(self):
     w = WaitCondition(
         "mycondition",
         Count=10,
         CreationPolicy=CreationPolicy(
             ResourceSignal=ResourceSignal(
                 Timeout='PT15M')),
     )
     with self.assertRaises(ValueError):
         w.validate()
コード例 #10
0
 def test_json(self):
     policy = CreationPolicy(
         ResourceSignal=ResourceSignal(
             Count=2,
             Timeout='PT10M'
         )
     )
     p = json.loads(json.dumps(policy, cls=awsencode))
     self.assertEqual(p['ResourceSignal']['Count'], 2)
     self.assertEqual(p['ResourceSignal']['Timeout'], 'PT10M')
コード例 #11
0
ファイル: vpnjumpbox.py プロジェクト: gregwhitaker/VPNJumpbox
    def build_hook(self):

        if len(self.subnet_cidrs) != len(self.azs):
            raise ValueError('VPNJumpbox: Wrong number of CIDRs, should be %s' % len(self.azs))

        eip = self.add_resource(EIP(
            "%sEIP" % self.name,
            Domain="vpc",
        ))

        asg_name = '%sAutoscalingGroup' % self.name
        launch_config = self._get_launch_config(asg_name, eip)

        subnets = self._add_subnets()

        asg = self.add_resource(AutoScalingGroup(
            asg_name,
            AvailabilityZones=self.azs,
            LaunchConfigurationName=Ref(launch_config),
            MaxSize=1,
            MinSize=1,
            DesiredCapacity=1,
            VPCZoneIdentifier=subnets,
            CreationPolicy=CreationPolicy(
                ResourceSignal=ResourceSignal(
                    Count=1,
                    Timeout='PT10M'
                )
            ),
            DependsOn=[]))

        asg.Tags = [ASGTag('Name', self.name, True)]

        self.add_output(Output(
            'JumpboxEIP',
            Value=Ref(eip)
        ))
コード例 #12
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
コード例 #13
0
def main():
    '''Function: Generates the Cloudformation template'''
    template = Template()
    template.add_description("A target server for CI/CD tests.")

    keyname_param = template.add_parameter(
        Parameter(
            'KeyName',
            Description='An existing EC2 KeyPair.',
            ConstraintDescription='An existing EC2 KeyPair.',
            Type='AWS::EC2::KeyPair::KeyName',
        ))

    template.add_mapping(
        'RegionMap', {
            'ap-south-1': {
                'ami': 'ami-0dba8796fe499ae48'
            },
            'eu-west-3': {
                'ami': 'ami-07b2287c6776361c8'
            },
            'eu-north-1': {
                'ami': 'ami-34c14f4a'
            },
            'eu-west-2': {
                'ami': 'ami-0573b1dbbd809d6c3'
            },
            'eu-west-1': {
                'ami': 'ami-001b0e20a92d8db1e'
            },
            'ap-northeast-2': {
                'ami': 'ami-0dc961dd0c2c83bdd'
            },
            'ap-northeast-1': {
                'ami': 'ami-0f2c38ac2e37197be'
            },
            'sa-east-1': {
                'ami': 'ami-04ab6be036f8635bd'
            },
            'ca-central-1': {
                'ami': 'ami-0de195e1958cc0d52'
            },
            'ap-southeast-1': {
                'ami': 'ami-08540b8d2f7fa85a5'
            },
            'ap-southeast-2': {
                'ami': 'ami-0bbcf853aaf6ca4a6'
            },
            'eu-central-1': {
                'ami': 'ami-0332a5c40cf835528'
            },
            'us-east-1': {
                'ami': 'ami-0edd3706ab2e952c4'
            },
            'us-east-2': {
                'ami': 'ami-050553a7784d00d21'
            },
            'us-west-1': {
                'ami': 'ami-065ebd3e6b63c75d5'
            },
            'us-west-2': {
                'ami': 'ami-00f13b45242aff065'
            }
        })

    ec2_security_group = template.add_resource(
        ec2.SecurityGroup(
            'EC2SecurityGroup',
            Tags=[
                {
                    'Key': 'Name',
                    'Value': Ref('AWS::StackName')
                },
            ],
            GroupDescription='EC2 Security Group',
            SecurityGroupIngress=[
                ec2.SecurityGroupRule(IpProtocol='tcp',
                                      FromPort='22',
                                      ToPort='22',
                                      CidrIp='0.0.0.0/0',
                                      Description='SSH'),
                ec2.SecurityGroupRule(IpProtocol='tcp',
                                      FromPort='80',
                                      ToPort='80',
                                      CidrIp='0.0.0.0/0',
                                      Description='HTTP'),
                ec2.SecurityGroupRule(IpProtocol='tcp',
                                      FromPort='443',
                                      ToPort='443',
                                      CidrIp='0.0.0.0/0',
                                      Description='HTTPS'),
            ],
        ))

    ec2_instance = template.add_resource(
        ec2.Instance(
            'Instance',
            Metadata=Metadata(
                Init({
                    "config":
                    InitConfig(files=InitFiles({
                        "/tmp/instance.txt":
                        InitFile(content=Ref('AWS::StackName'),
                                 mode="000644",
                                 owner="root",
                                 group="root")
                    }), )
                }), ),
            CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal(
                Timeout='PT15M')),
            Tags=[
                {
                    'Key': 'Name',
                    'Value': Ref('AWS::StackName')
                },
            ],
            ImageId=FindInMap('RegionMap', Ref('AWS::Region'), 'ami'),
            InstanceType='t2.micro',
            KeyName=Ref(keyname_param),
            SecurityGroups=[Ref(ec2_security_group)],
            UserData=Base64(
                Join('', [
                    '#!/bin/bash -x\n',
                    'exec > /tmp/user-data.log 2>&1\n',
                    'unset UCF_FORCE_CONFFOLD\n',
                    'export UCF_FORCE_CONFFNEW=YES\n',
                    'ucf --purge /boot/grub/menu.lst\n',
                    'export DEBIAN_FRONTEND=noninteractive\n',
                    'apt-get update\n',
                    'apt-get -o Dpkg::Options::="--force-confnew" --force-yes -fuy upgrade\n',
                    'apt-get install -y nginx supervisor build-essential libssl-dev libffi-dev python-pip python3-pip python3-dev python3-setuptools python3-venv\n',
                    'pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n',
                    '# Signal Cloudformation when set up is complete\n',
                    '/usr/local/bin/cfn-signal -e $? --resource=Instance --region=',
                    Ref('AWS::Region'),
                    ' --stack=',
                    Ref('AWS::StackName'),
                    '\n',
                ]))))

    template.add_output([
        Output(
            'InstanceDnsName',
            Description='PublicDnsName',
            Value=GetAtt(ec2_instance, 'PublicDnsName'),
        ),
    ])

    print(template.to_yaml())
コード例 #14
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)
コード例 #15
0
 def test_json(self):
     policy = CreationPolicy(
         ResourceSignal=ResourceSignal(Count=2, Timeout='PT10M'))
     p = policy.to_dict()
     self.assertEqual(p['ResourceSignal']['Count'], 2)
     self.assertEqual(p['ResourceSignal']['Timeout'], 'PT10M')
コード例 #16
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
コード例 #17
0
ファイル: test_policies.py プロジェクト: gsoyka/troposphere
 def test_json(self):
     policy = CreationPolicy(
         ResourceSignal=ResourceSignal(Count=2, Timeout="PT10M"))
     p = policy.to_dict()
     self.assertEqual(p["ResourceSignal"]["Count"], 2)
     self.assertEqual(p["ResourceSignal"]["Timeout"], "PT10M")
コード例 #18
0
ファイル: simple.py プロジェクト: managedkaos/troposphere
def main():
    '''Function: Generates the Cloudformation template'''
    template = Template()

    keyname_param = template.add_parameter(
        Parameter(
            'KeyName',
            Description='Name of an existing EC2 KeyPair for SSH access',
            ConstraintDescription='must be the name of an existing EC2 KeyPair.',
            Type='AWS::EC2::KeyPair::KeyName',
        )
    )
    password_param = template.add_parameter(
        Parameter(
            'PassWord',
            Type='String',
            NoEcho=True,
            MinLength=8,
            MaxLength=64,
            Description='Password for the admin account',
            ConstraintDescription='A complex password at least eight chars long with alphanumeric characters, dashes and underscores.',
            AllowedPattern="[-_a-zA-Z0-9]*",
        )
    )

    ec2_security_group = template.add_resource(
        ec2.SecurityGroup(
            'SecurityGroup',
            GroupDescription='SSH, HTTP/HTTPS open for 0.0.0.0/0',
            SecurityGroupIngress=[
                ec2.SecurityGroupRule(
                    IpProtocol='tcp',
                    FromPort='22',
                    ToPort='22',
                    CidrIp='0.0.0.0/0'),
                ec2.SecurityGroupRule(
                    IpProtocol='tcp',
                    FromPort='80',
                    ToPort='80',
                    CidrIp='0.0.0.0/0'),
            ],
        )
    )

    ec2_instance = template.add_resource(
        ec2.Instance(
            'Instance',
            Metadata=Metadata(
            Init({
                    "config": InitConfig(
                        files=InitFiles({
                            "/etc/nginx/conf.d/app.conf": InitFile(
                                content='server { listen 80 default_server; listen [::]:80  default_server; location / { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }',
                                mode="000644",
                                owner="root",
                                group="root"
                            )
                        }),
                    )
                }),
            ),
            CreationPolicy=CreationPolicy(
                ResourceSignal=ResourceSignal(
                Timeout='PT15M')),
            Tags=[{'Key':'Name', 'Value':'Simple Stack Instance {}'.format(time.strftime('%c'))},],
            ImageId='ami-39c28c41',
            InstanceType='t2.micro',
            KeyName=Ref(keyname_param),
            SecurityGroups=[Ref(ec2_security_group)],
            UserData=Base64(
                Join(
                    '',
                    [
                        '#!/bin/bash -x\n',
                        'exec > /tmp/user-data.log 2>&1\n'
                        'apt-get update\n',
			            'apt-get install -y python-pip\n',
			            'pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n',
                        'apt-get install -y nginx\n',
                        'apt-get install -y openjdk-8-jdk\n',
                        '/usr/local/bin/cfn-init --verbose --resource=Instance --region=', Ref('AWS::Region'), ' --stack=', Ref('AWS::StackName'), '\n',
                        'unlink /etc/nginx/sites-enabled/default\n'
                        'systemctl reload nginx\n',
                        '/usr/local/bin/cfn-signal -e 0 --resource Instance --region us-west-2 --stack simple\n',
                    ]
                )
            )
        )
    )

    template.add_output([
        Output(
            'PublicDnsName',
            Description='PublicDnsName',
            Value=GetAtt(ec2_instance, 'PublicDnsName'),
        ),
    ])

    print(template.to_yaml())
コード例 #19
0
        "export java_version=", ref_java_version ,"\n",
        "export install_ambari_agent=", install_ambari_agent ,"\n",
        "export install_ambari_server=", install_ambari_server ,"\n",
    ]
    return exports + bootstrap_script_body.splitlines(True)

AmbariNode = t.add_resource(ec2.Instance(
    "AmbariNode",
    UserData=Base64(Join("", my_bootstrap_script('AmbariNode','true','true','127.0.0.1'))),
    ImageId=FindInMap("CENTOS7", Ref("AWS::Region"), "AMI"),
    BlockDeviceMappings=If( "AmbariUseEBSBool",
        my_block_device_mappings_ebs(ref_disk_ambari_ebs_diskcount,"/dev/sd",ref_disk_ambari_ebs_volumesize,"gp2"),
        my_block_device_mappings_ephemeral(24,"/dev/sd")),
    CreationPolicy=CreationPolicy(
        ResourceSignal=ResourceSignal(
          Count=1,
          Timeout="PT60M"
    )),
    KeyName=Ref(KeyName),
    InstanceType=Ref(AmbariInstanceType),
    NetworkInterfaces=[
    ec2.NetworkInterfaceProperty(
        DeleteOnTermination="true",
        DeviceIndex="0",
        SubnetId=Ref(PublicSubnet),
        GroupSet=[Ref(AmbariSecurityGroup)],
        AssociatePublicIpAddress="true",
    ),
    ],
))
コード例 #20
0
    ec2.Instance(
        "AmbariNode",
        UserData=Base64(
            Join(
                "",
                my_bootstrap_script('AmbariNode', 'true', 'true',
                                    '127.0.0.1'))),
        ImageId=FindInMap("RHEL66", Ref("AWS::Region"), "AMI"),
        BlockDeviceMappings=If(
            "UseEBSBool",
            my_block_device_mappings_ebs(ref_disk_worker_ebs_diskcount,
                                         "/dev/sd",
                                         ref_disk_worker_ebs_volumesize,
                                         "gp2"),
            my_block_device_mappings_ephemeral(24, "/dev/sd")),
        CreationPolicy=CreationPolicy(
            ResourceSignal=ResourceSignal(Count=1, Timeout="PT30M")),
        KeyName=Ref(KeyName),
        IamInstanceProfile=Ref(AmbariInstanceProfile),
        InstanceType=Ref(InstanceType),
        NetworkInterfaces=[
            ec2.NetworkInterfaceProperty(
                DeleteOnTermination="true",
                DeviceIndex="0",
                SubnetId=Ref(PublicSubnet),
                GroupSet=[Ref(AmbariSecurityGroup)],
                AssociatePublicIpAddress="true",
            ),
        ],
    ))

WorkerNodeLaunchConfig = t.add_resource(
コード例 #21
0
instance = t.add_resource(
    Instance(
        config_file['ec2']['name'],
        ImageId=FindInMap(
            'AWSRegionArch2AMI', config_file['vpc']['region'],
            FindInMap('AWSInstanceType2Arch', config_file['ec2']['type'],
                      'Arch')),
        InstanceType=config_file['ec2']['type'],
        KeyName=Ref(keyname_param),
        NetworkInterfaces=[
            NetworkInterfaceProperty(GroupSet=[Ref(instanceSecurityGroup)],
                                     AssociatePublicIpAddress='true',
                                     DeviceIndex='0',
                                     DeleteOnTermination='true',
                                     SubnetId=Ref(subnet))
        ],
        CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal(
            Timeout='PT15M')),
        Tags=Tags(Application=ref_stack_id),
    ))

ipAddress = t.add_resource(
    EIP('IPAddress',
        DependsOn='AttachGateway',
        Domain='vpc',
        InstanceId=Ref(instance)))

# WRITE TEMPLATE
json = t.to_json()
output_file.write(json)
コード例 #22
0
    def add_ec2_instance(self):

        instance_metadata = Metadata(
            Init({
                'config':
                InitConfig(
                    packages={'yum': {
                        'openvpn': []
                    }},
                    files=InitFiles({
                        '/etc/openvpn/server.conf':
                        InitFile(content=Join('\n', [
                            'port 1194',
                            'proto tcp-server',
                            'dev tun1',
                            'ifconfig 172.16.1.2 172.16.1.3',
                            'status server-tcp.log',
                            'verb 3',
                            'secret /etc/openvpn/static.key',
                            'keepalive 10 60',
                            'ping-timer-rem',
                            'persist-tun',
                            'persist-key',
                            'user nobody',
                            'group nobody',
                            'daemon',
                        ]),
                                 mode='000644',
                                 owner='root',
                                 group='root'),
                        '/etc/openvpn/client.ovpn':
                        InitFile(content=Join('\n', [
                            'proto tcp-client',
                            'remote {{public_ip}}',
                            'port 1194',
                            'dev tun',
                            'secret /tmp/secret.key',
                            'ifconfig 10.4.0.2 10.4.0.1',
                        ]),
                                 mode='000644',
                                 owner='root',
                                 group='root'),
                        '/etc/cfn/cfn-hup.conf':
                        InitFile(content=Join('', [
                            '[main]\n',
                            'stack=',
                            Ref('AWS::StackId'),
                            '\n',
                            'region=',
                            Ref('AWS::Region'),
                            '\n',
                        ]),
                                 mode='000400',
                                 owner='root',
                                 group='root'),
                        '/etc/cfn/hooks.d/cfn-auto-reloader.conf':
                        InitFile(content=Join('', [
                            '[cfn-auto-reloader-hook]\n',
                            'triggers=post.update\n',
                            'path=Resources.OpenVpn.Metadata.AWS::CloudFormation::Init\n',
                            'action=/opt/aws/bin/cfn-init -v --stack ',
                            Ref('AWS::StackName'),
                            '--resource OpenVpn ',
                            ' --region ',
                            Ref('AWS::Region'),
                            '\n',
                            'runas=root\n',
                        ]))
                    }),
                    services={
                        'sysvinit':
                        InitServices({
                            'openvpn':
                            InitService(enabled=True,
                                        ensureRunning=True,
                                        files=['/etc/openvpn/server.conf']),
                            'cfn-hup':
                            InitService(
                                enabled=True,
                                ensureRunning=True,
                                files=[
                                    '/etc/cfn/cfn-hup.conf',
                                    '/etc/cfn/hooks.d/cfn-auto-reloader.conf'
                                ])
                        })
                    })
            }))

        self.ec2_instance = self.template.add_resource(
            ec2.Instance(
                "OpenVpn",
                ImageId=FindInMap("RegionMap", Ref("AWS::Region"), "AMI"),
                InstanceType="t2.micro",
                KeyName=self.sceptre_user_data["keyname"],
                SecurityGroupIds=[Ref(self.securityGroup)],
                IamInstanceProfile=Ref(self.cfninstanceprofile),
                SubnetId=ImportValue('deploy-dev-vpc-PublicSubnet'),
                Metadata=instance_metadata,
                UserData=Base64(
                    Join('', [
                        '#!/bin/bash -xe\n',
                        'yum install easy-rsa -y --enablerepo=epel\n',
                        'yum update -y aws-cfn-bootstrap\n',
                        '/opt/aws/bin/cfn-init -v --stack ',
                        Ref('AWS::StackName'),
                        ' --resource OpenVpn --region ',
                        Ref('AWS::Region'),
                        '\n',
                        '/opt/aws/bin/cfn-signal -e $? --stack ',
                        Ref('AWS::StackName'),
                        ' --resource OpenVpn --region ',
                        Ref('AWS::Region'),
                        '\n',
                        'cd /etc/openvpn\n',
                        'openvpn --genkey --secret static.key\n',
                        'aws s3 cp static.key s3://',
                        ImportValue('deploy-dev-s3bucket-s3bucketname'),
                        '/\n',
                        'sudo modprobe iptable_nat',
                        '\n',
                        'echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward',
                        '\n',
                        'sudo iptables -t nat -A POSTROUTING -s 10.4.0.1/2 -o eth0 -j MASQUERADE',
                        '\n',
                        'external_ip=`curl http://169.254.169.254/latest/meta-data/public-ipv4`',
                        '\n',
                        'sed -i "s|{{public_ip}}|$external_ip|g" /etc/openvpn/client.ovpn',
                        '\n',
                        'aws s3 cp client.ovpn s3://',
                        ImportValue('deploy-dev-s3bucket-s3bucketname'),
                        '\n',
                    ])),
                CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal(
                    Timeout='PT15M')),
                Tags=Tags(Name="vpn-server"),
            ))
コード例 #23
0
ファイル: test_policies.py プロジェクト: yasra002/troposphere
 def test_pausetime(self):
     with self.assertRaises(ValueError):
         CreationPolicy(
             ResourceSignal=ResourceSignal(Count=2, Timeout='90'))
コード例 #24
0
                    Ref("AWS::StackName"),
                    "         --resource WebServerInstance ",
                    "         --region ",
                    Ref("AWS::Region"),
                    "\n",
                    "/opt/aws/bin/cfn-signal -e $? ",
                    "         --stack ",
                    Ref("AWS::StackName"),
                    "         --resource WebServerInstance ",
                    "         --region ",
                    Ref("AWS::Region"),
                    "\n",
                ],
            )
        ),
        CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal(Timeout="PT15M")),
        Tags=Tags(Application=ref_stack_id),
    )
)

ipAddress = t.add_resource(
    EIP("IPAddress", DependsOn="AttachGateway", Domain="vpc", InstanceId=Ref(instance))
)

t.add_output(
    [
        Output(
            "URL",
            Description="Newly created application URL",
            Value=Join("", ["http://", GetAtt("WebServerInstance", "PublicIp")]),
        )
コード例 #25
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)
コード例 #26
0
def build_template(keyPair, instanceType):
    ''' Builds the CloudFormation template which will create EC2 and supporting resources. '''
    print
    print '################ 2. Template Build Phase ################'
    print 'Starting CloudFormation template build.'

    ### Template Info ###
    mini_template = Template()

    # Define template version and description
    mini_template.add_version('2010-09-09')
    mini_template.add_description(
        'Provisions VPC, IGW, Route Table, Subnet, and EC2 instance in AWS to support a static website.'
    )

    ### Parameters ###
    instance_type = mini_template.add_parameter(
        Parameter(
            'InstanceType',
            Type='String',
            Description='EC2 instance type',
            Default=instanceType,
            AllowedValues=[
                't1.micro', 't2.micro', 't2.small', 't2.medium', 'm1.small',
                'm1.medium', 'm1.large', 'm1.xlarge', 'm2.xlarge',
                'm2.2xlarge', 'm2.4xlarge', 'm3.medium', 'm3.large',
                'm3.xlarge', 'm3.2xlarge', 'm4.large', 'm4.xlarge',
                'm4.2xlarge', 'm4.4xlarge', 'm4.10xlarge', 'c1.medium',
                'c1.xlarge', 'c3.large', 'c3.xlarge', 'c3.2xlarge',
                'c3.4xlarge', 'c3.8xlarge', 'c4.large', 'c4.xlarge',
                'c4.2xlarge', 'c4.4xlarge', 'c4.8xlarge', 'g2.2xlarge',
                'r3.large', 'r3.xlarge', 'r3.2xlarge', 'r3.4xlarge',
                'r3.8xlarge', 'i2.xlarge', 'i2.2xlarge', 'i2.4xlarge',
                'i2.8xlarge', 'd2.xlarge', 'd2.2xlarge', 'd2.4xlarge',
                'd2.8xlarge', 'hi1.4xlarge', 'hs1.8xlarge', 'cr1.8xlarge',
                'cc2.8xlarge', 'cg1.4xlarge'
            ],
            ConstraintDescription='must be a valid EC2 instance type.',
        ))

    ### Mappings ###

    # AMI Mapping for Amazon Linux AMI as of 03-Jan-2017
    mini_template.add_mapping(
        'AWSRegionArch2AMI', {
            'us-east-1': {
                'HVM64': 'ami-9be6f38c'
            },
            'us-east-2': {
                'HVM64': 'ami-38cd975d'
            },
            'us-west-1': {
                'HVM64': 'ami-b73d6cd7'
            },
            'us-west-2': {
                'HVM64': 'ami-1e299d7e'
            },
            'ca-central-1': {
                'HVM64': 'ami-eb20928f'
            },
            'eu-west-1': {
                'HVM64': 'ami-c51e3eb6'
            },
            'eu-west-2': {
                'HVM64': 'ami-bfe0eadb'
            },
            'eu-central-1': {
                'HVM64': 'ami-211ada4e'
            },
            'ap-southeast-1': {
                'HVM64': 'ami-4dd6782e'
            },
            'ap-southeast-2': {
                'HVM64': 'ami-28cff44b'
            },
            'ap-northeast-1': {
                'HVM64': 'ami-9f0c67f8'
            },
            'ap-northeast-2': {
                'HVM64': 'ami-94bb6dfa'
            },
            'ap-south-1': {
                'HVM64': 'ami-9fc7b0f0'
            },
            'sa-east-1': {
                'HVM64': 'ami-bb40d8d7'
            }
        })

    ### Resources ###

    # VPC
    vpc = mini_template.add_resource(
        VPC('VPC',
            CidrBlock='172.16.0.0/16',
            EnableDnsSupport='True',
            EnableDnsHostnames='True',
            Tags=Tags(Name=stack_name + '-vpc', Project=stack_name)))

    # Internet Gateway
    igw = mini_template.add_resource(
        InternetGateway('InternetGateway',
                        Tags=Tags(Name=stack_name + '-igw',
                                  Project=stack_name)))

    # Attach IGW to VPC
    attach_gateway = mini_template.add_resource(
        VPCGatewayAttachment('AttachGateway',
                             VpcId=Ref(vpc),
                             InternetGatewayId=Ref(igw)))

    # Route Table
    route_table = mini_template.add_resource(
        RouteTable('RouteTable',
                   VpcId=Ref(vpc),
                   Tags=Tags(Name=stack_name + '-routetable',
                             Project=stack_name)))

    # Route 0.0.0.0 -> IGW
    route01 = mini_template.add_resource(
        Route('Route',
              DependsOn='AttachGateway',
              GatewayId=Ref(igw),
              DestinationCidrBlock='0.0.0.0/0',
              RouteTableId=Ref(route_table)))

    # Subnet
    subnet = mini_template.add_resource(
        Subnet('Subnet',
               CidrBlock='172.16.10.0/24',
               VpcId=Ref(vpc),
               MapPublicIpOnLaunch='True',
               Tags=Tags(Name=stack_name + '-subnet', Project=stack_name)))

    # Subnet -> Route Table
    subnet_route_associate = mini_template.add_resource(
        SubnetRouteTableAssociation('SubnetRouteTableAssociation',
                                    SubnetId=Ref(subnet),
                                    RouteTableId=Ref(route_table)))

    # Security Group allowing access via SSH and HTTP
    web_security_group = mini_template.add_resource(
        SecurityGroup('WebSecurityGroup',
                      GroupDescription=
                      'Enable access to the web server on ports 80 and 22.',
                      VpcId=Ref(vpc),
                      Tags=Tags(Name=stack_name + '-securitygroup',
                                Project=stack_name),
                      SecurityGroupIngress=[
                          SecurityGroupRule(IpProtocol='tcp',
                                            FromPort='22',
                                            ToPort='22',
                                            CidrIp='0.0.0.0/0'),
                          SecurityGroupRule(IpProtocol='tcp',
                                            FromPort='80',
                                            ToPort='80',
                                            CidrIp='0.0.0.0/0')
                      ]))

    # Metadata to install Apache
    ec2_metadata = Metadata(
        Init({
            'config':
            InitConfig(
                packages={'yum': {
                    'httpd': []
                }},
                files=InitFiles({
                    '/var/www/html/index.html':
                    InitFile(
                        content=
                        '<html><body><h2>Automation for the People!</h2></body></html>',
                        mode='000644',
                        owner='root',
                        group='root')
                }),
                services={
                    'sysvinit':
                    InitServices({
                        'httpd':
                        InitService(enabled=True, ensureRunning=True)
                    })
                })
        }))

    # EC2 Instance
    ec2 = mini_template.add_resource(
        Instance('Ec2Instance',
                 ImageId=FindInMap('AWSRegionArch2AMI', Ref('AWS::Region'),
                                   'HVM64'),
                 Metadata=ec2_metadata,
                 InstanceType=Ref(instance_type),
                 KeyName=keyPair,
                 SecurityGroupIds=[
                     Ref(web_security_group),
                 ],
                 SubnetId=Ref(subnet),
                 Tags=Tags(Name=stack_name + '-ec2', Project=stack_name),
                 CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal(
                     Timeout='PT15M')),
                 UserData=Base64(
                     Join('', [
                         '#!/bin/bash -x\n',
                         'yum update -y\n',
                         'yum update -y aws-cfn-bootstrap\n',
                         '/opt/aws/bin/cfn-init -v ',
                         '         --stack ',
                         Ref('AWS::StackName'),
                         '         --resource Ec2Instance ',
                         '         --region ',
                         Ref('AWS::Region'),
                         '\n',
                         '/opt/aws/bin/cfn-signal -e $? ',
                         '         --stack ',
                         Ref('AWS::StackName'),
                         '         --resource Ec2Instance ',
                         '         --region ',
                         Ref('AWS::Region'),
                         '\n',
                     ]))))

    ### Outputs ###

    # Output the Public DNS address for the EC2 instance
    mini_template.add_output(
        Output('URL',
               Description='HTTP Server URL',
               Value=Join('',
                          ['http://',
                           GetAtt('Ec2Instance', 'PublicDnsName')])))

    print 'CloudFormation template build is completed.'
    return mini_template
コード例 #27
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
コード例 #28
0
def main():
    '''Function: Generates the Cloudformation template'''
    template = Template()

    keyname_param = template.add_parameter(
        Parameter(
            'KeyName',
            Description='Name of an existing EC2 KeyPair for SSH access',
            ConstraintDescription='Must be the name of an existing EC2 KeyPair.',
            Type='AWS::EC2::KeyPair::KeyName',
        )
    )

    password_param = template.add_parameter(
        Parameter(
            'PassWord',
            Type='String',
            NoEcho=True,
            MinLength=8,
            MaxLength=64,
            Description='Password for the admin account',
            ConstraintDescription='A complex password at least eight chars long with alphanumeric characters, dashes and underscores.',
            AllowedPattern="[-_a-zA-Z0-9]*",
        )
    )

    template.add_mapping('RegionMap', {'ap-south-1': {'ami': 'ami-ee8ea481'}, 'eu-west-3': {'ami': 'ami-daf040a7'}, 'eu-west-2': {'ami': 'ami-ddb950ba'}, 'eu-west-1': {'ami': 'ami-d2414e38'}, 'ap-northeast-2': {'ami': 'ami-65d86d0b'}, 'ap-northeast-1': {'ami': 'ami-e875a197'}, 'sa-east-1': {'ami': 'ami-ccd48ea0'}, 'ca-central-1': {'ami': 'ami-c3e567a7'}, 'ap-southeast-1': {'ami': 'ami-31e7e44d'}, 'ap-southeast-2': {'ami': 'ami-23c51c41'}, 'eu-central-1': {'ami': 'ami-3c635cd7'}, 'us-east-1': {'ami': 'ami-5cc39523'}, 'us-east-2': {'ami': 'ami-67142d02'}, 'us-west-1': {'ami': 'ami-d7b355b4'}, 'us-west-2': {'ami': 'ami-39c28c41'}})

    ec2_security_group = template.add_resource(
        ec2.SecurityGroup(
            'SecurityGroup',
            GroupDescription='SSH, HTTP/HTTPS open for 0.0.0.0/0',
            SecurityGroupIngress=[
                ec2.SecurityGroupRule(
                    IpProtocol='tcp',
                    FromPort='22',
                    ToPort='22',
                    CidrIp='0.0.0.0/0'),
                ec2.SecurityGroupRule(
                    IpProtocol='tcp',
                    FromPort='80',
                    ToPort='80',
                    CidrIp='0.0.0.0/0'),
                ec2.SecurityGroupRule(
                    IpProtocol='tcp',
                    FromPort='443',
                    ToPort='443',
                    CidrIp='0.0.0.0/0'),
            ],
        )
    )
    ec2_role = template.add_resource(
        Role('EC2Role',
		AssumeRolePolicyDocument={ "Version" : "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "ec2.amazonaws.com" ] }, "Action": [ "sts:AssumeRole" ] } ] },
    	)
    )
    ec2_policy = template.add_resource(
        ManagedPolicy(
        'EC2Policy',
            PolicyDocument={ "Version": "2012-10-17", "Statement": [ { "Action": "ec2:*", "Resource": "*", "Effect": "Allow" } ] }, Roles=[Ref(ec2_role)]
        )
    )
    ec2_profile = template.add_resource(
        InstanceProfile("EC2InstanceProfile", Roles=[Ref(ec2_role)])
    )
    ec2_instance = template.add_resource(
        ec2.Instance(
            'Instance',
            Metadata=Metadata(
            Init({
                    "config": InitConfig(
                        files=InitFiles({
                            "/etc/nginx/conf.d/jenkins.conf": InitFile(
                                content='server { listen 80 default_server; listen [::]:80  default_server; location / { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }',
                                mode="000644",
                                owner="root",
                                group="root"
                            )
                        }),
                    )
                }),
            ),
            CreationPolicy=CreationPolicy(
                ResourceSignal=ResourceSignal(Timeout='PT15M')
            ),
            ImageId=FindInMap('RegionMap', Ref('AWS::Region'), 'ami'),
            InstanceType='t2.micro',
            IamInstanceProfile=Ref(ec2_profile),
            KeyName=Ref(keyname_param),
            SecurityGroups=[Ref(ec2_security_group)],
            UserData=Base64(
                Join(
                    '',
                    [
                        '#!/bin/bash -x\n',
                        'exec > /tmp/user-data.log 2>&1\n'
                        'unset UCF_FORCE_CONFFOLD\n',
                        'export UCF_FORCE_CONFFNEW=YES\n',
                        'ucf --purge /boot/grub/menu.lst\n',
                        'export DEBIAN_FRONTEND=noninteractive\n',
                        'echo "deb http://pkg.jenkins-ci.org/debian binary/" > /etc/apt/sources.list.d/jenkins.list\n',
                        'wget -q -O jenkins-ci.org.key http://pkg.jenkins-ci.org/debian-stable/jenkins-ci.org.key\n'
                        'apt-key add jenkins-ci.org.key\n',
                        'apt-get update\n',
                        'apt-get -o Dpkg::Options::="--force-confnew" --force-yes -fuy upgrade\n',
                        'apt-get install -y python-pip\n',
                        'pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n',
                        'apt-get install -y nginx\n',
                        'apt-get install -y openjdk-8-jdk\n',
                        'apt-get install -y jenkins\n',
                        '# Wait for Jenkins to Set Up\n'
                        "until [ $(curl -o /dev/null --silent --head --write-out '%{http_code}\n' http://localhost:8080) -eq 403 ]; do sleep 1; done\n",
                        'sleep 10\n',
                        '# Change the password for the admin account\n',
                        "echo 'jenkins.model.Jenkins.instance.securityRealm.createAccount(\"admin\", \"",Ref(password_param),"\")' | java -jar /var/cache/jenkins/war/WEB-INF/jenkins-cli.jar -s \"http://localhost:8080/\" -auth \"admin:$(cat /var/lib/jenkins/secrets/initialAdminPassword)\" groovy =\n",
                        '/usr/local/bin/cfn-init --resource=Instance --region=', Ref('AWS::Region'), ' --stack=', Ref('AWS::StackName'), '\n',
                        'unlink /etc/nginx/sites-enabled/default\n',
                        'systemctl reload nginx\n',
                        '/usr/local/bin/cfn-signal -e $? --resource=Instance --region=', Ref('AWS::Region'),
                        ' --stack=', Ref('AWS::StackName'), '\n',
                    ]
                )
            )
        )
    )

    template.add_output([
        Output(
            'PublicDnsName',
            Description='PublicDnsName',
            Value=Join('',['http://', GetAtt(ec2_instance, 'PublicDnsName'),])
        ),
    ])

    print(template.to_yaml())
コード例 #29
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
コード例 #30
0
def buildStack(bootstrap, env):
    t = Template()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    if (bootstrap):
        return t

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    # print(t.to_json())
    return t
コード例 #31
0
        "\n",
    ]
    return exports + bootstrap_script_body.splitlines(True)


AmbariNode = t.add_resource(
    ec2.Instance(
        "AmbariNode",
        UserData=Base64(
            Join(
                "",
                my_bootstrap_script('AmbariNode', 'true', 'true',
                                    '127.0.0.1'))),
        ImageId=FindInMap(ref_os, Ref("AWS::Region"), "AMI"),
        BlockDeviceMappings=my_block_device_mappings_ephemeral(24, "/dev/sd"),
        CreationPolicy=CreationPolicy(
            ResourceSignal=ResourceSignal(Count=1, Timeout="PT15M")),
        Tags=Tags(Name=ref_stack_name, ),
        KeyName=Ref(KeyName),
        InstanceType=Ref(InstanceType),
        SubnetId=Ref(SubnetId),
        SecurityGroupIds=Ref(SecurityGroups),
    ))

AdditionalNodeLaunchConfig = t.add_resource(
    LaunchConfiguration(
        "AdditionalNodeLaunchConfig",
        UserData=Base64(
            Join(
                "",
                my_bootstrap_script('AdditionalNodes', 'true', 'false',
                                    ref_ambariserver))),
コード例 #32
0
ファイル: ElastiCacheRedis.py プロジェクト: ecout/troposphere
def main():
    """
    Create a ElastiCache Redis Node and EC2 Instance
    """

    template = Template()

    # Description
    template.set_description(
        'AWS CloudFormation Sample Template ElastiCache_Redis:'
        'Sample template showing how to create an Amazon'
        'ElastiCache Redis Cluster. **WARNING** This template'
        'creates an Amazon EC2 Instance and an Amazon ElastiCache'
        'Cluster. You will be billed for the AWS resources used'
        'if you create a stack from this template.')

    # Mappings
    template.add_mapping('AWSInstanceType2Arch', {
        't1.micro':     {'Arch': 'PV64'},
        't2.micro':     {'Arch': 'HVM64'},
        't2.small':     {'Arch': 'HVM64'},
        't2.medium':    {'Arch': 'HVM64'},
        'm1.small':     {'Arch': 'PV64'},
        'm1.medium':    {'Arch': 'PV64'},
        'm1.large':     {'Arch': 'PV64'},
        'm1.xlarge':    {'Arch': 'PV64'},
        'm2.xlarge':    {'Arch': 'PV64'},
        'm2.2xlarge':   {'Arch': 'PV64'},
        'm2.4xlarge':   {'Arch': 'PV64'},
        'm3.medium':    {'Arch': 'HVM64'},
        'm3.large':     {'Arch': 'HVM64'},
        'm3.xlarge':    {'Arch': 'HVM64'},
        'm3.2xlarge':   {'Arch': 'HVM64'},
        'c1.medium':    {'Arch': 'PV64'},
        'c1.xlarge':    {'Arch': 'PV64'},
        'c3.large':     {'Arch': 'HVM64'},
        'c3.xlarge':    {'Arch': 'HVM64'},
        'c3.2xlarge':   {'Arch': 'HVM64'},
        'c3.4xlarge':   {'Arch': 'HVM64'},
        'c3.8xlarge':   {'Arch': 'HVM64'},
        'c4.large':     {'Arch': 'HVM64'},
        'c4.xlarge':    {'Arch': 'HVM64'},
        'c4.2xlarge':   {'Arch': 'HVM64'},
        'c4.4xlarge':   {'Arch': 'HVM64'},
        'c4.8xlarge':   {'Arch': 'HVM64'},
        'g2.2xlarge':   {'Arch': 'HVMG2'},
        'r3.large':     {'Arch': 'HVM64'},
        'r3.xlarge':    {'Arch': 'HVM64'},
        'r3.2xlarge':   {'Arch': 'HVM64'},
        'r3.4xlarge':   {'Arch': 'HVM64'},
        'r3.8xlarge':   {'Arch': 'HVM64'},
        'i2.xlarge':    {'Arch': 'HVM64'},
        'i2.2xlarge':   {'Arch': 'HVM64'},
        'i2.4xlarge':   {'Arch': 'HVM64'},
        'i2.8xlarge':   {'Arch': 'HVM64'},
        'd2.xlarge':    {'Arch': 'HVM64'},
        'd2.2xlarge':   {'Arch': 'HVM64'},
        'd2.4xlarge':   {'Arch': 'HVM64'},
        'd2.8xlarge':   {'Arch': 'HVM64'},
        'hi1.4xlarge':  {'Arch': 'HVM64'},
        'hs1.8xlarge':  {'Arch': 'HVM64'},
        'cr1.8xlarge':  {'Arch': 'HVM64'},
        'cc2.8xlarge':  {'Arch': 'HVM64'}
        })

    template.add_mapping('AWSRegionArch2AMI', {
        'us-east-1': {'PV64': 'ami-0f4cfd64',
                      'HVM64': 'ami-0d4cfd66',
                      'HVMG2': 'ami-5b05ba30'},
        'us-west-2': {'PV64': 'ami-d3c5d1e3',
                      'HVM64': 'ami-d5c5d1e5',
                      'HVMG2': 'ami-a9d6c099'},
        'us-west-1': {'PV64': 'ami-85ea13c1',
                      'HVM64': 'ami-87ea13c3',
                      'HVMG2': 'ami-37827a73'},
        'eu-west-1': {'PV64': 'ami-d6d18ea1',
                      'HVM64': 'ami-e4d18e93',
                      'HVMG2': 'ami-72a9f105'},
        'eu-central-1': {'PV64': 'ami-a4b0b7b9',
                         'HVM64': 'ami-a6b0b7bb',
                         'HVMG2': 'ami-a6c9cfbb'},
        'ap-northeast-1': {'PV64': 'ami-1a1b9f1a',
                           'HVM64': 'ami-1c1b9f1c',
                           'HVMG2': 'ami-f644c4f6'},
        'ap-southeast-1': {'PV64': 'ami-d24b4280',
                           'HVM64': 'ami-d44b4286',
                           'HVMG2': 'ami-12b5bc40'},
        'ap-southeast-2': {'PV64': 'ami-ef7b39d5',
                           'HVM64': 'ami-db7b39e1',
                           'HVMG2': 'ami-b3337e89'},
        'sa-east-1': {'PV64': 'ami-5b098146',
                      'HVM64': 'ami-55098148',
                      'HVMG2': 'NOT_SUPPORTED'},
        'cn-north-1': {'PV64': 'ami-bec45887',
                       'HVM64': 'ami-bcc45885',
                       'HVMG2': 'NOT_SUPPORTED'}
        })

    template.add_mapping('Region2Principal', {
        'us-east-1': {'EC2Principal': 'ec2.amazonaws.com',
                      'OpsWorksPrincipal': 'opsworks.amazonaws.com'},
        'us-west-2': {'EC2Principal': 'ec2.amazonaws.com',
                      'OpsWorksPrincipal': 'opsworks.amazonaws.com'},
        'us-west-1': {'EC2Principal': 'ec2.amazonaws.com',
                      'OpsWorksPrincipal': 'opsworks.amazonaws.com'},
        'eu-west-1': {'EC2Principal': 'ec2.amazonaws.com',
                      'OpsWorksPrincipal': 'opsworks.amazonaws.com'},
        'ap-southeast-1': {'EC2Principal': 'ec2.amazonaws.com',
                           'OpsWorksPrincipal': 'opsworks.amazonaws.com'},
        'ap-northeast-1': {'EC2Principal': 'ec2.amazonaws.com',
                           'OpsWorksPrincipal': 'opsworks.amazonaws.com'},
        'ap-southeast-2': {'EC2Principal': 'ec2.amazonaws.com',
                           'OpsWorksPrincipal': 'opsworks.amazonaws.com'},
        'sa-east-1': {'EC2Principal': 'ec2.amazonaws.com',
                      'OpsWorksPrincipal': 'opsworks.amazonaws.com'},
        'cn-north-1': {'EC2Principal': 'ec2.amazonaws.com.cn',
                       'OpsWorksPrincipal': 'opsworks.amazonaws.com.cn'},
        'eu-central-1': {'EC2Principal': 'ec2.amazonaws.com',
                         'OpsWorksPrincipal': 'opsworks.amazonaws.com'}
        })

    # Parameters
    cachenodetype = template.add_parameter(Parameter(
        'ClusterNodeType',
        Description='The compute and memory capacity of the nodes in the Redis'
                    ' Cluster',
        Type='String',
        Default='cache.m1.small',
        AllowedValues=['cache.m1.small',
                       'cache.m1.large',
                       'cache.m1.xlarge',
                       'cache.m2.xlarge',
                       'cache.m2.2xlarge',
                       'cache.m2.4xlarge',
                       'cache.c1.xlarge'],
        ConstraintDescription='must select a valid Cache Node type.',
        ))

    instancetype = template.add_parameter(Parameter(
        'InstanceType',
        Description='WebServer EC2 instance type',
        Type='String',
        Default='t2.micro',
        AllowedValues=['t1.micro',
                       't2.micro',
                       't2.small',
                       't2.medium',
                       'm1.small',
                       'm1.medium',
                       'm1.large',
                       'm1.xlarge',
                       'm2.xlarge',
                       'm2.2xlarge',
                       'm2.4xlarge',
                       'm3.medium',
                       'm3.large',
                       'm3.xlarge',
                       'm3.2xlarge',
                       'c1.medium',
                       'c1.xlarge',
                       'c3.large',
                       'c3.xlarge',
                       'c3.2xlarge',
                       'c3.4xlarge',
                       'c3.8xlarge',
                       'c4.large',
                       'c4.xlarge',
                       'c4.2xlarge',
                       'c4.4xlarge',
                       'c4.8xlarge',
                       'g2.2xlarge',
                       'r3.large',
                       'r3.xlarge',
                       'r3.2xlarge',
                       'r3.4xlarge',
                       'r3.8xlarge',
                       'i2.xlarge',
                       'i2.2xlarge',
                       'i2.4xlarge',
                       'i2.8xlarge',
                       'd2.xlarge',
                       'd2.2xlarge',
                       'd2.4xlarge',
                       'd2.8xlarge',
                       'hi1.4xlarge',
                       'hs1.8xlarge',
                       'cr1.8xlarge',
                       'cc2.8xlarge',
                       'cg1.4xlarge'],
        ConstraintDescription='must be a valid EC2 instance type.',
        ))

    keyname = template.add_parameter(Parameter(
        'KeyName',
        Description='Name of an existing EC2 KeyPair to enable SSH access'
                    ' to the instance',
        Type='AWS::EC2::KeyPair::KeyName',
        ConstraintDescription='must be the name of an existing EC2 KeyPair.',
        ))

    sshlocation = template.add_parameter(Parameter(
        'SSHLocation',
        Description='The IP address range that can be used to SSH to'
                    ' the EC2 instances',
        Type='String',
        MinLength='9',
        MaxLength='18',
        Default='0.0.0.0/0',
        AllowedPattern='(\\d{1,3})\\.(\\d{1,3})\\.'
                       '(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})',
        ConstraintDescription='must be a valid IP CIDR range of the'
                              ' form x.x.x.x/x.'
        ))

    # Resources
    webserverrole = template.add_resource(iam.Role(
        'WebServerRole',
        AssumeRolePolicyDocument=PolicyDocument(
            Statement=[
                Statement(
                    Effect=Allow,
                    Action=[AssumeRole],
                    Principal=Principal('Service',
                                        [FindInMap('Region2Principal',
                                                   Ref('AWS::Region'),
                                                   'EC2Principal')]),
                    )
                ]
            ),
        Path='/',
    ))

    template.add_resource(iam.PolicyType(
        'WebServerRolePolicy',
        PolicyName='WebServerRole',
        PolicyDocument=PolicyDocument(
            Statement=[awacs.aws.Statement(
                Action=[awacs.aws.Action("elasticache",
                        "DescribeCacheClusters")],
                Resource=["*"],
                Effect=awacs.aws.Allow
            )]
        ),
        Roles=[Ref(webserverrole)],
    ))

    webserverinstanceprofile = template.add_resource(iam.InstanceProfile(
        'WebServerInstanceProfile',
        Path='/',
        Roles=[Ref(webserverrole)],
    ))

    webserversg = template.add_resource(ec2.SecurityGroup(
        'WebServerSecurityGroup',
        GroupDescription='Enable HTTP and SSH access',
        SecurityGroupIngress=[
            ec2.SecurityGroupRule(
                IpProtocol='tcp',
                FromPort='22',
                ToPort='22',
                CidrIp=Ref(sshlocation),
                ),
            ec2.SecurityGroupRule(
                IpProtocol='tcp',
                FromPort='80',
                ToPort='80',
                CidrIp='0.0.0.0/0',
                )
            ]
        ))

    webserverinstance = template.add_resource(ec2.Instance(
        'WebServerInstance',
        Metadata=cloudformation.Metadata(
            cloudformation.Init({
                'config': cloudformation.InitConfig(
                    packages={
                        'yum': {
                            'httpd':     [],
                            'php':       [],
                            'php-devel': [],
                            'gcc':       [],
                            'make':      []
                            }
                        },

                    files=cloudformation.InitFiles({
                        '/var/www/html/index.php': cloudformation.InitFile(
                            content=Join('', [
                                '<?php\n',
                                'echo \"<h1>AWS CloudFormation sample'
                                ' application for Amazon ElastiCache'
                                ' Redis Cluster</h1>\";\n',
                                '\n',
                                '$cluster_config = json_decode('
                                'file_get_contents(\'/tmp/cacheclusterconfig\''
                                '), true);\n',
                                '$endpoint = $cluster_config[\'CacheClusters'
                                '\'][0][\'CacheNodes\'][0][\'Endpoint\'][\'Add'
                                'ress\'];\n',
                                '$port = $cluster_config[\'CacheClusters\'][0]'
                                '[\'CacheNodes\'][0][\'Endpoint\'][\'Port\'];'
                                '\n',
                                '\n',
                                'echo \"<p>Connecting to Redis Cache Cluster '
                                'node \'{$endpoint}\' on port {$port}</p>\";'
                                '\n',
                                '\n',
                                '$redis=new Redis();\n',
                                '$redis->connect($endpoint, $port);\n',
                                '$redis->set(\'testkey\', \'Hello World!\');'
                                '\n',
                                '$return = $redis->get(\'testkey\');\n',
                                '\n',
                                'echo \"<p>Retrieved value: $return</p>\";'
                                '\n',
                                '?>\n'
                                ]),
                            mode='000644',
                            owner='apache',
                            group='apache'
                            ),
                        '/etc/cron.d/get_cluster_config':
                            cloudformation.InitFile(
                                content='*/5 * * * * root'
                                        ' /usr/local/bin/get_cluster_config',
                                mode='000644',
                                owner='root',
                                group='root'
                                ),
                        '/usr/local/bin/get_cluster_config':
                            cloudformation.InitFile(
                                content=Join('', [
                                    '#! /bin/bash\n',
                                    'aws elasticache describe-cache-clusters ',
                                    '         --cache-cluster-id ',
                                    Ref('RedisCluster'),
                                    '         --show-cache-node-info'
                                    ' --region ', Ref('AWS::Region'),
                                    ' > /tmp/cacheclusterconfig\n'
                                    ]),
                                mode='000755',
                                owner='root',
                                group='root'
                                ),
                        '/usr/local/bin/install_phpredis':
                            cloudformation.InitFile(
                                content=Join('', [
                                    '#! /bin/bash\n',
                                    'cd /tmp\n',
                                    'wget https://github.com/nicolasff/'
                                    'phpredis/zipball/master -O phpredis.zip'
                                    '\n',
                                    'unzip phpredis.zip\n',
                                    'cd nicolasff-phpredis-*\n',
                                    'phpize\n',
                                    './configure\n',
                                    'make && make install\n',
                                    'touch /etc/php.d/redis.ini\n',
                                    'echo extension=redis.so > /etc/php.d/'
                                    'redis.ini\n'
                                    ]),
                                mode='000755',
                                owner='root',
                                group='root'
                                ),
                        '/etc/cfn/cfn-hup.conf': cloudformation.InitFile(
                            content=Join('', [
                                '[main]\n',
                                'stack=', Ref('AWS::StackId'), '\n',
                                'region=', Ref('AWS::Region'), '\n'
                                ]),
                            mode='000400',
                            owner='root',
                            group='root'
                            ),
                        '/etc/cfn/hooks.d/cfn-auto-reloader.conf':
                            cloudformation.InitFile(
                                content=Join('', [
                                    '[cfn-auto-reloader-hook]\n',
                                    'triggers=post.update\n',
                                    'path=Resources.WebServerInstance.Metadata'
                                    '.AWS::CloudFormation::Init\n',
                                    'action=/opt/aws/bin/cfn-init -v ',
                                    '         --stack ', Ref('AWS::StackName'),
                                    '         --resource WebServerInstance ',
                                    '         --region ', Ref('AWS::Region'),
                                    '\n',
                                    'runas=root\n'
                                    ]),
                                # Why doesn't the Amazon template have this?
                                # mode='000400',
                                # owner='root',
                                # group='root'
                                ),
                        }),

                    commands={
                        '01-install_phpredis': {
                            'command': '/usr/local/bin/install_phpredis'
                            },
                        '02-get-cluster-config': {
                            'command': '/usr/local/bin/get_cluster_config'
                            }
                        },

                    services={
                        "sysvinit": cloudformation.InitServices({
                            "httpd": cloudformation.InitService(
                                enabled=True,
                                ensureRunning=True,
                                ),
                            "cfn-hup": cloudformation.InitService(
                                enabled=True,
                                ensureRunning=True,
                                files=['/etc/cfn/cfn-hup.conf',
                                       '/etc/cfn/hooks.d/'
                                       'cfn-auto-reloader.conf']
                                ),
                            }),
                        },
                    )
                })
            ),
        ImageId=FindInMap('AWSRegionArch2AMI', Ref('AWS::Region'),
                          FindInMap('AWSInstanceType2Arch',
                                    Ref(instancetype), 'Arch')),
        InstanceType=Ref(instancetype),
        SecurityGroups=[Ref(webserversg)],
        KeyName=Ref(keyname),
        IamInstanceProfile=Ref(webserverinstanceprofile),
        UserData=Base64(Join('', [
            '#!/bin/bash -xe\n',
            'yum update -y aws-cfn-bootstrap\n',

            '# Setup the PHP sample application\n',
            '/opt/aws/bin/cfn-init -v ',
            '         --stack ', Ref('AWS::StackName'),
            '         --resource WebServerInstance ',
            '         --region ', Ref('AWS::Region'), '\n',

            '# Signal the status of cfn-init\n',
            '/opt/aws/bin/cfn-signal -e $? ',
            '         --stack ', Ref('AWS::StackName'),
            '         --resource WebServerInstance ',
            '         --region ', Ref('AWS::Region'), '\n'
            ])),
        CreationPolicy=CreationPolicy(
            ResourceSignal=ResourceSignal(Timeout='PT15M')
            ),
        Tags=Tags(Application=Ref('AWS::StackId'),
                  Details='Created using Troposhpere')
        ))

    redisclustersg = template.add_resource(elasticache.SecurityGroup(
        'RedisClusterSecurityGroup',
        Description='Lock the cluster down',
        ))

    template.add_resource(elasticache.SecurityGroupIngress(
        'RedisClusterSecurityGroupIngress',
        CacheSecurityGroupName=Ref(redisclustersg),
        EC2SecurityGroupName=Ref(webserversg),
        ))

    template.add_resource(elasticache.CacheCluster(
        'RedisCluster',
        Engine='redis',
        CacheNodeType=Ref(cachenodetype),
        NumCacheNodes='1',
        CacheSecurityGroupNames=[Ref(redisclustersg)],
        ))

    # Outputs
    template.add_output([
        Output(
            'WebsiteURL',
            Description='Application URL',
            Value=Join('', [
                'http://',
                GetAtt(webserverinstance, 'PublicDnsName'),

                ])
            )
        ])

    # Print CloudFormation Template
    print(template.to_json())