Exemple #1
0
    def _default_lambda_role(self):
        lambda_trust_policy = make_simple_assume_policy('lambda.amazonaws.com')

        return self._add(
            r.aws_iam_role(self.titled('role'),
                           name=self.env_titled('role'),
                           assume_role_policy=lambda_trust_policy.to_json()))
Exemple #2
0
    def _get_replicated_lambda_state_machine_role(
        self,
        remover_function,  # type: Dict[str, Union[awslambda.Function, iam.Role, Any]] # noqa pylint: disable=line-too-long
        self_destruct_function  # type: Dict[str, Union[awslambda.Function, iam.Role, Any]] # noqa pylint: disable=line-too-long
    ):
        # type (...) -> iam.Role
        entity = Join('.', ['states', Region, 'amazonaws.com'])

        return self.template.add_resource(
            iam.Role(
                'StateMachineRole',
                AssumeRolePolicyDocument=make_simple_assume_policy(entity),
                Policies=[
                    iam.Policy(
                        PolicyName="InvokeLambda",
                        PolicyDocument=PolicyDocument(
                            Version="2012-10-17",
                            Statement=[
                                Statement(
                                    Action=[awacs.awslambda.InvokeFunction],
                                    Effect=Allow,
                                    Resource=[
                                        remover_function.get_att('Arn'),
                                        self_destruct_function.get_att('Arn')
                                    ])
                            ]))
                ]))
Exemple #3
0
    def add_lambda_execution_role(
            self,
            name='LambdaExecutionRole',  # type: str
            function_name=''  # type: str
    ):  # noqa: E124
        # type: (...) -> iam.Role
        """Create the Lambda@Edge execution role."""
        variables = self.get_variables()

        lambda_resource = Join('', [
            'arn:', Partition, ':logs:*:', AccountId,
            ':log-group:/aws/lambda/', StackName,
            '-%s-*' % function_name
        ])

        edge_resource = Join('', [
            'arn:',
            Partition,
            ':logs:*:',
            AccountId,
            ':log-group:/aws/lambda/*.',
            StackName,
            '-%s-*' % function_name,
        ])

        return self.template.add_resource(
            iam.Role(
                name,
                AssumeRolePolicyDocument=make_simple_assume_policy(
                    'lambda.amazonaws.com', 'edgelambda.amazonaws.com'),
                PermissionsBoundary=(variables['RoleBoundaryArn']
                                     if self.role_boundary_specified else
                                     NoValue),
                Policies=[
                    iam.Policy(PolicyName="LambdaLogCreation",
                               PolicyDocument=PolicyDocument(
                                   Version='2012-10-17',
                                   Statement=[
                                       Statement(Action=[
                                           awacs.logs.CreateLogGroup,
                                           awacs.logs.CreateLogStream,
                                           awacs.logs.PutLogEvents
                                       ],
                                                 Effect=Allow,
                                                 Resource=[
                                                     lambda_resource,
                                                     edge_resource
                                                 ])
                                   ])),
                ],
            ))
Exemple #4
0
    def _get_replicated_lambda_state_machine_role(
        self,
        remover_function,  # type: Dict[str, Union[awslambda.Function, iam.Role, Any]]
        self_destruct_function,  # type: Dict[str, Union[awslambda.Function, iam.Role, Any]]
    ):
        # type (...) -> iam.Role
        variables = self.get_variables()
        entity = Join(".", ["states", Region, "amazonaws.com"])

        return self.template.add_resource(
            iam.Role(
                "StateMachineRole",
                AssumeRolePolicyDocument=make_simple_assume_policy(entity),
                PermissionsBoundary=(
                    variables["RoleBoundaryArn"]
                    if self.role_boundary_specified
                    else NoValue
                ),
                Policies=[
                    iam.Policy(
                        PolicyName="InvokeLambda",
                        PolicyDocument=PolicyDocument(
                            Version="2012-10-17",
                            Statement=[
                                Statement(
                                    Action=[awacs.awslambda.InvokeFunction],
                                    Effect=Allow,
                                    Resource=[
                                        remover_function.get_att("Arn"),
                                        self_destruct_function.get_att("Arn"),
                                    ],
                                )
                            ],
                        ),
                    )
                ],
            )
        )
Exemple #5
0
    def _get_replicated_lambda_state_machine_role(self,
                                                  remover_function,  # type: Dict[str, Union[awslambda.Function, iam.Role, Any]] # noqa pylint: disable=line-too-long
                                                  self_destruct_function # type: Dict[str, Union[awslambda.Function, iam.Role, Any]] # noqa pylint: disable=line-too-long
                                                  # TODO remove after dropping python 2
                                                  ):  # pylint: disable=bad-continuation
        # type (...) -> iam.Role
        variables = self.get_variables()
        entity = Join('.', ['states', Region, 'amazonaws.com'])

        return self.template.add_resource(
            iam.Role(
                'StateMachineRole',
                AssumeRolePolicyDocument=make_simple_assume_policy(entity),
                PermissionsBoundary=(
                    variables['RoleBoundaryArn'] if self.role_boundary_specified
                    else NoValue
                ),
                Policies=[
                    iam.Policy(
                        PolicyName="InvokeLambda",
                        PolicyDocument=PolicyDocument(
                            Version="2012-10-17",
                            Statement=[
                                Statement(
                                    Action=[awacs.awslambda.InvokeFunction],
                                    Effect=Allow,
                                    Resource=[
                                        remover_function.get_att('Arn'),
                                        self_destruct_function.get_att('Arn')
                                    ]
                                )
                            ]
                        )
                    )
                ]
            )
        )
Exemple #6
0
    def create_template(self):
        """Create template (main function called by Stacker)."""
        template = self.template
        # variables = self.get_variables()
        template.add_version('2010-09-09')
        template.add_description('Kubernetes IAM policies - V1.0.0')

        # Resources
        nodeinstancerole = template.add_resource(
            iam.Role(
                'NodeInstanceRole',
                AssumeRolePolicyDocument=make_simple_assume_policy(
                    'ec2.amazonaws.com'),
                ManagedPolicyArns=[
                    IAM_POLICY_ARN_PREFIX + i for i in [
                        'AmazonEKSWorkerNodePolicy',
                        'AmazonEKS_CNI_Policy',
                        'AmazonEC2ContainerRegistryReadOnly',
                        # SSM agent not shipped ootb
                        # 'AmazonSSMManagedInstanceCore'
                    ]
                ]))
        template.add_output(
            Output('NodeInstanceRole',
                   Description='The node instance role name',
                   Value=nodeinstancerole.ref()))
        template.add_output(
            Output('NodeInstanceRoleArn',
                   Description='The node instance role ARN',
                   Value=nodeinstancerole.get_att('Arn')))

        nodeinstanceprofile = template.add_resource(
            iam.InstanceProfile('NodeInstanceProfile',
                                Path='/',
                                Roles=[nodeinstancerole.ref()]))
        template.add_output(
            Output('NodeInstanceProfile',
                   Description='The node instance profile',
                   Value=nodeinstanceprofile.ref()))
        template.add_output(
            Output('NodeInstanceProfileArn',
                   Description='The node instance profile ARN',
                   Value=nodeinstanceprofile.get_att('Arn')))

        template.add_resource(
            iam.Role(
                'ClusterAutoScalerInstanceRole',
                AssumeRolePolicyDocument=make_simple_assume_policy(
                    'ec2.amazonaws.com'),
                Policies=[
                    iam.Policy(
                        PolicyName='cluster-autoscaler',
                        PolicyDocument=PolicyDocument(
                            Version='2012-10-17',
                            Statement=[
                                Statement(
                                    Action=[
                                        awacs.autoscaling.
                                        DescribeAutoScalingGroups,  # noqa
                                        awacs.autoscaling.
                                        DescribeAutoScalingInstances,  # noqa
                                        awacs.autoscaling.DescribeTags,
                                        awacs.autoscaling.
                                        SetDesiredCapacity,  # noqa
                                        awacs.autoscaling.
                                        TerminateInstanceInAutoScalingGroup
                                    ],  # noqa pylint: disable=line-too-long
                                    Effect=Allow,
                                    Resource=['*'])
                            ]))
                ]))
Exemple #7
0
        def add_test_resources(test_name):
            """Add the resources for the given test."""
            codebuild_role = template.add_resource(
                iam.Role(
                    "CodeBuildRole{}".format(test_name),
                    AssumeRolePolicyDocument=make_simple_assume_policy(
                        "codebuild.amazonaws.com"),
                    Policies=IAM_POLICY_BUILDER.build(test_name),
                ))

            template.add_resource(
                codebuild.Project(
                    f"RunwayIntegrationTest{test_name}",
                    Artifacts=codebuild.Artifacts(Type="NO_ARTIFACTS"),
                    Description=f"{test_name} runway integration tests",
                    Environment=codebuild.Environment(
                        ComputeType="BUILD_GENERAL1_SMALL",
                        EnvironmentVariables=[
                            codebuild.EnvironmentVariable(
                                Name="DEPLOY_ENVIRONMENT",
                                Type="PLAINTEXT",
                                Value=variables["EnvironmentName"].ref,
                            ),
                            codebuild.EnvironmentVariable(
                                Name="TEST_TO_RUN",
                                Type="PLAINTEXT",
                                Value=test_name.lower(),
                            ),
                            codebuild.EnvironmentVariable(
                                # Disable emojis in output.
                                Name="PIPENV_HIDE_EMOJIS",
                                Type="PLAINTEXT",
                                Value="1",
                            ),
                            codebuild.EnvironmentVariable(
                                # disable terminal spinner.
                                Name="PIPENV_NOSPIN",
                                Type="PLAINTEXT",
                                Value="1",
                            ),
                            codebuild.EnvironmentVariable(
                                # Pipenv automatically assumes “yes” at all prompts.
                                Name="PIPENV_YES",
                                Type="PLAINTEXT",
                                Value="1",
                            ),
                        ],
                        Image="aws/codebuild/standard:2.0",
                        Type="LINUX_CONTAINER",
                    ),
                    Name=f"runway-int-test-{test_name}",
                    ServiceRole=codebuild_role.get_att("Arn"),
                    Source=codebuild.Source(
                        Type="GITHUB", Location=variables["GitHubUrl"].ref),
                    Triggers=codebuild.ProjectTriggers(
                        Webhook=True,
                        FilterGroups=[[
                            codebuild.WebhookFilter(
                                Type="ACTOR_ACCOUNT_ID",
                                Pattern="|".join(
                                    str(x) for x in GITHUB_ACCOUNT_IDS),
                            ),
                            codebuild.WebhookFilter(
                                Type="EVENT",
                                Pattern="PULL_REQUEST_CREATED,"
                                "PULL_REQUEST_UPDATED,"
                                "PULL_REQUEST_REOPENED",
                            ),
                            codebuild.WebhookFilter(
                                Type="BASE_REF",
                                Pattern="^refs/heads/release$"),
                            codebuild.WebhookFilter(
                                Type="HEAD_REF",
                                Pattern="^refs/heads/master$"),
                        ]],
                    ),
                ))
Exemple #8
0
    def create_template(self):
        """Create template (main function called by Stacker)."""
        template = self.template
        variables = self.get_variables()
        template.add_version('2010-09-09')
        template.add_description('Kubernetes Master via EKS - V1.0.0')

        # Resources
        ccpsecuritygroup = template.add_resource(
            ec2.SecurityGroup(
                'ClusterControlPlaneSecurityGroup',
                GroupDescription='Cluster communication with worker nodes',
                Tags=[
                    {'Key': Sub('kubernetes.io/cluster/${EksClusterName}'),
                     'Value': 'owned'},
                    {'Key': 'Product',
                     'Value': 'Kubernetes'},
                    {'Key': 'Project',
                     'Value': 'eks'},
                    {'Key': 'Name',
                     'Value': Sub('${EksClusterName}-sg-worker-nodes')}
                ],
                VpcId=variables['VPC'].ref
            )
        )
        template.add_output(
            Output(
                ccpsecuritygroup.title,
                Description='Cluster communication with worker nodes',
                Export=Export(
                    Sub('${AWS::StackName}-ControlPlaneSecurityGroup')
                ),
                Value=ccpsecuritygroup.ref()
            )
        )

        eksservicerole = template.add_resource(
            iam.Role(
                'EksServiceRole',
                AssumeRolePolicyDocument=make_simple_assume_policy(
                    'eks.amazonaws.com'
                ),
                ManagedPolicyArns=[
                    IAM_POLICY_ARN_PREFIX + i for i in [
                        'AmazonEKSClusterPolicy',
                        'AmazonEKSServicePolicy'
                    ]
                ],
                Policies=[
                    iam.Policy(
                        PolicyName='EksServiceRolePolicy',
                        PolicyDocument=PolicyDocument(
                            Statement=[
                                Statement(
                                    Action=[awacs.iam.CreateServiceLinkedRole,
                                            awacs.iam.PutRolePolicy],
                                    Condition=Condition(
                                        StringLike(
                                            'iam:AWSServiceName',
                                            'elasticloadbalancing.amazonaws.com'  # noqa
                                        )
                                    ),
                                    Effect=Allow,
                                    Resource=[
                                        Sub('arn:aws:iam::${AWS::AccountId}:role/'  # noqa
                                            'aws-service-role/'
                                            'elasticloadbalancing.amazonaws.com/'  # noqa
                                            'AWSServiceRoleForElasticLoadBalancing*')  # noqa
                                    ]
                                )
                            ]
                        )
                    )
                ]
            )
        )

        ekscluster = template.add_resource(
            eks.Cluster(
                'EksCluster',
                Name=variables['EksClusterName'].ref,
                Version=variables['EksVersion'].ref,
                RoleArn=eksservicerole.get_att('Arn'),
                ResourcesVpcConfig=eks.ResourcesVpcConfig(
                    SecurityGroupIds=[ccpsecuritygroup.ref()],
                    SubnetIds=variables['EksSubnets'].ref
                )
            )
        )
        template.add_output(
            Output(
                "%sName" % ekscluster.title,
                Description='EKS Cluster Name',
                Export=Export(
                    Sub("${AWS::StackName}-%sName" % ekscluster.title)
                ),
                Value=ekscluster.ref()
            )
        )
        template.add_output(
            Output(
                "%sEndpoint" % ekscluster.title,
                Description='EKS Cluster Endpoint',
                Export=Export(
                    Sub("${AWS::StackName}-%sEndpoint" % ekscluster.title)
                ),
                Value=ekscluster.get_att('Endpoint')
            )
        )

        # Additional Outputs
        template.add_output(
            Output(
                'VpcId',
                Description='EKS Cluster VPC Id',
                Export=Export(
                    Sub('${AWS::StackName}-VpcId')
                ),
                Value=variables['VPC'].ref
            )
        )
        template.add_output(
            Output(
                'Subnets',
                Description='EKS Cluster Subnets',
                Export=Export(
                    Sub('${AWS::StackName}-Subnets')
                ),
                Value=Join(',', variables['EksSubnets'].ref)
            )
        )
Exemple #9
0
def get_application_autoscaling_assumerole_policy(region=''):
    """ Helper function for building the AWS Lambda AssumeRole Policy"""
    service = make_service_domain_name('application-autoscaling', region)
    return make_simple_assume_policy(service)
Exemple #10
0
    def add_lambda_execution_role(self,
                                  name: str = "LambdaExecutionRole",
                                  function_name: str = "") -> iam.Role:
        """Create the Lambda@Edge execution role.

        Args:
            name: Name for the Lambda Execution Role.
            function_name: Name of the Lambda Function the Role will be
                attached to.

        """
        lambda_resource = Join(
            "",
            [
                "arn:",
                Partition,
                ":logs:*:",
                AccountId,
                ":log-group:/aws/lambda/",
                StackName,
                "-%s-*" % function_name,
            ],
        )

        edge_resource = Join(
            "",
            [
                "arn:",
                Partition,
                ":logs:*:",
                AccountId,
                ":log-group:/aws/lambda/*.",
                StackName,
                "-%s-*" % function_name,
            ],
        )

        return self.template.add_resource(
            iam.Role(
                name,
                AssumeRolePolicyDocument=make_simple_assume_policy(
                    "lambda.amazonaws.com", "edgelambda.amazonaws.com"),
                PermissionsBoundary=(self.variables["RoleBoundaryArn"]
                                     if self.role_boundary_specified else
                                     NoValue),
                Policies=[
                    iam.Policy(
                        PolicyName="LambdaLogCreation",
                        PolicyDocument=PolicyDocument(
                            Version="2012-10-17",
                            Statement=[
                                Statement(
                                    Action=[
                                        awacs.logs.CreateLogGroup,
                                        awacs.logs.CreateLogStream,
                                        awacs.logs.PutLogEvents,
                                    ],
                                    Effect=Allow,
                                    Resource=[lambda_resource, edge_resource],
                                )
                            ],
                        ),
                    ),
                ],
            ))
Exemple #11
0
    def _get_replicated_lambda_remover_lambda(self):
        # type: () -> Dict[str, Any]
        res = {}
        variables = self.get_variables()
        res["role"] = self.template.add_resource(
            iam.Role(
                "ReplicatedLambdaRemoverRole",
                AssumeRolePolicyDocument=make_simple_assume_policy(
                    "lambda.amazonaws.com"
                ),
                PermissionsBoundary=(
                    variables["RoleBoundaryArn"]
                    if self.role_boundary_specified
                    else NoValue
                ),
                Policies=[
                    iam.Policy(
                        PolicyName="LambdaLogCreation",
                        PolicyDocument=PolicyDocument(
                            Version="2012-10-17",
                            Statement=[
                                Statement(
                                    Action=[
                                        awacs.logs.CreateLogGroup,
                                        awacs.logs.CreateLogStream,
                                        awacs.logs.PutLogEvents,
                                    ],
                                    Effect=Allow,
                                    Resource=[
                                        Join(
                                            "",
                                            [
                                                "arn:",
                                                Partition,
                                                ":logs:*:",
                                                AccountId,
                                                ":log-group:/aws/lambda/",
                                                StackName,
                                                "-ReplicatedLambdaRemover-*",
                                            ],
                                        )
                                    ],
                                )
                            ],
                        ),
                    ),
                    iam.Policy(
                        PolicyName="DeleteLambda",
                        PolicyDocument=PolicyDocument(
                            Version="2012-10-17",
                            Statement=[
                                Statement(
                                    Action=[awacs.awslambda.DeleteFunction],
                                    Effect=Allow,
                                    Resource=self.get_variables()["function_arns"],
                                )
                            ],
                        ),
                    ),
                ],
            )
        )

        self.template.add_output(
            Output(
                "ReplicatedLambdaRemoverRole",
                Description="The name of the Replicated Lambda Remover Role",
                Value=res["role"].ref(),
            )
        )

        res["function"] = self.template.add_resource(
            awslambda.Function(
                "ReplicatedLambdaRemover",
                Code=awslambda.Code(
                    ZipFile=read_value_from_path(
                        "file://"
                        + os.path.join(
                            os.path.dirname(__file__),
                            "templates/replicated_lambda_remover.template.py",
                        )
                    )
                ),
                Description="Checks for Replicated Lambdas created during the main stack and "
                "deletes them when they are ready.",
                Handler="index.handler",
                Role=res["role"].get_att("Arn"),
                Runtime="python3.7",
            )
        )

        self.template.add_output(
            Output(
                "ReplicatedLambdaRemoverArn",
                Description="The ARN of the Replicated Function",
                Value=res["function"].get_att("Arn"),
            )
        )

        return res
Exemple #12
0
    def _get_self_destruct(self, replicated_lambda_remover):
        # type: (Dict[str, Union[awslambda.Function, Any]]) -> Dict[str, Any]
        res = {}
        variables = self.get_variables()

        res["role"] = self.template.add_resource(
            iam.Role(
                "SelfDestructRole",
                AssumeRolePolicyDocument=make_simple_assume_policy(
                    "lambda.amazonaws.com"
                ),
                PermissionsBoundary=(
                    variables["RoleBoundaryArn"]
                    if self.role_boundary_specified
                    else NoValue
                ),
                Policies=[
                    iam.Policy(
                        PolicyName="LambdaLogCreation",
                        PolicyDocument=PolicyDocument(
                            Version="2012-10-17",
                            Statement=[
                                Statement(
                                    Action=[
                                        awacs.logs.CreateLogGroup,
                                        awacs.logs.CreateLogStream,
                                        awacs.logs.PutLogEvents,
                                    ],
                                    Effect=Allow,
                                    Resource=[
                                        Join(
                                            "",
                                            [
                                                "arn:",
                                                Partition,
                                                ":logs:*:",
                                                AccountId,
                                                ":log-group:/aws/lambda/",
                                                StackName,
                                                "-SelfDestruct-*",
                                            ],
                                        )
                                    ],
                                )
                            ],
                        ),
                    ),
                    iam.Policy(
                        PolicyName="DeleteStateMachine",
                        PolicyDocument=PolicyDocument(
                            Version="2012-10-17",
                            Statement=[
                                Statement(
                                    Action=[awacs.states.DeleteStateMachine],
                                    Effect=Allow,
                                    Resource=[
                                        # StateMachine
                                        Join(
                                            "",
                                            [
                                                "arn:",
                                                Partition,
                                                ":states:",
                                                Region,
                                                ":",
                                                AccountId,
                                                ":stateMachine:StaticSiteCleanup-",
                                                variables["stack_name"],
                                            ],
                                        )
                                    ],
                                )
                            ],
                        ),
                    ),
                    iam.Policy(
                        PolicyName="DeleteRolesAndPolicies",
                        PolicyDocument=PolicyDocument(
                            Version="2012-10-17",
                            Statement=[
                                Statement(
                                    Action=[
                                        awacs.iam.DeleteRolePolicy,
                                        awacs.iam.DeleteRole,
                                    ],
                                    Effect=Allow,
                                    Resource=[
                                        Join(
                                            "",
                                            [
                                                "arn:",
                                                Partition,
                                                ":iam::",
                                                AccountId,
                                                ":role/",
                                                StackName,
                                                "-*",
                                            ],
                                        ),
                                    ],
                                )
                            ],
                        ),
                    ),
                    iam.Policy(
                        PolicyName="DeleteLambdas",
                        PolicyDocument=PolicyDocument(
                            Version="2012-10-17",
                            Statement=[
                                Statement(
                                    Action=[awacs.awslambda.DeleteFunction],
                                    Effect=Allow,
                                    Resource=[
                                        Join(
                                            "",
                                            [
                                                "arn:",
                                                Partition,
                                                ":lambda:",
                                                Region,
                                                ":",
                                                AccountId,
                                                ":function:%s-SelfDestruct-*"
                                                % (variables["stack_name"]),
                                            ],
                                        ),
                                        replicated_lambda_remover["function"].get_att(
                                            "Arn"
                                        ),
                                    ],
                                )
                            ],
                        ),
                    ),
                    iam.Policy(
                        PolicyName="DeleteStack",
                        PolicyDocument=PolicyDocument(
                            Version="2012-10-17",
                            Statement=[
                                Statement(
                                    Action=[awacs.cloudformation.DeleteStack],
                                    Effect=Allow,
                                    Resource=[
                                        Join(
                                            "",
                                            [
                                                "arn:",
                                                Partition,
                                                ":cloudformation:",
                                                Region,
                                                ":",
                                                AccountId,
                                                ":stack/%s/*"
                                                % (variables["stack_name"]),
                                            ],
                                        )
                                    ],
                                )
                            ],
                        ),
                    ),
                ],
            )
        )

        self.template.add_output(
            Output(
                "SelfDestructLambdaRole",
                Description="The name of the Self Destruct Role",
                Value=res["role"].ref(),
            )
        )

        res["function"] = self.template.add_resource(
            awslambda.Function(
                "SelfDestruct",
                Code=awslambda.Code(
                    ZipFile=read_value_from_path(
                        "file://"
                        + os.path.join(
                            os.path.dirname(__file__),
                            "templates/self_destruct.template.py",
                        )
                    )
                ),
                Description="Issues a Delete Stack command to the Cleanup stack",
                Handler="index.handler",
                Role=res["role"].get_att("Arn"),
                Runtime="python3.7",
            )
        )

        self.template.add_output(
            Output(
                "SelfDestructLambdaArn",
                Description="The ARN of the Replicated Function",
                Value=res["function"].get_att("Arn"),
            )
        )

        return res
Exemple #13
0
 def get_role(self, service_name):
     service = '{0}.amazonaws.com'.format(service_name)
     return trust.make_simple_assume_policy(service)
Exemple #14
0
    def create_template(self):
        """Create template (main function called by Stacker)."""
        template = self.template
        variables = self.get_variables()
        template.set_version('2010-09-09')
        template.set_description('Runway CodeBuild Project')

        # Resources
        deploy_name_list = [
            'runway-integration-tests-', variables['EnvironmentName'].ref
        ]

        # This must match what is in the the Terraform
        # integration tests. This corresponds to the template listed in
        # integration_tests\test_terraform\tf_state.cfn
        test_suite_prefix = 'testsuite-tf-state'
        codebuild_role = template.add_resource(
            iam.Role(
                'CodeBuildRole',
                AssumeRolePolicyDocument=make_simple_assume_policy(
                    'codebuild.amazonaws.com'),
                # todo: drop this broad access in favor of more narrow
                # permissions (will mean identifying all the needed
                # permissions across all tests)
                ManagedPolicyArns=[
                    'arn:aws:iam::aws:policy/AdministratorAccess'
                ],
                Policies=[
                    iam.Policy(
                        PolicyName=Join('', deploy_name_list + ['-policy']),
                        PolicyDocument=PolicyDocument(
                            Version='2012-10-17',
                            Statement=[
                                Statement(Action=[
                                    awacs.logs.CreateLogGroup,
                                    awacs.logs.CreateLogStream,
                                    awacs.logs.PutLogEvents
                                ],
                                          Effect=Allow,
                                          Resource=[
                                              Join('', [
                                                  'arn:', Partition, ':logs:',
                                                  Region, ':', AccountId,
                                                  ':log-group:/aws/codebuild/'
                                              ] + deploy_name_list + ['*'] + x)
                                              for x in [[':*'], [':*/*']]
                                          ]),
                                Statement(
                                    Action=[awacs.sts.AssumeRole],
                                    Effect=Allow,
                                    Resource=[
                                        Join(
                                            '',
                                            [
                                                'arn:',
                                                Partition,
                                                ':iam::',
                                                ALT_TESTING_ACCOUNT_ID,
                                                ':role/runway-integration-test-role-',  # noqa
                                                variables['EnvironmentName'].
                                                ref
                                            ])
                                    ]),
                                Statement(
                                    Action=[Action('cloudformation', '*')],
                                    Effect=Allow,
                                    Resource=[
                                        Join(':', [
                                            'arn', Partition, 'cloudformation',
                                            Region, AccountId,
                                            Sub('stack/${prefix}/*',
                                                {'prefix': test_suite_prefix})
                                        ])
                                    ]),
                                Statement(
                                    Action=[Action('dynamodb', '*')],
                                    Effect=Allow,
                                    Resource=[
                                        Join(':', [
                                            'arn', Partition, 'dynamodb',
                                            Region, AccountId,
                                            Sub('table/${prefix}-*',
                                                {'prefix': test_suite_prefix})
                                        ])
                                    ]),
                                Statement(
                                    Action=[Action('s3',
                                                   '*')],
                                    Effect=Allow,
                                    Resource=[
                                        Join(':', [
                                            'arn', Partition,
                                            Sub('s3:::${prefix}',
                                                {'prefix': test_suite_prefix})
                                        ]),
                                        Join(':', [
                                            'arn', Partition,
                                            Sub('s3:::${prefix}/*',
                                                {'prefix': test_suite_prefix})
                                        ])
                                    ]),
                                Statement(
                                    Action=[Action('sqs', '*')],
                                    Effect=Allow,
                                    Resource=[
                                        Join(':', [
                                            'arn', Partition, 'sqs', Region,
                                            AccountId, 'terraform-*'
                                        ])
                                    ])
                            ]))
                ]))

        template.add_resource(
            codebuild.Project(
                'RunwayIntegrationTests',
                Artifacts=codebuild.Artifacts(Type='NO_ARTIFACTS'),
                Environment=codebuild.Environment(
                    ComputeType='BUILD_GENERAL1_SMALL',
                    EnvironmentVariables=[
                        codebuild.EnvironmentVariable(Name='CI',
                                                      Type='PLAINTEXT',
                                                      Value='1'),
                        codebuild.EnvironmentVariable(
                            Name='DEPLOY_ENVIRONMENT',
                            Type='PLAINTEXT',
                            Value=variables['EnvironmentName'].ref)
                    ],
                    Image='aws/codebuild/standard:2.0',
                    Type='LINUX_CONTAINER'),
                Name=Join('', deploy_name_list),
                ServiceRole=codebuild_role.get_att('Arn'),
                Source=codebuild.Source(Type='GITHUB',
                                        Location=variables['GitHubUrl'].ref),
                Triggers=codebuild.ProjectTriggers(
                    Webhook=True,
                    FilterGroups=[[
                        codebuild.WebhookFilter(
                            Type='ACTOR_ACCOUNT_ID',
                            Pattern='|'.join(
                                str(x) for x in GITHUB_ACCOUNT_IDS)),
                        codebuild.WebhookFilter(
                            Type='EVENT',
                            Pattern=
                            'PULL_REQUEST_CREATED,PULL_REQUEST_UPDATED,PULL_REQUEST_REOPENED'  # noqa
                        ),
                        codebuild.WebhookFilter(
                            Type='BASE_REF', Pattern='^refs/heads/release$'),
                        codebuild.WebhookFilter(Type='HEAD_REF',
                                                Pattern='^refs/heads/master$')
                    ]])))
Exemple #15
0
    def create_template(self):
        """Create template (main function called by Stacker)."""
        template = self.template
        variables = self.get_variables()
        template.set_version('2010-09-09')
        template.set_description('App - Build Pipeline')

        # Resources
        boundary_arn = Join('', [
            'arn:', Partition, ':iam::', AccountId, ':policy/',
            variables['RolePermissionsBoundaryName'].ref
        ])

        # Repo image limit is 1000 by default; this lambda function will prune
        # old images
        image_param_path = Join(
            '', ['/', variables['AppPrefix'].ref, '/current-hash'])
        image_param_arn = Join('', [
            'arn:', Partition, ':ssm:', Region, ':', AccountId, ':parameter',
            image_param_path
        ])
        ecr_repo_arn = Join('', [
            'arn:', Partition, ':ecr:', Region, ':', AccountId, ':repository/',
            variables['EcrRepoName'].ref
        ])
        cleanuplambdarole = template.add_resource(
            iam.Role('CleanupLambdaRole',
                     AssumeRolePolicyDocument=make_simple_assume_policy(
                         'lambda.amazonaws.com'),
                     ManagedPolicyArns=[
                         IAM_ARN_PREFIX + 'AWSLambdaBasicExecutionRole'
                     ],
                     PermissionsBoundary=boundary_arn,
                     Policies=[
                         iam.Policy(
                             PolicyName=Join(
                                 '',
                                 [variables['AppPrefix'].ref, '-ecrcleanup']),
                             PolicyDocument=PolicyDocument(
                                 Version='2012-10-17',
                                 Statement=[
                                     Statement(Action=[awacs.ssm.GetParameter],
                                               Effect=Allow,
                                               Resource=[image_param_arn]),
                                     Statement(Action=[
                                         awacs.ecr.DescribeImages,
                                         awacs.ecr.BatchDeleteImage
                                     ],
                                               Effect=Allow,
                                               Resource=[ecr_repo_arn])
                                 ]))
                     ]))
        cleanupfunction = template.add_resource(
            awslambda.Function(
                'CleanupFunction',
                Description='Cleanup stale ECR images',
                Code=awslambda.Code(
                    ZipFile=variables['ECRCleanupLambdaFunction']),
                Environment=awslambda.Environment(
                    Variables={
                        'ECR_REPO_NAME': variables['EcrRepoName'].ref,
                        'SSM_PARAM': image_param_path
                    }),
                Handler='index.handler',
                Role=cleanuplambdarole.get_att('Arn'),
                Runtime='python3.6',
                Timeout=120))
        cleanuprule = template.add_resource(
            events.Rule('CleanupRule',
                        Description='Regularly invoke CleanupFunction',
                        ScheduleExpression='rate(7 days)',
                        State='ENABLED',
                        Targets=[
                            events.Target(Arn=cleanupfunction.get_att('Arn'),
                                          Id='CleanupFunction')
                        ]))
        template.add_resource(
            awslambda.Permission(
                'AllowCWLambdaInvocation',
                FunctionName=cleanupfunction.ref(),
                Action=awacs.awslambda.InvokeFunction.JSONrepr(),
                Principal='events.amazonaws.com',
                SourceArn=cleanuprule.get_att('Arn')))

        appsource = template.add_resource(
            codecommit.Repository(
                'AppSource',
                RepositoryName=Join('-',
                                    [variables['AppPrefix'].ref, 'source'])))
        for i in ['Name', 'Arn']:
            template.add_output(
                Output("AppRepo%s" % i,
                       Description="%s of app source repo" % i,
                       Value=appsource.get_att(i)))

        bucket = template.add_resource(
            s3.Bucket(
                'Bucket',
                AccessControl=s3.Private,
                LifecycleConfiguration=s3.LifecycleConfiguration(Rules=[
                    s3.LifecycleRule(NoncurrentVersionExpirationInDays=90,
                                     Status='Enabled')
                ]),
                VersioningConfiguration=s3.VersioningConfiguration(
                    Status='Enabled')))
        template.add_output(
            Output('PipelineBucketName',
                   Description='Name of pipeline bucket',
                   Value=bucket.ref()))

        # This list must be kept in sync between the CodeBuild project and its
        # role
        build_name = Join('', [variables['AppPrefix'].ref, '-build'])

        build_role = template.add_resource(
            iam.Role(
                'BuildRole',
                AssumeRolePolicyDocument=make_simple_assume_policy(
                    'codebuild.amazonaws.com'),
                PermissionsBoundary=boundary_arn,
                Policies=[
                    iam.Policy(
                        PolicyName=Join('', [build_name, '-policy']),
                        PolicyDocument=PolicyDocument(
                            Version='2012-10-17',
                            Statement=[
                                Statement(
                                    Action=[awacs.s3.GetObject],
                                    Effect=Allow,
                                    Resource=[
                                        Join('', [bucket.get_att('Arn'), '/*'])
                                    ]),
                                Statement(
                                    Action=[awacs.ecr.GetAuthorizationToken],
                                    Effect=Allow,
                                    Resource=['*']),
                                Statement(Action=[
                                    awacs.ecr.BatchCheckLayerAvailability,
                                    awacs.ecr.BatchGetImage,
                                    awacs.ecr.CompleteLayerUpload,
                                    awacs.ecr.DescribeImages,
                                    awacs.ecr.GetDownloadUrlForLayer,
                                    awacs.ecr.InitiateLayerUpload,
                                    awacs.ecr.PutImage,
                                    awacs.ecr.UploadLayerPart
                                ],
                                          Effect=Allow,
                                          Resource=[ecr_repo_arn]),
                                Statement(Action=[
                                    awacs.ssm.GetParameter,
                                    awacs.ssm.PutParameter
                                ],
                                          Effect=Allow,
                                          Resource=[image_param_arn]),
                                Statement(Action=[
                                    awacs.logs.CreateLogGroup,
                                    awacs.logs.CreateLogStream,
                                    awacs.logs.PutLogEvents
                                ],
                                          Effect=Allow,
                                          Resource=[
                                              Join('', [
                                                  'arn:', Partition, ':logs:',
                                                  Region, ':', AccountId,
                                                  ':log-group:/aws/codebuild/',
                                                  build_name
                                              ] + x)
                                              for x in [[':*'], [':*/*']]
                                          ])
                            ]))
                ]))

        buildproject = template.add_resource(
            codebuild.Project(
                'BuildProject',
                Artifacts=codebuild.Artifacts(Type='CODEPIPELINE'),
                Environment=codebuild.Environment(
                    ComputeType='BUILD_GENERAL1_SMALL',
                    EnvironmentVariables=[
                        codebuild.EnvironmentVariable(
                            Name='AWS_DEFAULT_REGION',
                            Type='PLAINTEXT',
                            Value=Region),
                        codebuild.EnvironmentVariable(Name='AWS_ACCOUNT_ID',
                                                      Type='PLAINTEXT',
                                                      Value=AccountId),
                        codebuild.EnvironmentVariable(
                            Name='IMAGE_REPO_NAME',
                            Type='PLAINTEXT',
                            Value=variables['EcrRepoName'].ref),
                    ],
                    Image='aws/codebuild/docker:18.09.0',
                    Type='LINUX_CONTAINER'),
                Name=build_name,
                ServiceRole=build_role.get_att('Arn'),
                Source=codebuild.Source(
                    Type='CODEPIPELINE',
                    BuildSpec=variables['BuildProjectBuildSpec'])))

        pipelinerole = template.add_resource(
            iam.Role(
                'PipelineRole',
                AssumeRolePolicyDocument=make_simple_assume_policy(
                    'codepipeline.amazonaws.com'),
                PermissionsBoundary=boundary_arn,
                Policies=[
                    iam.Policy(
                        PolicyName=Join('', [build_name, '-pipeline-policy']),
                        PolicyDocument=PolicyDocument(
                            Version='2012-10-17',
                            Statement=[
                                Statement(
                                    Action=[
                                        awacs.codecommit.GetBranch,
                                        awacs.codecommit.GetCommit,
                                        awacs.codecommit.UploadArchive,
                                        awacs.codecommit.
                                        GetUploadArchiveStatus,  # noqa
                                        awacs.codecommit.CancelUploadArchive
                                    ],  # noqa
                                    Effect=Allow,
                                    Resource=[appsource.get_att('Arn')]),
                                Statement(
                                    Action=[awacs.s3.GetBucketVersioning],
                                    Effect=Allow,
                                    Resource=[bucket.get_att('Arn')]),
                                Statement(
                                    Action=[
                                        awacs.s3.GetObject, awacs.s3.PutObject
                                    ],
                                    Effect=Allow,
                                    Resource=[
                                        Join('', [bucket.get_att('Arn'), '/*'])
                                    ]),
                                Statement(
                                    Action=[
                                        awacs.codebuild.BatchGetBuilds,
                                        awacs.codebuild.StartBuild
                                    ],
                                    Effect=Allow,
                                    Resource=[buildproject.get_att('Arn')])
                            ]))
                ]))

        template.add_resource(
            codepipeline.Pipeline(
                'Pipeline',
                ArtifactStore=codepipeline.ArtifactStore(Location=bucket.ref(),
                                                         Type='S3'),
                Name=build_name,
                RoleArn=pipelinerole.get_att('Arn'),
                Stages=[
                    codepipeline.Stages(
                        Name='Source',
                        Actions=[
                            codepipeline.Actions(
                                Name='CodeCommit',
                                ActionTypeId=codepipeline.ActionTypeId(
                                    Category='Source',
                                    Owner='AWS',
                                    Provider='CodeCommit',
                                    Version='1'),
                                Configuration={
                                    'RepositoryName':
                                    appsource.get_att('Name'),  # noqa
                                    'BranchName': 'master'
                                },
                                OutputArtifacts=[
                                    codepipeline.OutputArtifacts(
                                        Name='CodeCommitRepo')
                                ]),
                        ]),
                    codepipeline.Stages(
                        Name='Build',
                        Actions=[
                            codepipeline.Actions(
                                Name='Build',
                                ActionTypeId=codepipeline.ActionTypeId(
                                    Category='Build',
                                    Owner='AWS',
                                    Provider='CodeBuild',
                                    Version='1'),
                                Configuration={
                                    'ProjectName': buildproject.ref()
                                },
                                InputArtifacts=[
                                    codepipeline.InputArtifacts(
                                        Name='CodeCommitRepo')
                                ])
                        ])
                ]))
 def _allow_assume_role_service(self, service_name):
     # make_simple_assume_policy does not add a version number,
     # so this is a wrapper that injects the version string.
     policy = make_simple_assume_policy('%s.amazonaws.com' % service_name, )
     policy.Version = '2012-10-17'
     return policy
Exemple #17
0
    def create_template(self):
        """Create template (main function called by Stacker)."""
        template = self.template
        variables = self.get_variables()
        template.add_version("2010-09-09")
        template.add_description("Kubernetes Master via EKS - V1.0.0")

        # Resources
        ccpsecuritygroup = template.add_resource(
            ec2.SecurityGroup(
                "ClusterControlPlaneSecurityGroup",
                GroupDescription="Cluster communication with worker nodes",
                Tags=[
                    {
                        "Key": Sub("kubernetes.io/cluster/${EksClusterName}"),
                        "Value": "owned",
                    },
                    {
                        "Key": "Product",
                        "Value": "Kubernetes"
                    },
                    {
                        "Key": "Project",
                        "Value": "eks"
                    },
                    {
                        "Key": "Name",
                        "Value": Sub("${EksClusterName}-sg-worker-nodes")
                    },
                ],
                VpcId=variables["VPC"].ref,
            ))
        template.add_output(
            Output(
                ccpsecuritygroup.title,
                Description="Cluster communication with worker nodes",
                Export=Export(
                    Sub("${AWS::StackName}-ControlPlaneSecurityGroup")),
                Value=ccpsecuritygroup.ref(),
            ))

        eksservicerole = template.add_resource(
            iam.Role(
                "EksServiceRole",
                AssumeRolePolicyDocument=make_simple_assume_policy(
                    "eks.amazonaws.com"),
                ManagedPolicyArns=[
                    IAM_POLICY_ARN_PREFIX + "AmazonEKSClusterPolicy"
                ],
                Policies=[
                    iam.Policy(
                        PolicyName="EksServiceRolePolicy",
                        PolicyDocument=PolicyDocument(Statement=[
                            Statement(
                                Action=[
                                    awacs.iam.CreateServiceLinkedRole,
                                    awacs.iam.PutRolePolicy,
                                ],
                                Condition=Condition(
                                    StringLike(
                                        "iam:AWSServiceName",
                                        "elasticloadbalancing.amazonaws.com",
                                    )),
                                Effect=Allow,
                                Resource=[
                                    Sub("arn:aws:iam::${AWS::AccountId}:role/"
                                        "aws-service-role/"
                                        "elasticloadbalancing.amazonaws.com/"
                                        "AWSServiceRoleForElasticLoadBalancing*"
                                        )
                                ],
                            )
                        ]),
                    )
                ],
            ))

        ekscluster = template.add_resource(
            eks.Cluster(
                "EksCluster",
                Name=variables["EksClusterName"].ref,
                Version=variables["EksVersion"].ref,
                RoleArn=eksservicerole.get_att("Arn"),
                ResourcesVpcConfig=eks.ResourcesVpcConfig(
                    SecurityGroupIds=[ccpsecuritygroup.ref()],
                    SubnetIds=variables["EksSubnets"].ref,
                ),
            ))
        template.add_output(
            Output(
                "%sName" % ekscluster.title,
                Description="EKS Cluster Name",
                Export=Export(
                    Sub("${AWS::StackName}-%sName" % ekscluster.title)),
                Value=ekscluster.ref(),
            ))
        template.add_output(
            Output(
                "%sEndpoint" % ekscluster.title,
                Description="EKS Cluster Endpoint",
                Export=Export(
                    Sub("${AWS::StackName}-%sEndpoint" % ekscluster.title)),
                Value=ekscluster.get_att("Endpoint"),
            ))

        # Additional Outputs
        template.add_output(
            Output(
                "VpcId",
                Description="EKS Cluster VPC Id",
                Export=Export(Sub("${AWS::StackName}-VpcId")),
                Value=variables["VPC"].ref,
            ))
        template.add_output(
            Output(
                "Subnets",
                Description="EKS Cluster Subnets",
                Export=Export(Sub("${AWS::StackName}-Subnets")),
                Value=Join(",", variables["EksSubnets"].ref),
            ))
Exemple #18
0
 def _allow_assume_role_service(self, service_name):
     policy = make_simple_assume_policy(
         '%s.amazonaws.com' % service_name,
     )
     policy.Version = '2012-10-17'
     return policy
Exemple #19
0
    def _get_self_destruct(self, replicated_lambda_remover):
        # type: (Dict[str, Union[awslambda.Function, Any]]) -> Dict[str, Any]
        res = {}
        variables = self.get_variables()

        res['role'] = self.template.add_resource(
            iam.Role(
                'SelfDestructRole',
                AssumeRolePolicyDocument=make_simple_assume_policy(
                    'lambda.amazonaws.com'),
                Policies=[
                    iam.Policy(PolicyName="LambdaLogCreation",
                               PolicyDocument=PolicyDocument(
                                   Version='2012-10-17',
                                   Statement=[
                                       Statement(
                                           Action=[
                                               awacs.logs.CreateLogGroup,
                                               awacs.logs.CreateLogStream,
                                               awacs.logs.PutLogEvents
                                           ],
                                           Effect=Allow,
                                           Resource=[
                                               Join('', [
                                                   'arn:', Partition,
                                                   ':logs:*:', AccountId,
                                                   ':log-group:/aws/lambda/',
                                                   StackName, '-SelfDestruct-*'
                                               ])
                                           ])
                                   ])),
                    iam.Policy(
                        PolicyName="DeleteStateMachine",
                        PolicyDocument=PolicyDocument(
                            Version="2012-10-17",
                            Statement=[
                                Statement(
                                    Action=[awacs.states.DeleteStateMachine],
                                    Effect=Allow,
                                    Resource=[
                                        # StateMachine
                                        Join('', [
                                            'arn:', Partition, ':states:',
                                            Region, ':', AccountId,
                                            ':stateMachine:StaticSiteCleanup-',
                                            variables['stack_name']
                                        ])
                                    ])
                            ])),
                    iam.Policy(PolicyName="DeleteRolesAndPolicies",
                               PolicyDocument=PolicyDocument(
                                   Version="2012-10-17",
                                   Statement=[
                                       Statement(
                                           Action=[
                                               awacs.iam.DeleteRolePolicy,
                                               awacs.iam.DeleteRole
                                           ],
                                           Effect=Allow,
                                           Resource=[
                                               Join('', [
                                                   'arn:', Partition, ':iam::',
                                                   AccountId, ':role/',
                                                   StackName, '-*'
                                               ]),
                                           ])
                                   ])),
                    iam.Policy(
                        PolicyName="DeleteLambdas",
                        PolicyDocument=PolicyDocument(
                            Version="2012-10-17",
                            Statement=[
                                Statement(
                                    Action=[awacs.awslambda.DeleteFunction],
                                    Effect=Allow,
                                    Resource=[
                                        Join('', [
                                            'arn:', Partition, ':lambda:',
                                            Region, ':', AccountId,
                                            ':function:%s-SelfDestruct-*' %
                                            (variables['stack_name'])
                                        ]),
                                        replicated_lambda_remover['function'].
                                        get_att('Arn')
                                    ])
                            ])),
                    iam.Policy(
                        PolicyName="DeleteStack",
                        PolicyDocument=PolicyDocument(
                            Version="2012-10-17",
                            Statement=[
                                Statement(
                                    Action=[awacs.cloudformation.DeleteStack],
                                    Effect=Allow,
                                    Resource=[
                                        Join('', [
                                            'arn:', Partition,
                                            ':cloudformation:', Region, ':',
                                            AccountId,
                                            ':stack/%s/*' %
                                            (variables['stack_name'])
                                        ])
                                    ])
                            ]))
                ],
            ))

        self.template.add_output(
            Output('SelfDestructLambdaRole',
                   Description='The name of the Self Destruct Role',
                   Value=res['role'].ref()))

        res['function'] = self.template.add_resource(
            awslambda.Function(
                'SelfDestruct',
                Code=awslambda.Code(ZipFile=read_value_from_path(
                    'file://' +
                    os.path.join(os.path.dirname(__file__),
                                 'templates/self_destruct.template.py'))),
                Description=
                "Issues a Delete Stack command to the Cleanup stack",
                Handler='index.handler',
                Role=res['role'].get_att('Arn'),
                Runtime='python3.7'))

        self.template.add_output(
            Output('SelfDestructLambdaArn',
                   Description='The ARN of the Replicated Function',
                   Value=res['function'].get_att('Arn')))

        return res
Exemple #20
0
    def create_template(self):
        """Create template (main function called by Stacker)."""
        template = self.template
        # variables = self.get_variables()
        template.add_version("2010-09-09")
        template.add_description("Kubernetes IAM policies - V1.0.0")

        # Resources
        nodeinstancerole = template.add_resource(
            iam.Role(
                "NodeInstanceRole",
                AssumeRolePolicyDocument=make_simple_assume_policy("ec2.amazonaws.com"),
                ManagedPolicyArns=[
                    IAM_POLICY_ARN_PREFIX + i
                    for i in [
                        "AmazonEKSWorkerNodePolicy",
                        "AmazonEKS_CNI_Policy",
                        "AmazonEC2ContainerRegistryReadOnly",
                        # SSM agent not shipped ootb
                        # 'AmazonSSMManagedInstanceCore'
                    ]
                ],
            )
        )
        template.add_output(
            Output(
                "NodeInstanceRole",
                Description="The node instance role name",
                Value=nodeinstancerole.ref(),
            )
        )
        template.add_output(
            Output(
                "NodeInstanceRoleArn",
                Description="The node instance role ARN",
                Value=nodeinstancerole.get_att("Arn"),
            )
        )

        nodeinstanceprofile = template.add_resource(
            iam.InstanceProfile(
                "NodeInstanceProfile", Path="/", Roles=[nodeinstancerole.ref()]
            )
        )
        template.add_output(
            Output(
                "NodeInstanceProfile",
                Description="The node instance profile",
                Value=nodeinstanceprofile.ref(),
            )
        )
        template.add_output(
            Output(
                "NodeInstanceProfileArn",
                Description="The node instance profile ARN",
                Value=nodeinstanceprofile.get_att("Arn"),
            )
        )

        template.add_resource(
            iam.Role(
                "ClusterAutoScalerInstanceRole",
                AssumeRolePolicyDocument=make_simple_assume_policy("ec2.amazonaws.com"),
                Policies=[
                    iam.Policy(
                        PolicyName="cluster-autoscaler",
                        PolicyDocument=PolicyDocument(
                            Version="2012-10-17",
                            Statement=[
                                Statement(
                                    Action=[
                                        awacs.autoscaling.DescribeAutoScalingGroups,
                                        awacs.autoscaling.DescribeAutoScalingInstances,
                                        awacs.autoscaling.DescribeTags,
                                        awacs.autoscaling.SetDesiredCapacity,
                                        awacs.autoscaling.TerminateInstanceInAutoScalingGroup,
                                    ],
                                    Effect=Allow,
                                    Resource=["*"],
                                )
                            ],
                        ),
                    )
                ],
            )
        )
Exemple #21
0
    def _get_replicated_lambda_remover_lambda(self):
        # type: () -> Dict[str, Any]
        res = {}
        res['role'] = self.template.add_resource(
            iam.Role(
                'ReplicatedLambdaRemoverRole',
                AssumeRolePolicyDocument=make_simple_assume_policy(
                    'lambda.amazonaws.com'),
                Policies=[
                    iam.Policy(PolicyName="LambdaLogCreation",
                               PolicyDocument=PolicyDocument(
                                   Version='2012-10-17',
                                   Statement=[
                                       Statement(
                                           Action=[
                                               awacs.logs.CreateLogGroup,
                                               awacs.logs.CreateLogStream,
                                               awacs.logs.PutLogEvents
                                           ],
                                           Effect=Allow,
                                           Resource=[
                                               Join('', [
                                                   'arn:', Partition,
                                                   ':logs:*:', AccountId,
                                                   ':log-group:/aws/lambda/',
                                                   StackName,
                                                   '-ReplicatedLambdaRemover-*'
                                               ])
                                           ])
                                   ])),
                    iam.Policy(PolicyName="DeleteLambda",
                               PolicyDocument=PolicyDocument(
                                   Version="2012-10-17",
                                   Statement=[
                                       Statement(Action=[
                                           awacs.awslambda.DeleteFunction
                                       ],
                                                 Effect=Allow,
                                                 Resource=self.get_variables()
                                                 ['function_arns'])
                                   ]))
                ],
            ))

        self.template.add_output(
            Output(
                'ReplicatedLambdaRemoverRole',
                Description='The name of the Replicated Lambda Remover Role',
                Value=res['role'].ref()))

        res['function'] = self.template.add_resource(
            awslambda.Function(
                'ReplicatedLambdaRemover',
                Code=awslambda.Code(
                    ZipFile=read_value_from_path('file://' + os.path.join(
                        os.path.dirname(__file__),
                        'templates/replicated_lambda_remover.template.py'))),
                Description=
                "Checks for Replicated Lambdas created during the main stack and "
                "deletes them when they are ready.",
                Handler='index.handler',
                Role=res['role'].get_att('Arn'),
                Runtime='python3.7'))

        self.template.add_output(
            Output('ReplicatedLambdaRemoverArn',
                   Description='The ARN of the Replicated Function',
                   Value=res['function'].get_att('Arn')))

        return res
Exemple #22
0
    def create_template(self):
        """Create template (main function called by Stacker)."""
        template = self.template
        variables = self.get_variables()
        template.set_version("2010-09-09")
        template.set_description("App - Build Pipeline")

        # Resources
        boundary_arn = Join(
            "",
            [
                "arn:",
                Partition,
                ":iam::",
                AccountId,
                ":policy/",
                variables["RolePermissionsBoundaryName"].ref,
            ],
        )

        # Repo image limit is 1000 by default; this lambda function will prune
        # old images
        image_param_path = Join("", ["/", variables["AppPrefix"].ref, "/current-hash"])
        image_param_arn = Join(
            "",
            [
                "arn:",
                Partition,
                ":ssm:",
                Region,
                ":",
                AccountId,
                ":parameter",
                image_param_path,
            ],
        )
        ecr_repo_arn = Join(
            "",
            [
                "arn:",
                Partition,
                ":ecr:",
                Region,
                ":",
                AccountId,
                ":repository/",
                variables["EcrRepoName"].ref,
            ],
        )
        cleanuplambdarole = template.add_resource(
            iam.Role(
                "CleanupLambdaRole",
                AssumeRolePolicyDocument=make_simple_assume_policy(
                    "lambda.amazonaws.com"
                ),
                ManagedPolicyArns=[IAM_ARN_PREFIX + "AWSLambdaBasicExecutionRole"],
                PermissionsBoundary=boundary_arn,
                Policies=[
                    iam.Policy(
                        PolicyName=Join(
                            "", [variables["AppPrefix"].ref, "-ecrcleanup"]
                        ),
                        PolicyDocument=PolicyDocument(
                            Version="2012-10-17",
                            Statement=[
                                Statement(
                                    Action=[awacs.ssm.GetParameter],
                                    Effect=Allow,
                                    Resource=[image_param_arn],
                                ),
                                Statement(
                                    Action=[
                                        awacs.ecr.DescribeImages,
                                        awacs.ecr.BatchDeleteImage,
                                    ],
                                    Effect=Allow,
                                    Resource=[ecr_repo_arn],
                                ),
                            ],
                        ),
                    )
                ],
            )
        )
        cleanupfunction = template.add_resource(
            awslambda.Function(
                "CleanupFunction",
                Description="Cleanup stale ECR images",
                Code=awslambda.Code(ZipFile=variables["ECRCleanupLambdaFunction"]),
                Environment=awslambda.Environment(
                    Variables={
                        "ECR_REPO_NAME": variables["EcrRepoName"].ref,
                        "SSM_PARAM": image_param_path,
                    }
                ),
                Handler="index.handler",
                Role=cleanuplambdarole.get_att("Arn"),
                Runtime="python3.6",
                Timeout=120,
            )
        )
        cleanuprule = template.add_resource(
            events.Rule(
                "CleanupRule",
                Description="Regularly invoke CleanupFunction",
                ScheduleExpression="rate(7 days)",
                State="ENABLED",
                Targets=[
                    events.Target(
                        Arn=cleanupfunction.get_att("Arn"), Id="CleanupFunction"
                    )
                ],
            )
        )
        template.add_resource(
            awslambda.Permission(
                "AllowCWLambdaInvocation",
                FunctionName=cleanupfunction.ref(),
                Action=awacs.awslambda.InvokeFunction.JSONrepr(),
                Principal="events.amazonaws.com",
                SourceArn=cleanuprule.get_att("Arn"),
            )
        )

        appsource = template.add_resource(
            codecommit.Repository(
                "AppSource",
                RepositoryName=Join("-", [variables["AppPrefix"].ref, "source"]),
            )
        )
        for i in ["Name", "Arn"]:
            template.add_output(
                Output(
                    "AppRepo%s" % i,
                    Description="%s of app source repo" % i,
                    Value=appsource.get_att(i),
                )
            )

        bucket = template.add_resource(
            s3.Bucket(
                "Bucket",
                AccessControl=s3.Private,
                LifecycleConfiguration=s3.LifecycleConfiguration(
                    Rules=[
                        s3.LifecycleRule(
                            NoncurrentVersionExpirationInDays=90, Status="Enabled"
                        )
                    ]
                ),
                VersioningConfiguration=s3.VersioningConfiguration(Status="Enabled"),
            )
        )
        template.add_output(
            Output(
                "PipelineBucketName",
                Description="Name of pipeline bucket",
                Value=bucket.ref(),
            )
        )

        # This list must be kept in sync between the CodeBuild project and its
        # role
        build_name = Join("", [variables["AppPrefix"].ref, "-build"])

        build_role = template.add_resource(
            iam.Role(
                "BuildRole",
                AssumeRolePolicyDocument=make_simple_assume_policy(
                    "codebuild.amazonaws.com"
                ),
                PermissionsBoundary=boundary_arn,
                Policies=[
                    iam.Policy(
                        PolicyName=Join("", [build_name, "-policy"]),
                        PolicyDocument=PolicyDocument(
                            Version="2012-10-17",
                            Statement=[
                                Statement(
                                    Action=[awacs.s3.GetObject],
                                    Effect=Allow,
                                    Resource=[Join("", [bucket.get_att("Arn"), "/*"])],
                                ),
                                Statement(
                                    Action=[awacs.ecr.GetAuthorizationToken],
                                    Effect=Allow,
                                    Resource=["*"],
                                ),
                                Statement(
                                    Action=[
                                        awacs.ecr.BatchCheckLayerAvailability,
                                        awacs.ecr.BatchGetImage,
                                        awacs.ecr.CompleteLayerUpload,
                                        awacs.ecr.DescribeImages,
                                        awacs.ecr.GetDownloadUrlForLayer,
                                        awacs.ecr.InitiateLayerUpload,
                                        awacs.ecr.PutImage,
                                        awacs.ecr.UploadLayerPart,
                                    ],
                                    Effect=Allow,
                                    Resource=[ecr_repo_arn],
                                ),
                                Statement(
                                    Action=[
                                        awacs.ssm.GetParameter,
                                        awacs.ssm.PutParameter,
                                    ],
                                    Effect=Allow,
                                    Resource=[image_param_arn],
                                ),
                                Statement(
                                    Action=[
                                        awacs.logs.CreateLogGroup,
                                        awacs.logs.CreateLogStream,
                                        awacs.logs.PutLogEvents,
                                    ],
                                    Effect=Allow,
                                    Resource=[
                                        Join(
                                            "",
                                            [
                                                "arn:",
                                                Partition,
                                                ":logs:",
                                                Region,
                                                ":",
                                                AccountId,
                                                ":log-group:/aws/codebuild/",
                                                build_name,
                                            ]
                                            + x,
                                        )
                                        for x in [[":*"], [":*/*"]]
                                    ],
                                ),
                            ],
                        ),
                    )
                ],
            )
        )

        buildproject = template.add_resource(
            codebuild.Project(
                "BuildProject",
                Artifacts=codebuild.Artifacts(Type="CODEPIPELINE"),
                Environment=codebuild.Environment(
                    ComputeType="BUILD_GENERAL1_SMALL",
                    EnvironmentVariables=[
                        codebuild.EnvironmentVariable(
                            Name="AWS_DEFAULT_REGION", Type="PLAINTEXT", Value=Region
                        ),
                        codebuild.EnvironmentVariable(
                            Name="AWS_ACCOUNT_ID", Type="PLAINTEXT", Value=AccountId
                        ),
                        codebuild.EnvironmentVariable(
                            Name="IMAGE_REPO_NAME",
                            Type="PLAINTEXT",
                            Value=variables["EcrRepoName"].ref,
                        ),
                    ],
                    Image="aws/codebuild/docker:18.09.0",
                    Type="LINUX_CONTAINER",
                ),
                Name=build_name,
                ServiceRole=build_role.get_att("Arn"),
                Source=codebuild.Source(
                    Type="CODEPIPELINE", BuildSpec=variables["BuildProjectBuildSpec"]
                ),
            )
        )

        pipelinerole = template.add_resource(
            iam.Role(
                "PipelineRole",
                AssumeRolePolicyDocument=make_simple_assume_policy(
                    "codepipeline.amazonaws.com"
                ),
                PermissionsBoundary=boundary_arn,
                Policies=[
                    iam.Policy(
                        PolicyName=Join("", [build_name, "-pipeline-policy"]),
                        PolicyDocument=PolicyDocument(
                            Version="2012-10-17",
                            Statement=[
                                Statement(
                                    Action=[
                                        awacs.codecommit.GetBranch,
                                        awacs.codecommit.GetCommit,
                                        awacs.codecommit.UploadArchive,
                                        awacs.codecommit.GetUploadArchiveStatus,  # noqa
                                        awacs.codecommit.CancelUploadArchive,
                                    ],  # noqa
                                    Effect=Allow,
                                    Resource=[appsource.get_att("Arn")],
                                ),
                                Statement(
                                    Action=[awacs.s3.GetBucketVersioning],
                                    Effect=Allow,
                                    Resource=[bucket.get_att("Arn")],
                                ),
                                Statement(
                                    Action=[awacs.s3.GetObject, awacs.s3.PutObject],
                                    Effect=Allow,
                                    Resource=[Join("", [bucket.get_att("Arn"), "/*"])],
                                ),
                                Statement(
                                    Action=[
                                        awacs.codebuild.BatchGetBuilds,
                                        awacs.codebuild.StartBuild,
                                    ],
                                    Effect=Allow,
                                    Resource=[buildproject.get_att("Arn")],
                                ),
                            ],
                        ),
                    )
                ],
            )
        )

        template.add_resource(
            codepipeline.Pipeline(
                "Pipeline",
                ArtifactStore=codepipeline.ArtifactStore(
                    Location=bucket.ref(), Type="S3"
                ),
                Name=build_name,
                RoleArn=pipelinerole.get_att("Arn"),
                Stages=[
                    codepipeline.Stages(
                        Name="Source",
                        Actions=[
                            codepipeline.Actions(
                                Name="CodeCommit",
                                ActionTypeId=codepipeline.ActionTypeId(
                                    Category="Source",
                                    Owner="AWS",
                                    Provider="CodeCommit",
                                    Version="1",
                                ),
                                Configuration={
                                    "RepositoryName": appsource.get_att("Name"),  # noqa
                                    "BranchName": "master",
                                },
                                OutputArtifacts=[
                                    codepipeline.OutputArtifacts(Name="CodeCommitRepo")
                                ],
                            ),
                        ],
                    ),
                    codepipeline.Stages(
                        Name="Build",
                        Actions=[
                            codepipeline.Actions(
                                Name="Build",
                                ActionTypeId=codepipeline.ActionTypeId(
                                    Category="Build",
                                    Owner="AWS",
                                    Provider="CodeBuild",
                                    Version="1",
                                ),
                                Configuration={"ProjectName": buildproject.ref()},
                                InputArtifacts=[
                                    codepipeline.InputArtifacts(Name="CodeCommitRepo")
                                ],
                            )
                        ],
                    ),
                ],
            )
        )