예제 #1
0
def get_instance_metadata(instance_name):
    return autoscaling.Metadata(
        cfn.Init({
            'config':
            cfn.InitConfig(
                packages={'yum': {
                    'httpd': []
                }},
                files=cfn.InitFiles({
                    '/etc/cfn/cfn-hup.conf':
                    cfn.InitFile(content=Join('', [
                        '[main]\n',
                        'stack=',
                        Ref('AWS::StackName'),
                        '\n',
                        'region=',
                        Ref('AWS::Region'),
                        '\n',
                    ]),
                                 mode='000400',
                                 owner='root',
                                 group='root'),
                    '/etc/cfn/hooks.d/cfn-auto-reloader.conf':
                    cfn.InitFile(content=Join('', [
                        '[cfn-auto-reloader-hook]\n',
                        'triggers=post.update\n',
                        'path=Resources.',
                        instance_name,
                        '.Metadata.AWS::CloudFormation::Init\n',
                        'action=/opt/aws/bin/cfn-init -v ',
                        '         --stack=',
                        Ref('AWS::StackName'),
                        '         --resource=',
                        instance_name,
                        '         --region=',
                        Ref('AWS::Region'),
                        '\n',
                        'runas=root\n',
                    ]))
                }),
                services={
                    'sysvinit':
                    cfn.InitServices({
                        'httpd':
                        cfn.InitService(enabled=True, ensureRunning=True),
                        'cfn-hup':
                        cfn.InitService(
                            enabled=True,
                            ensureRunning=True,
                            files=[
                                '/etc/cfn/cfn-hup.conf',
                                '/etc/cfn/hooks.d/cfn-auto-reloader.conf'
                            ])
                    })
                })
        }))
def configure_for_follower(instance, counter):
    subnet_index = counter % NUM_AZS
    if counter == 2:
        instance.DependsOn = "MonitorInstance"
    else:
        instance.DependsOn = BASE_NAME + str(counter - 1)  #base_instance.title
    instance.SubnetId = Select(str(subnet_index),
                               Ref(PrivateSubnetsToSpanParam))
    # instance.AvailabilityZone = Select(str(subnet_index), Ref(AvailabilityZonesParam))
    instance.Metadata = cloudformation.Metadata(
        cloudformation.Authentication({
            "S3AccessCreds":
            cloudformation.AuthenticationBlock(
                type="S3",
                roleName=Ref(StorReduceHostRole),  #Ref(HostRoleParam),
                buckets=[Ref(QSS3BucketNameParam)])
        }),
        cloudformation.Init({
            "config":
            cloudformation.InitConfig(
                files=cloudformation.InitFiles({
                    "/home/ec2-user/connect-srr.sh":
                    cloudformation.InitFile(source=Sub(
                        "https://${" + QSS3BucketNameParam.title +
                        "}.${QSS3Region}.amazonaws.com/${" +
                        QSS3KeyPrefixParam.title + "}scripts/connect-srr.sh",
                        **{
                            "QSS3Region":
                            If("GovCloudCondition", "s3-us-gov-west-1", "s3")
                        }),
                                            mode="000550",
                                            owner="root",
                                            group="root")
                }),
                commands={
                    "connect-srr": {
                        "command":
                        Join("", [
                            "/home/ec2-user/connect-srr.sh \"",
                            GetAtt(base_instance, "PrivateDnsName"), "\" \'",
                            Ref(StorReducePasswordParam), "\' ", "\"",
                            Ref(ShardsNumParam), "\" ", "\"",
                            Ref(ReplicaShardsNumParam), "\" ", "\"",
                            Ref(elasticLB), "\" ", "\"",
                            Ref("AWS::Region"), "\" ", "\"",
                            GetAtt("Eth0", "PrimaryPrivateIpAddress"), "\" ",
                            "\"",
                            Ref(NumSRRHostsParam), "\""
                        ])
                    }
                })
        }))
    instance.Tags = [{"Key": "Name", "Value": "StorReduce-QS-Host"}]
예제 #3
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)
예제 #4
0
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())
예제 #5
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
예제 #6
0
 def _launch_config(self):
     return LaunchConfiguration(
         "LaunchConfiguration",
         Metadata=autoscaling.Metadata(
             cloudformation.Init({
                 "config":
                 cloudformation.InitConfig(files=cloudformation.InitFiles({
                     '/etc/cfn/cfn-hup.conf':
                     cloudformation.InitFile(content=Join(
                         '', [
                             '[main]\n',
                             'stack=',
                             self.ref_stack_id,
                             '\n',
                             'region=',
                             self.ref_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 ',
                             self.ref_stack_name,
                             '         --resource WebServerInstance ',
                             '         --region ',
                             self.ref_region,
                             '\n',
                             'runas=root\n',
                         ]))
                 }),
                                           services={
                                               "sysvinit":
                                               cloudformation.InitServices({
                                                   "rsyslog":
                                                   cloudformation.
                                                   InitService(
                                                       enabled=True,
                                                       ensureRunning=True,
                                                       files=[
                                                           '/etc/rsyslog.d/20-somethin.conf'
                                                       ])
                                               })
                                           })
             })),
         UserData=Base64(Join('', self.config['app_instance_user_data'])),
         ImageId=FindInMap("RegionMap", Ref("AWS::Region"), "AMI"),
         KeyName=self.config['sshkey'],
         IamInstanceProfile=Ref(self.instance_iam_role_instance_profile),
         BlockDeviceMappings=[
             ec2.BlockDeviceMapping(DeviceName=self.config['device_name'],
                                    Ebs=ec2.EBSBlockDevice(VolumeSize="8")),
         ],
         SecurityGroups=self.config['app_sg'],
         InstanceType=self.config['instance_type'],
     )
예제 #7
0
파일: client.py 프로젝트: doerodney/cloud
def generate_stack_template():
    template = Template()

    generate_description(template)

    generate_version(template)

    # ---Parameters------------------------------------------------------------
    param_vpc_id = Parameter(
        'VpcIdentifer',
        Description=
        'The identity of the VPC (vpc-abcdwxyz) in which this stack shall be created.',
        Type='AWS::EC2::VPC::Id',
    )
    template.add_parameter(param_vpc_id)

    param_vpc_security_group = Parameter(
        'VpcSecurityGroup',
        Description=
        'The security group (sg-abcdwxyz) to apply to the resources created by this stack.',
        Type='AWS::EC2::SecurityGroup::Id',
    )
    template.add_parameter(param_vpc_security_group)

    param_webserver_instance_subnet_id = Parameter(
        'VpcSubnetIdentifer',
        Description=
        'The identity of the public subnet (subnet-abcdwxyz) in which the web server shall be created.',
        Type='AWS::EC2::Subnet::Id',
    )
    template.add_parameter(param_webserver_instance_subnet_id)

    param_keyname = Parameter(
        'PemKeyName',
        Description=
        'Name of an existing EC2 KeyPair file (.pem) to use to create EC2 instances',
        Type='AWS::EC2::KeyPair::KeyName')
    template.add_parameter(param_keyname)

    param_instance_type = Parameter(
        'EC2InstanceType',
        Description=
        'EC2 instance type, reference this parameter to insure consistency',
        Type='String',
        Default=
        't2.medium',  # Prices from (2015-12-03) (Windows, us-west (North CA))
        AllowedValues=[  # Source :  https://aws.amazon.com/ec2/pricing/
            't2.small',  # $0.044/hour
            't2.micro',  # $0.022/hour
            't2.medium',  # $0.088/hour
            't2.large',  # $0.166/hour
            'm3.medium',  # $0.140/hour
            'm3.large',  # $0.28/hour
            'c4.large'  # $0.221/hour
        ],
        ConstraintDescription='Must be a valid EC2 instance type')
    template.add_parameter(param_instance_type)

    #---Mappings---------------------------------------------------------------
    mapping_environment_attribute_map = template.add_mapping(
        'EnvironmentAttributeMap', {
            'ap-southeast-1': {
                'WebServerAmi': 'ami-1ddc0b7e'
            },
            'ap-southeast-2': {
                'WebServerAmi': 'ami-0c95b86f'
            },
            'us-east-1': {
                'WebServerAmi': 'ami-a4827dc9'
            },
            'us-west-1': {
                'WebServerAmi': 'ami-f5f41398'
            }
        })

    # ---Resources-------------------------------------------------------------
    ref_region = Ref('AWS::Region')
    ref_stack_name = Ref('AWS::StackName')

    # Create the metadata for the server instance.
    name_web_server = 'WebServer'
    webserver_instance_metadata = cloudformation.Metadata(
        cloudformation.Init({
            'config':
            cloudformation.InitConfig(
                packages={'yum': {
                    'nginx': [],
                    'git': []
                }},
                files=cloudformation.InitFiles({
                    # cfn-hup.conf initialization
                    '/etc/cfn/authorapp.conf':
                    cloudformation.InitFile(content=Join(
                        '', [
                            'server {',
                            '\n',
                            '	listen 3030 ssl http2;',
                            '\n',
                            '	root /var/www/authorapp;',
                            '\n',
                            '\n',
                            '	ssl_certificate       /vagrant/ssl/ca.crt;',
                            '\n',
                            '	ssl_certificate_key   /vagrant/ssl/ca.key;',
                            '\n',
                            '\n',
                            '	location / {',
                            '\n',
                            '	}',
                            '\n',
                            '\n',
                            '	location /api {',
                            '\n',
                            '		proxy_pass http://10.50.50.1:3000;',
                            '\n',
                            '	}',
                            '\n',
                            '}',
                            '\n',
                        ]),
                                            mode='000400',
                                            owner='root',
                                            group='root'),
                }),
                services=dict(sysvinit=cloudformation.InitServices({
                    # start cfn-hup service -
                    # required for CloudFormation stack update
                    'cfn-hup':
                    cloudformation.InitService(
                        enabled=True,
                        ensureRunning=True,
                        files=[
                            '/etc/cfn/cfn-hup.conf',
                            '/etc/cfn/hooks.d/cfn-auto-reloader.conf'
                        ]),
                    # Disable sendmail service - not required.
                    'sendmail':
                    cloudformation.InitService(enabled=False,
                                               ensureRunning=False)
                })))
        }))

    resource_web_server = ec2.Instance(
        name_web_server,
        Metadata=webserver_instance_metadata,
        ImageId=FindInMap('EnvironmentAttributeMap', ref_region,
                          'WebServerAmi'),
        InstanceType=Ref(param_instance_type),
        KeyName=Ref(param_keyname),
        NetworkInterfaces=[
            ec2.NetworkInterfaceProperty(
                AssociatePublicIpAddress=str(True),
                DeleteOnTermination=str(True),
                Description='Network interface for web server',
                DeviceIndex=str(0),
                GroupSet=[Ref(param_vpc_security_group)],
                SubnetId=Ref(param_webserver_instance_subnet_id),
            )
        ],
        Tags=Tags(Name=name_web_server, VPC=Ref(param_vpc_id)),
        UserData=Base64(
            Join('', [
                '#!/bin/bash -xe\n', 'yum update -y aws-cfn-bootstrap\n',
                'yum update -y', '\n'
                '/opt/aws/bin/cfn-init --verbose ', ' --stack ',
                ref_stack_name,
                ' --resource %s ' % name_web_server, ' --region ', ref_region,
                '\n', '/opt/aws/bin/cfn-signal --exit-code $? ', ' --stack ',
                ref_stack_name, ' --resource ', name_web_server, '\n'
            ])))
    template.add_resource(resource_web_server)
    template.add_output(
        Output('WebServer',
               Description='Web Server',
               Value=GetAtt(name_web_server, 'PublicIp')))

    return template
예제 #8
0
                )
            }),
            cloudformation.Init({
            "config": cloudformation.InitConfig(
                files=cloudformation.InitFiles({
                    "/home/ec2-user/script.sh": cloudformation.InitFile(
                        source=Join('', [
                            "http://",
                            Ref(DeployBucket),
                            ".s3.amazonaws.com/scripts/script.sh"
                        ]),
                        mode="000550",
                        owner="root",
                        group="root",
                        authentication="DeployUserAuth"),

                    "/usr/sbin/configure-storreduce-pat.sh": cloudformation.InitFile(
                        source=Join('', [
                            "http://",
                            Ref(DeployBucket),
                            ".s3.amazonaws.com/scripts/configure-storreduce-pat.sh"
                        ]),
                        mode="000550",
                        owner="root",
                        group="root",
                        authentication="DeployUserAuth"),
                }),
                commands={
                    "init": {
                        "command": Join("", [
                            "/home/ec2-user/script.sh && \
 LaunchConfiguration(
     "LaunchConfiguration",
     Metadata=autoscaling.Metadata(
         cloudformation.Init({
             "config":
             cloudformation.InitConfig(
                 files=cloudformation.InitFiles({
                     "/etc/rsyslog.d/20-somethin.conf":
                     cloudformation.InitFile(
                         source=Join(
                             "",
                             [
                                 "http://",
                                 Ref(DeployBucket),
                                 ".s3.amazonaws.com/stacks/",
                                 Ref(RootStackName),
                                 "/env/etc/rsyslog.d/20-somethin.conf",
                             ],
                         ),
                         mode="000644",
                         owner="root",
                         group="root",
                         authentication="DeployUserAuth",
                     )
                 }),
                 services={
                     "sysvinit":
                     cloudformation.InitServices({
                         "rsyslog":
                         cloudformation.InitService(
                             enabled=True,
def template():

    t = Template()

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

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

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

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

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

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

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

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

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

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

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

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

    return t.to_json()
예제 #11
0
def generate_stack_template():
    template = Template()

    generate_description(template)

    generate_version(template)

    # ---Parameters------------------------------------------------------------
    param_vpc_id = Parameter(
        'VpcIdentifer',
        Description=
        'The identity of the VPC (vpc-abcdwxyz) in which this stack shall be created.',
        Type='AWS::EC2::VPC::Id',
    )
    template.add_parameter(param_vpc_id)

    param_vpc_cidr_block = Parameter(
        'VpcCidrBlock',
        Description=
        'The CIDR block of the VPC (w.x.y.z/n) in which this stack shall be created.',
        Type='String',
        Default='10.0.0.0/16')
    template.add_parameter(param_vpc_cidr_block)

    param_database_instance_subnet_id = Parameter(
        'VpcSubnetIdentifer',
        Description=
        'The identity of the private subnet (subnet-abcdwxyz) in which the database server shall be created.',
        Type='AWS::EC2::Subnet::Id',
    )
    template.add_parameter(param_database_instance_subnet_id)

    param_keyname = Parameter(
        'PemKeyName',
        Description=
        'Name of an existing EC2 KeyPair file (.pem) to use to create EC2 instances',
        Type='AWS::EC2::KeyPair::KeyName')
    template.add_parameter(param_keyname)

    param_instance_type = Parameter(
        'EC2InstanceType',
        Description=
        'EC2 instance type, reference this parameter to insure consistency',
        Type='String',
        Default=
        't2.medium',  # Prices from (2015-12-03) (Windows, us-west (North CA))
        AllowedValues=[  # Source :  https://aws.amazon.com/ec2/pricing/
            't2.small',  # $0.044/hour
            't2.micro',  # $0.022/hour
            't2.medium',  # $0.088/hour
            't2.large',  # $0.166/hour
            'm3.medium',  # $0.140/hour
            'm3.large',  # $0.28/hour
            'c4.large'  # $0.221/hour
        ],
        ConstraintDescription='Must be a valid EC2 instance type')
    template.add_parameter(param_instance_type)

    param_s3_bucket = Parameter(
        'S3Bucket',
        Description='The bucket in which applicable content can be found.',
        Type='String',
        Default='author-it-deployment-test-us-east-1')
    template.add_parameter(param_s3_bucket)

    param_s3_key = Parameter(
        'S3Key',
        Description=
        'The key within the bucket in which relevant files are located.',
        Type='String',
        Default='source/database/postgresql/single')
    template.add_parameter(param_s3_key)

    param_database_admin_password = Parameter(
        'PostgresAdminPassword',
        Description='The password to be used by user postgres.',
        Type='String',
        NoEcho=True)
    template.add_parameter(param_database_admin_password)

    #---Mappings---------------------------------------------------------------
    mapping_environment_attribute_map = template.add_mapping(
        'EnvironmentAttributeMap', {
            'ap-southeast-1': {
                'DatabaseServerAmi': 'ami-1ddc0b7e'
            },
            'ap-southeast-2': {
                'DatabaseServerAmi': 'ami-0c95b86f'
            },
            'us-east-1': {
                'DatabaseServerAmi': 'ami-a4827dc9'
            },
            'us-west-1': {
                'DatabaseServerAmi': 'ami-f5f41398'
            }
        })

    # ---Resources-------------------------------------------------------------
    ref_stack_id = Ref('AWS::StackId')
    ref_region = Ref('AWS::Region')
    ref_stack_name = Ref('AWS::StackName')
    path_database_admin_script = 'usr/ec2-user/postgresql/set_admin_password.sql'
    name_database_server_wait_handle = 'DatabaseServerWaitHandle'

    cmd_postgresql_initdb = dict(command='service postgresql-95 initdb')

    cmd_start_postgresql_service = dict(command='service postgresql-95 start')

    cmd_set_postgres_user_password = dict(command='psql -U postgres -f %s' %
                                          path_database_admin_script)

    cmd_start_postgresql_on_startup = dict(command='chkconfig postgresql on')

    cmd_signal_success = dict(command='cfn-signal --exit-code $?')

    # Create an instance of AWS::IAM::Role for the instance.
    # This allows:
    # - Access to S3 bucket content.
    # - Stack updates
    resource_instance_role = template.add_resource(
        iam.Role('InstanceRole',
                 AssumeRolePolicyDocument=Policy(Statement=[
                     Statement(Action=[AssumeRole],
                               Effect=Allow,
                               Principal=Principal('Service',
                                                   ['ec2.amazonaws.com']))
                 ]),
                 Path='/'))

    # Create the S3 policy and attach it to the role.
    template.add_resource(
        iam.PolicyType(
            'InstanceS3DownloadPolicy',
            PolicyName='S3Download',
            PolicyDocument={
                'Statement': [{
                    'Effect':
                    'Allow',
                    'Action': ['s3:GetObject'],
                    'Resource':
                    Join('', ['arn:aws:s3:::',
                              Ref(param_s3_bucket), '/*'])
                }, {
                    'Effect':
                    'Allow',
                    'Action':
                    ['cloudformation:DescribeStacks', 'ec2:DescribeInstances'],
                    'Resource':
                    '*'
                }]
            },
            Roles=[Ref(resource_instance_role)]))

    # Create the CloudFormation stack update policy and attach it to the role.
    template.add_resource(
        iam.PolicyType('InstanceStackUpdatePolicy',
                       PolicyName='StackUpdate',
                       PolicyDocument={
                           'Statement': [{
                               "Effect": "Allow",
                               "Action": "Update:*",
                               "Resource": "*"
                           }]
                       },
                       Roles=[Ref(resource_instance_role)]))

    # Create the AWS::IAM::InstanceProfile from the role for reference in the
    # database server instance definition.
    resource_instance_profile = template.add_resource(
        iam.InstanceProfile('InstanceProfile',
                            Path='/',
                            Roles=[Ref(resource_instance_role)]))

    # Create a security group for the postgresql instance.
    # This must be internal to the VPC only.
    name_security_group_database = 'VpcDatabaseSecurityGroup'
    resource_database_security_group = ec2.SecurityGroup(
        name_security_group_database,
        GroupDescription=Join(
            ' ', ['Security group for VPC database',
                  Ref(param_vpc_id)]),
        Tags=Tags(Name=name_security_group_database),
        VpcId=Ref(param_vpc_id))
    template.add_resource(resource_database_security_group)

    template.add_output(
        Output('SecurityGroupForDatabase',
               Description='Security group created for database in VPC.',
               Value=Ref(resource_database_security_group)))

    # Add ingress rule from VPC to database security group for database traffic.
    database_port = 5432
    ssh_port = 22
    template.add_resource(
        ec2.SecurityGroupIngress('DatabaseSecurityGroupDatabaseIngress',
                                 CidrIp=Ref(param_vpc_cidr_block),
                                 FromPort=str(database_port),
                                 GroupId=Ref(resource_database_security_group),
                                 IpProtocol='tcp',
                                 ToPort=str(database_port)))

    # Add ingress rule from VPC to database security group for ssh traffic.
    ssh_port = 22
    template.add_resource(
        ec2.SecurityGroupIngress('DatabaseSecurityGroupSshIngress',
                                 CidrIp=Ref(param_vpc_cidr_block),
                                 FromPort=str(ssh_port),
                                 GroupId=Ref(resource_database_security_group),
                                 IpProtocol='tcp',
                                 ToPort=str(ssh_port)))

    # Create the metadata for the database instance.
    name_database_server = 'DatabaseServer'
    database_instance_metadata = cloudformation.Metadata(
        cloudformation.Init({
            'config':
            cloudformation.InitConfig(
                packages={
                    'rpm': {
                        'postgresql':
                        'https://download.postgresql.org/pub/repos/yum/9.5/redhat/rhel-6-x86_64/pgdg-ami201503-95-9.5-2.noarch.rpm'
                    },
                    'yum': {
                        'postgresql95': [],
                        'postgresql95-libs': [],
                        'postgresql95-server': [],
                        'postgresql95-devel': [],
                        'postgresql95-contrib': [],
                        'postgresql95-docs': []
                    }
                },
                files=cloudformation.InitFiles({
                    # cfn-hup.conf initialization
                    '/etc/cfn/cfn-hup.conf':
                    cloudformation.InitFile(content=Join(
                        '', [
                            '[main]\n', 'stack=', ref_stack_id, '\n',
                            'region=', ref_region, '\n', 'interval=2', '\n',
                            'verbose=true', '\n'
                        ]),
                                            mode='000400',
                                            owner='root',
                                            group='root'),
                    # cfn-auto-reloader.conf initialization
                    '/etc/cfn/cfn-auto-reloader.conf':
                    cloudformation.InitFile(
                        content=Join(
                            '',
                            [
                                '[cfn-auto-reloader-hook]\n',
                                'triggers=post.update\n',
                                'path=Resources.%s.Metadata.AWS::CloudFormation::Init\n'
                                % name_database_server,
                                'action=cfn-init.exe ',
                                ' --verbose '
                                ' --stack ',
                                ref_stack_name,
                                ' --resource %s ' %
                                name_database_server,  # resource that defines the Metadata
                                ' --region ',
                                ref_region,
                                '\n'
                            ]),
                        mode='000400',
                        owner='root',
                        group='root'),
                    #
                    # pg_hba.conf retrieval from S3
                    '/var/lib/pgsql9/data/pg_hba.conf':
                    cloudformation.InitFile(
                        source=Join(
                            '/',
                            [
                                # Join('', ['https://s3-', ref_region, '.', 'amazonaws.com']),
                                'https://s3.amazonaws.com',
                                Ref(param_s3_bucket),
                                Ref(param_s3_key),
                                'conf'
                                'pg_hba.conf'
                            ]),
                        mode='000400',
                        owner='root',
                        group='root'),
                    # postgresql.conf retrieval from S3
                    '/var/lib/pgsql9/data/postgresql.conf':
                    cloudformation.InitFile(
                        source=Join(
                            '/',
                            [
                                #Join('', ['https://s3-', ref_region, '.', 'amazonaws.com']),
                                'https://s3.amazonaws.com',
                                Ref(param_s3_bucket),
                                Ref(param_s3_key),
                                'conf'
                                'postgresql.conf'
                            ]),
                        mode='000400',
                        owner='root',
                        group='root'),
                    # pg_ident.conf retrieval from S3
                    '/var/lib/pgsql9/data/pg_ident.conf':
                    cloudformation.InitFile(
                        source=Join(
                            '/',
                            [
                                #Join('', ['https://s3-', ref_region, '.', 'amazonaws.com']),
                                'https://s3.amazonaws.com',
                                Ref(param_s3_bucket),
                                Ref(param_s3_key),
                                'conf'
                                'pg_ident.conf'
                            ]),
                        mode='000400',
                        owner='root',
                        group='root'),
                    # script to set postgresql admin password.
                    # (admin user = '******')
                    path_database_admin_script:
                    cloudformation.InitFile(
                        source=Join('', [
                            'ALTER USER postgres WITH PASSWORD ',
                            Ref(param_database_admin_password), ';', '\n'
                        ]))
                }),
                commands={
                    '10-postgresql_initdb':
                    cmd_postgresql_initdb,
                    '20-start_postgresql_service':
                    cmd_start_postgresql_service,
                    '30-set-postgres-user-password':
                    cmd_set_postgres_user_password,
                    '40-start-postgresql-on-startup':
                    cmd_start_postgresql_on_startup,
                    #'99-signal-success': cmd_signal_success
                },
                services=dict(sysvinit=cloudformation.InitServices({
                    # start cfn-hup service -
                    # required for CloudFormation stack update
                    'cfn-hup':
                    cloudformation.InitService(
                        enabled=True,
                        ensureRunning=True,
                        files=[
                            '/etc/cfn/cfn-hup.conf',
                            '/etc/cfn/hooks.d/cfn-auto-reloader.conf'
                        ]),
                    # start postgresql service
                    'postgresql-9.5':
                    cloudformation.InitService(enabled=True,
                                               ensureRunning=True),
                    # Disable sendmail service - not required.
                    'sendmail':
                    cloudformation.InitService(enabled=False,
                                               ensureRunning=False)
                })))
        }),
        cloudformation.Authentication({
            'S3AccessCredentials':
            cloudformation.AuthenticationBlock(
                buckets=[Ref(param_s3_bucket)],
                roleName=Ref(resource_instance_role),
                type='S3')
        }))

    # Add a wait handle to receive the completion signal.
    #resource_database_server_wait_handle = template.add_resource(
    #    cloudformation.WaitConditionHandle(
    #        name_database_server_wait_handle
    #    )
    # )

    #template.add_resource(
    #    cloudformation.WaitCondition(
    #        'DatabaseServerWaitCondition',
    #        DependsOn=name_database_server,
    #        Handle=Ref(resource_database_server_wait_handle),
    #        Timeout=300,
    #    )
    #)

    resource_database_server = ec2.Instance(
        name_database_server,
        DependsOn=name_security_group_database,
        IamInstanceProfile=Ref(resource_instance_profile),
        Metadata=database_instance_metadata,
        ImageId=FindInMap('EnvironmentAttributeMap', ref_region,
                          'DatabaseServerAmi'),
        InstanceType=Ref(param_instance_type),
        KeyName=Ref(param_keyname),
        SecurityGroupIds=[Ref(resource_database_security_group)],
        SubnetId=Ref(param_database_instance_subnet_id),
        Tags=Tags(Name=name_database_server, VPC=Ref(param_vpc_id)),
        UserData=Base64(
            Join('', [
                '#!/bin/bash -xe\n', 'yum update -y aws-cfn-bootstrap\n',
                '/opt/aws/bin/cfn-init --verbose ', ' --stack ',
                ref_stack_name, ' --resource DatabaseServer ', ' --region ',
                ref_region, '\n', '/opt/aws/bin/cfn-signal --exit-code $? ',
                ' --stack ', ref_stack_name, ' --resource ',
                name_database_server, '\n'
            ])))
    template.add_resource(resource_database_server)
    template.add_output(
        Output('DatabaseServer',
               Description='PostgreSQL single instance database server',
               Value=Ref(resource_database_server)))

    return template
def generate_new_instance(counter):
    # Create base StorReduce instance
    instance = ec2.Instance(BASE_NAME + str(counter))
    instance.DependsOn = [
        elasticLB.title, SrrBucket.title, StorReduceHostProfile.title,
        AllInternalAccessSecurityGroup.title
    ]
    instance.ImageId = FindInMap("AWSAMIRegion", Ref("AWS::Region"), "AMI")
    instance.IamInstanceProfile = Ref(StorReduceHostProfile)
    # instance.AvailabilityZone = Select("0", Ref(AvailabilityZonesParam))
    instance.InstanceType = Ref(InstanceTypeParam)
    instance.KeyName = Ref(KeyPairNameParam)
    #instance.SecurityGroupIds = Ref(SecurityGroupIdsParam)
    instance.SecurityGroupIds = [Ref(AllInternalAccessSecurityGroup)]

    instance.SubnetId = Select("0", Ref(PrivateSubnetsToSpanParam))
    instance.UserData = Base64(
        Join("", [
            """
    #!/bin/bash -xe
    /opt/aws/bin/cfn-init -v --stack """,
            Ref("AWS::StackName"),
            " --resource " + instance.title + " --region ",
            Ref("AWS::Region"), "\n", "/opt/aws/bin/cfn-signal -e $? --stack ",
            Ref("AWS::StackName"),
            "    --resource " + instance.title + " --region ",
            Ref("AWS::Region")
        ]))

    instance.Metadata = cloudformation.Metadata(
        cloudformation.Authentication({
            "S3AccessCreds":
            cloudformation.AuthenticationBlock(
                type="S3",
                roleName=Ref(StorReduceHostRole),  #Ref(HostRoleParam),
                buckets=[Ref(QSS3BucketNameParam)])
        }),
        cloudformation.Init({
            "config":
            cloudformation.InitConfig(
                files=cloudformation.InitFiles({
                    "/home/ec2-user/init-srr.sh":
                    cloudformation.InitFile(source=Sub(
                        "https://${" + QSS3BucketNameParam.title +
                        "}.${QSS3Region}.amazonaws.com/${" +
                        QSS3KeyPrefixParam.title + "}scripts/init-srr.sh", **{
                            "QSS3Region":
                            If("GovCloudCondition", "s3-us-gov-west-1", "s3")
                        }),
                                            mode="000550",
                                            owner="root",
                                            group="root")
                }),
                commands={
                    "init-srr": {
                        "command":
                        Join("", [
                            "/home/ec2-user/init-srr.sh \"",
                            Ref(BucketNameParam), "\" \'",
                            Ref(StorReduceLicenseParam), "\' ", "\'",
                            Ref(StorReducePasswordParam), "\' ", "\'",
                            Ref(ShardsNumParam), "\' ", "\'",
                            Ref(ReplicaShardsNumParam), "\' ", "\"",
                            Ref(StorReduceHostNameParam), "\" ", "\"",
                            GetAtt(elasticLB, "DNSName"), "\" ", "\"",
                            Ref(elasticLB), "\" ", "\"",
                            Ref("AWS::Region"), "\" ", "\"",
                            GetAtt("Eth0", "PrimaryPrivateIpAddress"), "\" ",
                            "\"",
                            Ref(NumSRRHostsParam), "\""
                        ])
                    }
                })
        }))

    instance.Tags = [{"Key": "Name", "Value": "StorReduce-QS-Base-Host"}]

    instance.CreationPolicy = CreationPolicy(ResourceSignal=ResourceSignal(
        Timeout='PT15M'))
    return instance
     "S3AccessCreds":
     cloudformation.AuthenticationBlock(
         type="S3",
         roleName=Ref(StorReduceHostRole),  #Ref(HostRoleParam),
         buckets=[Ref(QSS3BucketNameParam)])
 }),
 cloudformation.Init({
     "config":
     cloudformation.InitConfig(
         files=cloudformation.InitFiles({
             "/home/ec2-user/monitor-srr.sh":
             cloudformation.InitFile(source=Sub(
                 "https://${" + QSS3BucketNameParam.title +
                 "}.${QSS3Region}.amazonaws.com/${" +
                 QSS3KeyPrefixParam.title + "}scripts/monitor-srr.sh", **{
                     "QSS3Region":
                     If("GovCloudCondition", "s3-us-gov-west-1", "s3")
                 }),
                                     mode="000550",
                                     owner="root",
                                     group="root"),
         }),
         commands={
             "monitor-srr": {
                 "command":
                 Join("", [
                     "/home/ec2-user/monitor-srr.sh \"",
                     GetAtt(base_instance, "PrivateDnsName"), "\" \'",
                     Ref(StorReducePasswordParam), "\'"
                 ])
             }
예제 #14
0
                files=cloudformation.InitFiles({
                    "/home/ec2-user/init-cron.sh": cloudformation.InitFile(
                        source=Join('', [
                            "http://",
                            Ref(DeployBucket),
                            ".s3.", Ref("AWS::Region"), ".amazonaws.com/scripts/init-cron.sh"
                        ]),
                        mode="000550",
                        owner="root",
                        group="root",
                        authentication="DeployUserAuth"),

                    "/home/ec2-user/configure-s3-nat.sh": cloudformation.InitFile(
                        source=Join('', [
                            "http://",
                            Ref(DeployBucket),
                            ".s3.", Ref("AWS::Region"), ".amazonaws.com/scripts/configure-s3-nat.sh"
                        ]),
                        mode="000550",
                        owner="root",
                        group="root",
                        authentication="DeployUserAuth"),

                    "/home/ec2-user/metrics.sh": cloudformation.InitFile(
                        source=Join('', [
                            "http://",
                            Ref(DeployBucket),
                            ".s3.", Ref("AWS::Region"), ".amazonaws.com/scripts/metrics.sh"
                        ]),
                        mode="000550",
                        owner="root",
                        group="root",
                        authentication="DeployUserAuth"),
                    
                    "/home/ec2-user/nat-globals.sh": cloudformation.InitFile(
                        source=Join('', [
                            "http://",
                            Ref(DeployBucket),
                            ".s3.", Ref("AWS::Region"), ".amazonaws.com/scripts/nat-globals.sh"
                        ]),
                        mode="000550",
                        owner="root",
                        group="root",
                        authentication="DeployUserAuth"),

                    "/home/ec2-user/nat-lib.sh": cloudformation.InitFile(
                        source=Join('', [
                            "http://",
                            Ref(DeployBucket),
                            ".s3.", Ref("AWS::Region"), ".amazonaws.com/scripts/nat-lib.sh"
                        ]),
                        mode="000550",
                        owner="root",
                        group="root",
                        authentication="DeployUserAuth"),

                    "/home/ec2-user/s3-nat-watchdog.sh": cloudformation.InitFile(
                        source=Join('', [
                            "http://",
                            Ref(DeployBucket),
                            ".s3.", Ref("AWS::Region"), ".amazonaws.com/scripts/s3-nat-watchdog.sh"
                        ]),
                        mode="000550",
                        owner="root",
                        group="root",
                        authentication="DeployUserAuth"),

                    "/home/ec2-user/test-s3-nat.sh": cloudformation.InitFile(
                        source=Join('', [
                            "http://",
                            Ref(DeployBucket),
                            ".s3.", Ref("AWS::Region"), ".amazonaws.com/scripts/test-s3-nat.sh"
                        ]),
                        mode="000550",
                        owner="root",
                        group="root",
                        authentication="DeployUserAuth"),
                }),
예제 #15
0
        Metadata=Metadata(
            cf.Init({
                "configsets":
                cf.InitConfigSets(InstallandRun=["install", "config"]),
                "install":
                cf.InitConfig(packages={"yum": {
                    "git": [],
                    "wget": []
                }}),
                "config":
                cf.InitConfig(files=cf.InitFiles({
                    "/tmp/example.txt":
                    cf.InitFile(content=Join('', [
                        "This is a file example.\n",
                        "See another examples in:\n",
                        "https://github.com/rabeloo/cf-templates\n"
                    ]),
                                owner="root",
                                group="root",
                                mode="000600")
                }), ),
            }))))

autoscaling_group_resource = t.add_resource(
    AutoScalingGroup("myAutoScalingGroup",
                     DesiredCapacity=Ref(desInstances_param),
                     MinSize=Ref(minInstances_param),
                     MaxSize=Ref(maxInstances_param),
                     Cooldown="300",
                     LoadBalancerNames=FindInMap("RegionMap",
                                                 {"Ref": "AWS::Region"},
예제 #16
0
# Define our launch configuration (AWS compatibility resource)
launch_config = template.add_resource(autoscaling.LaunchConfiguration(
    "MyLaunchConfig",
    KeyName="bootstrap",
    InstanceType="t1.micro",
    ImageId="Ubuntu",
    SecurityGroups=[Ref(security_group)],
    Metadata=cloudformation.Init({
        "config": cloudformation.InitConfig(
            files=cloudformation.InitFiles({
                "file1": cloudformation.InitFile(
                    content=Join('\n', [
                        "This is a",
                        "test file"
                    ]),
                    mode="000755",
                    owner="root",
                    group="root",
                    context=cloudformation.InitFileContext({
                        "security_group_id": Ref(security_group)
                    })
                )
            })
        )
    }),
    UserData=Base64(Join('\n', [
        "#!/bin/bash",
        "echo \"Upgrade started at $(date)\"",
        "apt-get update",
        "apt-get -y upgrade",
        "echo \"Upgrade complete at $(date)\"",
    ]))
예제 #17
0
 }},
 files=cfn.InitFiles({
     '/etc/cfn/cfn-hup.conf':
     cfn.InitFile(content=Join('', [
         '[main]\n',
         'stack=',
         Ref('AWS::StackName'),
         '\n',
         'region=',
         Ref('AWS::Region'),
         '\n',
     ]),
                  mode='000400',
                  owner='root',
                  group='root'),
     '/etc/cfn/hooks.d/cfn-auto-reloader.conf':
     cfn.InitFile(content=Join('', [
         '[cfn-auto-reloader-hook]\n',
         'triggers=post.update\n',
         'path=Resources.NatInstance.Metadata.AWS::CloudFormation::Init\n',
         'action=/opt/aws/bin/cfn-init -v ',
         '         --stack=',
         Ref('AWS::StackName'),
         '         --resource=NatInstance',
         '         --region=',
         Ref('AWS::Region'),
         '\n',
         'runas=root\n',
     ]))
 }),
 services={
예제 #18
0
 files=cloudformation.InitFiles({
     "/etc/cfn/cfn-hup.conf":
     cloudformation.InitFile(
         content=Join("", [
             "[main]\n",
             "template=",
             Ref(AWS_STACK_ID),
             "\n",
             "region=",
             Ref(AWS_REGION),
             "\n",
         ]),
         mode="000400",
         owner="root",
         group="root",
     ),
     "/etc/cfn/hooks.d/cfn-auto-reload.conf":
     cloudformation.InitFile(
         content=Join("", [
             "[cfn-auto-reloader-hook]\n",
             "triggers=post.update\n",
             "path=Resources.%s." %
             container_instance_configuration_name,
             "Metadata.AWS::CloudFormation::Init\n",
             "action=/opt/aws/bin/cfn-init -v ",
             "         --stack",
             Ref(AWS_STACK_NAME),
             "         --resource %s" %
             container_instance_configuration_name,
             "         --region ",
             Ref("AWS::Region"),
             "\n",
             "runas=root\n",
         ]))
 }),
예제 #19
0
            cfn.InitConfig(files=cfn.InitFiles({
                "/etc/profile.d/cellos.sh":
                cfn.InitFile(
                    content=make_content("""\
#!/bin/bash
export cell_backend="aws"
export cell_name="{{cell_name}}"
export full_cell_name="cell-os--{{cell_name}}"
export zk_elb="{{zk_elb}}"
export zk_base_url="{{zk_base_url}}"
export zk_cluster_list="{{zk_base_url}}/cluster/list"
export marathon_elb="{{marathon_elb}}"
export mesos_elb="{{mesos_elb}}"
export gateway_elb="{{gateway_elb}}"
export internal_gateway_elb="{{internal_gateway_elb}}"
export SAASBASE_ACCESS_KEY_ID="{{saasbase_access_key_id}}"
export SAASBASE_SECRET_ACCESS_KEY="{{saasbase_secret_access_key}}"
export repository="{{repository}}"
export cellos_version="{{cellos_version}}"
export cell_bucket_name="{{cell_bucket_name}}"
export cell_role="{{cell_role}}"
export cell_modules="{{cell_modules}}"

export machine_tags="{{machine_tags}}"
export instance_id=`wget -qO- http://169.254.169.254/latest/meta-data/instance-id`
export aws_stack_name="{{aws_stack_name}}"
export aws_parent_stack_name="{{aws_parent_stack_name}}"
export aws_region="{{aws_region}}"
export aws_access_key_id="{{aws_access_key_id}}"
export aws_secret_access_key="{{aws_secret_access_key}}"
export aws_wait_handle="{{aws_wait_handle}}"
"""),
                    owner="root",
                    group="root",
                    mode="000755",
                    context=cfn.InitFileContext({
                        "zk_base_url":
                        Join("",
                             ["http://",
                              Ref("ZookeeperElb"), "/exhibitor/v1"]),
                        "zk_elb":
                        Ref("ZookeeperElb"),
                        "marathon_elb":
                        Ref("MarathonElb"),
                        "mesos_elb":
                        Ref("MesosElb"),
                        "gateway_elb":
                        Ref("GatewayElb"),
                        "internal_gateway_elb":
                        Ref("InternalGatewayElb"),
                        "aws_stack_name":
                        Ref("AWS::StackName"),
                        "aws_parent_stack_name":
                        Ref("ParentStackName"),
                        "aws_region":
                        Ref("AWS::Region"),
                        "saasbase_access_key_id":
                        Ref("SaasBaseAccessKeyId"),
                        "saasbase_secret_access_key":
                        Ref("SaasBaseSecretAccessKey"),
                        "repository":
                        Ref("Repository"),
                        "cellos_version":
                        Ref("CellOsVersionBundle"),
                        "cell_bucket_name":
                        Ref("BucketName"),
                        "cell_name":
                        Ref("CellName"),
                        "cell_role":
                        Ref("Role"),
                        "cell_modules":
                        Ref("CellModules"),
                        "machine_tags":
                        Ref("Tags"),
                        "aws_wait_handle":
                        Ref("WaitHandle"),
                    })),
            }))