Пример #1
0
    def add_topic_and_lambda(self, topic_name, lambda_meta_data):
        """Adds a SNS topic and SAM Function to the CloudFormation template

        :param topic_name: (str) the SNS topic name
        :param lambda_meta_data: (LambdaMetaData) an object specifying info about the lambda
                to create

        :return: a sns.Topic object
        """
        topic = sns.Topic(
            "{}Topic".format(topic_name),
            TopicName=topic_name,
        )
        self.add_resource(topic)

        self.add_resource(
            serverless.Function(
                "{}Lambda".format(lambda_meta_data.name),
                Description=lambda_meta_data.description,
                MemorySize=128,
                FunctionName=lambda_meta_data.name,
                Runtime=LAMBDA_RUNTIME,
                Handler='index.handler',
                CodeUri='lambda-src/',
                Timeout=10,
                Environment=awslambda.Environment(
                    Variables={
                        'WEBHOOK_URL': lambda_meta_data.webhook_url,
                        'MESSAGE_PREFIX': lambda_meta_data.message_prefix,
                    }),
                Events={
                    'SNS': serverless.SNSEvent('sns', Topic=Ref(topic)),
                },
            ))
        return topic
Пример #2
0
    def build_template(self, template=None):

        if not template:
            t = self._init_template()
        else:
            t = template

        topic = t.add_resource(
            sns.Topic(
                "{}SNSTopic".format(self.stack_name),
                TopicName=self.stack_name,
                DisplayName=self.stack_name,
            ))

        for s in self.subscriptions:

            sub = s.build_subscription(t, topic)
            subr = t.add_resource(
                sns.SubscriptionResource('{}SNSSubscription'.format(s.name),
                                         Protocol=sub[0],
                                         Endpoint=sub[1],
                                         TopicArn=Ref(topic)))
            t.add_output(
                [Output('{}SNSSubscription'.format(s.name), Value=Ref(subr))])

        t.add_output(
            [Output("{}SNSTopic".format(self.stack_name), Value=Ref(topic))])

        return t
Пример #3
0
def render_sns(context, template):
    for topic_name in context['sns']:
        topic = template.add_resource(
            sns.Topic(_sanitize_title(topic_name) + "Topic",
                      TopicName=topic_name))
        template.add_output(
            Output(_sanitize_title(topic_name) + "TopicArn", Value=Ref(topic)))
Пример #4
0
 def resources(self, stack: Stack) -> list[AWSObject]:
     """Compute AWS resources for the construct."""
     return [
         sns.Topic(
             name_to_id(self.name),
             TopicName=self.name,
             Subscription=self.subscriptions,
         ),
         *self.optional_resources,
     ]
Пример #5
0
def public_topic(base_name: str) -> (sns.Topic, sns.TopicPolicy):
    topic = sns.Topic(f"{base_name}Topic")
    topic_policy = sns.TopicPolicy(
        f"{base_name}TopicPolicy",
        Topics=[topic.ref()],
        PolicyDocument=dict(
            Version="2008-10-17",
            Statement=[_owner_policy(topic),
                       _public_broadcast(topic)]),
    )
    return topic, topic_policy
Пример #6
0
    def _add_pipeline_notifications(self, pipeline):
        subscriptions = self._create_sns_subscriptions()
        topic = sns.Topic(
            'AppPipelineDeployments',
            DisplayName='AppPipelineDeployments',
            Subscription=subscriptions,
        )
        self._t.add_resource(topic)

        topic_policy = sns.TopicPolicy(
            'AllowCloudWatchEventsPublish',
            PolicyDocument=Policy(Version='2012-10-17',
                                  Statement=[
                                      Statement(
                                          Sid='AllowCloudWatchEventsToPublish',
                                          Effect=Allow,
                                          Action=[_sns.Publish],
                                          Principal=Principal(
                                              'Service',
                                              'events.amazonaws.com'),
                                          Resource=[topic.Ref()],
                                      )
                                  ]),
            Topics=[topic.Ref()],
        )
        self._t.add_resource(topic_policy)

        sns_target = [events.Target(Id='1', Arn=topic.Ref())]
        cw_event = events.Rule(
            'PipelineEvents',
            Description='CloudWatch Events Rule for app pipeline.',
            EventPattern={
                "source": ["aws.codepipeline"],
                "detail-type": [
                    'CodePipeline Action Execution State Change',
                ],
                'detail': {
                    'type': {
                        # Notify when a deploy fails/succeeds
                        # or when an approval is needed.
                        # We could also add something when any
                        # part of the pipeline fails.
                        'category': ['Deploy', 'Approval'],
                    },
                    'pipeline': [pipeline.Ref()],
                }
            },
            Targets=sns_target,
        )
        self._t.add_resource(cw_event)
        return topic
Пример #7
0
    def add_resources(self):
        """Add resources to template."""
        template = self.template

        pagerdutyalert = template.add_resource(
            sns.Topic(
                'Topic'
            )
        )

        template.add_output(
            Output(
                "%sARN" % pagerdutyalert.title,
                Description='SNS topic',
                Value=Ref(pagerdutyalert)
            )
        )
Пример #8
0
    def create_custom_cloudformation_resources(self):
        t = self.template

        queue = sqs.Queue("CustomResourcesQueue")
        topic = sns.Topic(
            "CustomResourcesTopic",
            Subscription=[sns.Subscription(
                Protocol="sqs",
                Endpoint=GetAtt("CustomResourcesQueue", "Arn"))])
        queue_policy = sqs.QueuePolicy(
            "CustomResourcesQueuePolicy",
            Queues=[Ref(queue)],
            PolicyDocument=sns_to_sqs_policy(Ref(topic)))

        t.add_resource(queue)
        t.add_resource(topic)
        t.add_resource(queue_policy)
def get_template(
    puppet_version,
    all_regions,
    source,
    is_caching_enabled,
    is_manual_approvals: bool,
    scm_skip_creation_of_repo: bool,
    should_validate: bool,
) -> t.Template:
    is_codecommit = source.get("Provider", "").lower() == "codecommit"
    is_github = source.get("Provider", "").lower() == "github"
    is_codestarsourceconnection = (source.get(
        "Provider", "").lower() == "codestarsourceconnection")
    is_custom = (source.get("Provider", "").lower() == "custom")
    is_s3 = source.get("Provider", "").lower() == "s3"
    description = f"""Bootstrap template used to bring up the main ServiceCatalog-Puppet AWS CodePipeline with dependencies
{{"version": "{puppet_version}", "framework": "servicecatalog-puppet", "role": "bootstrap-master"}}"""

    template = t.Template(Description=description)

    version_parameter = template.add_parameter(
        t.Parameter("Version", Default=puppet_version, Type="String"))
    org_iam_role_arn_parameter = template.add_parameter(
        t.Parameter("OrgIamRoleArn", Default="None", Type="String"))
    with_manual_approvals_parameter = template.add_parameter(
        t.Parameter(
            "WithManualApprovals",
            Type="String",
            AllowedValues=["Yes", "No"],
            Default="No",
        ))
    puppet_code_pipeline_role_permission_boundary_parameter = template.add_parameter(
        t.Parameter(
            "PuppetCodePipelineRolePermissionBoundary",
            Type="String",
            Description=
            "IAM Permission Boundary to apply to the PuppetCodePipelineRole",
            Default=awscs_iam.ARN(resource="policy/AdministratorAccess").data,
        ))
    source_role_permissions_boundary_parameter = template.add_parameter(
        t.Parameter(
            "SourceRolePermissionsBoundary",
            Type="String",
            Description="IAM Permission Boundary to apply to the SourceRole",
            Default=awscs_iam.ARN(resource="policy/AdministratorAccess").data,
        ))
    puppet_generate_role_permission_boundary_parameter = template.add_parameter(
        t.Parameter(
            "PuppetGenerateRolePermissionBoundary",
            Type="String",
            Description=
            "IAM Permission Boundary to apply to the PuppetGenerateRole",
            Default=awscs_iam.ARN(resource="policy/AdministratorAccess").data,
        ))
    puppet_deploy_role_permission_boundary_parameter = template.add_parameter(
        t.Parameter(
            "PuppetDeployRolePermissionBoundary",
            Type="String",
            Description=
            "IAM Permission Boundary to apply to the PuppetDeployRole",
            Default=awscs_iam.ARN(resource="policy/AdministratorAccess").data,
        ))
    puppet_provisioning_role_permissions_boundary_parameter = template.add_parameter(
        t.Parameter(
            "PuppetProvisioningRolePermissionsBoundary",
            Type="String",
            Description=
            "IAM Permission Boundary to apply to the PuppetProvisioningRole",
            Default=awscs_iam.ARN(resource="policy/AdministratorAccess").data,
        ))
    cloud_formation_deploy_role_permissions_boundary_parameter = template.add_parameter(
        t.Parameter(
            "CloudFormationDeployRolePermissionsBoundary",
            Type="String",
            Description=
            "IAM Permission Boundary to apply to the CloudFormationDeployRole",
            Default=awscs_iam.ARN(resource="policy/AdministratorAccess").data,
        ))
    deploy_environment_compute_type_parameter = template.add_parameter(
        t.Parameter(
            "DeployEnvironmentComputeType",
            Type="String",
            Description="The AWS CodeBuild Environment Compute Type",
            Default="BUILD_GENERAL1_SMALL",
        ))
    spoke_deploy_environment_compute_type_parameter = template.add_parameter(
        t.Parameter(
            "SpokeDeployEnvironmentComputeType",
            Type="String",
            Description=
            "The AWS CodeBuild Environment Compute Type for spoke execution mode",
            Default="BUILD_GENERAL1_SMALL",
        ))
    deploy_num_workers_parameter = template.add_parameter(
        t.Parameter(
            "DeployNumWorkers",
            Type="Number",
            Description=
            "Number of workers that should be used when running a deploy",
            Default=10,
        ))
    puppet_role_name_parameter = template.add_parameter(
        t.Parameter("PuppetRoleName", Type="String", Default="PuppetRole"))
    puppet_role_path_template_parameter = template.add_parameter(
        t.Parameter("PuppetRolePath",
                    Type="String",
                    Default="/servicecatalog-puppet/"))

    template.add_condition(
        "ShouldUseOrgs",
        t.Not(t.Equals(t.Ref(org_iam_role_arn_parameter), "None")))
    template.add_condition(
        "HasManualApprovals",
        t.Equals(t.Ref(with_manual_approvals_parameter), "Yes"))

    template.add_resource(
        s3.Bucket(
            "StacksRepository",
            BucketName=t.Sub("sc-puppet-stacks-repository-${AWS::AccountId}"),
            VersioningConfiguration=s3.VersioningConfiguration(
                Status="Enabled"),
            BucketEncryption=s3.BucketEncryption(
                ServerSideEncryptionConfiguration=[
                    s3.ServerSideEncryptionRule(
                        ServerSideEncryptionByDefault=s3.
                        ServerSideEncryptionByDefault(SSEAlgorithm="AES256"))
                ]),
            PublicAccessBlockConfiguration=s3.PublicAccessBlockConfiguration(
                BlockPublicAcls=True,
                BlockPublicPolicy=True,
                IgnorePublicAcls=True,
                RestrictPublicBuckets=True,
            ),
            Tags=t.Tags({"ServiceCatalogPuppet:Actor": "Framework"}),
        ))

    manual_approvals_param = template.add_resource(
        ssm.Parameter(
            "ManualApprovalsParam",
            Type="String",
            Name="/servicecatalog-puppet/manual-approvals",
            Value=t.Ref(with_manual_approvals_parameter),
        ))
    template.add_resource(
        ssm.Parameter(
            "SpokeDeployEnvParameter",
            Type="String",
            Name=constants.SPOKE_EXECUTION_MODE_DEPLOY_ENV_PARAMETER_NAME,
            Value=t.Ref(spoke_deploy_environment_compute_type_parameter),
        ))
    param = template.add_resource(
        ssm.Parameter(
            "Param",
            Type="String",
            Name="service-catalog-puppet-version",
            Value=t.Ref(version_parameter),
        ))
    partition_parameter = template.add_resource(
        ssm.Parameter(
            "PartitionParameter",
            Type="String",
            Name="/servicecatalog-puppet/partition",
            Value=t.Ref("AWS::Partition"),
        ))
    puppet_role_name_parameter = template.add_resource(
        ssm.Parameter(
            "PuppetRoleNameParameter",
            Type="String",
            Name="/servicecatalog-puppet/puppet-role/name",
            Value=t.Ref(puppet_role_name_parameter),
        ))
    puppet_role_path_parameter = template.add_resource(
        ssm.Parameter(
            "PuppetRolePathParameter",
            Type="String",
            Name="/servicecatalog-puppet/puppet-role/path",
            Value=t.Ref(puppet_role_path_template_parameter),
        ))
    share_accept_function_role = template.add_resource(
        iam.Role(
            "ShareAcceptFunctionRole",
            RoleName="ShareAcceptFunctionRole",
            ManagedPolicyArns=[
                t.Sub(
                    "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
                )
            ],
            Path=t.Ref(puppet_role_path_template_parameter),
            Policies=[
                iam.Policy(
                    PolicyName="ServiceCatalogActions",
                    PolicyDocument={
                        "Version":
                        "2012-10-17",
                        "Statement": [{
                            "Action": ["sts:AssumeRole"],
                            "Resource": {
                                "Fn::Sub":
                                "arn:${AWS::Partition}:iam::*:role${PuppetRolePath}${PuppetRoleName}"
                            },
                            "Effect": "Allow",
                        }],
                    },
                )
            ],
            AssumeRolePolicyDocument={
                "Version":
                "2012-10-17",
                "Statement": [{
                    "Action": ["sts:AssumeRole"],
                    "Effect": "Allow",
                    "Principal": {
                        "Service": ["lambda.amazonaws.com"]
                    },
                }],
            },
        ))

    provisioning_role = template.add_resource(
        iam.Role(
            "ProvisioningRole",
            RoleName="PuppetProvisioningRole",
            AssumeRolePolicyDocument={
                "Version":
                "2012-10-17",
                "Statement": [
                    {
                        "Action": ["sts:AssumeRole"],
                        "Effect": "Allow",
                        "Principal": {
                            "Service": ["codebuild.amazonaws.com"]
                        },
                    },
                    {
                        "Action": ["sts:AssumeRole"],
                        "Effect": "Allow",
                        "Principal": {
                            "AWS": {
                                "Fn::Sub": "${AWS::AccountId}"
                            }
                        },
                    },
                ],
            },
            ManagedPolicyArns=[
                t.Sub(
                    "arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess"
                )
            ],
            PermissionsBoundary=t.Ref(
                puppet_provisioning_role_permissions_boundary_parameter),
            Path=t.Ref(puppet_role_path_template_parameter),
        ))

    cloud_formation_deploy_role = template.add_resource(
        iam.Role(
            "CloudFormationDeployRole",
            RoleName="CloudFormationDeployRole",
            AssumeRolePolicyDocument={
                "Version":
                "2012-10-17",
                "Statement": [
                    {
                        "Action": ["sts:AssumeRole"],
                        "Effect": "Allow",
                        "Principal": {
                            "Service": ["cloudformation.amazonaws.com"]
                        },
                    },
                    {
                        "Action": ["sts:AssumeRole"],
                        "Effect": "Allow",
                        "Principal": {
                            "AWS": {
                                "Fn::Sub": "${AWS::AccountId}"
                            }
                        },
                    },
                ],
            },
            ManagedPolicyArns=[
                t.Sub(
                    "arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess"
                )
            ],
            PermissionsBoundary=t.Ref(
                cloud_formation_deploy_role_permissions_boundary_parameter),
            Path=t.Ref(puppet_role_path_template_parameter),
        ))

    pipeline_role = template.add_resource(
        iam.Role(
            "PipelineRole",
            RoleName="PuppetCodePipelineRole",
            AssumeRolePolicyDocument={
                "Version":
                "2012-10-17",
                "Statement": [{
                    "Action": ["sts:AssumeRole"],
                    "Effect": "Allow",
                    "Principal": {
                        "Service": ["codepipeline.amazonaws.com"]
                    },
                }],
            },
            ManagedPolicyArns=[
                t.Sub(
                    "arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess"
                )
            ],
            PermissionsBoundary=t.Ref(
                puppet_code_pipeline_role_permission_boundary_parameter),
            Path=t.Ref(puppet_role_path_template_parameter),
        ))

    source_role = template.add_resource(
        iam.Role(
            "SourceRole",
            RoleName="PuppetSourceRole",
            AssumeRolePolicyDocument={
                "Version":
                "2012-10-17",
                "Statement": [
                    {
                        "Action": ["sts:AssumeRole"],
                        "Effect": "Allow",
                        "Principal": {
                            "Service": ["codepipeline.amazonaws.com"]
                        },
                    },
                    {
                        "Action": ["sts:AssumeRole"],
                        "Effect": "Allow",
                        "Principal": {
                            "AWS": {
                                "Fn::Sub":
                                "arn:${AWS::Partition}:iam::${AWS::AccountId}:root"
                            }
                        },
                    },
                ],
            },
            ManagedPolicyArns=[
                t.Sub(
                    "arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess"
                )
            ],
            PermissionsBoundary=t.Ref(
                source_role_permissions_boundary_parameter),
            Path=t.Ref(puppet_role_path_template_parameter),
        ))

    dry_run_notification_topic = template.add_resource(
        sns.Topic(
            "DryRunNotificationTopic",
            DisplayName="service-catalog-puppet-dry-run-approvals",
            TopicName="service-catalog-puppet-dry-run-approvals",
            Condition="HasManualApprovals",
        ))

    deploy_role = template.add_resource(
        iam.Role(
            "DeployRole",
            RoleName="PuppetDeployRole",
            AssumeRolePolicyDocument={
                "Version":
                "2012-10-17",
                "Statement": [{
                    "Action": ["sts:AssumeRole"],
                    "Effect": "Allow",
                    "Principal": {
                        "Service": ["codebuild.amazonaws.com"]
                    },
                }],
            },
            ManagedPolicyArns=[
                t.Sub(
                    "arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess"
                )
            ],
            PermissionsBoundary=t.Ref(
                puppet_deploy_role_permission_boundary_parameter),
            Path=t.Ref(puppet_role_path_template_parameter),
        ))

    num_workers_ssm_parameter = template.add_resource(
        ssm.Parameter(
            "NumWorkersSSMParameter",
            Type="String",
            Name="/servicecatalog-puppet/deploy/num-workers",
            Value=t.Sub("${DeployNumWorkers}"),
        ))

    parameterised_source_bucket = template.add_resource(
        s3.Bucket(
            "ParameterisedSourceBucket",
            PublicAccessBlockConfiguration=s3.PublicAccessBlockConfiguration(
                IgnorePublicAcls=True,
                BlockPublicPolicy=True,
                BlockPublicAcls=True,
                RestrictPublicBuckets=True,
            ),
            BucketEncryption=s3.BucketEncryption(
                ServerSideEncryptionConfiguration=[
                    s3.ServerSideEncryptionRule(
                        ServerSideEncryptionByDefault=s3.
                        ServerSideEncryptionByDefault(SSEAlgorithm="AES256"))
                ]),
            Tags=t.Tags.from_dict(
                **{"ServiceCatalogPuppet:Actor": "Framework"}),
            BucketName=t.Sub("sc-puppet-parameterised-runs-${AWS::AccountId}"),
            VersioningConfiguration=s3.VersioningConfiguration(
                Status="Enabled"),
        ))

    source_stage = codepipeline.Stages(
        Name="Source",
        Actions=[
            codepipeline.Actions(
                RunOrder=1,
                RoleArn=t.GetAtt("SourceRole", "Arn"),
                ActionTypeId=codepipeline.ActionTypeId(
                    Category="Source",
                    Owner="AWS",
                    Version="1",
                    Provider="S3",
                ),
                OutputArtifacts=[
                    codepipeline.OutputArtifacts(Name="ParameterisedSource")
                ],
                Configuration={
                    "S3Bucket": t.Ref(parameterised_source_bucket),
                    "S3ObjectKey": "parameters.zip",
                    "PollForSourceChanges": True,
                },
                Name="ParameterisedSource",
            )
        ],
    )

    install_spec = {
        "runtime-versions":
        dict(python="3.7"),
        "commands": [
            f"pip install {puppet_version}" if "http" in puppet_version else
            f"pip install aws-service-catalog-puppet=={puppet_version}",
        ],
    }

    deploy_env_vars = [
        {
            "Type": "PLAINTEXT",
            "Name": "PUPPET_ACCOUNT_ID",
            "Value": t.Ref("AWS::AccountId"),
        },
        {
            "Type": "PLAINTEXT",
            "Name": "PUPPET_REGION",
            "Value": t.Ref("AWS::Region"),
        },
        {
            "Type": "PARAMETER_STORE",
            "Name": "PARTITION",
            "Value": t.Ref(partition_parameter),
        },
        {
            "Type": "PARAMETER_STORE",
            "Name": "PUPPET_ROLE_NAME",
            "Value": t.Ref(puppet_role_name_parameter),
        },
        {
            "Type": "PARAMETER_STORE",
            "Name": "PUPPET_ROLE_PATH",
            "Value": t.Ref(puppet_role_path_parameter),
        },
    ]

    if is_codecommit:
        template.add_resource(
            codecommit.Repository(
                "CodeRepo",
                RepositoryName=source.get("Configuration").get(
                    "RepositoryName"),
                RepositoryDescription=
                "Repo to store the servicecatalog puppet solution",
                DeletionPolicy="Retain",
            ))

        source_stage.Actions.append(
            codepipeline.Actions(
                RunOrder=1,
                RoleArn=t.GetAtt("SourceRole", "Arn"),
                ActionTypeId=codepipeline.ActionTypeId(
                    Category="Source",
                    Owner="AWS",
                    Version="1",
                    Provider="CodeCommit",
                ),
                OutputArtifacts=[codepipeline.OutputArtifacts(Name="Source")],
                Configuration={
                    "RepositoryName":
                    source.get("Configuration").get("RepositoryName"),
                    "BranchName":
                    source.get("Configuration").get("BranchName"),
                    "PollForSourceChanges":
                    source.get("Configuration").get("PollForSourceChanges",
                                                    True),
                },
                Name="Source",
            ))

    if is_github:
        source_stage.Actions.append(
            codepipeline.Actions(
                RunOrder=1,
                ActionTypeId=codepipeline.ActionTypeId(
                    Category="Source",
                    Owner="ThirdParty",
                    Version="1",
                    Provider="GitHub",
                ),
                OutputArtifacts=[codepipeline.OutputArtifacts(Name="Source")],
                Configuration={
                    "Owner":
                    source.get("Configuration").get("Owner"),
                    "Repo":
                    source.get("Configuration").get("Repo"),
                    "Branch":
                    source.get("Configuration").get("Branch"),
                    "OAuthToken":
                    t.Join(
                        "",
                        [
                            "{{resolve:secretsmanager:",
                            source.get("Configuration").get(
                                "SecretsManagerSecret"),
                            ":SecretString:OAuthToken}}",
                        ],
                    ),
                    "PollForSourceChanges":
                    source.get("Configuration").get("PollForSourceChanges"),
                },
                Name="Source",
            ))

    if is_custom:
        source_stage.Actions.append(
            codepipeline.Actions(
                RunOrder=1,
                ActionTypeId=codepipeline.ActionTypeId(
                    Category="Source",
                    Owner="Custom",
                    Version=source.get("Configuration").get(
                        "CustomActionTypeVersion"),
                    Provider=source.get("Configuration").get(
                        "CustomActionTypeProvider"),
                ),
                OutputArtifacts=[codepipeline.OutputArtifacts(Name="Source")],
                Configuration={
                    "GitUrl": source.get("Configuration").get("GitUrl"),
                    "Branch": source.get("Configuration").get("Branch"),
                    "PipelineName": t.Sub("${AWS::StackName}-pipeline"),
                },
                Name="Source",
            ))
        webhook = codepipeline.Webhook(
            "Webhook",
            Authentication="IP",
            TargetAction="Source",
            AuthenticationConfiguration=codepipeline.WebhookAuthConfiguration(
                AllowedIPRange=source.get("Configuration").get(
                    "GitWebHookIpAddress")),
            Filters=[
                codepipeline.WebhookFilterRule(
                    JsonPath="$.changes[0].ref.id",
                    MatchEquals="refs/heads/{Branch}")
            ],
            TargetPipelineVersion=1,
            TargetPipeline=t.Sub("${AWS::StackName}-pipeline"),
        )
        template.add_resource(webhook)
        values_for_sub = {
            "GitUrl": source.get("Configuration").get("GitUrl"),
            "WebhookUrl": t.GetAtt(webhook, "Url"),
        }
        output_to_add = t.Output("WebhookUrl")
        output_to_add.Value = t.Sub("${GitUrl}||${WebhookUrl}",
                                    **values_for_sub)
        output_to_add.Export = t.Export(t.Sub("${AWS::StackName}-pipeline"))
        template.add_output(output_to_add)

    if is_codestarsourceconnection:
        source_stage.Actions.append(
            codepipeline.Actions(
                RunOrder=1,
                RoleArn=t.GetAtt("SourceRole", "Arn"),
                ActionTypeId=codepipeline.ActionTypeId(
                    Category="Source",
                    Owner="AWS",
                    Version="1",
                    Provider="CodeStarSourceConnection",
                ),
                OutputArtifacts=[codepipeline.OutputArtifacts(Name="Source")],
                Configuration={
                    "ConnectionArn":
                    source.get("Configuration").get("ConnectionArn"),
                    "FullRepositoryId":
                    source.get("Configuration").get("FullRepositoryId"),
                    "BranchName":
                    source.get("Configuration").get("BranchName"),
                    "OutputArtifactFormat":
                    source.get("Configuration").get("OutputArtifactFormat"),
                },
                Name="Source",
            ))

    if is_s3:
        bucket_name = source.get("Configuration").get("S3Bucket")
        if not scm_skip_creation_of_repo:
            template.add_resource(
                s3.Bucket(
                    bucket_name,
                    PublicAccessBlockConfiguration=s3.
                    PublicAccessBlockConfiguration(
                        IgnorePublicAcls=True,
                        BlockPublicPolicy=True,
                        BlockPublicAcls=True,
                        RestrictPublicBuckets=True,
                    ),
                    BucketEncryption=s3.BucketEncryption(
                        ServerSideEncryptionConfiguration=[
                            s3.ServerSideEncryptionRule(
                                ServerSideEncryptionByDefault=s3.
                                ServerSideEncryptionByDefault(
                                    SSEAlgorithm="AES256"))
                        ]),
                    Tags=t.Tags.from_dict(
                        **{"ServiceCatalogPuppet:Actor": "Framework"}),
                    BucketName=bucket_name,
                    VersioningConfiguration=s3.VersioningConfiguration(
                        Status="Enabled"),
                ))

        source_stage.Actions.append(
            codepipeline.Actions(
                RunOrder=1,
                ActionTypeId=codepipeline.ActionTypeId(
                    Category="Source",
                    Owner="AWS",
                    Version="1",
                    Provider="S3",
                ),
                OutputArtifacts=[codepipeline.OutputArtifacts(Name="Source")],
                Configuration={
                    "S3Bucket":
                    bucket_name,
                    "S3ObjectKey":
                    source.get("Configuration").get("S3ObjectKey"),
                    "PollForSourceChanges":
                    source.get("Configuration").get("PollForSourceChanges"),
                },
                Name="Source",
            ))

    single_account_run_project_build_spec = dict(
        version=0.2,
        phases=dict(
            install=install_spec,
            build={
                "commands": [
                    'echo "single_account: \\"${SINGLE_ACCOUNT_ID}\\"" > parameters.yaml',
                    "cat parameters.yaml",
                    "zip parameters.zip parameters.yaml",
                    "aws s3 cp parameters.zip s3://sc-puppet-parameterised-runs-${PUPPET_ACCOUNT_ID}/parameters.zip",
                ]
            },
            post_build={
                "commands": [
                    "servicecatalog-puppet wait-for-parameterised-run-to-complete",
                ]
            },
        ),
        artifacts=dict(
            name="DeployProject",
            files=[
                "ServiceCatalogPuppet/manifest.yaml",
                "ServiceCatalogPuppet/manifest-expanded.yaml",
                "results/*/*",
                "output/*/*",
                "exploded_results/*/*",
                "tasks.log",
            ],
        ),
    )

    single_account_run_project_args = dict(
        Name="servicecatalog-puppet-single-account-run",
        Description="Runs puppet for a single account - SINGLE_ACCOUNT_ID",
        ServiceRole=t.GetAtt(deploy_role, "Arn"),
        Tags=t.Tags.from_dict(**{"ServiceCatalogPuppet:Actor": "Framework"}),
        Artifacts=codebuild.Artifacts(Type="NO_ARTIFACTS", ),
        TimeoutInMinutes=480,
        Environment=codebuild.Environment(
            ComputeType=t.Ref(deploy_environment_compute_type_parameter),
            Image="aws/codebuild/standard:4.0",
            Type="LINUX_CONTAINER",
            EnvironmentVariables=[
                {
                    "Type": "PLAINTEXT",
                    "Name": "SINGLE_ACCOUNT_ID",
                    "Value": "CHANGE_ME",
                },
            ] + deploy_env_vars,
        ),
        Source=codebuild.Source(
            Type="NO_SOURCE",
            BuildSpec=yaml.safe_dump(single_account_run_project_build_spec),
        ),
    )

    single_account_run_project = template.add_resource(
        codebuild.Project("SingleAccountRunProject",
                          **single_account_run_project_args))

    single_account_run_project_build_spec["phases"]["post_build"]["commands"] = [
        "servicecatalog-puppet wait-for-parameterised-run-to-complete --on-complete-url $CALLBACK_URL"
    ]
    single_account_run_project_args[
        "Name"] = "servicecatalog-puppet-single-account-run-with-callback"
    single_account_run_project_args[
        "Description"] = "Runs puppet for a single account - SINGLE_ACCOUNT_ID and then does a http put"
    single_account_run_project_args.get(
        "Environment").EnvironmentVariables.append({
            "Type": "PLAINTEXT",
            "Name": "CALLBACK_URL",
            "Value": "CHANGE_ME",
        })
    single_account_run_project_args["Source"] = codebuild.Source(
        Type="NO_SOURCE",
        BuildSpec=yaml.safe_dump(single_account_run_project_build_spec),
    )
    single_account_run_project_with_callback = template.add_resource(
        codebuild.Project("SingleAccountRunWithCallbackProject",
                          **single_account_run_project_args))

    stages = [source_stage]

    if should_validate:
        template.add_resource(
            codebuild.Project(
                "ValidateProject",
                Name="servicecatalog-puppet-validate",
                ServiceRole=t.GetAtt("DeployRole", "Arn"),
                Tags=t.Tags.from_dict(
                    **{"ServiceCatalogPuppet:Actor": "Framework"}),
                Artifacts=codebuild.Artifacts(Type="CODEPIPELINE"),
                TimeoutInMinutes=60,
                Environment=codebuild.Environment(
                    ComputeType="BUILD_GENERAL1_SMALL",
                    Image="aws/codebuild/standard:4.0",
                    Type="LINUX_CONTAINER",
                ),
                Source=codebuild.Source(
                    BuildSpec=yaml.safe_dump(
                        dict(
                            version="0.2",
                            phases={
                                "install": {
                                    "runtime-versions": {
                                        "python": "3.7",
                                    },
                                    "commands": [
                                        f"pip install {puppet_version}"
                                        if "http" in puppet_version else
                                        f"pip install aws-service-catalog-puppet=={puppet_version}",
                                    ],
                                },
                                "build": {
                                    "commands": [
                                        "servicecatalog-puppet validate manifest.yaml"
                                    ]
                                },
                            },
                        )),
                    Type="CODEPIPELINE",
                ),
                Description="Validate the manifest.yaml file",
            ))
        stages.append(
            codepipeline.Stages(
                Name="Validate",
                Actions=[
                    codepipeline.Actions(
                        InputArtifacts=[
                            codepipeline.InputArtifacts(Name="Source"),
                        ],
                        Name="Validate",
                        ActionTypeId=codepipeline.ActionTypeId(
                            Category="Build",
                            Owner="AWS",
                            Version="1",
                            Provider="CodeBuild",
                        ),
                        OutputArtifacts=[
                            codepipeline.OutputArtifacts(
                                Name="ValidateProject")
                        ],
                        Configuration={
                            "ProjectName": t.Ref("ValidateProject"),
                            "PrimarySource": "Source",
                        },
                        RunOrder=1,
                    ),
                ],
            ))

    if is_manual_approvals:
        deploy_stage = codepipeline.Stages(
            Name="Deploy",
            Actions=[
                codepipeline.Actions(
                    InputArtifacts=[
                        codepipeline.InputArtifacts(Name="Source"),
                        codepipeline.InputArtifacts(
                            Name="ParameterisedSource"),
                    ],
                    Name="DryRun",
                    ActionTypeId=codepipeline.ActionTypeId(
                        Category="Build",
                        Owner="AWS",
                        Version="1",
                        Provider="CodeBuild",
                    ),
                    OutputArtifacts=[
                        codepipeline.OutputArtifacts(Name="DryRunProject")
                    ],
                    Configuration={
                        "ProjectName": t.Ref("DryRunProject"),
                        "PrimarySource": "Source",
                    },
                    RunOrder=1,
                ),
                codepipeline.Actions(
                    ActionTypeId=codepipeline.ActionTypeId(
                        Category="Approval",
                        Owner="AWS",
                        Version="1",
                        Provider="Manual",
                    ),
                    Configuration={
                        "NotificationArn":
                        t.Ref("DryRunNotificationTopic"),
                        "CustomData":
                        "Approve when you are happy with the dry run.",
                    },
                    Name="DryRunApproval",
                    RunOrder=2,
                ),
                codepipeline.Actions(
                    InputArtifacts=[
                        codepipeline.InputArtifacts(Name="Source"),
                        codepipeline.InputArtifacts(
                            Name="ParameterisedSource"),
                    ],
                    Name="Deploy",
                    ActionTypeId=codepipeline.ActionTypeId(
                        Category="Build",
                        Owner="AWS",
                        Version="1",
                        Provider="CodeBuild",
                    ),
                    OutputArtifacts=[
                        codepipeline.OutputArtifacts(Name="DeployProject")
                    ],
                    Configuration={
                        "ProjectName": t.Ref("DeployProject"),
                        "PrimarySource": "Source",
                    },
                    RunOrder=3,
                ),
            ],
        )
    else:
        deploy_stage = codepipeline.Stages(
            Name="Deploy",
            Actions=[
                codepipeline.Actions(
                    InputArtifacts=[
                        codepipeline.InputArtifacts(Name="Source"),
                        codepipeline.InputArtifacts(
                            Name="ParameterisedSource"),
                    ],
                    Name="Deploy",
                    ActionTypeId=codepipeline.ActionTypeId(
                        Category="Build",
                        Owner="AWS",
                        Version="1",
                        Provider="CodeBuild",
                    ),
                    OutputArtifacts=[
                        codepipeline.OutputArtifacts(Name="DeployProject")
                    ],
                    Configuration={
                        "ProjectName":
                        t.Ref("DeployProject"),
                        "PrimarySource":
                        "Source",
                        "EnvironmentVariables":
                        '[{"name":"EXECUTION_ID","value":"#{codepipeline.PipelineExecutionId}","type":"PLAINTEXT"}]',
                    },
                    RunOrder=1,
                ),
            ],
        )

    stages.append(deploy_stage)

    pipeline = template.add_resource(
        codepipeline.Pipeline(
            "Pipeline",
            RoleArn=t.GetAtt("PipelineRole", "Arn"),
            Stages=stages,
            Name=t.Sub("${AWS::StackName}-pipeline"),
            ArtifactStore=codepipeline.ArtifactStore(
                Type="S3",
                Location=t.Sub(
                    "sc-puppet-pipeline-artifacts-${AWS::AccountId}-${AWS::Region}"
                ),
            ),
            RestartExecutionOnUpdate=True,
        ))

    if is_github:
        template.add_resource(
            codepipeline.Webhook(
                "Webhook",
                AuthenticationConfiguration=codepipeline.
                WebhookAuthConfiguration(SecretToken=t.Join(
                    "",
                    [
                        "{{resolve:secretsmanager:",
                        source.get("Configuration").get(
                            "SecretsManagerSecret"),
                        ":SecretString:SecretToken}}",
                    ],
                )),
                Filters=[
                    codepipeline.WebhookFilterRule(
                        JsonPath="$.ref",
                        MatchEquals="refs/heads/" +
                        source.get("Configuration").get("Branch"),
                    )
                ],
                Authentication="GITHUB_HMAC",
                TargetPipeline=t.Ref(pipeline),
                TargetAction="Source",
                Name=t.Sub("${AWS::StackName}-webhook"),
                TargetPipelineVersion=t.GetAtt(pipeline, "Version"),
                RegisterWithThirdParty="true",
            ))

    deploy_project_build_spec = dict(
        version=0.2,
        phases=dict(
            install={
                "runtime-versions":
                dict(python="3.7"),
                "commands": [
                    f"pip install {puppet_version}"
                    if "http" in puppet_version else
                    f"pip install aws-service-catalog-puppet=={puppet_version}",
                ],
            },
            pre_build={
                "commands": [
                    "servicecatalog-puppet --info expand --parameter-override-file $CODEBUILD_SRC_DIR_ParameterisedSource/parameters.yaml manifest.yaml",
                ]
            },
            build={
                "commands": [
                    "servicecatalog-puppet --info deploy --num-workers ${NUM_WORKERS} manifest-expanded.yaml",
                ]
            },
        ),
        artifacts=dict(
            name="DeployProject",
            files=[
                "manifest-expanded.yaml",
                "results/*/*",
                "output/*/*",
                "exploded_results/*/*",
                "tasks.log",
            ],
        ),
    )

    deploy_project_args = dict(
        Name="servicecatalog-puppet-deploy",
        ServiceRole=t.GetAtt(deploy_role, "Arn"),
        Tags=t.Tags.from_dict(**{"ServiceCatalogPuppet:Actor": "Framework"}),
        Artifacts=codebuild.Artifacts(Type="CODEPIPELINE", ),
        TimeoutInMinutes=480,
        Environment=codebuild.Environment(
            ComputeType=t.Ref(deploy_environment_compute_type_parameter),
            Image="aws/codebuild/standard:4.0",
            Type="LINUX_CONTAINER",
            EnvironmentVariables=[
                {
                    "Type": "PARAMETER_STORE",
                    "Name": "NUM_WORKERS",
                    "Value": t.Ref(num_workers_ssm_parameter),
                },
                {
                    "Type":
                    "PARAMETER_STORE",
                    "Name":
                    "SPOKE_EXECUTION_MODE_DEPLOY_ENV",
                    "Value":
                    constants.SPOKE_EXECUTION_MODE_DEPLOY_ENV_PARAMETER_NAME,
                },
            ] + deploy_env_vars,
        ),
        Source=codebuild.Source(
            Type="CODEPIPELINE",
            BuildSpec=yaml.safe_dump(deploy_project_build_spec),
        ),
        Description="deploys out the products to be deployed",
    )

    deploy_project = template.add_resource(
        codebuild.Project("DeployProject", **deploy_project_args))

    deploy_project_build_spec["phases"]["build"]["commands"] = [
        "servicecatalog-puppet --info dry-run manifest-expanded.yaml"
    ]
    deploy_project_build_spec["artifacts"]["name"] = "DryRunProject"
    deploy_project_args["Name"] = "servicecatalog-puppet-dryrun"
    deploy_project_args[
        "Description"] = "dry run of servicecatalog-puppet-dryrun"
    deploy_project_args["Source"] = codebuild.Source(
        Type="CODEPIPELINE",
        BuildSpec=yaml.safe_dump(deploy_project_build_spec),
    )

    dry_run_project = template.add_resource(
        codebuild.Project("DryRunProject", **deploy_project_args))

    bootstrap_project = template.add_resource(
        codebuild.Project(
            "BootstrapProject",
            Name="servicecatalog-puppet-bootstrap-spokes-in-ou",
            ServiceRole=t.GetAtt("DeployRole", "Arn"),
            Tags=t.Tags.from_dict(
                **{"ServiceCatalogPuppet:Actor": "Framework"}),
            Artifacts=codebuild.Artifacts(Type="NO_ARTIFACTS"),
            TimeoutInMinutes=60,
            Environment=codebuild.Environment(
                ComputeType="BUILD_GENERAL1_SMALL",
                Image="aws/codebuild/standard:4.0",
                Type="LINUX_CONTAINER",
                EnvironmentVariables=[
                    {
                        "Type": "PLAINTEXT",
                        "Name": "OU_OR_PATH",
                        "Value": "CHANGE_ME"
                    },
                    {
                        "Type": "PLAINTEXT",
                        "Name": "IAM_ROLE_NAME",
                        "Value": "OrganizationAccountAccessRole",
                    },
                    {
                        "Type": "PLAINTEXT",
                        "Name": "IAM_ROLE_ARNS",
                        "Value": ""
                    },
                ],
            ),
            Source=codebuild.Source(
                BuildSpec=
                "version: 0.2\nphases:\n  install:\n    runtime-versions:\n      python: 3.7\n    commands:\n      - pip install aws-service-catalog-puppet\n  build:\n    commands:\n      - servicecatalog-puppet bootstrap-spokes-in-ou $OU_OR_PATH $IAM_ROLE_NAME $IAM_ROLE_ARNS\nartifacts:\n  files:\n    - results/*/*\n    - output/*/*\n  name: BootstrapProject\n",
                Type="NO_SOURCE",
            ),
            Description="Bootstrap all the accounts in an OU",
        ))

    template.add_resource(
        codebuild.Project(
            "BootstrapASpokeProject",
            Name="servicecatalog-puppet-bootstrap-spoke",
            ServiceRole=t.GetAtt("DeployRole", "Arn"),
            Tags=t.Tags.from_dict(
                **{"ServiceCatalogPuppet:Actor": "Framework"}),
            Artifacts=codebuild.Artifacts(Type="NO_ARTIFACTS"),
            TimeoutInMinutes=60,
            Environment=codebuild.Environment(
                ComputeType="BUILD_GENERAL1_SMALL",
                Image="aws/codebuild/standard:4.0",
                Type="LINUX_CONTAINER",
                EnvironmentVariables=[
                    {
                        "Type": "PLAINTEXT",
                        "Name": "PUPPET_ACCOUNT_ID",
                        "Value": t.Sub("${AWS::AccountId}"),
                    },
                    {
                        "Type": "PLAINTEXT",
                        "Name": "ORGANIZATION_ACCOUNT_ACCESS_ROLE_ARN",
                        "Value": "CHANGE_ME",
                    },
                    {
                        "Type": "PLAINTEXT",
                        "Name": "ASSUMABLE_ROLE_IN_ROOT_ACCOUNT",
                        "Value": "CHANGE_ME",
                    },
                ],
            ),
            Source=codebuild.Source(
                BuildSpec=yaml.safe_dump(
                    dict(
                        version=0.2,
                        phases=dict(
                            install=install_spec,
                            build={
                                "commands": [
                                    "servicecatalog-puppet bootstrap-spoke-as ${PUPPET_ACCOUNT_ID} ${ASSUMABLE_ROLE_IN_ROOT_ACCOUNT} ${ORGANIZATION_ACCOUNT_ACCESS_ROLE_ARN}"
                                ]
                            },
                        ),
                    )),
                Type="NO_SOURCE",
            ),
            Description="Bootstrap given account as a spoke",
        ))

    cloud_formation_events_queue = template.add_resource(
        sqs.Queue(
            "CloudFormationEventsQueue",
            QueueName="servicecatalog-puppet-cloudformation-events",
            Tags=t.Tags.from_dict(
                **{"ServiceCatalogPuppet:Actor": "Framework"}),
        ))

    cloud_formation_events_queue_policy = template.add_resource(
        sqs.QueuePolicy(
            "CloudFormationEventsQueuePolicy",
            Queues=[t.Ref(cloud_formation_events_queue)],
            PolicyDocument={
                "Id":
                "AllowSNS",
                "Version":
                "2012-10-17",
                "Statement": [{
                    "Sid": "allow-send-message",
                    "Effect": "Allow",
                    "Principal": {
                        "AWS": "*"
                    },
                    "Action": ["sqs:SendMessage"],
                    "Resource": "*",
                    "Condition": {
                        "ArnEquals": {
                            "aws:SourceArn":
                            t.Sub(
                                "arn:${AWS::Partition}:sns:*:${AWS::AccountId}:servicecatalog-puppet-cloudformation-regional-events"
                            )
                        }
                    },
                }],
            },
        ))

    spoke_deploy_bucket = template.add_resource(
        s3.Bucket(
            "SpokeDeployBucket",
            PublicAccessBlockConfiguration=s3.PublicAccessBlockConfiguration(
                IgnorePublicAcls=True,
                BlockPublicPolicy=True,
                BlockPublicAcls=True,
                RestrictPublicBuckets=True,
            ),
            BucketEncryption=s3.BucketEncryption(
                ServerSideEncryptionConfiguration=[
                    s3.ServerSideEncryptionRule(
                        ServerSideEncryptionByDefault=s3.
                        ServerSideEncryptionByDefault(SSEAlgorithm="AES256"))
                ]),
            Tags=t.Tags.from_dict(
                **{"ServiceCatalogPuppet:Actor": "Framework"}),
            BucketName=t.Sub("sc-puppet-spoke-deploy-${AWS::AccountId}"),
            VersioningConfiguration=s3.VersioningConfiguration(
                Status="Enabled"),
        ))

    caching_bucket = template.add_resource(
        s3.Bucket(
            "CachingBucket",
            PublicAccessBlockConfiguration=s3.PublicAccessBlockConfiguration(
                BlockPublicAcls=True,
                BlockPublicPolicy=True,
                IgnorePublicAcls=True,
                RestrictPublicBuckets=True,
            ),
            BucketEncryption=s3.BucketEncryption(
                ServerSideEncryptionConfiguration=[
                    s3.ServerSideEncryptionRule(
                        ServerSideEncryptionByDefault=s3.
                        ServerSideEncryptionByDefault(SSEAlgorithm="AES256"))
                ]),
            Tags=t.Tags.from_dict(
                **{"ServiceCatalogPuppet:Actor": "Framework"}),
            BucketName=t.Sub(
                "sc-puppet-caching-bucket-${AWS::AccountId}-${AWS::Region}"),
            VersioningConfiguration=s3.VersioningConfiguration(
                Status="Enabled"),
        ))

    template.add_output(
        t.Output(
            "CloudFormationEventsQueueArn",
            Value=t.GetAtt(cloud_formation_events_queue, "Arn"),
        ))
    template.add_output(t.Output("Version", Value=t.GetAtt(param, "Value")))
    template.add_output(
        t.Output("ManualApprovalsParam",
                 Value=t.GetAtt(manual_approvals_param, "Value")))

    template.add_resource(
        ssm.Parameter(
            "DefaultTerraformVersion",
            Type="String",
            Name=constants.DEFAULT_TERRAFORM_VERSION_PARAMETER_NAME,
            Value=constants.DEFAULT_TERRAFORM_VERSION_VALUE,
        ))

    return template
Пример #10
0
        InvitationId=Ref(member_invitation),
    ))

# You can create multiple members if you have multiple members accounts
member = t.add_resource(
    guardduty.Member("Member",
                     Condition="IsMaster",
                     Status="Invited",
                     MemberId=MEMBER_ACCOUNT_ID,
                     Email=MEMBER_ACCOUNT_EMAIL,
                     DetectorId=Ref(detector)))

snstopic = t.add_resource(
    sns.Topic(
        "SNSTopic",
        Condition="IsMaster",
        Subscription=[
            # put any subscriptions here
        ]))

event = t.add_resource(
    events.Rule("EventsRule",
                Condition="IsMaster",
                EventPattern={"source": ["aws.guardduty"]},
                State="ENABLED",
                Targets=[events.Target(
                    Arn=Ref(snstopic),
                    Id="sns",
                )]))

# Allow events to send notifications to SNS
t.add_resource(
        Runtime='python3.6',
        Timeout=30,
        Environment=awslambda.Environment(
            Variables={
                'SOURCE_REGION': Ref(AWS_REGION),
                'TARGET_REGION': Ref(target_region_parameter),
                'KMS_KEY_ID': Ref(kms_key_parameter),
                'CLUSTERS_TO_USE': Ref(clusters_to_use_parameter)
            })))

# SNS topic for event subscriptions
rds_topic = template.add_resource(
    sns.Topic('RDSBackupTopic',
              Subscription=[
                  sns.Subscription(
                      Protocol="lambda",
                      Endpoint=GetAtt(backup_rds_function, 'Arn'),
                  )
              ]))

# Event subscription - RDS will notify SNS when backup is started and finished
template.add_resource(
    rds.EventSubscription("RDSBackupEvent",
                          Enabled=True,
                          EventCategories=["backup"],
                          SourceType="db-instance",
                          SnsTopicArn=Ref(rds_topic),
                          SourceIds=If("UseAllDatabases", Ref(AWS_NO_VALUE),
                                       Ref(databases_to_use_parameter))))

# Permission for SNS to trigger the Lambda
Пример #12
0
 def construct_basics(self):
     my_topic1 = sns.Topic("SNSTopic1", TopicName=self.topic_name)
     self.t.add_resource(my_topic1)
alarm_topic = t.add_resource(sns.Topic(
    'AlarmTopic',

    DisplayName=If('HasDisplayNameCondition', Ref(param_display_name),
                   Ref(AWS_NO_VALUE)),

    Subscription=[

        sns.Subscription(
            Endpoint=Select(0, Ref(param_alarm_emails)),
            Protocol='email'),

        If('TwoEmailsCondition',
           sns.Subscription(
               Endpoint=Select(1, Ref(param_alarm_emails)),
               Protocol='email'
           ),
           Ref(AWS_NO_VALUE)),

        If('ThreeEmailsCondition',
           sns.Subscription(
               Endpoint=Select(2, Ref(param_alarm_emails)),
               Protocol='email'
           ),
           Ref(AWS_NO_VALUE)),

        If('FourEmailsCondition',
           sns.Subscription(
               Endpoint=Select(3, Ref(param_alarm_emails)),
               Protocol='email'
           ),
           Ref(AWS_NO_VALUE)),

        If('FiveEmailsCondition',
           sns.Subscription(
               Endpoint=Select(4, Ref(param_alarm_emails)),
               Protocol='email'
           ),
           Ref(AWS_NO_VALUE)),

        If('SixEmailsCondition',
           sns.Subscription(
               Endpoint=Select(5, Ref(param_alarm_emails)),
               Protocol='email'
           ),
           Ref(AWS_NO_VALUE)),

    ],
))
Пример #14
0
# Add Security Group for Bastion Hosts
resource_tags.update({"Name": "ApiDev-Dev-VPC-Bastion-SG"})
BastionSGProperties = {
    "GroupDescription": "Used for source/dest rules",
    "Tags": Tags(resource_tags),
    "VpcId": Ref("VPC")
}
BastionSG = ec2.SecurityGroup(
    "BastionSG",
    GroupDescription=BastionSGProperties.get("GroupDescription"),
    Tags=BastionSGProperties.get("Tags"),
    VpcId=BastionSGProperties.get("VpcId"))
template.add_resource(BastionSG)

# Add CloudWatch Alarm Topic from SNS
CloudWatchAlarmTopic = sns.Topic("CloudWatchAlarmTopic",
                                 TopicName="ApiDev-Dev-CloudWatchAlarms")
template.add_resource(CloudWatchAlarmTopic)

# Add DHCP Options
resource_tags.update({"Name": "ApiDev-Dev-DhcpOptions"})
DhcpOptions = ec2.DHCPOptions(
    "DhcpOptions",
    DomainName=Join("", (Ref("AWS::Region"), ".compute.internal")),
    DomainNameServers=["AmazonProvidedDNS"],
    Tags=Tags(resource_tags))
template.add_resource(DhcpOptions)

# Add Internet Gateway
resource_tags.update({"Name": "ApiDev-Dev-InternetGateway"})
InternetGateway = ec2.InternetGateway("InternetGateway",
                                      Tags=Tags(resource_tags))
Пример #15
0
from troposphere import sns, Ref

from stacks.parameters import email_address

emails_sns_topic = sns.Topic(
    "EmailsSNSTopic",
    Subscription=[
        sns.Subscription(Endpoint=Ref(email_address), Protocol="email")
    ],
)
Пример #16
0
    def build_template(self):

        t = self._init_template()

        # make iam policy
        policy = t.add_resource(
            iam.Role(
                "{}SlackSNSRole".format(self.stack_name),
                AssumeRolePolicyDocument=aws.Policy(Statement=[
                    aws.Statement(Action=[awacs.sts.AssumeRole],
                                  Effect=aws.Allow,
                                  Principal=aws.Principal(
                                      "Service", ["lambda.amazonaws.com"]))
                ]),
                Path="/",
                Policies=[
                    iam.Policy(
                        PolicyName='snspublic',
                        PolicyDocument=aws.PolicyDocument(Statement=[
                            aws.Statement(Effect=aws.Allow,
                                          Action=[
                                              awacs.sns.Publish,
                                              awacs.logs.PutLogEvents,
                                              awacs.logs.CreateLogGroup,
                                              awacs.logs.CreateLogStream,
                                          ],
                                          Resource=["*"])
                        ]))
                ],
                ManagedPolicyArns=[
                    # "arn:aws:iam::aws:policy/AdministratorAccess"
                ]))

        code = ["import sys"]
        # make lambda function
        fn = t.add_resource(
            awslambda.Function('{}SlackTopicFN'.format(self.stack_name),
                               Handler='index.handle',
                               Runtime='python3.6',
                               Role=GetAtt(policy, "Arn"),
                               Code=awslambda.Code(ZipFile=Join("", code))))

        topic = t.add_resource(
            sns.Topic(
                "{}SNSTopic".format(self.stack_name),
                TopicName=self.stack_name,
                DisplayName=self.stack_name,
                Subscription=[
                    sns.Subscription(Protocol='lambda',
                                     Endpoint=GetAtt(fn, "Arn"))
                ],
            ))

        t.add_resource(
            awslambda.Permission('{}LambdaPerm'.format(self.stack_name),
                                 Action='lambda:InvokeFunction',
                                 FunctionName=GetAtt(fn, "Arn"),
                                 SourceArn=Ref(topic),
                                 Principal="sns.amazonaws.com"))

        t.add_output(
            [Output("{}SNSTopic".format(self.stack_name), Value=Ref(topic))])

        return t
Пример #17
0
    def create_ecs_resources(self):
        t = self.template

        # Give the instances access that the Empire daemon needs.
        t.add_resource(
            PolicyType(
                "AccessPolicy",
                PolicyName="empire",
                PolicyDocument=empire_policy({
                    "Environment":
                    Ref("Environment"),
                    "CustomResourcesTopic":
                    Ref("CustomResourcesTopic"),
                    "CustomResourcesQueue": (GetAtt("CustomResourcesQueue",
                                                    "Arn")),
                    "TemplateBucket":
                    (Join("", ["arn:aws:s3:::",
                               Ref("TemplateBucket"), "/*"]))
                }),
                Roles=[Ref("InstanceRole")]))

        t.add_resource(
            sns.Topic(
                EVENTS_TOPIC,
                DisplayName="Empire events",
                Condition="CreateSNSTopic",
            ))
        t.add_output(
            Output("EventsSNSTopic",
                   Value=Ref(EVENTS_TOPIC),
                   Condition="CreateSNSTopic"))

        # Add SNS Events policy if Events are enabled
        t.add_resource(
            PolicyType("SNSEventsPolicy",
                       PolicyName="EmpireSNSEventsPolicy",
                       Condition="EnableSNSEvents",
                       PolicyDocument=sns_events_policy(
                           If("CreateSNSTopic", Ref(EVENTS_TOPIC),
                              Ref("EventsSNSTopicName"))),
                       Roles=[Ref("InstanceRole")]))

        # Add run logs policy if run logs are enabled
        t.add_resource(
            PolicyType("RunLogsPolicy",
                       PolicyName="EmpireRunLogsPolicy",
                       Condition="EnableCloudwatchLogs",
                       PolicyDocument=runlogs_policy(
                           If("CreateRunLogsGroup", Ref(RUN_LOGS),
                              Ref("RunLogsCloudwatchGroup"))),
                       Roles=[Ref("InstanceRole")]))

        # Allow the controller to write empire events to kinesis if kinesis is
        # enabled.
        t.add_resource(
            PolicyType("AppEventStreamPolicy",
                       PolicyName="EmpireAppEventStreamPolicy",
                       Condition="EnableAppEventStream",
                       PolicyDocument=logstream_policy(),
                       Roles=[Ref("InstanceRole")]))

        t.add_resource(
            ecs.TaskDefinition(
                "TaskDefinition",
                Volumes=[
                    ecs.Volume(
                        Name="dockerSocket",
                        Host=ecs.Host(SourcePath="/var/run/docker.sock")),
                    ecs.Volume(Name="dockerCfg",
                               Host=ecs.Host(SourcePath="/root/.dockercfg"))
                ],
                ContainerDefinitions=[
                    ecs.ContainerDefinition(
                        Command=["server", "-automigrate=true"],
                        Name="empire",
                        Environment=self.get_empire_environment(),
                        Essential=True,
                        Image=Ref("DockerImage"),
                        MountPoints=[
                            ecs.MountPoint(
                                SourceVolume="dockerSocket",
                                ContainerPath="/var/run/docker.sock",
                                ReadOnly=False),
                            ecs.MountPoint(SourceVolume="dockerCfg",
                                           ContainerPath="/root/.dockercfg",
                                           ReadOnly=False)
                        ],
                        PortMappings=[
                            ecs.PortMapping(HostPort=8081, ContainerPort=8081)
                        ],
                        Cpu=Ref("TaskCPU"),
                        Memory=Ref("TaskMemory"))
                ]))

        t.add_resource(
            Role("ServiceRole",
                 AssumeRolePolicyDocument=get_ecs_assumerole_policy(),
                 Path="/",
                 Policies=[
                     Policy(PolicyName="ecs-service-role",
                            PolicyDocument=service_role_policy())
                 ]))

        t.add_resource(
            ecs.Service(
                "Service",
                Cluster=Ref("ControllerCluster"),
                DeploymentConfiguration=ecs.DeploymentConfiguration(
                    MaximumPercent=Ref("ServiceMaximumPercent"),
                    MinimumHealthyPercent=Ref("ServiceMinimumHealthyPercent"),
                ),
                DesiredCount=Ref("DesiredCount"),
                LoadBalancers=[
                    ecs.LoadBalancer(ContainerName="empire",
                                     ContainerPort=8081,
                                     LoadBalancerName=Ref("LoadBalancer"))
                ],
                Role=Ref("ServiceRole"),
                TaskDefinition=Ref("TaskDefinition")))
Пример #18
0
domain = os.environ.get("EMAIL_CONTACT_DOMAIN", "http://test")
parsed_domain = urlparse(domain)
if not parsed_domain.scheme:
    raise ValueError(
        f"Domain '{domain}' requires a scheme. This is needed for CORS headers."
    )
email_target = os.environ.get("EMAIL_TARGET", "*****@*****.**")
recaptcha_secret = os.environ.get("RECAPTCHA_SECRET")
cdomain = parsed_domain.netloc.replace(
    ".", "-")[:24]  # AWS names have a character limit

### SNS
send_to = sns.Subscription(Protocol="email", Endpoint=email_target)

topic = sns.Topic("EmailContactForm", Subscription=[send_to])

### Lambda
environment = {"ORIGIN_DOMAIN": domain, "TOPIC_ARN": Ref(topic)}
if recaptcha_secret:
    environment["RECAPTCHA_SECRET"] = recaptcha_secret

lambda_environment = awslambda.Environment(Variables=environment)

sns_publish_policy = iam.Policy(
    PolicyName=f"lambda-sns-publish-policy-contact-form-{cdomain}",
    PolicyDocument={
        "Version":
        "2012-10-17",
        "Statement": [{
            "Effect": "Allow",
                        '([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|'
                        '([a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\.'
                        '([a-zA-Z]{2,6}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,3})$'),
        Default='example.com',
        Description=
        'FQDN of the main domain or subdomain used to access the site.',
        MaxLength=100,
        MinLength=4,
        Type='String'))
# endregion

# region Resources
notifications = template.add_resource(
    sns.Topic('Notifications',
              Subscription=[
                  sns.Subscription(Endpoint=Ref(email), Protocol='email'),
                  sns.Subscription(Endpoint=Ref(phone), Protocol='sms')
              ]))

main_domain_check = template.add_resource(
    route53.HealthCheck('MainDomainCheck',
                        HealthCheckConfig=route53.HealthCheckConfiguration(
                            EnableSNI=True,
                            FullyQualifiedDomainName=Ref(main_domain),
                            Port='443',
                            Type='HTTPS')))

main_domain_alarm = template.add_resource(
    cloudwatch.Alarm(
        'MainDomainAlarm',
        AlarmActions=[Ref(notifications)],
Пример #20
0
def GenerateStepPublisherLayer():
    t = Template()

    t.add_description("""\
    StepScheduler Layer
    """)

    stackname_param = t.add_parameter(
        Parameter(
            "StackName",
            Description="Environment Name (default: hackathon)",
            Type="String",
            Default="hackathon",
        ))

    vpcid_param = t.add_parameter(
        Parameter(
            "VpcId",
            Type="String",
            Description="VpcId of your existing Virtual Private Cloud (VPC)",
            Default="vpc-fab00e9f"))

    subnets = t.add_parameter(
        Parameter(
            "Subnets",
            Type="CommaDelimitedList",
            Description=(
                "The list SubnetIds, for public subnets in the "
                "region and in your Virtual Private Cloud (VPC) - minimum one"
            ),
            Default="subnet-b68f3bef,subnet-9a6208ff,subnet-bfdd4fc8"))

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

    scheduler_ami_id_param = t.add_parameter(
        Parameter(
            "SchedulerAmiId",
            Description="Scheduler server AMI ID (default: ami-a10897d6)",
            Type="String",
            Default="ami-a10897d6"))

    cluster_ami_id_param = t.add_parameter(
        Parameter("ClusterAmiId",
                  Description="Cluster server AMI ID (default: ami-3db4ca4a)",
                  Type="String",
                  Default="ami-3db4ca4a"))

    iam_role_param = t.add_parameter(
        Parameter(
            "IamRole",
            Description="IAM Role name",
            Type="String",
        ))

    hashkeyname_param = t.add_parameter(
        Parameter(
            "HaskKeyElementName",
            Description="HashType PrimaryKey Name (default: id)",
            Type="String",
            AllowedPattern="[a-zA-Z0-9]*",
            MinLength="1",
            MaxLength="2048",
            ConstraintDescription="must contain only alphanumberic characters",
            Default="id"))

    crontab_tablename_param = t.add_parameter(
        Parameter(
            "CrontabTablename",
            Description="Crontab Table Name",
            Type="String",
        ))

    containerlauncher_param = t.add_parameter(
        Parameter(
            "Containerlauncher",
            Description=
            "Container Launcher zip file (default: containerLauncher-1.0.zip)",
            Type="String",
            Default="containerLauncher-1.0.zip"))

    zipfileversion_param = t.add_parameter(
        Parameter(
            "ZipfileVersion",
            Description="Container Launcher zip file version",
            Type="String",
        ))

    # --------- Lambda Container Launcher

    lambda_function = t.add_resource(
        Function(
            "containerLauncher",
            Code=Code(
                S3Bucket="hackathon-glueteam-lambda",
                S3Key=Ref(containerlauncher_param),
                S3ObjectVersion=Ref(zipfileversion_param),
            ),
            Description=Join('',
                             [Ref(stackname_param), " container Launcher"]),
            MemorySize=256,
            Handler="com.philips.glueteam.DockerLauncher::myHandler",
            Runtime="java8",
            Timeout=60,
            Role=Join('', [
                "arn:aws:iam::",
                Ref("AWS::AccountId"), ":role/",
                Ref(iam_role_param)
            ]),
        ))

    townclock_topic = t.add_resource(
        sns.Topic(
            "TownClock",
            Subscription=[
                sns.Subscription(Endpoint=GetAtt("containerLauncher", "Arn"),
                                 Protocol="lambda"),
            ],
        ))

    # --------- Scheduler instance

    scheduler_sg = t.add_resource(
        ec2.SecurityGroup(
            'SchedulerSG',
            GroupDescription='Security group for Scheduler host',
            VpcId=Ref(vpcid_param),
            Tags=Tags(Name=Join("", [Ref(stackname_param), "SchedulerSG"])),
            SecurityGroupIngress=[
                ec2.SecurityGroupRule(
                    IpProtocol="tcp",
                    FromPort="22",
                    ToPort="22",
                    CidrIp="0.0.0.0/0",
                ),
                ec2.SecurityGroupRule(
                    IpProtocol="tcp",
                    FromPort="8080",
                    ToPort="8080",
                    CidrIp="0.0.0.0/0",
                ),
            ]))

    cluster = t.add_resource(ecs.Cluster("ECSCluster", ))

    scheduler_host = t.add_resource(
        ec2.Instance(
            'SchedulerHost',
            ImageId=Ref(scheduler_ami_id_param),
            InstanceType='t2.micro',
            KeyName=Ref(keypair_param),
            IamInstanceProfile=Ref(iam_role_param),
            NetworkInterfaces=[
                ec2.NetworkInterfaceProperty(
                    AssociatePublicIpAddress=True,
                    SubnetId=Select(0, Ref(subnets)),
                    DeleteOnTermination=True,
                    GroupSet=[
                        Ref(scheduler_sg),
                    ],
                    DeviceIndex=0,
                ),
            ],
            Tags=Tags(Name=Join("", [Ref(stackname_param), "Scheduler"]),
                      Id=Join("", [Ref(stackname_param), "Scheduler"])),
            UserData=Base64(
                Join('', [
                    '#!/bin/bash\n',
                    'yum update -y aws-cfn-bootstrap\n',
                    'sns_topic_arn="',
                    Ref(townclock_topic),
                    '"\n',
                    'region="',
                    Ref("AWS::Region"),
                    '"\n',
                    'crontab_tablename="',
                    Ref(crontab_tablename_param),
                    '"\n',
                    'ecs_clustername="',
                    Ref(cluster),
                    '"\n',
                    'publish_source=https://raw.githubusercontent.com/hngkr/hackathon/master/ansible/files/unreliable-town-clock-publish\n',
                    'publish=/usr/local/bin/unreliable-town-clock-publish\n',
                    'curl -s --location --retry 10 -o $publish $publish_source\n',
                    'chmod +x $publish\n',
                    'cat <<EOF >/etc/cron.d/unreliable-town-clock\n',
                    '*/2 * * * * ec2-user $publish "$sns_topic_arn" "$region" "$crontab_tablename" "$ecs_clustername"\n',
                    'EOF\n',
                ])),
        ))

    cluster_sg = t.add_resource(
        ec2.SecurityGroup(
            'ClusterSG',
            GroupDescription='Security group for Cluster host',
            VpcId=Ref(vpcid_param),
            Tags=Tags(Name=Join("", [Ref(stackname_param), "ClusterSG"])),
            SecurityGroupIngress=[
                ec2.SecurityGroupRule(
                    IpProtocol="tcp",
                    FromPort="22",
                    ToPort="22",
                    CidrIp="0.0.0.0/0",
                ),
            ]))

    cluster_host = t.add_resource(
        ec2.Instance(
            'ClusterHost',
            ImageId=Ref(cluster_ami_id_param),
            InstanceType='t2.micro',
            KeyName=Ref(keypair_param),
            # TODO: Should have multiple separate iam roles for townclock / clusterhost
            IamInstanceProfile=Ref(iam_role_param),
            NetworkInterfaces=[
                ec2.NetworkInterfaceProperty(
                    AssociatePublicIpAddress=True,
                    SubnetId=Select(0, Ref(subnets)),
                    DeleteOnTermination=True,
                    GroupSet=[
                        Ref(cluster_sg),
                    ],
                    DeviceIndex=0,
                ),
            ],
            Tags=Tags(Name=Join("", [Ref(stackname_param), "ClusterNode"]),
                      Id=Join("", [Ref(stackname_param), "ClusterNode"])),
            UserData=Base64(
                Join('', [
                    '#!/bin/bash\n',
                    'mkdir /etc/ecs\n',
                    'cat <<EOF >/etc/ecs/ecs.config\n',
                    'ECS_CLUSTER=',
                    Ref(cluster),
                    '\n',
                    'EOF\n',
                ])),
        ))

    # --------- Expected DynamoDB Tables

    dirtylist_table = t.add_resource(
        dynamodb.Table(
            "DirtyList",
            AttributeDefinitions=[
                dynamodb.AttributeDefinition(Ref(hashkeyname_param), "S"),
            ],
            KeySchema=[dynamodb.Key(Ref(hashkeyname_param), "HASH")],
            ProvisionedThroughput=dynamodb.ProvisionedThroughput(1, 1)))

    runlog_table = t.add_resource(
        dynamodb.Table(
            "RunLog",
            AttributeDefinitions=[
                dynamodb.AttributeDefinition(Ref(hashkeyname_param), "S"),
            ],
            KeySchema=[dynamodb.Key(Ref(hashkeyname_param), "HASH")],
            ProvisionedThroughput=dynamodb.ProvisionedThroughput(1, 1)))

    # --------- Outputs
    t.add_output(
        [Output(
            "clusterid",
            Description="Cluster Id",
            Value=Ref(cluster),
        )])

    t.add_output([
        Output(
            "dirtylist",
            Description="DirtyList Tablename",
            Value=Ref(dirtylist_table),
        )
    ])

    t.add_output([
        Output(
            "runlog",
            Description="Runlog Tablename",
            Value=Ref(runlog_table),
        )
    ])

    t.add_output([
        Output(
            "lambdafunctionname",
            Description="Lambda Function Name",
            Value=Ref(lambda_function),
        )
    ])

    t.add_output([
        Output(
            "clocktowertopicarn",
            Description="Clock Tower Topic Arn",
            Value=Ref(townclock_topic),
        )
    ])

    return t
Пример #21
0
from troposphere import (
    Ref,
    sns,
)

sns_topic = sns.Topic("SNSTopic", )
subscription = sns.SubscriptionResource('SNSTopicSubscription',
                                        Protocol='email',
                                        Endpoint='*****@*****.**',
                                        TopicArn=Ref(sns_topic))
Пример #22
0
def generate_cf_template():
    """
    Returns an entire CloudFormation stack by using troposphere to construct
    each piece
    """
    # Header of CloudFormation template
    t = Template()
    t.add_version("2010-09-09")
    t.add_description("Lambda Chat AWS Resources")
    # Paramters
    description = "should match [0-9]+-[a-z0-9]+.apps.googleusercontent.com"
    google_oauth_client_id = t.add_parameter(Parameter(
        "GoogleOAuthClientID",
        AllowedPattern="[0-9]+-[a-z0-9]+.apps.googleusercontent.com",
        Type="String",
        Description="The Client ID of your Google project",
        ConstraintDescription=description
    ))

    website_s3_bucket_name = t.add_parameter(Parameter(
        "WebsiteS3BucketName",
        AllowedPattern="[a-zA-Z0-9\-]*",
        Type="String",
        Description="Name of S3 bucket to store the website in",
        ConstraintDescription="can contain only alphanumeric characters and dashes.",
    ))

    # The SNS topic the website will publish chat messages to
    website_sns_topic = t.add_resource(sns.Topic(
        'WebsiteSnsTopic',
        TopicName='lambda-chat',
        DisplayName='Lambda Chat'
    ))
    t.add_output(Output(
        "WebsiteSnsTopic",
        Description="sns_topic_arn",
        Value=Ref(website_sns_topic),
    ))

    # The IAM Role and Policy the website will assume to publish to SNS
    website_role = t.add_resource(iam.Role(
        "WebsiteRole",
        Path="/",
        AssumeRolePolicyDocument=Policy(
            Statement=[
                Statement(
                    Effect=Allow,
                    Action=[Action("sts", "AssumeRoleWithWebIdentity")],
                    Principal=Principal("Federated", "accounts.google.com"),
                    Condition=Condition(
                        StringEquals(
                            "accounts.google.com:aud",
                            Ref(google_oauth_client_id)
                        )
                    ),
                ),
            ],
        ),
    ))
    t.add_resource(iam.PolicyType(
        "WebsitePolicy",
        PolicyName="lambda-chat-website-policy",
        Roles=[Ref(website_role)],
        PolicyDocument=Policy(
            Version="2012-10-17",
            Statement=[
                Statement(
                    Effect=Allow,
                    Action=[Action("sns", "Publish")],
                    Resource=[
                        Ref(website_sns_topic)
                    ],
                ),
            ],
        )
    ))
    t.add_output(Output(
        "WebsiteRole",
        Description="website_iam_role_arn",
        Value=GetAtt(website_role, "Arn"),
    ))

    website_bucket = t.add_resource(s3.Bucket(
        'WebsiteS3Bucket',
        BucketName=Ref(website_s3_bucket_name),
        WebsiteConfiguration=s3.WebsiteConfiguration(
            ErrorDocument="error.html",
            IndexDocument="index.html"
        )
    ))
    t.add_output(Output(
        "S3Bucket",
        Description="s3_bucket",
        Value=Ref(website_bucket),
    ))
    t.add_resource(s3.BucketPolicy(
        'WebsiteS3BucketPolicy',
        Bucket=Ref(website_bucket),
        PolicyDocument={
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Sid": "PublicAccess",
                    "Effect": "Allow",
                    "Principal": "*",
                    "Action": ["s3:GetObject"],
                    "Resource": [{
                        "Fn::Join": [
                            "",
                            [
                                "arn:aws:s3:::",
                                {
                                    "Ref": "WebsiteS3Bucket",
                                },
                                "/*"
                            ]
                        ]
                    }]
                }
            ]
        }
    ))

    return t
Пример #23
0
                Action=[awacs.s3.GetBucketAcl],
                Resource=[Sub('arn:${AWS::Partition}:s3:::${ConfigBucket}')]),
            Statement(
                Sid='AWSConfigBucketDelivery',
                Effect=Allow,
                Principal=config_service_principal,
                Action=[awacs.s3.PutObject],
                Resource=[
                    Sub('arn:${AWS::Partition}:s3:::${ConfigBucket}/AWSLogs/${AWS::AccountId}/*'
                        )
                ])
        ])))

config_topic = template.add_resource(
    sns.Topic('ConfigTopic',
              TopicName=Sub('config-topic-${AWS::AccountId}'),
              DisplayName='AWS Config Notification Topic'))

config_topic_policy = template.add_resource(
    sns.TopicPolicy("ConfigTopicPolicy",
                    Topics=[Ref(config_topic)],
                    PolicyDocument=PolicyDocument(Statement=[
                        Statement(Sid='AWSConfigSNSPolicy',
                                  Action=[awacs.sns.Publish],
                                  Effect=Allow,
                                  Resource=Ref(config_topic),
                                  Principal=config_service_principal)
                    ])))

email_notification = template.add_resource(
    sns.SubscriptionResource('EmailNotification',
Пример #24
0
from troposphere import Template
from troposphere import sns

template = Template()

android = template.add_resource(
    sns.Topic('AndroidDevicesTopic',
              TopicName='devices-android'))

android_created = template.add_resource(
    sns.Topic('AndroidDevicesEndpointCreatedTopic',
              TopicName='devices-android-created'))

android_deleted = template.add_resource(
    sns.Topic('AndroidDevicesEndpointDeletedTopic',
              TopicName='devices-android-deleted'))

android_updated = template.add_resource(
    sns.Topic('AndroidDevicesEndpointUpdatedTopic',
              TopicName='devices-android-updated'))

android_delivery_failed = template.add_resource(
    sns.Topic('AndroidDevicesDeliveryFailedTopic',
              TopicName='devices-android-delivery-failed'))
def main():
    # TODO:
    # - SNS topic is probably not complete
    # - BuildCopyCFNProject Encryption keys
    # - build_copy_cfn_project, validate_resource_project TimeoutInMinutes property
    # - Lambda function execute permissions
    # - Build role GetBucketTagging permissions. Only used in build-env step, may be obsolete in other scenarios
    # - Add customer name to CodeCommit repositories
    # - What to do with the password of the codecommit user?
    # - InputArtifact is not used in pipeline
    # - buildspec.env in project definition itself
    # - CodeCommitUser Permissions on troporepo and CFNvalidaterepo only!

    # INIT section

    template = Template()
    projectName = "dummy-mytestrepo"

    # PARAMETERS section

    github_oauth_token_parameter = template.add_parameter(
        Parameter(
            "GithubOauthToken",
            Type="String",
            Description="Github OAuthToken",
            NoEcho=True,
        ))

    github_owner_parameter = template.add_parameter(
        Parameter(
            "GithubOwner",
            Type="String",
            Description="Github owner",
            Default="cta-int",
        ))

    github_branch_parameter = template.add_parameter(
        Parameter(
            "GithubBranch",
            Type="String",
            Description="Github branch",
            Default="master",
        ))

    github_repository_parameter = template.add_parameter(
        Parameter(
            "GithubRepository",
            Type="String",
            Description="Github repository",
            Default="aws-bootstrap",
        ))

    # RESOURCES section

    approve_topic = template.add_resource(
        sns.Topic("ApproveTopic",
                  Subscription=[
                      sns.Subscription(
                          Endpoint="*****@*****.**",
                          Protocol="email",
                      )
                  ]))

    artifact_store_s3_bucket = template.add_resource(
        s3.Bucket(
            "ArtifactStoreS3Bucket",
            AccessControl=s3.Private,
        ))

    # ROLES section

    cloud_formation_role = template.add_resource(
        iam.Role(
            "CloudFormationRole",
            AssumeRolePolicyDocument=Policy(
                Version="2012-10-17",
                Statement=[
                    Statement(Effect=Allow,
                              Principal=Principal(
                                  "Service", "cloudformation.amazonaws.com"),
                              Action=[Action("sts", "AssumeRole")])
                ]),
            Path="/",
            Policies=[
                iam.Policy(PolicyName="CloudFormationNestedCFNAccessPolicy",
                           PolicyDocument=Policy(Version="2012-10-17",
                                                 Statement=[
                                                     Statement(
                                                         Effect=Allow,
                                                         Action=[Action("*")],
                                                         Resource=["*"])
                                                 ]))
            ]))

    code_build_role = template.add_resource(
        iam.Role(
            "CodeBuildRole",
            AssumeRolePolicyDocument=Policy(
                Version="2012-10-17",
                Statement=[
                    Statement(
                        Effect=Allow,
                        Principal=Principal("Service",
                                            "codebuild.amazonaws.com"),
                        Action=[Action("sts", "AssumeRole")],
                    )
                ]),
            Path="/",
            Policies=[
                iam.Policy(
                    PolicyName="CodeBuildAccessPolicy",
                    PolicyDocument=Policy(
                        Version="2012-10-17",
                        Statement=[
                            Statement(
                                Effect=Allow,
                                Action=[
                                    Action("cloudformation", "Get*"),
                                    Action("cloudformation", "Describe*"),
                                    Action("cloudformation", "List*"),
                                ],
                                Resource=[
                                    Sub("arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${AWS::StackName}*"
                                        ),
                                ]),
                            Statement(Effect=Allow,
                                      Action=[
                                          Action("ec2", "Describe*"),
                                          Action("cloudformation",
                                                 "ValidateTemplate"),
                                          Action("elasticloadbalancing",
                                                 "Describe*"),
                                          Action("autoscaling", "Describe*"),
                                          Action("iam", "Get*"),
                                          Action("iam", "List*"),
                                          Action("logs", "Describe*"),
                                          Action("logs", "Get*"),
                                          Action("tag", "Get*"),
                                      ],
                                      Resource=["*"]),
                            Statement(
                                Effect=Allow,
                                Action=[
                                    Action("logs", "CreateLogGroup"),
                                    Action("logs", "CreateLogStream"),
                                    Action("logs", "PutLogEvents"),
                                ],
                                Resource=[
                                    Sub("arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/*"
                                        ),
                                ]),
                            Statement(Effect=Allow,
                                      Action=[
                                          Action("lambda", "ListFunctions"),
                                          Action("lambda", "InvokeFunction"),
                                      ],
                                      Resource=[
                                          "*",
                                      ]),
                            Statement(
                                Effect=Allow,
                                Action=[
                                    Action("s3",
                                           "PutObject"),
                                    Action("s3",
                                           "GetObject"),
                                    Action("s3",
                                           "GetObjectVersion"),
                                    Action("s3",
                                           "ListBucket"),
                                ],
                                Resource=[
                                    Sub("arn:aws:s3:::codepipeline-${AWS::Region}-*"
                                        ),
                                    GetAtt(artifact_store_s3_bucket, "Arn"),
                                    Join("", [
                                        GetAtt(artifact_store_s3_bucket,
                                               "Arn"), "/*"
                                    ]),
                                ]),
                            Statement(Effect=Allow,
                                      Action=[
                                          Action("s3", "GetBucketTagging"),
                                      ],
                                      Resource=[
                                          Sub("arn:aws:s3:::*"),
                                      ])
                        ]))
            ]))

    code_pipeline_role = template.add_resource(
        iam.Role(
            "CodePipelineRole",
            AssumeRolePolicyDocument=Policy(
                Version="2012-10-17",
                Statement=[
                    Statement(
                        Effect=Allow,
                        Principal=Principal("Service",
                                            "codepipeline.amazonaws.com"),
                        Action=[Action("sts", "AssumeRole")],
                    )
                ]),
            Path="/",
            Policies=[
                iam.Policy(
                    PolicyName="CodePipelineAccessPolicy",
                    PolicyDocument=Policy(
                        Version="2012-10-17",
                        Statement=[
                            Statement(Effect=Allow,
                                      Action=[Action("s3", "*")],
                                      Resource=[
                                          GetAtt(artifact_store_s3_bucket,
                                                 "Arn"),
                                          Join("", [
                                              GetAtt(artifact_store_s3_bucket,
                                                     "Arn"), "/*"
                                          ]),
                                      ]),
                            Statement(Effect=Allow,
                                      Action=[
                                          Action("sns", "Publish"),
                                      ],
                                      Resource=[
                                          Ref(approve_topic),
                                      ]),
                            Statement(
                                Effect=Allow,
                                Action=[
                                    Action("codebuild", "StartBuild"),
                                    Action("codebuild", "BatchGetBuilds"),
                                ],
                                Resource=[
                                    Sub("arn:aws:codebuild:${AWS::Region}:${AWS::AccountId}:project/codebuild-"
                                        + projectName),
                                ]),
                            Statement(Effect=Allow,
                                      Action=[
                                          Action("lambda", "ListFunctions"),
                                          Action("lambda", "InvokeFunction"),
                                      ],
                                      Resource=[
                                          "*",
                                      ]),
                            Statement(
                                Effect=Allow,
                                Action=[
                                    Action("iam", "PassRole"),
                                ],
                                Resource=[
                                    GetAtt(cloud_formation_role, "Arn"),
                                ],
                            )
                        ]))
            ]))

    code_build_dummy = template.add_resource(
        codebuild.Project(
            "CodeBuildDummy",
            Source=codebuild.Source(Type="CODEPIPELINE"),
            Artifacts=codebuild.Artifacts(Type="CODEPIPELINE"),
            Description="Generate cloudformation templates",
            Environment=codebuild.Environment(
                ComputeType='BUILD_GENERAL1_SMALL',
                Image='aws/codebuild/python:3.3.6',
                Type='LINUX_CONTAINER',
            ),
            Name="codebuild-" + projectName,
            ServiceRole=GetAtt(code_build_role, "Arn"),
        ))

    code_pipeline_dummy = template.add_resource(
        codepipeline.Pipeline(
            "CodePipelineDummy",
            Name="pipeline-" + projectName,
            RoleArn=GetAtt(code_pipeline_role, "Arn"),
            ArtifactStore=codepipeline.ArtifactStore(
                Type="S3",
                Location=Ref(artifact_store_s3_bucket),
            ),
            Stages=[
                codepipeline.Stages(
                    Name="Source",
                    Actions=[
                        codepipeline.Actions(
                            Name="Source",
                            ActionTypeId=codepipeline.ActionTypeID(
                                Category="Source",
                                Owner="ThirdParty",
                                Provider="GitHub",
                                Version="1",
                            ),
                            OutputArtifacts=[
                                codepipeline.OutputArtifacts(Name="Source", )
                            ],
                            Configuration={
                                "Branch": Ref(github_branch_parameter),
                                "Repo": Ref(github_repository_parameter),
                                "PollForSourceChanges": True,
                                "Owner": Ref(github_owner_parameter),
                                "OAuthToken":
                                Ref(github_oauth_token_parameter),
                            },
                            RunOrder="1",
                        ),
                    ]),
                codepipeline.Stages(
                    Name="Build",
                    Actions=[
                        codepipeline.Actions(
                            Name="Build",
                            ActionTypeId=codepipeline.ActionTypeID(
                                Category="Build",
                                Owner="AWS",
                                Provider="CodeBuild",
                                Version="1",
                            ),
                            InputArtifacts=[
                                codepipeline.InputArtifacts(Name="Source", )
                            ],
                            OutputArtifacts=[
                                codepipeline.OutputArtifacts(Name="Build", )
                            ],
                            Configuration={
                                "ProjectName": Ref(code_build_dummy),
                            },
                            RunOrder="1",
                        ),
                    ]),
                codepipeline.Stages(
                    Name="UAT",
                    Actions=[
                        codepipeline.Actions(
                            Name="CreateUATStack",
                            InputArtifacts=[
                                codepipeline.InputArtifacts(Name="Build", )
                            ],
                            ActionTypeId=codepipeline.ActionTypeID(
                                Category="Invoke",
                                Owner="AWS",
                                Version="1",
                                Provider="Lambda",
                            ),
                            Configuration={
                                "FunctionName":
                                "lambda-cfn-provider",
                                "UserParameters":
                                Sub(
                                    json.dumps({
                                        "ActionMode":
                                        "CREATE_UPDATE",
                                        "ConfigPath":
                                        "Build::config.json",
                                        "StackName":
                                        projectName + "-UAT",
                                        "TemplatePath":
                                        "Build::dummy.json",
                                    }))
                            },
                            OutputArtifacts=[
                                codepipeline.OutputArtifacts(
                                    Name="CreateUATStack", )
                            ],
                            RunOrder="1",
                        ),
                        codepipeline.Actions(
                            Name="CreatePRODChangeSet",
                            InputArtifacts=[
                                codepipeline.InputArtifacts(Name="Build", )
                            ],
                            ActionTypeId=codepipeline.ActionTypeID(
                                Category="Invoke",
                                Owner="AWS",
                                Version="1",
                                Provider="Lambda",
                            ),
                            Configuration={
                                "FunctionName":
                                "lambda-cfn-provider",
                                "UserParameters":
                                Sub(
                                    json.dumps({
                                        "ActionMode":
                                        "CHANGE_SET_REPLACE",
                                        "ChangeSetName":
                                        projectName + "-PROD-CHANGE-SET",
                                        "StackName":
                                        projectName + "-PROD",
                                        "TemplateConfiguration":
                                        "Build::config.json",
                                        "TemplatePath":
                                        "Build::dummy.json",
                                    }))
                            },
                            OutputArtifacts=[
                                codepipeline.OutputArtifacts(
                                    Name="CreatePRODChangeSet", )
                            ],
                            RunOrder="2",
                        ),
                    ]),
                codepipeline.Stages(
                    Name="PROD-ApproveChangeSet",
                    Actions=[
                        codepipeline.Actions(
                            Name="ApprovePRODChangeSet",
                            ActionTypeId=codepipeline.ActionTypeID(
                                Category="Approval",
                                Owner="AWS",
                                Version="1",
                                Provider="Manual",
                            ),
                            Configuration={
                                "NotificationArn": Ref(approve_topic),
                                "CustomData":
                                "Approve deployment in production.",
                            },
                            RunOrder="1",
                        ),
                    ]),
                codepipeline.Stages(
                    Name="PROD-ExecuteChangeSet",
                    Actions=[
                        codepipeline.Actions(
                            Name="ExecutePRODChangeSet",
                            InputArtifacts=[
                                codepipeline.InputArtifacts(Name="Build", )
                            ],
                            ActionTypeId=codepipeline.ActionTypeID(
                                Category="Invoke",
                                Owner="AWS",
                                Version="1",
                                Provider="Lambda",
                            ),
                            Configuration={
                                "FunctionName":
                                "lambda-cfn-provider",
                                "UserParameters":
                                Sub(
                                    json.dumps({
                                        "ActionMode":
                                        "CHANGE_SET_EXECUTE",
                                        "ChangeSetName":
                                        projectName + "-PROD-CHANGE-SET",
                                        "StackName":
                                        projectName + "-PROD",
                                    }))
                            },
                            OutputArtifacts=[
                                codepipeline.OutputArtifacts(
                                    Name="ExecutePRODChangeSet", )
                            ],
                            RunOrder="1",
                        ),
                    ]),
            ]))

    # OUTPUT section

    template.add_output([
        Output(
            "ArtifactStoreS3Bucket",
            Description=
            "ResourceName of the S3 bucket containg the artifacts of the pipeline(s)",
            Value=Ref(artifact_store_s3_bucket),
            Export=Export(projectName + "-ArtifactS3Bucket"),
        ),
        Output(
            "ArtifactStoreS3BucketArn",
            Description=
            "Arn of the S3 bucket containg the artifacts of the pipeline(s)",
            Value=GetAtt(artifact_store_s3_bucket, "Arn"),
            Export=Export(projectName + "-ArtifactS3BucketArn"),
        ),
        Output(
            "CodeBuildRole",
            Description=
            "Logical name of the role that is used by the CodeBuild projects in the CodePipeline",
            Value=Ref(code_build_role),
            Export=Export(projectName + "-CodeBuildRole"),
        ),
        Output(
            "CloudFormationRoleArn",
            Description=
            "Arn of the S3 bucket containing the artifacts of the pipeline(s)",
            Value=GetAtt(cloud_formation_role, "Arn"),
            Export=Export(projectName + "-CloudFormationRoleArn"),
        ),
        Output(
            "CodePipelineRoleArn",
            Description=
            "Logical name of the role that is used by the CodePipeline",
            Value=GetAtt(code_pipeline_role, "Arn"),
            Export=Export(projectName + "-CodePipelineRoleArn"),
        )
    ])

    print(template.to_json())
Пример #26
0
from troposphere import sns

bucket_updates_topic = sns.Topic("BucketUpdatesTopic")
def get_template(version: str, default_region_value) -> t.Template:
    description = f"""Bootstrap template used to bootstrap a region of ServiceCatalog-Puppet master
{{"version": "{version}", "framework": "servicecatalog-puppet", "role": "bootstrap-master-region"}}"""

    template = t.Template(Description=description)

    version_parameter = template.add_parameter(
        t.Parameter("Version", Default=version, Type="String")
    )
    default_region_value_parameter = template.add_parameter(
        t.Parameter("DefaultRegionValue", Default=default_region_value, Type="String")
    )

    template.add_resource(
        ssm.Parameter(
            "DefaultRegionParam",
            Name="/servicecatalog-puppet/home-region",
            Type="String",
            Value=t.Ref(default_region_value_parameter),
            Tags={"ServiceCatalogPuppet:Actor": "Framework"},
        )
    )
    version_ssm_parameter = template.add_resource(
        ssm.Parameter(
            "Param",
            Name="service-catalog-puppet-regional-version",
            Type="String",
            Value=t.Ref(version_parameter),
            Tags={"ServiceCatalogPuppet:Actor": "Framework"},
        )
    )

    template.add_resource(
        s3.Bucket(
            "PipelineArtifactBucket",
            BucketName=t.Sub(
                "sc-puppet-pipeline-artifacts-${AWS::AccountId}-${AWS::Region}"
            ),
            VersioningConfiguration=s3.VersioningConfiguration(Status="Enabled"),
            BucketEncryption=s3.BucketEncryption(
                ServerSideEncryptionConfiguration=[
                    s3.ServerSideEncryptionRule(
                        ServerSideEncryptionByDefault=s3.ServerSideEncryptionByDefault(
                            SSEAlgorithm="AES256"
                        )
                    )
                ]
            ),
            PublicAccessBlockConfiguration=s3.PublicAccessBlockConfiguration(
                BlockPublicAcls=True,
                BlockPublicPolicy=True,
                IgnorePublicAcls=True,
                RestrictPublicBuckets=True,
            ),
            Tags=t.Tags({"ServiceCatalogPuppet:Actor": "Framework"}),
        )
    )

    regional_product_topic = template.add_resource(
        sns.Topic(
            "RegionalProductTopic",
            DisplayName="servicecatalog-puppet-cloudformation-regional-events",
            TopicName="servicecatalog-puppet-cloudformation-regional-events",
            Subscription=[
                sns.Subscription(
                    Endpoint=t.Sub(
                        "arn:${AWS::Partition}:sqs:${DefaultRegionValue}:${AWS::AccountId}:servicecatalog-puppet-cloudformation-events"
                    ),
                    Protocol="sqs",
                )
            ],
        ),
    )

    template.add_output(
        t.Output("Version", Value=t.GetAtt(version_ssm_parameter, "Value"))
    )
    template.add_output(
        t.Output("RegionalProductTopic", Value=t.Ref(regional_product_topic))
    )

    return template