Exemple #1
0
    def __init__(self, stack, paco_ctx):
        resource = stack.resource
        super().__init__(stack, paco_ctx)
        self.set_aws_name('DBClusterParameterGroup', self.resource_group_name, resource.name)
        self.init_template('DB Cluster Parameter Group')

        # Resources
        cfn_export_dict = {
            'Family': resource.family,
            'Parameters': {}
        }
        if resource.description != None:
            cfn_export_dict['Description'] = resource.description
        else:
            cfn_export_dict['Description'] = troposphere.Ref('AWS::StackName')

        for key, value in resource.parameters.items():
            cfn_export_dict['Parameters'][key] = value

        dbparametergroup_resource = troposphere.rds.DBClusterParameterGroup.from_dict(
            'DBClusterParameterGroup',
            cfn_export_dict
        )
        self.template.add_resource(dbparametergroup_resource)

        # Outputs
        self.create_output(
            title='DBClusterParameterGroupName',
            description='DB Cluster Parameter Group Name',
            value=troposphere.Ref(dbparametergroup_resource),
            ref=[self.resource.paco_ref_parts, self.resource.paco_ref_parts + ".name"]
        )
Exemple #2
0
    def get_or_create_resource(self, path, api, template):
        """Returns the ID of the Resource ``path`` in ``api``.
        If the resorce doesn't exits, create a new one and add it to
        ``template``."""

        # Add leading slash
        if path and path[0] != '/':
            path = '/{}'.format(path)

        # Remove trailing slash
        if path and path[-1] == '/':
            path = path[:-1]

        # Make / the root path
        if not path:
            path = '/'

        # Return API root resource if
        if path == '/':
            return troposphere.GetAtt(api, 'RootResourceId')

        if path in self._resources:
            return self._resources[path]

        parent_path, path_part = path.rsplit('/', 1)
        parent_id = self.get_or_create_resource(parent_path, api, template)
        resource = Resource(utils.valid_cloudformation_name(
            self.name, 'Resource', *path.split('/')),
                            ParentId=parent_id,
                            PathPart=path_part,
                            RestApiId=troposphere.Ref(api))

        template.add_resource(resource)
        self._resources[path] = troposphere.Ref(resource)
        return self._resources[path]
Exemple #3
0
 def queue_policy(self):
     return ts.sqs.QueuePolicy(
         self._get_logical_id('QueuePolicy'),
         Queues=[ts.Ref(self.queue)],
         PolicyDocument={
             'Version':
             '2012-10-17',
             'Statement': [{
                 'Sid': 'allow-sns-notifications',
                 'Effect': 'Allow',
                 'Principal': {
                     'AWS': '*',
                 },
                 'Action': ['sqs:SendMessage'],
                 'Resource': '*',
                 'Condition': {
                     # todo: allow all topics?
                     # 'ArnEquals': {'aws:SourceArn': self.config['SourceTopics']}
                     'ArnLike': {
                         'aws:SourceArn':
                         ts.Join(':', [
                             'arn:aws:sns',
                             ts.Ref('AWS::Region'),
                             ts.Ref('AWS::AccountId'),
                             '*',
                         ])
                     },
                 },
             }],
         },
     )
Exemple #4
0
    def __init__(self, stack, paco_ctx):
        super().__init__(stack, paco_ctx)
        self.set_aws_name('Example', self.resource_group_name,
                          self.resource.name)

        # Troposphere Template Initialization
        self.init_template('Example Template')
        if not self.resource.is_enabled():
            return

        # Parameters
        example_param = self.create_cfn_parameter(
            name='ExampleParameterName',
            param_type='String',
            description='Example parameter.',
            value=self.resource.example_variable,
        )

        # Resource
        example_dict = {'some_property': troposphere.Ref(example_param)}
        example_res = troposphere.resource.Example.from_dict(
            'ExampleResource', example_dict)
        self.template.add_resource(example_res)

        # Outputs
        self.create_output(title='ExampleResourceId',
                           description="Example resource Id.",
                           value=troposphere.Ref(example_res),
                           ref=self.resource.paco_ref_parts + ".id")
Exemple #5
0
    def create_group(self, sg_group_id, sg_name, sg_config, template,
                     vpc_id_param):
        # GroupName
        group_name = self.create_resource_name_join(
            [
                self.env_ctx.netenv_id, self.env_ctx.env_id, sg_group_id,
                sg_name
            ],
            separator='-',
            camel_case=True,
            filter_id='SecurityGroup.GroupName')
        # GroupDescription
        if sg_config.group_description != None and sg_config.group_description != '':
            group_description = sg_config.group_description
        else:
            group_description = "Paco generated Security Group"
            # legacy_flag: aim_name_2019_11_28 - Use AIM name
            if self.paco_ctx.legacy_flag('aim_name_2019_11_28') == True:
                group_description = "AIM generated Security Group"

        # Security Group
        group_logical_id = self.create_cfn_logical_id(sg_name)
        group_res = troposphere.ec2.SecurityGroup(
            title=group_logical_id,
            template=template,
            GroupName=group_name,
            GroupDescription=group_description,
            VpcId=troposphere.Ref(vpc_id_param),
            Tags=troposphere.codebuild.Tags(Name=group_name))

        # Output
        group_config_ref = '.'.join([self.config_ref, sg_name])
        self.create_output(title=group_logical_id + 'Id',
                           value=troposphere.Ref(group_res),
                           ref=group_config_ref + '.id')
Exemple #6
0
 def create_lambda_invoke_properties(self, stage, action, info):
     function_arn_param = self.create_cfn_parameter(
         param_type='String',
         name=self.create_cfn_logical_id('Lambda' + stage.name +
                                         action.name),
         description='The name of the Lambda for stage {} and action {}'.
         format(stage.name, action.name),
         value=action.target_lambda + '.arn',
     )
     user_parameters_param = self.create_cfn_parameter(
         param_type='String',
         name=self.create_cfn_logical_id('UserParameters' + stage.name +
                                         action.name),
         description='The UserParameters for stage {} and action {}'.format(
             stage.name, action.name),
         value=action.user_parameters,
     )
     lambda_function_name = troposphere.Join('', [
         troposphere.Select(
             6, troposphere.Split(':', troposphere.Ref(function_arn_param)))
     ])
     return {
         'Configuration': {
             'FunctionName': lambda_function_name,
             'UserParameters': troposphere.Ref(user_parameters_param),
         },
     }
Exemple #7
0
    def register_resources_template(self, template):
        """Register one ``EventSourceMapping`` into the resources template.

        Note: We preprend a 30s Sleep before the creation of this resource
        because the IAM role of the lambda is not propagated fast enough uppon
        creation, and CloudFormation checks if the referenced lambda has
        permission to consume this stream on creation time.

        Because the ``Lambda`` and the ``EventSourceMapping`` are created in
        the same stack we need to introduce this as palliative measure, sorry!
        """
        sleep_lambda = 'lambda:contrib_helpers:sleep:current'
        sleep = Sleep.create_with(
            utils.valid_cloudformation_name(self.name, "Sleep"),
            DependsOn=[self.project.reference(sleep_lambda)],
            lambda_arn=troposphere.Ref(self.project.reference(sleep_lambda)),
            Time=30)
        template.add_resource(sleep)

        template.add_resource(
            awslambda.EventSourceMapping(
                self.in_project_cf_name,
                DependsOn=[sleep.name, self.get_function_name()],
                BatchSize=self.get_batch_size(),
                Enabled=self.get_enabled(),
                EventSourceArn=self.settings.get('stream'),
                FunctionName=troposphere.Ref(self.get_function_name()),
                StartingPosition=self.get_starting_position()))
Exemple #8
0
    def register_type_project_template(cls, project, template):
        """Registers into the project stack a S3 bucket where all lambdas
        code will be stored, as well as an output so any subsequent template
        can have a reference to this resource."""

        bucket_name = troposphere.Join(
            "-",
            [
                utils.validate_code_bucket(project.settings['code-bucket']),
                troposphere.Ref(troposphere.AWS_REGION),
                troposphere.Ref('Stage')
            ]
        )
        code_bucket = s3.Bucket(
            "CodeBucket",
            BucketName=bucket_name,
            AccessControl=s3.Private,
            VersioningConfiguration=s3.VersioningConfiguration(
                Status='Enabled'
            )
        )
        template.add_resource(code_bucket)
        template.add_output([
            troposphere.Output(
                "CodeBucket",
                Description="CodeBucket name",
                Value=bucket_name,
            )
        ])
Exemple #9
0
    def register_resources_template(self, template):
        targets, target_lambdas = [], []
        for name, target in six.iteritems(self.settings.get('targets', {})):
            target_lambdas.append(target['lambda'])
            targets.append(
                events.Target(
                    Arn=self.get_destination_arn(target['lambda']),
                    Id=self.get_function_name(target['lambda']),
                    Input=target.get('input', ''),
                    InputPath=target.get('input_path', ''),
                ))

        rule = events.Rule(utils.valid_cloudformation_name(self.name, "Rule"),
                           Description=self.settings.get('description', ''),
                           EventPattern=self.settings.get(
                               'event_pattern',
                               troposphere.Ref(troposphere.AWS_NO_VALUE)),
                           ScheduleExpression=self.settings.get(
                               'schedule_expression',
                               troposphere.Ref(troposphere.AWS_NO_VALUE)),
                           State=self.get_enabled(),
                           Targets=targets)
        template.add_resource(rule)

        for lambda_ in target_lambdas:
            template.add_resource(
                troposphere.awslambda.Permission(
                    utils.valid_cloudformation_name(self.name, 'rule',
                                                    'permission'),
                    Action="lambda:InvokeFunction",
                    FunctionName=self.get_destination_arn(lambda_),
                    Principal="events.amazonaws.com",
                    SourceArn=troposphere.GetAtt(rule, 'Arn'),
                ))
Exemple #10
0
 def ec2_user_data(self):
     return ts.Base64(
         ts.Join(
             '',
             [
                 # -x print commands as they're executed
                 # -e exit on error
                 '#!/bin/bash -xe',
                 '\n',
                 # todo: figure out what these commands do
                 'yum install -y aws-cfn-bootstrap',
                 '\n',
                 '/opt/aws/bin/cfn-init -v ',
                 '    --stack    ',
                 ts.Ref('AWS::StackName'),
                 '    --resource ',
                 self.launch_config_logical_id,
                 '    --region   ',
                 ts.Ref('AWS::Region'),
                 '\n',
                 '/opt/aws/bin/cfn-signal -e $? ',
                 '     --stack   ',
                 ts.Ref('AWS::StackName'),
                 '    --resource ',
                 self.auto_scaling_group_logical_id,
                 '    --region   ',
                 ts.Ref('AWS::Region'),
                 '\n',
             ]))
Exemple #11
0
    def __init__(self, stack, paco_ctx, network):
        efs_config = stack.resource
        super().__init__(stack, paco_ctx)
        self.set_aws_name('EFS', self.resource_group_name, self.resource.name)

        self.init_template('Elastic Filesystem')
        if not efs_config.is_enabled(): return

        # Parameters
        sg_list_param = self.create_cfn_ref_list_param(
            param_type='List<AWS::EC2::SecurityGroup::Id>',
            name='TargetSecurityGroupList',
            description='EFS mount target security group list.',
            value=efs_config.security_groups,
            ref_attribute='id',
        )
        encrypted_param = self.create_cfn_parameter(
            name='EncryptedAtRest',
            param_type='String',
            description=
            'Boolean indicating whether the data will be encrypted at rest.',
            value=efs_config.encrypted,
        )

        # Elastic File System
        if efs_config.enable_automatic_backups == True:
            efs_backup_policy = 'ENABLED'
        else:
            efs_backup_policy = 'DISABLED'
        efs_res = troposphere.efs.FileSystem(
            title='EFS',
            template=self.template,
            Encrypted=troposphere.Ref(encrypted_param),
            BackupPolicy=troposphere.efs.BackupPolicy(
                Status=efs_backup_policy))
        self.create_output(title=efs_res.title + 'Id',
                           description="Elastic File System ID.",
                           value=troposphere.Ref(efs_res),
                           ref=efs_config.paco_ref_parts + ".id")

        # Mount Targets
        for az_idx in range(1, network.availability_zones + 1):
            subnet_id_ref = network.vpc.segments[
                efs_config.segment].paco_ref_parts + '.az{}.subnet_id'.format(
                    az_idx)
            subnet_param = self.create_cfn_parameter(
                name='SubnetIdAZ{}'.format(az_idx),
                param_type='String',
                description='The SubnetId for AZ{}.'.format(az_idx),
                value='paco.ref ' + subnet_id_ref,
            )
            efs_mount_logical_id = self.create_cfn_logical_id(
                'EFSMountTargetAZ{}'.format(az_idx))
            troposphere.efs.MountTarget(
                title=efs_mount_logical_id,
                template=self.template,
                FileSystemId=troposphere.Ref(efs_res),
                SecurityGroups=troposphere.Ref(sg_list_param),
                SubnetId=troposphere.Ref(subnet_param))
Exemple #12
0
    def add_apigateway_resource(self, resource):
        resource_logical_id = 'ApiGatewayResource' + self.create_cfn_logical_id(resource.name + md5sum(str_data=resource.paco_ref_parts))
        cfn_export_dict = resource.cfn_export_dict
        parent_resource = resource.__parent__.__parent__
        # root resource
        if schemas.IApiGatewayRestApi.providedBy(parent_resource):
            cfn_export_dict["ParentId"] = troposphere.GetAtt(self.restapi_resource, "RootResourceId")
        # child resource
        else:
            cfn_export_dict["ParentId"] = troposphere.Ref(parent_resource.resource)
        cfn_export_dict["RestApiId"] = troposphere.Ref(self.restapi_resource)
        resource_resource = troposphere.apigateway.Resource.from_dict(resource_logical_id, cfn_export_dict)
        resource.resource = resource_resource
        self.template.add_resource(resource_resource)
        self.create_output(
            title=self.create_cfn_logical_id(f'ApiGatewayRestApiResource{resource.name}' + md5sum(str_data=resource.paco_ref_parts)),
            value=troposphere.Ref(resource_resource),
            ref=resource.paco_ref_parts + '.id',
        )
        # Add an OPTIONS method if CORS is enabled
        if resource.enable_cors == True:
            options_config = {
                'http_method': 'OPTIONS',
                'integration': {
                    'integration_type': 'MOCK',
                    'integration_http_method': 'OPTIONS',
                    'pass_through_behavior': 'WHEN_NO_MATCH',
                    'request_templates': {'application/json': '{"statusCode": 200}'},
                    'integration_responses': [{
                        'status_code': '200',
                        'response_parameters': {
                            'method.response.header.Access-Control-Allow-Headers': "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'",
                            'method.response.header.Access-Control-Allow-Methods': "'POST,OPTIONS'",
                            'method.response.header.Access-Control-Allow-Origin': "'*'",
                        },
                        'response_templates': {'application/json': ''},
                    },],
                },
                'method_responses': [{
                    'status_code': '200',
                    'response_models': [{
                        'content_type': 'application/json',
                        'model_name': 'emptyjson',
                    }],
                    'response_parameters': {
                        'method.response.header.Access-Control-Allow-Headers': False,
                        'method.response.header.Access-Control-Allow-Methods': False,
                        'method.response.header.Access-Control-Allow-Origin': False,
                    },
                }],
            }
            options_config['resource_name'] = resource.nested_name
            method_name = f'{resource.nested_name}PacoCORS'
            options_method = ApiGatewayMethod(method_name, self.apigatewayrestapi.methods)
            apply_attributes_from_config(options_method, options_config)
            self.apigatewayrestapi.methods[method_name] = options_method

        return resource_resource
    def __init__(
        self,
        stack,
        paco_ctx,
        sns_topic_list
    ):
        super().__init__(
            stack,
            paco_ctx,
            iam_capabilities=["CAPABILITY_NAMED_IAM"],
        )
        account_ctx = stack.account_ctx
        aws_region = stack.aws_region
        self.set_aws_name('LambdaSNSSubs', self.resource_group_name, self.resource_name)
        awslambda = self.awslambda = self.stack.resource
        self.init_template('Lambda SNS Subscriptions')

        # if not enabled finish with only empty placeholder
        if not self.awslambda.is_enabled(): return

        # Permissions
        # SNS Topic Lambda permissions and subscription

        lambda_arn_param = self.create_cfn_parameter(
            name='LambdaFunctionArn',
            param_type='String',
            description='An SNS Topic ARN to grant permission to.',
            value=self.awslambda.paco_ref + '.arn'
        )
        idx = 1
        for sns_topic in sns_topic_list:
            # SNS Topic Arn parameters
            if is_ref(sns_topic):
                sns_topic_value = sns_topic + '.arn'
                sns_topic_obj = get_model_obj_from_ref(sns_topic, self.paco_ctx.project)
                region_name = sns_topic_obj.region_name
            else:
                sns_topic_value = sns_topic
                region_name = sns_topic.split(':')[3]

            param_name = 'SNSTopicArn%d' % idx
            self.create_cfn_parameter(
                name=param_name,
                param_type='String',
                description='An SNS Topic ARN to grant permission to.',
                value=sns_topic_value
            )

            # SNS Topic subscription
            troposphere.sns.SubscriptionResource(
                title=param_name + 'Subscription',
                template=self.template,
                Endpoint=troposphere.Ref(lambda_arn_param),
                Protocol='lambda',
                TopicArn=troposphere.Ref(param_name),
                Region=region_name
            )
            idx += 1
    def __init__(self, paco_ctx, account_ctx, aws_region, stack_group,
                 stack_tags, zone_config, config_ref):
        super().__init__(paco_ctx,
                         account_ctx,
                         aws_region,
                         enabled=zone_config.is_enabled(),
                         config_ref=config_ref,
                         iam_capabilities=["CAPABILITY_NAMED_IAM"],
                         stack_group=stack_group,
                         stack_tags=stack_tags)
        self.set_aws_name('HostedZone', zone_config.name)

        self.init_template('Route53 Hosted Zone: ' + zone_config.domain_name)

        self.paco_ctx.log_action_col("Init", "Route53", "Hosted Zone",
                                     "{}".format(zone_config.domain_name))

        if zone_config.external_resource != None and zone_config.external_resource.is_enabled(
        ):
            hosted_zone_id_output_value = zone_config.external_resource.hosted_zone_id
            nameservers_output_value = ','.join(
                zone_config.external_resource.nameservers)
        else:
            hosted_zone_res = troposphere.route53.HostedZone(
                title='HostedZone',
                template=self.template,
                Name=zone_config.domain_name)
            hosted_zone_id_output_value = troposphere.Ref(hosted_zone_res)
            nameservers_output_value = troposphere.Join(
                ',', troposphere.GetAtt(hosted_zone_res, 'NameServers'))

        self.create_output(title='HostedZoneId',
                           value=hosted_zone_id_output_value,
                           ref=config_ref + '.id')
        self.create_output(title='HostedZoneNameServers',
                           value=nameservers_output_value,
                           ref=config_ref + '.name_servers')

        if len(zone_config.record_sets) > 0:
            record_set_list = []
            for record_set_config in zone_config.record_sets:
                record_set_res = troposphere.route53.RecordSet(
                    Name=record_set_config.record_name,
                    Type=record_set_config.type,
                    TTL=record_set_config.ttl,
                    ResourceRecords=record_set_config.resource_records)
                record_set_list.append(record_set_res)

            group_res = troposphere.route53.RecordSetGroup(
                title='RecordSetGroup',
                template=self.template,
                HostedZoneId=troposphere.Ref(hosted_zone_res),
                RecordSets=record_set_list)
            group_res.DependsOn = hosted_zone_res

        self.set_template()
Exemple #15
0
    def __init__(self, stack, paco_ctx, awslambda):
        super().__init__(stack, paco_ctx)
        self.set_aws_name('ApiGatewayLamdaPermission', self.resource_group_name, self.resource_name)
        self.init_template('Cross-account Api Gateway Lambda Permission')
        apigateway = self.resource

        api_gateway_id_param = self.create_cfn_parameter(
            name=self.create_cfn_logical_id('ApiGatewayRestApiId'),
            param_type='String',
            description='API Gateway Rest API Id',
            value=apigateway.paco_ref + '.id',
        )
        lambda_arn_param = self.create_cfn_parameter(
            name=self.create_cfn_logical_id('LambdaArn'),
            param_type='String',
            description='Lambda Arn',
            value=awslambda.paco_ref + '.arn',
        )

        # Lambda Permission for cross-account API Gateway invocation
        for method in apigateway.methods.values():
            if method.integration != None and method.integration.integration_lambda != None:
                if awslambda.paco_ref == method.integration.integration_lambda:
                    if apigateway.get_account().name != awslambda.get_account().name:
                        # Grant Cross-Account API Gateway permission
                        path_part = ''
                        if method.resource_name:
                            name_parts = method.resource_name.split('.')
                            resource = method.get_resource()
                            if len(name_parts) > 1:
                                # child resource
                                last_resource = resource
                                while schemas.IApiGatewayResource.providedBy(resource):
                                    last_resource = resource
                                    resource = resource.__parent__.__parent__
                                path_part = last_resource.path_part + '/*' # add /* to match all child resource
                            else:
                                # parent resource
                                path_part = resource.path_part
                        lambda_permission_resource = troposphere.awslambda.Permission(
                            title='ApiGatewayRestApiMethod' + md5sum(str_data=method.paco_ref),
                            Action="lambda:InvokeFunction",
                            FunctionName=troposphere.Ref(lambda_arn_param),
                            Principal='apigateway.amazonaws.com',
                            SourceArn=troposphere.Join('', [
                                "arn:aws:execute-api:",
                                awslambda.region_name, # lambda region
                                ":",
                                apigateway.get_account().account_id, # account id
                                ":",
                                troposphere.Ref(api_gateway_id_param),
                                f"/*/{method.http_method}/{path_part}",
                            ])
                        )
                        self.template.add_resource(lambda_permission_resource)
    def prepare_s3bucket_artifact(self, is_zip=False):
        """
        Add a Hook which will prepare the Lambda Code artifact and upload to an S3 Bucket if it
        doesn't already exist.

        Add Parameters for CodeS3Bucket and CodeS3Key. The Parameter values are placeholder values that
        will be updated by the hook.
        """
        ignore_changes = True
        # always create an artifact on CREATE
        stack_hooks = StackHooks()
        stack_hooks.add(
            name='PrepLambdaCodeArtifactToS3Bucket',
            stack_action=['create',],
            stack_timing='pre',
            hook_method=self.prepare_s3bucket_artifact_hook,
            cache_method=self.prepare_s3bucket_artifact_cache,
            hook_arg=is_zip,
        )
        self.stack.add_hooks(stack_hooks)

        # only UPDATE an artifact if --auto-publish-code is true
        if self.paco_ctx.auto_publish_code == True:
            ignore_changes = False
            stack_hooks = StackHooks()
            stack_hooks.add(
                name='PrepLambdaCodeArtifactToS3Bucket',
                stack_action=['update'],
                stack_timing='pre',
                hook_method=self.prepare_s3bucket_artifact_hook,
                cache_method=self.prepare_s3bucket_artifact_cache,
                hook_arg=is_zip,
            )
            self.stack.add_hooks(stack_hooks)

        self.s3bucket_param = self.create_cfn_parameter(
            name='CodeS3Bucket',
            description="S3 Bucket for the Lambda Code artifact",
            param_type='String',
            value='',
            ignore_changes=ignore_changes,
        )
        self.s3key_param = self.create_cfn_parameter(
            name='CodeS3Key',
            description="S3 Key for the Lambda Code artifact",
            param_type='String',
            value='',
            ignore_changes=ignore_changes,
        )
        cfn_s3_code = {
            'S3Bucket': troposphere.Ref(self.s3bucket_param),
            'S3Key': troposphere.Ref(self.s3key_param),
        }
        return cfn_s3_code
Exemple #17
0
 def ec2_launch_config(self):
     return ts.autoscaling.LaunchConfiguration(
         self.launch_config_logical_id,
         KeyName=self.key_name,
         ImageId=self.ami,
         AssociatePublicIpAddress=True,
         SecurityGroups=[ts.Ref(self.security_group)],
         IamInstanceProfile=ts.Ref(self.ec2_instance_profile),
         InstanceType=self.ec2_instance_type,
         Metadata=self.ec2_metadata,
         UserData=self.ec2_user_data,
     )
Exemple #18
0
 def ecs_service(self):
     return ts.ecs.Service(
         self._get_logical_id('EcsService'),
         Cluster=ts.Ref(self.ecs_cluster),
         DesiredCount=2,
         TaskDefinition=ts.Ref(self.ecs_task_def),
         # no limits on the order of stopping / starting tasks
         # data remains in the queue and workers are gracefully shut down
         DeploymentConfiguration=ts.ecs.DeploymentConfiguration(
             MaximumPercent=200,
             MinimumHealthyPercent=0,
         ),
     )
Exemple #19
0
 def listener(self):
     return ts.elasticloadbalancingv2.Listener(
         self._get_logical_id('Listener'),
         Protocol='HTTP',
         Port=80,
         LoadBalancerArn=ts.Ref(self.elb),
         DefaultActions=[
             ts.elasticloadbalancingv2.Action(
                 Type='forward',
                 TargetGroupArn=ts.Ref(self.target_group),
             )
         ],
     )
Exemple #20
0
 def get_integration_uri(self, resource):
     integration_type = self._get_integration_type(resource)
     if integration_type == LAMBDA_INTEGRATION:
         return troposphere.Join('', [
             'arn:aws:apigateway:',
             troposphere.Ref(troposphere.AWS_REGION),
             ':lambda:path/2015-03-31/functions/',
             troposphere.Ref(
                 self.get_function_name(resource)), '/invocations'
         ])
     elif integration_type == HTTP_INTEGRATION:
         return resource['integration']['uri']
     elif integration_type == MOCK_INTEGRATION:
         return troposphere.Ref(troposphere.AWS_NO_VALUE)
Exemple #21
0
    def __init__(self, stack, paco_ctx, role, s3_bucket_name):
        super().__init__(stack, paco_ctx)
        self.set_aws_name('Config')
        self.init_template('Config')
        config = stack.resource

        # Parameters
        role_arn_param = self.create_cfn_parameter(
            param_type='String',
            name='AWSConfigRoleArn',
            description='IAM Role assumed by AWS Config',
            value=role.get_arn())
        s3_bucket_name_param = self.create_cfn_parameter(
            param_type='String',
            name='S3BucketName',
            description='S3 Bucket',
            value=s3_bucket_name,
        )

        # ConfigurationRecorder resource
        include_global = False
        if config.global_resources_region == stack.aws_region:
            include_global = True
        config_recorder_dict = {
            'RecordingGroup': {
                'AllSupported': True,
                'IncludeGlobalResourceTypes': include_global,
            },
            'RoleARN': troposphere.Ref(role_arn_param),
        }
        config_recorder_resource = troposphere.config.ConfigurationRecorder.from_dict(
            'ConfigurationRecorder', config_recorder_dict)
        self.template.add_resource(config_recorder_resource)

        # DeliveryChannel resource
        delivery_channel_dict = {
            'ConfigSnapshotDeliveryProperties': {
                'DeliveryFrequency': config.delivery_frequency
            },
            'S3BucketName': troposphere.Ref(s3_bucket_name_param),
        }
        # ToDo: SnsTopic for Config
        #  SnsTopicARN: String

        delivery_channel_resource = troposphere.config.DeliveryChannel.from_dict(
            'DeliveryChannel',
            delivery_channel_dict,
        )
        #delivery_channel_resource.DependsOn = config_recorder_resource
        self.template.add_resource(delivery_channel_resource)
Exemple #22
0
    def create_s3deploy_properties(self, stage, action, info):
        base_name = stage.name + action.name
        s3_deploy_bucket_name_param = self.create_cfn_parameter(
            param_type='String',
            name=self.create_cfn_logical_id('S3DeployBucketName' + base_name),
            description='The name of the S3 bucket to deploy to.',
            value=action.bucket + '.name',
        )
        s3_deploy_extract_param = self.create_cfn_parameter(
            param_type='String',
            name=self.create_cfn_logical_id('S3DeployExtract' + base_name),
            description=
            'Boolean indicating whether the deployment artifact will be extracted.',
            value=action.extract,
        )
        s3_deploy_object_key_param = 'AWS::NoValue'
        if action.object_key != None:
            s3_deploy_object_key_param = self.create_cfn_parameter(
                param_type='String',
                name=self.create_cfn_logical_id('S3DeployObjectKey' +
                                                base_name),
                description=
                'S3 object key to store the deployment artifact as.',
                value=action.object_key,
            )

        bucket = get_model_obj_from_ref(action.bucket, self.paco_ctx.project)
        account = get_model_obj_from_ref(bucket.account, self.paco_ctx.project)
        input_artifacts = []
        for artifact in action.input_artifacts:
            stage_name, action_name = artifact.split('.')
            source_action = self.pipeline.stages[stage_name][action_name]
            input_name = '{}Artifact{}{}'.format(
                ACTION_MAP[source_action.type]['Name'],
                stage_name,
                action_name,
            )
            input_artifacts.append(
                troposphere.codepipeline.InputArtifacts(Name=input_name))
        return {
            'Configuration': {
                'BucketName': troposphere.Ref(s3_deploy_bucket_name_param),
                'Extract': troposphere.Ref(s3_deploy_extract_param),
                'ObjectKey': troposphere.Ref(s3_deploy_object_key_param),
            },
            'InputArtifacts': input_artifacts,
            'RoleArn': troposphere.Ref(self.s3deploy_buckets[account.name]),
            #'RunOrder': troposphere.If('ManualApprovalIsEnabled', 2, 1)
        }
    def __init__(self, stack, paco_ctx):
        pinpoint_app = stack.resource
        super().__init__(stack, paco_ctx)
        self.set_aws_name('PinpointApp', self.resource_group_name,
                          self.resource.name)

        self.init_template('Pinpoint Application')
        if not pinpoint_app.is_enabled(): return

        # Pinpoint Application
        pinpoint_app_logical_id = 'PinpointApplication'
        pinpointapp_resource = troposphere.pinpoint.App(
            pinpoint_app_logical_id,
            Name=pinpoint_app.title,
        )
        self.template.add_resource(pinpointapp_resource)

        if pinpoint_app.sms_channel:
            cfn_export_dict = pinpoint_app.sms_channel.cfn_export_dict
            cfn_export_dict['ApplicationId'] = troposphere.Ref(
                pinpoint_app_logical_id)
            sms_channel_resource = troposphere.pinpoint.SMSChannel.from_dict(
                'SMSChannel',
                cfn_export_dict,
            )
            self.template.add_resource(sms_channel_resource)

        if pinpoint_app.email_channel:
            cfn_export_dict = pinpoint_app.email_channel.cfn_export_dict
            cfn_export_dict['ApplicationId'] = troposphere.Ref(
                pinpoint_app_logical_id)
            cfn_export_dict[
                'Identity'] = f'arn:aws:ses:{self.aws_region}:{self.account_ctx.id}:identity/{pinpoint_app.email_channel.from_address}'
            email_channel_resource = troposphere.pinpoint.EmailChannel.from_dict(
                'EmailChannel',
                cfn_export_dict,
            )
            self.template.add_resource(email_channel_resource)

        # Output
        self.create_output(title=pinpointapp_resource.title + 'Id',
                           description="Pinpoint Application Id",
                           value=troposphere.Ref(pinpointapp_resource),
                           ref=pinpoint_app.paco_ref_parts + ".id")
        self.create_output(title=pinpointapp_resource.title + 'Arn',
                           description="Pinpoint Application Arn",
                           value=troposphere.GetAtt(pinpointapp_resource,
                                                    "Arn"),
                           ref=pinpoint_app.paco_ref_parts + ".arn")
Exemple #24
0
    def register_resources_template(self, template):

        extra = defaultdict(list)
        for notification_id, notification in six.iteritems(
                self._notifications):
            notification.register_destination_publish_permission(template)

            extra[notification.api_property].append(
                NotificationConfiguration(
                    Id=troposphere.Join('-', ['gordon', notification.id]),
                    DestinationArn=notification.get_destination_arn(),
                    Events=[e for e, _, _ in notification.events],
                    KeyFilters=[
                        KeyFilter(Name=name, Value=value)
                        for name, value in notification.filters
                    ]))

        bucket_notification_configuration_lambda = 'lambda:contrib_s3:bucket_notification_configuration:current'
        template.add_resource(
            S3BucketNotificationConfiguration.create_with(
                utils.valid_cloudformation_name(self.name),
                DependsOn=[
                    self.project.reference(
                        bucket_notification_configuration_lambda)
                ],
                lambda_arn=troposphere.Ref(
                    self.project.reference(
                        bucket_notification_configuration_lambda)),
                Bucket=self.get_bucket_name(),
                **dict([[k, v] for k, v in six.iteritems(extra) if v])))
Exemple #25
0
    def get_destination_arn(self):
        destination = self.settings['topic']
        region = troposphere.Ref(troposphere.AWS_REGION)

        if isinstance(destination, six.string_types):
            if destination.startswith('arn:aws:'):
                return destination
            account = troposphere.Ref(troposphere.AWS_ACCOUNT_ID)
        elif isinstance(destination, dict):
            account = destination['account_id']
            destination = destination['name']
        else:
            return destination

        return troposphere.Join(":",
                                ["arn:aws:sns", region, account, destination])
Exemple #26
0
    def get_destination_url(self):
        destination = self.settings['queue']
        region = troposphere.Ref(troposphere.AWS_REGION)

        if isinstance(destination, six.string_types):
            account = troposphere.Ref(troposphere.AWS_ACCOUNT_ID)
        elif isinstance(destination, dict):
            account = destination['account_id']
            destination = destination['name']
        else:
            return destination

        return troposphere.Join("", [
            "https://sqs.", region, ".amazonaws.com/", account, "/",
            destination
        ])
Exemple #27
0
    def init_custompolicy_permission(self, permission_config, assume_role_res):
        for managed_policy in permission_config.managed_policies:
            if 'ManagedPolicyArns' not in assume_role_res.properties.keys():
                assume_role_res.properties['ManagedPolicyArns'] = []
            assume_role_res.properties['ManagedPolicyArns'].append('arn:aws:iam::aws:policy/' + managed_policy)
        for policy in permission_config.policies:
            policy_statements = []
            for policy_statement in policy.statement:
                statement_dict = {
                    'Effect': policy_statement.effect,
                    'Action': [
                        Action(*action.split(':')) for action in policy_statement.action
                    ],
                }

                # Resource
                statement_dict['Resource'] = policy_statement.resource

                policy_statements.append(
                    Statement(**statement_dict)
                )
            # Make the policy
            managed_policy_res = troposphere.iam.ManagedPolicy(
                title=self.create_cfn_logical_id_join(
                    str_list=["CustomPolicy", policy.name],
                    camel_case=True
                ),
                PolicyDocument=PolicyDocument(
                    Version="2012-10-17",
                    Statement=policy_statements
                ),
                Roles=[ troposphere.Ref(assume_role_res) ]
            )
            self.template.add_resource(managed_policy_res)
Exemple #28
0
    def __init__(self, stack, paco_ctx):
        ebs_config = stack.resource
        super().__init__(stack, paco_ctx)
        self.set_aws_name('EBS', self.resource_group_name, self.resource.name)

        # Troposphere Template Initialization
        self.init_template('Elastic Block Store Volume')

        # EBS Resource
        ebs_dict = {
            'VolumeType': ebs_config.volume_type,
            'AvailabilityZone': vocabulary.aws_regions[self.aws_region]['zones'][ebs_config.availability_zone-1]
        }
        # Snapshot overrides Size
        if ebs_config.snapshot_id != None and ebs_config.snapshot_id != '':
            ebs_dict['SnapshotId'] = ebs_config.snapshot_id
        else:
            ebs_dict['Size'] = ebs_config.size_gib

        ebs_res = troposphere.ec2.Volume.from_dict(
            'EBS',
            ebs_dict
        )
        self.template.add_resource(ebs_res)

        # Outputs
        self.create_output(
            title='EBSVolumeId',
            description="The EBS Volume Id.",
            value=troposphere.Ref(ebs_res),
            ref=ebs_config.paco_ref_parts + ".id",
        )
Exemple #29
0
    def create_notification_params(self, alarm):
        "Create a Parameter for each SNS Topic an alarm should notify. Return a list of Refs to those Params."
        notification_paco_refs = []
        for group in alarm.notification_groups:
            if not self.notification_region:
                region = alarm.region_name
            else:
                region = self.notification_region
            notification_paco_refs.append(
                self.paco_ctx.project['resource']['snstopics'][region][group].paco_ref + '.arn'
            )

        notification_cfn_refs = []
        for notification_paco_ref in notification_paco_refs:
            # Create parameter
            param_name = 'Notification{}'.format(utils.md5sum(str_data=notification_paco_ref))
            if param_name in self.notification_param_map.keys():
                notification_param = self.notification_param_map[param_name]
            else:
                notification_param = self.create_cfn_parameter(
                    param_type='String',
                    name=param_name,
                    description='SNS Topic to notify',
                    value=notification_paco_ref,
                    min_length=1, # prevent borked empty values from breaking notification
                )
                self.notification_param_map[param_name] = notification_param
            notification_cfn_refs.append(troposphere.Ref(notification_param))
        return notification_cfn_refs
Exemple #30
0
    def set_alarm_actions_to_cfn_export(self, alarm, cfn_export_dict):
        "Sets the AlarmActions, OKActions and InsufficientDataActions for a Troposphere dict"
        alarm_action_list = []
        notification_groups = self.paco_ctx.project['resource'][
            'notificationgroups'][alarm.region_name]
        for alarm_action in alarm.get_alarm_actions_paco_refs(
                notification_groups):
            # Create parameter
            param_name = 'AlarmAction{}'.format(
                utils.md5sum(str_data=alarm_action))
            if param_name in self.alarm_action_param_map.keys():
                alarm_action_param = self.alarm_action_param_map[param_name]
            else:
                alarm_action_param = self.create_cfn_parameter(
                    param_type='String',
                    name=param_name,
                    description='SNSTopic for Alarm to notify.',
                    value=alarm_action)
                self.alarm_action_param_map[param_name] = alarm_action_param
            alarm_action_list.append(troposphere.Ref(alarm_action_param))

        cfn_export_dict['AlarmActions'] = alarm_action_list
        if getattr(alarm, 'enable_ok_actions', False):
            cfn_export_dict['OKActions'] = alarm_action_list
        if getattr(alarm, 'enable_insufficient_data_actions', False):
            cfn_export_dict['InsufficientDataActions'] = alarm_action_list