Example #1
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 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
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': '~'
                    }
                })))
Example #4
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" },
                                               }
                                }

            )
))
Example #5
0
def add_init(target, *configs):
    assert isinstance(target, (ec2.Instance, au.LaunchConfiguration))
    params = Join('', [
        'export CFN_PARAMS=\'',
        ' --region ',
        Ref('AWS::Region'),
        ' --stack ',
        Ref('AWS::StackName'),
        ' --resource ' + target.title + '\'',
    ])
    target.UserData = Base64(
        Join('\n', [
            '#!/bin/bash -xe', 'yum update -y', params,
            '/opt/aws/bin/cfn-init -v -c default $CFN_PARAMS',
            '/opt/aws/bin/cfn-signal -e 0 $CFN_PARAMS'
        ]))

    configs = [callable(c) and c() or c for c in configs]
    target.Metadata = cf.Init(
        cf.InitConfigSets(default=[c.title for c in configs]),
        **{c.title: c
           for c in configs})
    return target
Example #6
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
Example #7
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
Example #8
0
    --configsets Bootstrap \
    --region ${AWS::Region}
    
/opt/aws/bin/cfn-signal -e $? \
    --stack ${AWS::StackName} \
    --resource %(INSTANCE_NAME)s \
    --region ${AWS::Region}
''' % {'INSTANCE_NAME': instance_resource_name}))

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',
Example #9
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
Example #10
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
Example #11
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 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',
                    ]
                )
            ),
        })
         [
             "#!/bin/bash\n",
             "sudo apt-get update\n",
             "sudo apt-get -y install python-setuptools\n",
             "sudo apt-get -y install python-pip\n",
             "sudo pip install https://s3.amazonaws.com/cloudformation-examples/",
             "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',
def template():

    t = Template()

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

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

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

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

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

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

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

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

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

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

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

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

    return t.to_json()
Example #15
0
 KeyName=Ref(key_name),
 SecurityGroups=[Ref(security_group)],
 IamInstanceProfile='PullCredentials',
 UserData=Base64(
     Join('', [
         '#!/bin/bash\n', 'sudo apt-get update\n',
         'sudo apt-get -y install python-setuptools\n',
         'sudo apt-get -y install python-pip\n',
         'sudo pip install https://s3.amazonaws.com/cloudformation-examples/',
         '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',
Example #16
0
    VPCGatewayAttachment(
        "VPCGatewayAttachment",
        VpcId=Ref("VPC"),
        InternetGatewayId=Ref("InternetGateway"),
    ))

AppInstance = t.add_resource(
    Instance(
        "AppInstance",
        # 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"
                            }
                        }
                    },
 UserData=Base64(
     Join("", [
         "#!/bin/bash\n", "yum clean all\n", "yum update -y\n",
         "yum install pystache python-daemon -y\n",
         "/bin/rpm -U https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.amzn1.noarch.rpm\n",
         "/opt/aws/bin/cfn-init ", "         --stack ", {
             "Ref": "AWS::StackName"
         }, "         --resource myLaunchConfig",
         "         --configsets InstallandRun", "         --region ", {
             "Ref": "AWS::Region"
         }, "\n"
     ])),
 Metadata=Metadata(
     cf.Init({
         "configsets":
         cf.InitConfigSets(InstallandRun=["install", "config"]),
         "install":
         cf.InitConfig(packages={"yum": {
             "git": [],
             "wget": []
         }}),
         "config":
         cf.InitConfig(files=cf.InitFiles({
             "/tmp/example.txt":
             cf.InitFile(content=Join('', [
                 "This is a file example.\n",
                 "See another examples in:\n",
                 "https://github.com/rabeloo/cf-templates\n"
             ]),
                         owner="root",
                         group="root",
    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
Example #19
0
             Ref('AWS::StackName'),
             '" --region=',
             Ref('AWS::Region'),
             ' -r %s -c on_first_boot\n' % ec2_instance_name,
             # send the exit code from cfn-init to our CreationPolicy:
             'cfn-signal -e $? --stack="',
             Ref('AWS::StackName'),
             '" --region=',
             Ref('AWS::Region'),
             ' --resource %s\n' % ec2_instance_name,
         ])),
 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':
                     '~',
                 },
Example #20
0
def get_metadata(instance, volume):
    return cloudformation.Init(
        cloudformation.InitConfigSets(install=["install_cfn"],
                                      update=["resize"]),
        install_cfn=cloudformation.InitConfig(
            files={
                "/etc/cfn/cfn-hup.conf": {
                    "content":
                    Join("", [
                        "[main]\n", "stack=",
                        Ref("AWS::StackId"), "\n", "region=",
                        Ref("AWS::Region"), "\n", "interval=1\n",
                        "verbose=true\n"
                    ]),
                    "mode":
                    "000400",
                    "owner":
                    "root",
                    "group":
                    "root"
                },
                "/etc/cfn/hooks.d/cfn-auto-reloader.conf": {
                    "content":
                    Join("",
                         [
                             "[cfn-auto-reloader-hook]\n",
                             "triggers=post.update\n",
                             "path=Resources.{}\n".format(volume),
                             "action=/opt/aws/bin/cfn-init ", " --stack ",
                             Ref("AWS::StackName"),
                             " --resource {} ".format(instance),
                             " --configsets update ", " --region ",
                             Ref("AWS::Region")
                         ]),
                    "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"
                        ]
                    }
                }
            }),
        resize=cloudformation.InitConfig(
            commands={
                "resize": {
                    "command": "/sbin/resize2fs /dev/xvdh",
                    "env": {
                        "HOME": "/root"
                    }
                }
            }),
    )