예제 #1
0
 def create_server_metadata(metadata):
     return cloudformation.Metadata(
         cloudformation.Init({
             'config':
             cloudformation.InitConfig(packages=metadata['packages'],
                                       sources=metadata['sources'],
                                       files=metadata['files'],
                                       commands=metadata['commands'])
         }))
예제 #2
0
 def get_metadata(self):
     metadata = cloudformation.Metadata(
         cloudformation.Init(
             cloudformation.InitConfigSets(default=['install_and_run']),
             install_and_run=cloudformation.InitConfig(commands={
                 '01-startup': {
                     'command': 'echo hello world'
                 },
             })))
     return metadata
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"}]
예제 #4
0
 def get_metadata(self):
     metadata = cloudformation.Metadata(
         cloudformation.Init(
             cloudformation.InitConfigSets(default=['install_and_run']),
             install_and_run=cloudformation.InitConfig(
                 commands={
                     '01-startup': {
                         'command':
                         'nohup python -m SimpleHTTPServer 8000 &'
                     },
                 })))
     return metadata
예제 #5
0
def add_cfn_init():
    return cloudformation.Metadata(
        cloudformation.Init(
            cloudformation.InitConfigSets(ascending=['config'],
                                          descending=['config']),
            config=cloudformation.InitConfig(
                commands={
                    'test': {
                        'command': 'echo "$CFNTEST" > text.txt',
                        'env': {
                            'CFNTEST': 'I come from config.'
                        },
                        'cwd': '~'
                    }
                })))
예제 #6
0
def Meta(name, private_ip):
    return cfn.Metadata(
        cfn.Authentication({
            "default": cfn.AuthenticationBlock(type="S3", roleName=Ref(InstanceRole), buckets=[ Ref(Bucket) ])
        }),
        cfn.Init(
            cfn.InitConfigSets(default = ['SetupHost','SetupWebsite']),
            SetupHost = cfn.InitConfig(
                     files = {
                               "/etc/hostname":{
                                                 "content": Join(".",[ name, Ref(HostedZone) ])
                             },
                             "/root/set-hostname.sh":{
                                 "content": Join("",[
                                    "#!/bin/bash\n",
                                    "hostname --file /etc/hostname\n",
                                    "h=$(cat /etc/hostname)\n",
                                    "sed -i s/HOSTNAME=.*/HOSTNAME=$h/g /etc/sysconfig/network\n",
                                    "echo ", private_ip , " $h >>/etc/hosts \n",
                                    "service network restart"
                                 ]),
                                 "mode": "755"
                             },
                     },
                     commands={
                             "1-set-hostname": {
                                                 "command": "/root/set-hostname.sh "
                             }
                     }
            ),
            SetupWebsite = cfn.InitConfig(
                     packages = {
                                  "yum" : { 'httpd' : []}
                                },
                     sources =  {
                                  "/var/www/html/": Join("", [ "https://", Ref(Bucket), ".s3.amazonaws.com/3dstreetartindia.zip" ])
                                },
                     services = {
                                  "sysvinit" : {
                                                 "httpd"    : { "enabled" : "true", "ensureRunning" : "true" },
                                               }
                                }

            )
))
예제 #7
0
    def __init__(self):
        InitConfigSets = ASInitConfigSets()

        CfmInitArgs = {}
        IBoxEnvApp = []
        Tags = []
        UserDataApp = []

        for n in cfg.Apps:
            name = f'Apps{n}'  # Ex. Apps1
            envname = f'EnvApp{n}Version'  # Ex EnvApp1Version
            reponame = f'{name}RepoName'  # Ex Apps1RepoName

            UserDataApp.extend(['#${%s}\n' % envname])

            p_EnvAppVersion = Parameter(envname)
            p_EnvAppVersion.Description = f'Application {n} version'
            p_EnvAppVersion.AllowedPattern = '^[a-zA-Z0-9-_.]*$'

            p_AppsRepoName = Parameter(reponame)
            p_AppsRepoName.Description = (
                f'App {n} Repo Name - empty for default based on env/role')
            p_AppsRepoName.AllowedPattern = '^[a-zA-Z0-9-_.]*$'

            # parameters
            add_obj([
                p_EnvAppVersion,
                p_AppsRepoName,
            ])

            # conditions
            add_obj({
                name:
                And(Not(Equals(Ref(envname), '')),
                    Not(get_condition('', 'equals', 'None', reponame)))
            })

            InitConfigApps = ASInitConfigApps(name)
            CfmInitArgs[name] = InitConfigApps

            InitConfigAppsBuilAmi = ASInitConfigAppsBuildAmi(name)
            # AUTOSPOT - Let cfn-init always prepare instances on boot
            # CfmInitArgs[name + 'BuildAmi'] = InitConfigAppsBuilAmi
            CfmInitArgs[name] = InitConfigAppsBuilAmi

            IBoxEnvApp.extend([
                f'export EnvApp{n}Version=',
                Ref(envname),
                "\n",
                f'export EnvRepo{n}Name=',
                get_endvalue(reponame),
                "\n",
            ])

            InitConfigSetsApp = If(name, name, Ref('AWS::NoValue'))
            InitConfigSetsAppBuilAmi = If(name, f'{name}BuildAmi',
                                          Ref('AWS::NoValue'))
            IndexSERVICES = InitConfigSets.data['default'].index('SERVICES')
            InitConfigSets.data['default'].insert(IndexSERVICES,
                                                  InitConfigSetsApp)
            # AUTOSPOT - Let cfn-init always prepare instances on boot
            # InitConfigSets.data['buildamifull'].append(
            #    InitConfigSetsAppBuilAmi)
            InitConfigSets.data['buildamifull'].append(InitConfigSetsApp)

            Tags.append(asg.Tag(envname, Ref(envname), True))

            # resources
            # FOR MULTIAPP CODEDEPLOY
            if len(cfg.Apps) > 1:
                r_DeploymentGroup = CDDeploymentGroup(f'DeploymentGroup{name}')
                r_DeploymentGroup.setup(index=n)

                add_obj(r_DeploymentGroup)

            # outputs
            Output_app = Output(envname)
            Output_app.Value = Ref(envname)
            add_obj(Output_app)

            Output_repo = Output(reponame)
            Output_repo.Value = get_endvalue(reponame)
            add_obj(Output_repo)

        InitConfigSetup = ASInitConfigSetup()
        InitConfigSetup.ibox_env_app = IBoxEnvApp
        InitConfigSetup.setup()

        InitConfigCodeDeploy = ASInitConfigCodeDeploy()

        CfmInitArgs['SETUP'] = InitConfigSetup
        CfmInitArgs['CWAGENT'] = ASInitConfigCloudWatchAgent('')

        if cfg.Apps:
            CfmInitArgs['CODEDEPLOY'] = InitConfigCodeDeploy
            CD_DeploymentGroup()

        # LoadBalancerClassic External
        if cfg.LoadBalancerClassicExternal:
            InitConfigELBExternal = ASInitConfigELBClassicExternal()
            CfmInitArgs['ELBWAITER'] = InitConfigELBExternal

        # LoadBalancerClassic Internal
        if cfg.LoadBalancerClassicInternal:
            InitConfigELBInternal = ASInitConfigELBClassicInternal()
            CfmInitArgs['ELBWAITER'] = InitConfigELBInternal

        # LoadBalancerApplication External
        if cfg.LoadBalancerApplicationExternal:
            InitConfigELBExternal = ASInitConfigELBApplicationExternal()
            CfmInitArgs['ELBWAITER'] = InitConfigELBExternal

            # LoadBalancerApplication Internal
            InitConfigELBInternal = ASInitConfigELBApplicationInternal()
            CfmInitArgs['ELBWAITER'] = InitConfigELBInternal

        SecurityGroups = SG_SecurityGroupsEC2().SecurityGroups

        # Resources
        R_LaunchConfiguration = ASLaunchConfiguration('LaunchConfiguration',
                                                      UserDataApp=UserDataApp)
        R_LaunchConfiguration.SecurityGroups.extend(SecurityGroups)

        R_InstanceProfile = IAMInstanceProfile('InstanceProfile')

        # Import role specific cfn definition
        cfn_envrole = f'cfn_{cfg.classenvrole}'
        if cfn_envrole in globals():  # Ex cfn_client_portal
            CfnRole = globals()[cfn_envrole]()
            CfmInitArgs.update(CfnRole)

        R_LaunchConfiguration.Metadata = cfm.Metadata(
            {
                'CloudFormationInitVersion':
                If(
                    'CloudFormationInit',
                    Ref('EnvStackVersion'),
                    Ref('AWS::NoValue'),
                )
            }, cfm.Init(InitConfigSets, **CfmInitArgs),
            cfm.Authentication({
                'CfnS3Auth':
                cfm.AuthenticationBlock(type='S3',
                                        buckets=[
                                            Sub(cfg.BucketAppRepository),
                                            Sub(cfg.BucketAppData)
                                        ],
                                        roleName=Ref('RoleInstance'))
            }))

        R_LaunchConfigurationSpot = ASLaunchConfiguration(
            'LaunchConfigurationSpot', UserDataApp=UserDataApp, spot=True)
        R_LaunchConfigurationSpot.SecurityGroups = (
            R_LaunchConfiguration.SecurityGroups)
        R_LaunchConfigurationSpot.SpotPrice = get_endvalue('SpotPrice')

        add_obj([
            R_LaunchConfiguration,
            R_InstanceProfile,
        ])
        if cfg.SpotASG:
            add_obj(R_LaunchConfigurationSpot)

        self.LaunchConfiguration = R_LaunchConfiguration
        self.Tags = Tags
예제 #8
0
 Metadata=cloudformation.Metadata(
     cloudformation.Init(
         cloudformation.InitConfigSets(
             on_first_boot=[
                 'install_dokku', 'set_dokku_env', 'start_cfn_hup'
             ],
             on_metadata_update=['set_dokku_env'],
         ),
         # TODO: figure out how to reinstall Dokku if the version is changed (?)
         install_dokku=cloudformation.InitConfig(
             commands={
                 '01_fetch': {
                     'command':
                     Join('', [
                         'wget https://raw.githubusercontent.com/dokku/dokku/',
                         Ref(dokku_version),
                         '/bootstrap.sh',
                     ]),
                     'cwd':
                     '~',
                 },
                 '02_install': {
                     # docker-ce fails to install with this error if bootstrap.sh is run without sudo:
                     # "debconf: delaying package configuration, since apt-utils is not installed"
                     'command':
                     'sudo -E bash bootstrap.sh',  # use -E to make sure bash gets our env
                     'env': {
                         'DOKKU_TAG': Ref(dokku_version),
                         'DOKKU_VHOST_ENABLE': Ref(dokku_vhost_enable),
                         'DOKKU_WEB_CONFIG': Ref(dokku_web_config),
                         'DOKKU_HOSTNAME': domain_name,
                         'DOKKU_KEY_FILE':
                         '/home/ubuntu/.ssh/authorized_keys',  # use the key configured by key_name
                         'DOKKU_SKIP_KEY_FILE':
                         'false',  # should be the default, but be explicit just in case
                     },
                     'cwd': '~',
                 },
             }, ),
         set_dokku_env=cloudformation.InitConfig(
             commands={
                 '01_set_env': {
                     # redirect output to /dev/null so we don't write environment variables to log file
                     'command':
                     'dokku config:set --global {} >/dev/null'.format(
                         ' '.join([
                             '=$'.join([k, k])
                             for k, _ in environment_variables
                         ]), ),
                     'env':
                     dict(environment_variables),
                 },
             }, ),
         start_cfn_hup=cloudformation.InitConfig(
             commands={
                 '01_start': {
                     'command': 'service cfn-hup start',
                 },
             },
             files={
                 '/etc/cfn/cfn-hup.conf': {
                     'content':
                     Join(
                         '',
                         [
                             '[main]\n',
                             'stack=',
                             Ref('AWS::StackName'),
                             '\n',
                             'region=',
                             Ref('AWS::Region'),
                             '\n',
                             'umask=022\n',
                             'interval=1\n',  # check for changes every minute
                             'verbose=true\n',
                         ]),
                     'mode':
                     '000400',
                     'owner':
                     'root',
                     'group':
                     'root',
                 },
                 '/etc/cfn/hooks.d/cfn-auto-reloader.conf': {
                     'content':
                     Join(
                         '',
                         [
                             # trigger the on_metadata_update configset on any changes to Ec2Instance metadata
                             '[cfn-auto-reloader-hook]\n',
                             'triggers=post.update\n',
                             'path=Resources.%s.Metadata\n' %
                             ec2_instance_name,
                             'action=/usr/local/bin/cfn-init',
                             ' --stack=',
                             Ref('AWS::StackName'),
                             ' --resource=%s' % ec2_instance_name,
                             ' --configsets=on_metadata_update',
                             ' --region=',
                             Ref('AWS::Region'),
                             '\n',
                             'runas=root\n',
                         ]),
                     'mode':
                     '000400',
                     'owner':
                     'root',
                     'group':
                     'root',
                 },
             },
         ),
     ), ),
예제 #9
0
instance_metadata = cloudformation.Metadata(
    cloudformation.Init(
        cloudformation.InitConfigSets(
            Bootstrap=[
                'ConfigCFNTools',
                # 'InstallPackages',
            ],
            Update=[
                'ConfigCFNTools',
                # 'InstallPackages',
            ],
        ),
        ConfigCFNTools=cloudformation.InitConfig(
            files={
                '/etc/cfn/cfn-hup.conf': {
                    'content': Sub(
                        '[main]\n'
                        'stack=${AWS::StackId}\n'
                        'region=${AWS::Region}\n'
                        'interval=5\n'
                        'verbose=false\n'
                    ),
                    'mode': '000400',
                    'owner': 'root',
                    'group': 'root',
                },
                '/etc/cfn/hooks.d/cfn-auto-reloader.conf': {
                    'content': Sub(
                        '[cfn-auto-reloader-hook]\n'
                        'triggers=post.update\n'
                        'path=Resources.%(INSTANCE_NAME)s.Metadata.AWS::CloudFormation::Init\n'
                        'action=/opt/aws/bin/cfn-init -v'
                        '    --stack ${AWS::StackName}'
                        '    --resource %(INSTANCE_NAME)s'
                        '    --configsets Update'
                        '    --region ${AWS::Region}'
                        '\n'
                        'runas=root\n' % \
                        {'INSTANCE_NAME': instance_resource_name}
                    ),
                },
            },
            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',
                            ]
                        ),
                    }
                )
            },
        ),
        # InstallPackages=cloudformation.InitConfig(
        #     packages={
        #         'yum': {
        #             'python27-devel': [],
        #         },
        #
        #     },
        #     services={'sysvinit': cloudformation.InitServices(
        #         {
        #             'nginx': cloudformation.InitService(
        #                 enabled=True,
        #                 ensureRunning=True,
        #                 files=[
        #                     '/etc/nginx/nginx.conf',
        #                 ]
        #             ),
        #         }
        #     )},
        # ),
    )
)
예제 #10
0
def buildInstance(t, args):
    t.add_resource(
        ec2.SecurityGroup('WebserverSG',
                          GroupDescription='Global Webserver Access',
                          VpcId=Ref('VPC'),
                          Tags=Tags(Name='Global Webserver Access')))

    t.add_resource(
        ec2.SecurityGroupIngress('WebserverSGIngress1',
                                 GroupId=Ref('WebserverSG'),
                                 IpProtocol='tcp',
                                 CidrIp='0.0.0.0/0',
                                 FromPort='22',
                                 ToPort='22'))

    t.add_resource(
        ec2.SecurityGroupIngress('WebserverSGIngress2',
                                 GroupId=Ref('WebserverSG'),
                                 IpProtocol='tcp',
                                 CidrIp='0.0.0.0/0',
                                 FromPort='80',
                                 ToPort='80'))

    t.add_resource(
        ec2.SecurityGroupIngress('WebserverSGIngress3',
                                 GroupId=Ref('WebserverSG'),
                                 IpProtocol='tcp',
                                 CidrIp='0.0.0.0/0',
                                 FromPort='443',
                                 ToPort='443'))

    rolePolicyStatements = [{
        "Sid":
        "Stmt1500699052003",
        "Effect":
        "Allow",
        "Action": ["s3:ListBucket"],
        "Resource": [Join("",
                          ["arn:aws:s3:::", Ref('S3Bucket')])]
    }, {
        "Sid":
        "Stmt1500699052000",
        "Effect":
        "Allow",
        "Action": ["s3:PutObject", "s3:GetObject", "s3:DeleteObject"],
        "Resource":
        [Join("",
              ["arn:aws:s3:::", Ref('S3Bucket'), '/Backup/*'])]
    }, {
        "Sid":
        "Stmt1500612724002",
        "Effect":
        "Allow",
        "Action": ["kms:Encrypt", "kms:Decrypt", "kms:GenerateDataKey*"],
        "Resource": [OpenEMRKeyARN]
    }]

    t.add_resource(
        iam.ManagedPolicy('WebserverPolicy',
                          Description='Policy for webserver instance',
                          PolicyDocument={
                              "Version": "2012-10-17",
                              "Statement": rolePolicyStatements
                          }))

    t.add_resource(
        iam.Role('WebserverRole',
                 AssumeRolePolicyDocument={
                     "Version":
                     "2012-10-17",
                     "Statement": [{
                         "Effect": "Allow",
                         "Principal": {
                             "Service": ["ec2.amazonaws.com"]
                         },
                         "Action": ["sts:AssumeRole"]
                     }]
                 },
                 Path='/',
                 ManagedPolicyArns=[Ref('WebserverPolicy')]))

    t.add_resource(
        iam.InstanceProfile('WebserverInstanceProfile',
                            Path='/',
                            Roles=[Ref('WebserverRole')]))

    t.add_resource(
        ec2.Volume('DockerVolume',
                   DeletionPolicy='Delete' if args.dev else 'Snapshot',
                   Size=Ref('PracticeStorage'),
                   AvailabilityZone=Select("0", GetAZs("")),
                   VolumeType='gp2',
                   Encrypted=True,
                   KmsKeyId=OpenEMRKeyID,
                   Tags=Tags(Name="OpenEMR Practice")))

    bootstrapScript = [
        "#!/bin/bash -x\n", "exec > /tmp/part-001.log 2>&1\n",
        "apt-get -y update\n", "apt-get -y install python-pip\n",
        "pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
        "cfn-init -v ", "         --stack ", ref_stack_name,
        "         --resource WebserverInstance ",
        "         --configsets Setup ", "         --region ", ref_region, "\n",
        "cfn-signal -e $? ", "         --stack ", ref_stack_name,
        "         --resource WebserverInstance ", "         --region ",
        ref_region, "\n"
    ]

    setupScript = [
        "#!/bin/bash -xe\n", "exec > /tmp/cloud-setup.log 2>&1\n",
        "DEBIAN_FRONTEND=noninteractive apt-get dist-upgrade -y -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" --force-yes\n",
        "mkfs -t ext4 /dev/xvdd\n", "mkdir /mnt/docker\n",
        "cat /root/fstab.append >> /etc/fstab\n", "mount /mnt/docker\n",
        "ln -s /mnt/docker /var/lib/docker\n",
        "apt-get -y install python-boto awscli\n", "S3=",
        Ref('S3Bucket'), "\n", "KMS=", OpenEMRKeyID, "\n",
        "touch /root/cloud-backups-enabled\n",
        "echo $S3 > /root/.cloud-s3.txt\n",
        "echo $KMS > /root/.cloud-kms.txt\n", "touch /tmp/mypass\n",
        "chmod 500 /tmp/mypass\n", "openssl rand -base64 32 >> /tmp/mypass\n",
        "aws s3 cp /tmp/mypass s3://$S3/Backup/passphrase.txt --sse aws:kms --sse-kms-key-id $KMS\n",
        "rm /tmp/mypass\n",
        "curl -L https://raw.githubusercontent.com/openemr/openemr-devops/master/packages/lightsail/launch.sh > /root/launch.sh\n",
        "chmod +x /root/launch.sh && /root/launch.sh -s 0\n"
    ]

    fstabFile = ["/dev/xvdd /mnt/docker ext4 defaults,nofail 0 0\n"]

    bootstrapInstall = cloudformation.InitConfig(
        files={
            "/root/cloud-setup.sh": {
                "content": Join("", setupScript),
                "mode": "000500",
                "owner": "root",
                "group": "root"
            },
            "/root/fstab.append": {
                "content": Join("", fstabFile),
                "mode": "000400",
                "owner": "root",
                "group": "root"
            }
        },
        commands={"01_setup": {
            "command": "/root/cloud-setup.sh"
        }})

    bootstrapMetadata = cloudformation.Metadata(
        cloudformation.Init(cloudformation.InitConfigSets(Setup=['Install']),
                            Install=bootstrapInstall))

    t.add_resource(
        ec2.Instance('WebserverInstance',
                     Metadata=bootstrapMetadata,
                     ImageId=FindInMap('RegionData', ref_region, 'UbuntuAMI'),
                     InstanceType=Ref('InstanceSize'),
                     NetworkInterfaces=[
                         ec2.NetworkInterfaceProperty(
                             AssociatePublicIpAddress=True,
                             DeviceIndex="0",
                             GroupSet=[Ref('WebserverSG')],
                             SubnetId=Ref('PublicSubnet1'))
                     ],
                     KeyName=Ref('EC2KeyPair'),
                     IamInstanceProfile=Ref('WebserverInstanceProfile'),
                     Volumes=[{
                         "Device": "/dev/sdd",
                         "VolumeId": Ref('DockerVolume')
                     }],
                     Tags=Tags(Name='OpenEMR Express Plus'),
                     InstanceInitiatedShutdownBehavior='stop',
                     UserData=Base64(Join('', bootstrapScript)),
                     CreationPolicy={"ResourceSignal": {
                         "Timeout": "PT25M"
                     }}))

    return t
monitor_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/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), "\'"
                    ])
                }
            })
    }))
예제 #12
0
 # Incorrect interpretation from cfn2py
 # Metadata=Init(
 #     { "SaltMinion": { "files": { "/tmp/init.sh": { "source": "https://s3-us-west-2.amazonaws.com/perforce-ami-us-west-2/init.sh", "mode": "0755" } }, "commands": { "setupMinion": { "command": "/tmp/init.sh 10.0.0.101 p4d-host" } } }, "configSets": { "All": ["SaltMinion"] } },
 # ),
 Metadata=cloudformation.Metadata(
     cloudformation.Init(
         cloudformation.InitConfigSets(DeploySalt=['SaltMinion'], ),
         SaltMinion=cloudformation.InitConfig(commands={
             "SaltMinion": {
                 "files": {
                     "/tmp/init.sh": {
                         "source":
                         "https://s3-us-west-2.amazonaws.com/perforce-ami-us-west-2/init.sh",
                         "mode": "0755"
                     }
                 },
                 "commands": {
                     "setupMinion": {
                         "command": "/tmp/init.sh 10.0.0.101 app-host"
                     }
                 }
             },
             "configSets": {
                 "All": ["SaltMinion"]
             },
         }, ),
     )),
 # Expedited Json Obj,
 # "AWS::CloudFormation::Init": {
 #     "configSets": {
 #         "All": [
예제 #13
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())
                    "' -r Ec2Instance -c ascending",
                ],
            )),
        Metadata=cloudformation.Metadata(
            cloudformation.Init(
                cloudformation.InitConfigSets(
                    ascending=["config1", "config2"],
                    descending=["config2", "config1"]),
                config1=cloudformation.InitConfig(
                    commands={
                        "test": {
                            "command": 'echo "$CFNTEST" > text.txt',
                            "env": {
                                "CFNTEST": "I come from config1."
                            },
                            "cwd": "~",
                        }
                    }),
                config2=cloudformation.InitConfig(
                    commands={
                        "test": {
                            "command": 'echo "$CFNTEST" > text.txt',
                            "env": {
                                "CFNTEST": "I come from config2."
                            },
                            "cwd": "~",
                        }
                    }),
            )),
        Tags=Tags(Name="ops.cfninit", env="ops"),
    ))
    def add_ec2_instance(self):
        self._resources.update({
            'Ec2Instance': ec2.Instance(
                'Ec2Instance',
                ImageId=FindInMap("RegionMap", Ref("AWS::Region"), "AMI"),
                InstanceType=Ref(self._parameters['Ec2InstanceType']),
                KeyName=Ref(self._parameters['SshKeyName']),
                NetworkInterfaces=[
                    ec2.NetworkInterfaceProperty(
                        GroupSet=[
                            Ref(self._resources['Ec2InstanceSecurityGroup']),
                        ],
                        AssociatePublicIpAddress='true',
                        DeviceIndex='0',
                        DeleteOnTermination='true',
                        SubnetId=Ref(self._parameters['SubnetId']),
                    ),
                ],
                UserData=Base64(Join(
                    '',
                    [
                        '#!/bin/bash\n',
                        '# Install the files and packages from the metadata\n',
                        '/usr/local/bin/cfn-init -v ',
                        '         --stack ', self._stack_name,
                        '         --resource Ec2Instance ',
                        '         --configsets InstallAndConfigure ',
                        '         --region ', self._region, '\n',
                        # Add a temporary /usr/local/bin/streamlit so
                        # user knows its still installing.
                        'echo -e \'#!/bin/sh\necho Streamlit is still installing. Please try again in a few minutes.\n\' > /usr/local/bin/streamlit \n',
                        'chmod +x /usr/local/bin/streamlit \n',
                        # Create ~/sshfs dir which is the target of the sshfs mount commmand
                        'install -o ubuntu -g ubuntu -m 755 -d ~ubuntu/sshfs \n',
                        # Install streamlit.
                        '/home/ubuntu/anaconda3/bin/pip install streamlit \n',
                        # Install rmate.
                        'curl -o /usr/local/bin/rmate https://raw.githubusercontent.com/aurora/rmate/master/rmate \n',
                        'chmod +x /usr/local/bin/rmate \n',
                        # After streamlit is installed, remove the
                        # temporary script and add a link to point to
                        # streamlit in the anaconda directory.  This is
                        # needed so we dont have to make the user to
                        # `rehash` in order to pick up the new location.
                        'rm -f /usr/local/bin/streamlit \n',
                        'ln -fs /home/ubuntu/anaconda3/bin/streamlit /usr/local/bin/streamlit \n',
                        # Get streamlit config which has the proxy wait
                        # for 2 minutes and any other options we added.
                        'curl -o /tmp/config.toml https://streamlit.io/cf/config.toml \n',
                        'install -m 755 -o ubuntu -g ubuntu -d ~ubuntu/.streamlit \n',
                        'install -m 600 -o ubuntu -g ubuntu -t ~ubuntu/.streamlit /tmp/config.toml \n',
                    ]
                )),
                Metadata=cloudformation.Metadata(
                    cloudformation.Init(
                        cloudformation.InitConfigSets(InstallAndConfigure=['config']),
                        config=cloudformation.InitConfig(
                            files={
                                '/usr/local/bin/deletestack.sh' : {
                                    'content' : Join('\n', [
                                        Sub('aws cloudformation delete-stack --region ${AWS::Region} --stack-name ${AWS::StackName}'),
                                    ]),
                                    'mode'    : '000444',
                                    'owner'   : 'root',
                                    'group'   : 'root'
                                },
                            },
                            commands={
                                'schedule_stack_deletion': {
                                    'command': Join('', [
                                        'at -f /usr/local/bin/deletestack.sh "now + ',
                                        Ref(self._parameters['StackTTL']), ' ', Ref(self._parameters['StackTTLUnits']), '"'
                                    ]),
                                }
                            }
                        )
                    )
                ),
                Tags=Tags(
                    Application=self._stack_id,
                    Name=Sub('Streamlit EC2 Instance (${AWS::StackName})'),
                ),
                IamInstanceProfile=Ref(self._resources['Ec2IamInstanceProfile']),
                DependsOn='StackDeletorRole',
            ),
        })

        self._resources.update({
            'IPAddress': ec2.EIP(
                'IPAddress',
                Domain='vpc',
                InstanceId=Ref(self._resources['Ec2Instance']),
                DependsOn='StackDeletorRole',
            ),
        })

        self._outputs.update({
            'SshIp': Output(
                'SshIp',
                Description='SshIp',
                Value=GetAtt('Ec2Instance', 'PublicIp'),
            ),
            'SshCommand': Output(
                'SshCommand',
                Description='SshCommand',
                Value=Join('',
                    [
                        'ssh ubuntu@',
                        GetAtt('Ec2Instance', 'PublicIp'),
                    ]
                )
            ),
            'StreamlitEndpoint': Output(
                'StreamlitEndpoint',
                Description='Streamlit endpoint',
                Value=Join('',
                    [
                        GetAtt('Ec2Instance', 'PublicIp'),
                        ':8501',
                    ]
                )
            ),
        })
예제 #16
0
instance_metadata = cloudformation.Metadata(
    cloudformation.Init(
        cloudformation.InitConfigSets(
            Bootstrap=[
                'ConfigCFNTools',
                'InstallAWSTools',
                'InstallPackages',
            ],
            Update=[
                'ConfigCFNTools',
                'InstallAWSTools',
                'InstallPackages',
            ],
        ),
        ConfigCFNTools=cloudformation.InitConfig(
            files={
                '/etc/cfn/cfn-hup.conf': {
                    'content': Sub(
                        '[main]\n'
                        'stack=${AWS::StackId}\n'
                        'region=${AWS::Region}\n'
                        'interval=5\n'
                        'verbose=false\n'
                    ),
                    'mode': '000400',
                    'owner': 'root',
                    'group': 'root',
                },
                '/etc/cfn/hooks.d/cfn-auto-reloader.conf': {
                    'content': Sub(
                        '[cfn-auto-reloader-hook]\n'
                        'triggers=post.update\n'
                        'path=Resources.%(INSTANCE_NAME)s.Metadata.AWS::CloudFormation::Init\n'
                        'action=/opt/aws/bin/cfn-init -v'
                        '    --stack ${AWS::StackName}'
                        '    --resource %(INSTANCE_NAME)s'
                        '    --configsets Update'
                        '    --region ${AWS::Region}'
                        '\n'
                        'runas=root\n' % \
                        dict(INSTANCE_NAME=instance_resource_name)
                    ),
                },
            },
            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',
                            ]
                        ),
                    }
                )
            },
        ),
        InstallAWSTools=cloudformation.InitConfig(
            packages={
                'apt': {
                    'python-pip': [],
                },
                'python': {
                    'awscli': []
                },
            },
            files={
                '/home/ubuntu/.aws/config': {
                    'content': Sub(
                        '[default]\n'
                        's3 =\n'
                        '    signature_version = s3v4\n'
                        'region = ${AWS::Region}\n'
                    ),
                    'owner': 'ubuntu',
                    'group': 'ubuntu',
                },
            },
            commands={
            },
        ),
        InstallPackages=cloudformation.InitConfig(
            # packages={
            #     'apt': {
            #         'nginx': [],
            #     }
            # },
            # services={'sysvinit': cloudformation.InitServices(
            #     {
            #         'nginx': cloudformation.InitService(
            #             enabled=True,
            #             ensureRunning=True,
            #             files=[
            #                 '/etc/nginx/nginx.conf',
            #             ]
            #         ),
            #     }
            # )},
        ),
    )
)
예제 #17
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
예제 #18
0
                'aws-cfn-bootstrap-latest.tar.gz\n', 'cfn-init -s \'',
                Ref('AWS::StackName'), '\' -r Ec2Instance -c ascending'
            ])),
        Metadata=cloudformation.Metadata(
            cloudformation.Init(
                cloudformation.InitConfigSets(
                    ascending=['config1', 'config2'],
                    descending=['config2', 'config1']),
                config1=cloudformation.InitConfig(
                    commands={
                        'test': {
                            'command': 'echo "$CFNTEST" > text.txt',
                            'env': {
                                'CFNTEST': 'I come from config1.'
                            },
                            'cwd': '~'
                        }
                    }),
                config2=cloudformation.InitConfig(
                    commands={
                        'test': {
                            'command': 'echo "$CFNTEST" > text.txt',
                            'env': {
                                'CFNTEST': 'I come from config2.'
                            },
                            'cwd': '~'
                        }
                    }))),
        Tags=Tags(Name='ops.cfninit', env='ops')))

t.add_output(
예제 #19
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
예제 #20
0
def add_launch_template(template, hosts_sg):
    """Function to create a launch template.

    :param template: ECS Cluster template
    :type template: troposphere.Template
    :param hosts_sg: security group for the EC2 hosts
    :type hosts_sg: troposphere.ec2.SecurityGroup

    :return: launch_template
    :rtype: troposphere.ec2.LaunchTemplate
    """
    # from troposphere.cloudformation import (
    #     WaitCondition, WaitConditionHandle
    # )
    #  Deactivated conditions given you could run with no EC2 at all.
    # Tricky condition to do as the WaitCondition and Handler cannot be created on a CFN Update, but only at the
    # very creation of the stack.
    # wait_handle = WaitConditionHandle(
    #     'BootstrapHandle',
    #     template=template
    # )
    # WaitCondition(
    #     'BootStrapCondition',
    #     template=template,
    #     DependsOn=[hosts_role],
    #     Handle=Ref(wait_handle),
    #     Timeout='900'
    # )

    launch_template = LaunchTemplate(
        "LaunchTemplate",
        template=template,
        Metadata=cloudformation.Metadata(
            cloudformation.Init(
                cloudformation.InitConfigSets(
                    default=["awspackages", "dockerconfig", "ecsconfig", "awsservices"]
                ),
                awspackages=cloudformation.InitConfig(
                    packages={"yum": {"awslogs": [], "amazon-ssm-agent": []}},
                    commands={
                        "001-check-packages": {"command": "rpm -qa | grep amazon"},
                        "002-check-packages": {"command": "rpm -qa | grep aws"},
                    },
                ),
                awsservices=cloudformation.InitConfig(
                    services={
                        "sysvinit": {
                            "amazon-ssm-agent": {"enabled": True, "ensureRunning": True}
                        }
                    }
                ),
                dockerconfig=cloudformation.InitConfig(
                    commands={
                        "001-stop-docker": {"command": "systemctl stop docker"},
                        "098-reload-systemd": {"command": "systemctl daemon-reload"},
                    },
                    files={
                        "/etc/sysconfig/docker": {
                            "owner": "root",
                            "group": "root",
                            "mode": "644",
                            "content": Join(
                                "\n",
                                [
                                    "DAEMON_MAXFILES=1048576",
                                    Join(
                                        " ",
                                        ["OPTIONS=--default-ulimit nofile=1024:4096"],
                                    ),
                                    "DAEMON_PIDFILE_TIMEOUT=10",
                                    "#EOF",
                                    "",
                                ],
                            ),
                        }
                    },
                    services={
                        "sysvinit": {
                            "docker": {
                                "enabled": True,
                                "ensureRunning": True,
                                "files": ["/etc/sysconfig/docker"],
                                "commands": ["098-reload-systemd"],
                            }
                        }
                    },
                ),
                ecsconfig=cloudformation.InitConfig(
                    files={
                        "/etc/ecs/ecs.config": {
                            "owner": "root",
                            "group": "root",
                            "mode": "644",
                            "content": Join(
                                "\n",
                                [
                                    Sub(f"ECS_CLUSTER=${{{CLUSTER_NAME_T}}}"),
                                    "ECS_ENABLE_TASK_IAM_ROLE=true",
                                    "ECS_ENABLE_SPOT_INSTANCE_DRAINING=true",
                                    "ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST=true",
                                    "ECS_ENABLE_CONTAINER_METADATA=true",
                                    "ECS_ENABLE_UNTRACKED_IMAGE_CLEANUP=true",
                                    "ECS_UPDATES_ENABLED=true",
                                    "ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION=15m",
                                    "ECS_IMAGE_CLEANUP_INTERVAL=10m",
                                    "ECS_NUM_IMAGES_DELETE_PER_CYCLE=100",
                                    "ECS_ENABLE_TASK_ENI=true",
                                    "ECS_AWSVPC_BLOCK_IMDS=true",
                                    "ECS_TASK_METADATA_RPS_LIMIT=300,400",
                                    "ECS_ENABLE_AWSLOGS_EXECUTIONROLE_OVERRIDE=true",
                                    'ECS_AVAILABLE_LOGGING_DRIVERS=["awslogs", "json-file"]',
                                    "#EOF",
                                ],
                            ),
                        }
                    },
                    commands={
                        "0001-restartecs": {
                            "command": "systemctl --no-block restart ecs"
                        }
                    },
                ),
            )
        ),
        LaunchTemplateData=LaunchTemplateData(
            BlockDeviceMappings=[
                LaunchTemplateBlockDeviceMapping(
                    DeviceName="/dev/xvda",
                    Ebs=EBSBlockDevice(DeleteOnTermination=True, Encrypted=True),
                )
            ],
            ImageId=Ref(compute_params.ECS_AMI_ID),
            InstanceInitiatedShutdownBehavior="terminate",
            IamInstanceProfile=IamInstanceProfile(
                Arn=Sub(f"${{{HOST_PROFILE_T}.Arn}}")
            ),
            TagSpecifications=[
                TagSpecifications(
                    ResourceType="instance",
                    Tags=Tags(
                        Name=Sub(f"EcsNodes-${{{CLUSTER_NAME_T}}}"),
                        StackName=Ref("AWS::StackName"),
                        StackId=Ref("AWS::StackId"),
                    ),
                )
            ],
            InstanceType="m5a.large",
            Monitoring=Monitoring(Enabled=True),
            SecurityGroupIds=[GetAtt(hosts_sg, "GroupId")],
            UserData=Base64(
                Join(
                    "\n",
                    [
                        "#!/usr/bin/env bash",
                        "export PATH=$PATH:/opt/aws/bin",
                        "cfn-init -v || yum install aws-cfn-bootstrap -y",
                        Sub(
                            f"cfn-init --region ${{AWS::Region}} -r LaunchTemplate -s ${{AWS::StackName}}"
                        ),
                        # 'if [ $? -ne 0 ]; then',
                        # Sub(f'cfn-signal -e 1 -r "Failed to bootstrap" \'${{{wait_handle.title}}}\''),
                        # 'halt',
                        # 'else',
                        # Sub(f'cfn-signal -e 0 -r "Successfully bootstrapped" \'${{{wait_handle.title}}}\''),
                        # 'fi',
                        "# EOF",
                    ],
                )
            ),
        ),
        LaunchTemplateName=Ref(CLUSTER_NAME_T),
    )
    return launch_template
예제 #21
0
def AS_LaunchTemplate():
    cfg.use_cfn_init = True
    InitConfigSets = ASInitConfigSets()

    CfmInitArgs = {}
    IBoxEnvApp = []
    Tags_List = []
    UserDataApp = []

    for n in cfg.Apps:
        name = f"Apps{n}"  # Ex. Apps1
        envname = f"EnvApp{n}Version"  # Ex EnvApp1Version
        reponame = f"{name}RepoName"  # Ex Apps1RepoName

        UserDataApp.extend(["#${%s}\n" % envname])

        p_EnvAppVersion = Parameter(
            envname,
            Description=f"Application {n} version",
            AllowedPattern="^[a-zA-Z0-9-_.]*$",
        )

        p_AppsRepoName = Parameter(
            reponame,
            Description=f"App {n} Repo Name - empty for default based on env/role",
            AllowedPattern="^[a-zA-Z0-9-_.]*$",
        )

        # parameters
        add_obj(
            [
                p_EnvAppVersion,
                p_AppsRepoName,
            ]
        )

        # conditions
        add_obj(
            {
                name: And(
                    Not(Equals(Ref(envname), "")),
                    Not(get_condition("", "equals", "None", reponame)),
                )
            }
        )

        InitConfigApps = ASInitConfigApps(name)
        CfmInitArgs[name] = InitConfigApps

        InitConfigAppsBuilAmi = ASInitConfigAppsBuildAmi(name)
        # AUTOSPOT - Let cfn-init always prepare instances on boot
        # CfmInitArgs[name + 'BuildAmi'] = InitConfigAppsBuilAmi
        CfmInitArgs[name] = InitConfigAppsBuilAmi

        IBoxEnvApp.extend(
            [
                f"export EnvApp{n}Version=",
                Ref(envname),
                "\n",
                f"export EnvRepo{n}Name=",
                get_endvalue(reponame),
                "\n",
            ]
        )

        InitConfigSetsApp = If(name, name, Ref("AWS::NoValue"))
        InitConfigSetsAppBuilAmi = If(name, f"{name}BuildAmi", Ref("AWS::NoValue"))
        IndexSERVICES = InitConfigSets.data["default"].index("SERVICES")
        InitConfigSets.data["default"].insert(IndexSERVICES, InitConfigSetsApp)
        # AUTOSPOT - Let cfn-init always prepare instances on boot
        # InitConfigSets.data['buildamifull'].append(
        #    InitConfigSetsAppBuilAmi)
        InitConfigSets.data["buildamifull"].append(InitConfigSetsApp)

        Tags_List.append(asg.Tag(envname, Ref(envname), True))

        # outputs
        Output_app = Output(envname, Value=Ref(envname))
        Output_repo = Output(reponame, Value=get_endvalue(reponame))

        add_obj([Output_app, Output_repo])

    InitConfigSetup = ASInitConfigSetup()
    InitConfigSetup.ibox_env_app = IBoxEnvApp
    InitConfigSetup.setup()

    InitConfigCodeDeploy = ASInitConfigCodeDeploy()

    CfmInitArgs["SETUP"] = InitConfigSetup
    CfmInitArgs["CWAGENT"] = ASInitConfigCloudWatchAgent("")

    if cfg.CodeDeploy:
        CfmInitArgs["CODEDEPLOY"] = InitConfigCodeDeploy

    if not getattr(cfg, "IBOX_LAUNCH_TEMPLATE_NO_WAIT_ELB_HEALTH", False):
        for lb in cfg.LoadBalancer:
            # LoadBalancerClassic
            if cfg.LoadBalancerType == "Classic":
                InitConfigELB = ASInitConfigELBClassic(scheme=lb)
                CfmInitArgs["ELBWAITER"] = InitConfigELB

            # LoadBalancerApplication
            if cfg.LoadBalancerType == "Application":
                InitConfigELB = ASInitConfigELBApplication(scheme=lb)
                CfmInitArgs["ELBWAITER"] = InitConfigELB

            # LoadBalancerNetwork
            if cfg.LoadBalancerType == "Network":
                for k in cfg.Listeners:
                    InitConfigELB = ASInitConfigELBApplication(
                        scheme=f"TargetGroupListeners{k}{lb}"
                    )
                    CfmInitArgs["ELBWAITER"] = InitConfigELB

    if getattr(cfg, "IBOX_LAUNCH_TEMPLATE_NO_SG_EXTRA", False):
        SecurityGroups = []
    else:
        SecurityGroups = cfg.SecurityGroupsImport

    # Resources
    R_LaunchTemplate = ec2.LaunchTemplate(
        "LaunchTemplate",
        LaunchTemplateName=Sub("${AWS::StackName}-${EnvRole}"),
        LaunchTemplateData=ASLaunchTemplateData(
            "LaunchTemplateData", UserDataApp=UserDataApp
        ),
    )
    R_LaunchTemplate.LaunchTemplateData.NetworkInterfaces[0].Groups.extend(
        SecurityGroups
    )

    # Import role specific cfn definition
    try:
        # Do not use role but direct cfg yaml configuration (ecs + cluster)
        cfn_envrole = f"cfn_{cfg.IBOX_ROLE_EX}"
    except Exception:
        cfn_envrole = f"cfn_{cfg.envrole}"
    cfn_envrole = cfn_envrole.replace("-", "_")
    if cfn_envrole in globals():  # Ex cfn_client_portal
        CfnRole = globals()[cfn_envrole]()
        CfmInitArgs.update(CfnRole)

    if cfg.use_cfn_init:
        R_LaunchTemplate.Metadata = cfm.Metadata(
            {
                "CloudFormationInitVersion": If(
                    "CloudFormationInit",
                    Ref("EnvStackVersion"),
                    Ref("AWS::NoValue"),
                )
            },
            cfm.Init(InitConfigSets, **CfmInitArgs),
            cfm.Authentication(
                {
                    "CfnS3Auth": cfm.AuthenticationBlock(
                        type="S3",
                        buckets=[
                            Sub(cfg.BucketNameAppRepository),
                            Sub(cfg.BucketNameAppData),
                        ],
                        roleName=Ref("RoleInstance"),
                    )
                }
            ),
        )

    add_obj(R_LaunchTemplate)

    Tags = asg.Tags()
    Tags.tags = Tags_List
    return Tags
예제 #22
0
    def add_autoscaling_group(self):
        t = self.template

        self.asgLaunchConfig = t.add_resource(
            LaunchConfiguration(
                'ASGLaunchConfig',
                ImageId='ami-0b33d91d',  #TODO Mapping for different regions
                InstanceMonitoring=False,
                AssociatePublicIpAddress=False,
                InstanceType="t2.micro",
                SecurityGroups=[Ref(self.asgSg)],
                KeyName=Ref(self.keyPairParam),
                UserData=Base64(
                    Join(
                        "",
                        [
                            "#!/bin/bash -xe\n",
                            "yum update -y aws-cfn-bootstrap\n",
                            "/opt/aws/bin/cfn-init -v ",
                            "         --stack ",
                            {
                                "Ref": "AWS::StackName"
                            },
                            "         --resource LaunchConfig ",
                            "         --configsets wordpress_install ",
                            "         --region ",
                            {
                                "Ref": "AWS::Region"
                            },
                            "\n",

                            # "/opt/aws/bin/cfn-signal -e $? ",
                            # "         --stack ", { "Ref" : "AWS::StackName" },
                            # "         --resource WebServerGroup ",
                            # "         --region ", { "Ref" : "AWS::Region" }, "\n"
                        ])),
                Metadata=cfn.Metadata(
                    cfn.Init(
                        cfn.InitConfigSets(wordpress_install=[
                            'install_cfn', 'install_chefdk', "install_chef",
                            "install_wordpress", "run_chef"
                        ]),
                        install_cfn=cfn.InitConfig(
                            # Starts cfn-hup daemon which detects changes in metadata
                            # and runs user-specified actions when a change is detected.
                            # This allows configuration updates through UpdateStack.
                            # The cfn-hup.conf file stores the name of the stack and
                            # the AWS credentials that the cfn-hup daemon targets.
                            # The cfn-hup daemon parses and loads each file in the /etc/cfn/hooks.d directory.
                            files={
                                "/etc/cfn/cfn-hup.conf": {
                                    "content": {
                                        "Fn::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": {
                                    "content": {
                                        "Fn::Join": [
                                            "",
                                            [
                                                "[cfn-auto-reloader-hook]\n",
                                                "triggers=post.update\n",
                                                "path=Resources.LaunchConfig.Metadata.AWS::CloudFormation::Init\n",
                                                "action=/opt/aws/bin/cfn-init -v ",
                                                "         --stack ", {
                                                    "Ref": "AWS::StackName"
                                                },
                                                "         --resource LaunchConfig ",
                                                "         --configsets wordpress_install ",
                                                "         --region ", {
                                                    "Ref": "AWS::Region"
                                                }, "\n"
                                            ]
                                        ]
                                    },
                                    "mode": "000400",
                                    "owner": "root",
                                    "group": "root"
                                }
                            },
                            services={
                                "sysvinit": {
                                    "cfn-hup": {
                                        "enabled":
                                        "true",
                                        "ensureRunning":
                                        "true",
                                        "files": [
                                            "/etc/cfn/cfn-hup.conf",
                                            "/etc/cfn/hooks.d/cfn-auto-reloader.conf"
                                        ]
                                    }
                                }
                            }),
                        install_chefdk=cfn.InitConfig(
                            packages={
                                "rpm": {
                                    "chefdk":
                                    "https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chefdk-0.2.0-2.el6.x86_64.rpm"
                                }
                            }),
                        install_chef=cfn.InitConfig(
                            sources={
                                #  Set up a local Chef repository on the instance.
                                "/var/chef/chef-repo":
                                "http://github.com/opscode/chef-repo/tarball/master"
                            },
                            files={
                                #  Chef installation file.
                                "/tmp/install.sh": {
                                    "source":
                                    "https://www.opscode.com/chef/install.sh",
                                    "mode": "000400",
                                    "owner": "root",
                                    "group": "root"
                                },
                                # Knife configuration file.
                                "/var/chef/chef-repo/.chef/knife.rb": {
                                    "content": {
                                        "Fn::Join": [
                                            "",
                                            [
                                                "cookbook_path [ '/var/chef/chef-repo/cookbooks' ]\n",
                                                "node_path [ '/var/chef/chef-repo/nodes' ]\n"
                                            ]
                                        ]
                                    },
                                    "mode": "000400",
                                    "owner": "root",
                                    "group": "root"
                                },
                                # Chef client configuration file.
                                "/var/chef/chef-repo/.chef/client.rb": {
                                    "content": {
                                        "Fn::Join": [
                                            "",
                                            [
                                                "cookbook_path [ '/var/chef/chef-repo/cookbooks' ]\n",
                                                "node_path [ '/var/chef/chef-repo/nodes' ]\n"
                                            ]
                                        ]
                                    },
                                    "mode": "000400",
                                    "owner": "root",
                                    "group": "root"
                                }
                            },
                            commands={
                                #  make the /var/chef directory readable, run the
                                # Chef installation, and then start Chef local mode
                                # by using the client.rb file that was created.
                                # The commands are run in alphanumeric order.
                                "01_make_chef_readable": {
                                    "command": "chmod +rx /var/chef"
                                },
                                "02_install_chef": {
                                    "command": "bash /tmp/install.sh",
                                    "cwd": "/var/chef"
                                },
                                "03_create_node_list": {
                                    "command":
                                    "chef-client -z -c /var/chef/chef-repo/.chef/client.rb",
                                    "cwd": "/var/chef/chef-repo",
                                    "env": {
                                        "HOME": "/var/chef"
                                    }
                                }
                            }),
                        install_wordpress=cfn.InitConfig(
                            # Installs WordPress by using a WordPress cookbook.
                            files={
                                # knife.rb and client.rb files are overwritten to
                                # point to the cookbooks that are required to install WordPress.
                                "/var/chef/chef-repo/.chef/knife.rb": {
                                    "content": {
                                        "Fn::Join": [
                                            "",
                                            [
                                                "cookbook_path [ '/var/chef/chef-repo/cookbooks/wordpress/berks-cookbooks' ]\n",
                                                "node_path [ '/var/chef/chef-repo/nodes' ]\n"
                                            ]
                                        ]
                                    },
                                    "mode": "000400",
                                    "owner": "root",
                                    "group": "root"
                                },
                                "/var/chef/chef-repo/.chef/client.rb": {
                                    "content": {
                                        "Fn::Join": [
                                            "",
                                            [
                                                "cookbook_path [ '/var/chef/chef-repo/cookbooks/wordpress/berks-cookbooks' ]\n",
                                                "node_path [ '/var/chef/chef-repo/nodes' ]\n"
                                            ]
                                        ]
                                    },
                                    "mode": "000400",
                                    "owner": "root",
                                    "group": "root"
                                },
                                #  Specify the Amazon RDS database instance as the WordPress database
                                "/var/chef/chef-repo/cookbooks/wordpress/attributes/aws_rds_config.rb":
                                {
                                    "content": {
                                        "Fn::Join": [
                                            "",
                                            [
                                                "normal['wordpress']['db']['pass'] = '******'\n",
                                                "normal['wordpress']['db']['user'] = '******'\n",
                                                "normal['wordpress']['db']['host'] = '",
                                                GetAtt(self.rds,
                                                       "Endpoint.Address"),
                                                "'\n",
                                                "normal['wordpress']['db']['name'] = '",
                                                Ref(self.dbNameParam), "'\n"
                                            ]
                                        ]
                                    },
                                    "mode": "000400",
                                    "owner": "root",
                                    "group": "root"
                                }
                            },
                            commands={
                                "01_get_cookbook": {
                                    "command":
                                    "knife cookbook site download wordpress",
                                    "cwd": "/var/chef/chef-repo",
                                    "env": {
                                        "HOME": "/var/chef"
                                    }
                                },
                                "02_unpack_cookbook": {
                                    "command":
                                    "tar xvfz /var/chef/chef-repo/wordpress*",
                                    "cwd": "/var/chef/chef-repo/cookbooks"
                                },
                                "03_init_berkshelf": {
                                    "command":
                                    "berks init /var/chef/chef-repo/cookbooks/wordpress --skip-vagrant --skip-git",
                                    "cwd":
                                    "/var/chef/chef-repo/cookbooks/wordpress",
                                    "env": {
                                        "HOME": "/var/chef"
                                    }
                                },
                                "04_vendorize_berkshelf": {
                                    "command": "berks vendor",
                                    "cwd":
                                    "/var/chef/chef-repo/cookbooks/wordpress",
                                    "env": {
                                        "HOME": "/var/chef"
                                    }
                                },
                                "05_configure_node_run_list": {
                                    "command":
                                    "knife node run_list add -z `knife node list -z` recipe[wordpress]",
                                    "cwd": "/var/chef/chef-repo",
                                    "env": {
                                        "HOME": "/var/chef"
                                    }
                                }
                            }),
                        run_chef=cfn.InitConfig(
                            commands={
                                "01_run_chef_client": {
                                    "command":
                                    "chef-client -z -c /var/chef/chef-repo/.chef/client.rb",
                                    "cwd": "/var/chef/chef-repo",
                                    "env": {
                                        "HOME": "/var/chef"
                                    }
                                }
                            })))))

        webserverSubnetIds = [
            self.sceptreUserData['subnets']['privateWebAZ1Id'],
            self.sceptreUserData['subnets']['privateWebAZ2Id'],
            self.sceptreUserData['subnets']['privateWebAZ3Id']
        ]

        self.webServerASG = t.add_resource(
            AutoScalingGroup(
                'WebServerASG',
                LaunchConfigurationName=Ref(self.asgLaunchConfig),
                LoadBalancerNames=[Ref(self.elb)],
                MinSize='1',
                DesiredCapacity='2',
                Cooldown='1',
                MaxSize='5',
                UpdatePolicy=UpdatePolicy(
                    AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                        MinInstancesInService="1")),
                VPCZoneIdentifier=webserverSubnetIds,
                Tags=[
                    ASTag('Contact', Ref(self.ownerEmailParam), True),
                    ASTag('Name', Join("", [self.namePrefix, 'ASG']), True)
                ]))

        return 0
예제 #23
0
def buildInstance(t, args):
    t.add_resource(
        ec2.SecurityGroup('WebserverIngressSG',
                          GroupDescription='Global Webserver Access',
                          VpcId=Ref('VPC'),
                          Tags=Tags(Name='Global Webserver Access')))

    t.add_resource(
        ec2.SecurityGroupIngress('WebserverIngressSG80',
                                 GroupId=Ref('WebserverIngressSG'),
                                 IpProtocol='tcp',
                                 CidrIp='0.0.0.0/0',
                                 FromPort='80',
                                 ToPort='80'))

    t.add_resource(
        ec2.SecurityGroupIngress('WebserverIngress443',
                                 GroupId=Ref('WebserverIngressSG'),
                                 IpProtocol='tcp',
                                 CidrIp='0.0.0.0/0',
                                 FromPort='443',
                                 ToPort='443'))

    t.add_resource(
        ec2.SecurityGroup('SysAdminAccessSG',
                          GroupDescription='System Administrator Access',
                          VpcId=Ref('VPC'),
                          Tags=Tags(Name='System Administrator Access')))

    if (args.dev):
        t.add_resource(
            ec2.SecurityGroupIngress('DevSysadminIngress22',
                                     GroupId=Ref('SysAdminAccessSG'),
                                     IpProtocol='tcp',
                                     CidrIp='0.0.0.0/0',
                                     FromPort='22',
                                     ToPort='22'))

    rolePolicyStatements = [{
        "Sid":
        "Stmt1500699052003",
        "Effect":
        "Allow",
        "Action": ["s3:ListBucket"],
        "Resource": [Join("",
                          ["arn:aws:s3:::", Ref('S3Bucket')])]
    }, {
        "Sid":
        "Stmt1500699052000",
        "Effect":
        "Allow",
        "Action": ["s3:PutObject", "s3:GetObject", "s3:DeleteObject"],
        "Resource":
        [Join("",
              ["arn:aws:s3:::", Ref('S3Bucket'), '/Backup/*'])]
    }, {
        "Sid":
        "Stmt1500612724002",
        "Effect":
        "Allow",
        "Action": ["kms:Encrypt", "kms:Decrypt", "kms:GenerateDataKey*"],
        "Resource": [OpenEMRKeyARN]
    }]

    if (args.recovery):
        rolePolicyStatements.extend([
            {
                "Sid": "Stmt1500699052004",
                "Effect": "Allow",
                "Action": ["s3:ListBucket"],
                "Resource":
                [Join(
                    "",
                    ["arn:aws:s3:::", Ref('RecoveryS3Bucket')])]
            },
            {
                "Sid":
                "Stmt1500699052005",
                "Effect":
                "Allow",
                "Action": [
                    "s3:GetObject",
                ],
                "Resource": [
                    Join("", [
                        "arn:aws:s3:::",
                        Ref('RecoveryS3Bucket'), '/Backup/*'
                    ])
                ]
            },
        ])

    t.add_resource(
        iam.ManagedPolicy('WebserverPolicy',
                          Description='Policy for webserver instance',
                          PolicyDocument={
                              "Version": "2012-10-17",
                              "Statement": rolePolicyStatements
                          }))

    t.add_resource(
        iam.Role('WebserverRole',
                 AssumeRolePolicyDocument={
                     "Version":
                     "2012-10-17",
                     "Statement": [{
                         "Effect": "Allow",
                         "Principal": {
                             "Service": ["ec2.amazonaws.com"]
                         },
                         "Action": ["sts:AssumeRole"]
                     }]
                 },
                 Path='/',
                 ManagedPolicyArns=[Ref('WebserverPolicy')]))

    t.add_resource(
        iam.InstanceProfile('WebserverInstanceProfile',
                            Path='/',
                            Roles=[Ref('WebserverRole')]))

    t.add_resource(
        ec2.Volume('DockerVolume',
                   DeletionPolicy='Delete' if args.dev else 'Snapshot',
                   Size=Ref('PracticeStorage'),
                   AvailabilityZone=Select("0", GetAZs("")),
                   VolumeType='gp2',
                   Encrypted=True,
                   KmsKeyId=OpenEMRKeyID,
                   Tags=Tags(Name="OpenEMR Practice")))

    bootstrapScript = [
        "#!/bin/bash -x\n", "exec > /var/log/openemr-cfn-bootstrap 2>&1\n",
        "cfn-init -v ", "         --stack ", ref_stack_name,
        "         --resource WebserverInstance ",
        "         --configsets Setup ", "         --region ", ref_region, "\n",
        "cfn-signal -e $? ", "         --stack ", ref_stack_name,
        "         --resource WebserverInstance ", "         --region ",
        ref_region, "\n"
    ]

    setupScript = [
        "#!/bin/bash -xe\n", "exec > /tmp/cloud-setup.log 2>&1\n",
        "/root/openemr-devops/packages/standard/ami/ami-configure.sh\n"
    ]

    stackPassthroughFile = [
        "S3=", Ref('S3Bucket'), "\n", "KMS=", OpenEMRKeyID, "\n"
    ]

    if (args.recovery):
        stackPassthroughFile.extend([
            "RECOVERYS3=",
            Ref('RecoveryS3Bucket'),
            "\n",
            "RECOVERY_NEWRDS=",
            GetAtt('RDSInstance', 'Endpoint.Address'),
            "\n",
        ])

    if (args.recovery):
        dockerComposeFile = [
            "version: '3.1'\n", "services:\n", "  openemr:\n",
            "    restart: always\n", "    image: openemr/openemr",
            docker_version, "\n", "    ports:\n", "    - 80:80\n",
            "    - 443:443\n", "    volumes:\n",
            "    - logvolume01:/var/log\n",
            "    - sitevolume:/var/www/localhost/htdocs/openemr/sites\n",
            "    environment:\n", "      MANUAL_SETUP: 1\n", "volumes:\n",
            "  logvolume01: {}\n", "  sitevolume: {}\n"
        ]
    else:
        dockerComposeFile = [
            "version: '3.1'\n", "services:\n", "  openemr:\n",
            "    restart: always\n", "    image: openemr/openemr",
            docker_version, "\n", "    ports:\n", "    - 80:80\n",
            "    - 443:443\n", "    volumes:\n",
            "    - logvolume01:/var/log\n",
            "    - sitevolume:/var/www/localhost/htdocs/openemr/sites\n",
            "    environment:\n", "      MYSQL_HOST: '",
            GetAtt('RDSInstance', 'Endpoint.Address'), "'\n",
            "      MYSQL_ROOT_USER: openemr\n", "      MYSQL_ROOT_PASS: '******'RDSPassword'), "'\n", "      MYSQL_USER: openemr\n",
            "      MYSQL_PASS: '******'RDSPassword'), "'\n", "      OE_USER: admin\n",
            "      OE_PASS: '******'AdminPassword'), "'\n", "volumes:\n", "  logvolume01: {}\n",
            "  sitevolume: {}\n"
        ]

    bootstrapInstall = cloudformation.InitConfig(
        files={
            "/root/cloud-setup.sh": {
                "content": Join("", setupScript),
                "mode": "000500",
                "owner": "root",
                "group": "root"
            },
            "/root/cloud-variables": {
                "content": Join("", stackPassthroughFile),
                "mode": "000500",
                "owner": "root",
                "group": "root"
            },
            "/root/openemr-devops/packages/standard/docker-compose.yaml": {
                "content": Join("", dockerComposeFile),
                "mode": "000500",
                "owner": "root",
                "group": "root"
            }
        },
        commands={"01_setup": {
            "command": "/root/cloud-setup.sh"
        }})

    bootstrapMetadata = cloudformation.Metadata(
        cloudformation.Init(cloudformation.InitConfigSets(Setup=['Install']),
                            Install=bootstrapInstall))

    t.add_resource(
        ec2.Instance('WebserverInstance',
                     Metadata=bootstrapMetadata,
                     ImageId=FindInMap('RegionData', ref_region,
                                       'OpenEMRMktPlaceAMI'),
                     InstanceType=Ref('WebserverInstanceSize'),
                     NetworkInterfaces=[
                         ec2.NetworkInterfaceProperty(
                             AssociatePublicIpAddress=True,
                             DeviceIndex="0",
                             GroupSet=[
                                 Ref('ApplicationSecurityGroup'),
                                 Ref('WebserverIngressSG'),
                                 Ref('SysAdminAccessSG')
                             ],
                             SubnetId=Ref('PublicSubnet1'))
                     ],
                     KeyName=Ref('EC2KeyPair'),
                     IamInstanceProfile=Ref('WebserverInstanceProfile'),
                     Volumes=[{
                         "Device": "/dev/sdd",
                         "VolumeId": Ref('DockerVolume')
                     }],
                     Tags=Tags(Name='OpenEMR Cloud Standard'),
                     InstanceInitiatedShutdownBehavior='stop',
                     UserData=Base64(Join('', bootstrapScript)),
                     CreationPolicy={"ResourceSignal": {
                         "Timeout": "PT15M"
                     }}))

    return t
예제 #24
0
    Metadata=cloudformation.Metadata(
            cloudformation.Authentication({
                "DeployUserAuth": cloudformation.AuthenticationBlock(
                    type="S3",
                    roleName=Ref(EC2Role),
                    buckets=[Ref(DeployBucket)]
                )
                
            }),
            cloudformation.Init({
            "config": cloudformation.InitConfig(
                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"),
                }),

                commands={
                    "init": {
                        "command": Join("", [
                            "/home/ec2-user/configure-s3-nat.sh && ",
                            "/home/ec2-user/init-cron.sh \"", Ref("AWS::StackName"), "\" \"", Ref("AWS::StackName"), "-", Ref(NATNamespaceParam), "\" && ",
                            "/home/ec2-user/test-s3-nat.sh"
                        ])
                    }
                }
            )
        })
    ),
예제 #25
0
    def to_cloudformation_template(self, base_template):
        instance = ec2.Instance(self.name)
        instance.InstanceType = 't2.nano'
        instance.ImageId = IMAGE_ID

        base_template.add_resource(instance)

        if self.bootstrap_file_contents:
            newrelic_license_param = base_template.add_parameter(Parameter(
                "NewRelicLicenseKey",
                Description="Value of your New Relic License Key",
                Type="String",
            ))

            instance.UserData = CloudFormationHelper.create_user_data(self.bootstrap_file_contents, self.name)
            instance.Metadata = cloudformation.Metadata(
                cloudformation.Init(
                    cloudformation.InitConfigSets(
                        default=['new_relic']
                    ),
                    new_relic=cloudformation.InitConfig(
                        commands={
                            'write_dollop_version': {
                                'command': 'echo "$DOLLOP_VERSION" > dollop_init.txt',
                                'env': {
                                    'DOLLOP_VERSION': __version__
                                },
                                'cwd': '~'
                            },
                            'configure_new_relic': {
                                'command': Join('',
                                                ['nrsysmond-config --set license_key=', Ref(newrelic_license_param)])
                            }
                        },
                        services={
                            'sysvinit': {
                                'newrelic-sysmond': {
                                    'enabled': 'true',
                                    'ensureRunning': 'true'
                                }
                            }
                        }
                    )
                )
            )
        if SSH_PORT in self.open_ports:
            keyname_param = base_template.add_parameter(Parameter(
                "EC2KeyPair",
                Description="Name of an existing EC2 KeyPair to enable SSH access to the instance",
                Type="AWS::EC2::KeyPair::KeyName",
            ))

            security_group = base_template.add_resource(ec2.SecurityGroup(
                'DollopServerSecurityGroup',
                GroupDescription='Dollop-generated port access rules for an EC2 instance',
                SecurityGroupIngress=CloudFormationHelper.create_security_group_rules(self.open_ports),
                Tags=Tags(Name='ops.dollop.resource.sg'))
            )
            instance.KeyName = Ref(keyname_param)
            instance.SecurityGroups = [Ref(security_group)]

        # Template Output
        base_template.add_output([
            Output(
                "InstanceId",
                Description="InstanceId of the newly created EC2 instance",
                Value=Ref(instance),
            ),
            Output(
                "AZ",
                Description="Availability Zone of the newly created EC2 instance",
                Value=GetAtt(instance, "AvailabilityZone"),
            ),
            Output(
                "PublicIP",
                Description="Public IP address of the newly created EC2 instance",
                Value=GetAtt(instance, "PublicIp"),
            ),
            Output(
                "PrivateIP",
                Description="Private IP address of the newly created EC2 instance",
                Value=GetAtt(instance, "PrivateIp"),
            ),
            Output(
                "PublicDNS",
                Description="Public DNS Name of the newly created EC2 instance",
                Value=GetAtt(instance, "PublicDnsName"),
            ),
            Output(
                "PrivateDNS",
                Description="Private DNS Name of the newly created EC2 instance",
                Value=GetAtt(instance, "PrivateDnsName"),
            ),
        ])
        instance.Tags = Tags(Name=DollopServer.DefaultTag)
        return base_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
    def attach(self):
        """Attaches a bootstrapped Chef Node EC2 instance to an
        AWS CloudFormation template and returns the template.
        """
        parameters = ec2_parameters.EC2Parameters(self.template)
        parameters.attach()
        resources = ec2_resources.EC2Resources(self.template)
        resources.attach()

        security_group = self.template.add_resource(ec2.SecurityGroup(
            'SecurityGroup',
            GroupDescription='Allows SSH access from anywhere',
            SecurityGroupIngress=[
                ec2.SecurityGroupRule(
                    IpProtocol='tcp',
                    FromPort=22,
                    ToPort=22,
                    CidrIp=Ref(self.template.parameters['SSHLocation'])
                ),
                ec2.SecurityGroupRule(
                    IpProtocol='tcp',
                    FromPort=80,
                    ToPort=80,
                    CidrIp='0.0.0.0/0'
                ),
                ec2.SecurityGroupRule(
                    IpProtocol='tcp',
                    FromPort=8080,
                    ToPort=8080,
                    CidrIp='0.0.0.0/0'
                )
            ],
            VpcId=ImportValue("prod2-VPCID"),
            Tags=Tags(
                Name='{0}SecurityGroup'.format(EC2_INSTANCE_NAME)
            )
        ))

        self.template.add_resource(ec2.Instance(
            EC2_INSTANCE_NAME,
            ImageId=If(
                'IsCentos7',
                FindInMap(
                    "AWSRegionArch2Centos7LinuxAMI", Ref("AWS::Region"),
                    FindInMap("AWSInstanceType2Arch",
                              Ref(self.template.parameters['InstanceType']),
                              "Arch")),
                FindInMap(
                    "AWSRegionArch2AmazonLinuxAMI", Ref("AWS::Region"),
                    FindInMap("AWSInstanceType2Arch",
                              Ref(self.template.parameters['InstanceType']),
                              "Arch"))
            ),
            InstanceType=Ref(self.template.parameters['InstanceType']),
            KeyName=FindInMap('Region2KeyPair', Ref('AWS::Region'), 'key'),
            SecurityGroupIds=[Ref(security_group)],
            SubnetId=ImportValue("prod2-SubnetPublicAZ2"),
            IamInstanceProfile=Ref(
                self.template.resources['InstanceProfileResource']),
            UserData=Base64(Join('', [
                If('IsCentos7',
                   Join('\n', [
                       '#!/bin/bash ',
                       'sudo yum update -y ',
                       'sudo yum install -y vim ',
                       'sudo yum install -y epel-release ',
                       'sudo yum install -y awscli ',
                       '# Install CFN-BootStrap ',
                       ('/usr/bin/easy_install --script-dir /opt/aws/bin '
                        'https://s3.amazonaws.com/cloudformation-examples/'
                        'aws-cfn-bootstrap-latest.tar.gz '),
                       ('cp -v /usr/lib/python2*/site-packages/aws_cfn_'
                        'bootstrap*/init/redhat/cfn-hup /etc/init.d '),
                       'chmod +x /etc/init.d/cfn-hup ',
                       ]),
                   Join('\n', [
                       '#!/bin/bash -xe ',
                       'yum update -y ',
                       '# Update CFN-BootStrap ',
                       'yum update -y aws-cfn-bootstrap',
                       'sudo yum install -y awslogs ',
                       ])),
                Join('', [
                    '# Install the files and packages from the metadata\n'
                    '/opt/aws/bin/cfn-init -v ',
                    '         --stack ', Ref('AWS::StackName'),
                    '         --resource ', EC2_INSTANCE_NAME,
                    '         --configsets InstallAndRun',
                    '         --region ', Ref('AWS::Region'),
                    '         --role ',
                    Ref(self.template.resources['RoleResource']),
                    '\n',
                    '# Signal the status from cfn-init\n',
                    '/opt/aws/bin/cfn-signal -e $? '
                    '         --stack ', Ref('AWS::StackName'),
                    '         --resource ', EC2_INSTANCE_NAME,
                    '         --region ', Ref('AWS::Region'),
                    '         --role ',
                    Ref(self.template.resources['RoleResource']),
                    '\n'
                    ]),
                ]
                                )
                           ),
            Metadata=cloudformation.Metadata(
                cloudformation.Init(
                    cloudformation.InitConfigSets(
                        InstallAndRun=['Install', 'InstallLogs', 'InstallChef',
                                       'Configure']
                    ),
                    Install=cloudformation.InitConfig(
                        packages={
                            'yum': {
                                'stress': [],
                                'docker': []
                            }
                        },
                        files={
                            '/etc/cfn/cfn-hup.conf': {
                                'content': Join('\n', [
                                    '[main]',
                                    'stack={{stackid}}',
                                    'region={{region}}',
                                    'interval=1'
                                    ]),
                                'context': {
                                    'stackid': Ref('AWS::StackId'),
                                    'region': Ref('AWS::Region')
                                },
                                'mode': '000400',
                                'owner': 'root',
                                'group': 'root'
                            },
                            '/etc/cfn/hooks.d/cfn-auto-reloader.conf': {
                                'content': Join('\n', [
                                    '[cfn-auto-reloader-hook]',
                                    'triggers=post.update',
                                    ('path=Resources.{{instance_name}}'
                                     '.Metadata'
                                     '.AWS::CloudFormation::Init'),
                                    ('action=/opt/aws/bin/cfn-init -v '
                                     '     --stack {{stack_name}} '
                                     '     --resource {{instance_name}} '
                                     '     --configsets {{config_sets}} '
                                     '     --region {{region}} '),
                                    'runas={{run_as}}'
                                ]),
                                'context': {
                                    'instance_name': EC2_INSTANCE_NAME,
                                    'stack_name': Ref('AWS::StackName'),
                                    'region': Ref('AWS::Region'),
                                    'config_sets': 'InstallAndRun',
                                    'run_as': 'root'
                                }
                            }
                        },
                        services={
                            'sysvinit': {
                                'docker': {
                                    'enabled': 'true',
                                    'ensureRunning': 'true'
                                },
                                'cfn-hup': {
                                    'enabled': 'true',
                                    'ensureRunning': 'true'
                                }
                            }
                        },
                        commands={
                            '01_test': {
                                'command': 'echo "$CFNTEST" > Install.txt',
                                'env': {
                                    'CFNTEST': 'I come from Install.'
                                },
                                'cwd': '~'
                            }
                        }
                    ),
                    InstallLogs=cloudformation.InitConfig(
                        files={
                            '/etc/awslogs/awslogs.conf': {
                                'content': Join('\n', [
                                    '[general]',
                                    ('state_file= /var/awslogs/'
                                     'state/agent-state'),
                                    '',
                                    '[/var/log/cloud-init.log]',
                                    'file = /var/log/cloud-init.log',
                                    'log_group_name = {{log_group_name}}',
                                    ('log_stream_name = '
                                     '{instance_id}/cloud-init.log'),
                                    'datetime_format = {{datetime_format}}',
                                    '',
                                    '[/var/log/cloud-init-output.log]',
                                    'file = /var/log/cloud-init-output.log',
                                    'log_group_name = {{log_group_name}}',
                                    ('log_stream_name = '
                                     '{instance_id}/cloud-init-output.log'),
                                    'datetime_format = {{datetime_format}}',
                                    '',
                                    '[/var/log/cfn-init.log]',
                                    'file = /var/log/cfn-init.log',
                                    'log_group_name = {{log_group_name}}',
                                    ('log_stream_name = '
                                     '{instance_id}/cfn-init.log'),
                                    'datetime_format = {{datetime_format}}',
                                    '',
                                    '[/var/log/cfn-hup.log]',
                                    'file = /var/log/cfn-hup.log',
                                    'log_group_name = {{log_group_name}}',
                                    ('log_stream_name = '
                                     '{instance_id}/cfn-hup.log'),
                                    'datetime_format = {{datetime_format}}',
                                    '',
                                    '[/var/log/cfn-wire.log]',
                                    'file = /var/log/cfn-wire.log',
                                    'log_group_name = {{log_group_name}}',
                                    ('log_stream_name = '
                                     '{instance_id}/cfn-wire.log'),
                                    'datetime_format = {{datetime_format}}',
                                    '',
                                    '[/var/log/httpd]',
                                    'file = /var/log/httpd/*',
                                    'log_group_name = {{log_group_name}}',
                                    ('log_stream_name = '
                                     '{instance_id}/httpd'),
                                    'datetime_format = {{datetime_format}}'
                                ]),
                                'context': {
                                    'log_group_name': Ref(
                                        self.template.resources[
                                            'LogGroupResource']),
                                    'datetime_format': '%d/%b/%Y:%H:%M:%S'
                                }
                            },
                            '/etc/awslogs/awscli.conf': {
                                'content': Join('\n', [
                                    '[plugins]',
                                    'cwlogs = cwlogs',
                                    '[default]',
                                    'region = {{region}}'
                                ]),
                                'context': {
                                    'region': Ref('AWS::Region')
                                },
                                'mode': '000444',
                                'owner': 'root',
                                'group': 'root'
                            }
                        },
                        commands={
                            '01_create_state_directory': {
                                'command' : 'mkdir -p /var/awslogs/state'
                            },
                            '02_test': {
                                'command': 'echo "$CFNTEST" > InstallLogs.txt',
                                'env': {
                                    'CFNTEST': 'I come from install_logs.'
                                },
                                'cwd': '~'
                            },
                            '03_install_aws_logs_if_centos': {
                                'command': If('IsCentos7', Join('\n', [
                                    ('curl https://s3.amazonaws.com/aws-'
                                     'cloudwatch/downloads/latest/awslogs-'
                                     'agent-setup.py -O'),
                                    Join('', [
                                        'sudo python ./awslogs-agent-setup.py',
                                        '   --configfile /etc/awslogs/awslogs',
                                        '.conf   --non-interactive  --region ',
                                        Ref('AWS::Region')])
                                    ]), Join('', [
                                        'echo "not installing awslogs from ',
                                        'from source"'
                                        ]))
                            }
                        },
                        services={
                            'sysvinit': {
                                'awslogs': {
                                    'enabled': 'true',
                                    'ensureRunning': 'true',
                                    'files': ['/etc/awslogs/awslogs.conf']
                                }
                            }
                        }
                    ),
                    InstallChef=cloudformation.InitConfig(
                        commands={
                            '01_invoke_omnitruck_install': {
                                'command': (
                                    'curl -L '
                                    'https://omnitruck.chef.io/install.sh | '
                                    'bash'
                                ),
                            }
                        },
                        files={
                            '/etc/chef/client.rb': {
                                'source': S3_CLIENT_RB,
                                'mode': '000600',
                                'owner': 'root',
                                'group': 'root',
                                'authentication': 'S3AccessCreds'
                            },
                            '/etc/chef/jasondebolt-validator.pem': {
                                'source': S3_VALIDATOR_PEM,
                                'mode': '000600',
                                'owner': 'root',
                                'group': 'root',
                                'authentication': 'S3AccessCreds'
                            },
                            '/etc/chef/first-run.json': {
                                'source': S3_FIRST_RUN,
                                'mode': '000600',
                                'owner': 'root',
                                'group': 'root',
                                'authentication': 'S3AccessCreds'
                            }
                        }
                    ),
                    Configure=cloudformation.InitConfig(
                        commands={
                            '01_test': {
                                'command': 'echo "$CFNTEST" > Configure.txt',
                                'env': {
                                    'CFNTEST': 'I come from Configure.'
                                },
                                'cwd': '~'
                            },
                            '02_chef_bootstrap': {
                                'command': (
                                    'chef-client -j '
                                    '/etc/chef/first-run.json'
                                )
                            }
                        }
                    )
                ),
                cloudformation.Authentication({
                    'S3AccessCreds': cloudformation.AuthenticationBlock(
                        type='S3',
                        roleName=Ref(self.template.resources['RoleResource']))
                })
            ),
            Tags=Tags(
                Name=Ref('AWS::StackName'),
                env='ops'
            )
        ))

        self.template.add_output(Output(
            'PublicIp',
            Description='Public IP of the newly created EC2 instance',
            Value=GetAtt(EC2_INSTANCE_NAME, 'PublicIp')
        ))

        self.template.add_output(Output(
            'LinuxType',
            Description='The linux type of the EC2 instance.',
            Value=If('IsCentos7', 'centos_7', 'amazon_linux')
        ))
        return self.template
예제 #28
0
    Metadata=cloudformation.Metadata(
            cloudformation.Authentication({
            "DeployUserAuth": cloudformation.AuthenticationBlock(
                type="S3",
                accessKeyId=Ref(DeployUserAccessKey),
                secretKey=Ref(DeployUserSecretKey)
                )
            }),
            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 && \
                             /usr/sbin/configure-storreduce-pat.sh"
                        ])
                    }
                }
            )
        }))