Пример #1
0
 def ecs_task_execution_role(self) -> Role:
     """Return ecs task execution role, see role description for details."""
     return Role(
         name="ECSTaskExecutionRole",
         description="grants the Amazon ECS container agent permission to make "
         "AWS API calls on your behalf.",
         trust=Trust(services=["ecs-tasks"]),
         managed_policy_arns=[
             "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
         ],
     )
Пример #2
0
 def create_stack(self) -> list[Stack]:
     """Return MyCFNProject stack."""
     self.add(
         (
             Role(
                 name="TestRole",
                 description="TestRole description",
                 trust={"Service": "test"},
             )
         )
     )
     return self.stack
Пример #3
0
 def ecs_events_role(self) -> Role:
     """Return ecs events role, see role description for details."""
     return Role(
         name="ECSEventsRole",
         description="Allow CloudWatch Events service to run Amazon ECS tasks",
         trust=Trust(services=["events"]),
         managed_policy_arns=[
             "arn:aws:iam::aws:policy/service-role/"
             "AmazonEC2ContainerServiceEventsRole",
             Ref(name_to_id("ECSPassExecutionRolePolicy")),
         ],
     )
Пример #4
0
def test_role(stack: Stack) -> None:
    """Test IAM role creation.

    Creating a Role also tests PolicyDocument and Policystatement classes.
    """
    stack.add(
        Role(
            name="TestRole",
            description="TestRole description",
            principal={"Service": "test"},
        )
    )
    assert stack.export()["Resources"] == EXPECTED_ROLE
Пример #5
0
def test_role(stack: Stack) -> None:
    """Test IAM role creation.

    Creating a Role also tests PolicyDocument and Policystatement classes.
    """
    stack.add(
        Role(
            name="TestRole",
            description="TestRole description",
            max_session_duration=7200,
            trust={"Service": "test"},
            tags={"TestTagKey": "TestTagValue"},
        ))
    assert stack.export()["Resources"] == EXPECTED_ROLE
Пример #6
0
 def ecs_task_execution_role(self) -> Role:
     """Return ecs task execution role, see role description for details."""
     # For unknown reason if path is provided for this role it cannot be
     # use by ECS task definitions.
     return Role(
         name="ECSTaskExecutionRole",
         description=
         "grants the Amazon ECS container agent permission to make "
         "AWS API calls on your behalf.",
         trust=Trust(services=["ecs-tasks"]),
         managed_policy_arns=[
             "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
         ],
     )
Пример #7
0
def test_stackset(stack: Stack) -> None:
    """test Cloudformation stack set creation."""
    stack.s3_bucket = "cfn_bucket"
    stack.s3_key = "templates/"

    stack_set = StackSet(
        name="stack-set-test",
        description="this is a test",
        regions=["eu-west-1"],
        ous=["test-ou"],
    )

    stack_set.add(
        Role(
            name="TestRole",
            description="TestRole description",
            trust={"Service": "test"},
        )
    )
    stack_set.add_condition("", Equals(AccountId, "test_account_id"))
    stack.add(stack_set)
    assert stack.export()["Resources"] == EXPECTED_TEMPLATE
Пример #8
0
def build_and_deploy_tstacks() -> None:
    """Build and deploy two simple troposphere stacks.

    Two stacks in two different regions are deployed. An us stack define only a secure
    bucket. An eu stack define secure s3 buckets, a role to add object to the eu bucket
    and a AWSConfig recorder with rules that check s3 buckets security configurations
    across both regions.
    """
    sessions = {
        "eu": Session(regions=["eu-west-1"]),
        "us": Session(regions=["us-east-1"]),
    }
    stack = {}
    for region in ("eu", "us"):
        stack[region] = Stack(
            f"e3-example-{region}",
            sessions[region],
            opts={"Capabilities": ["CAPABILITY_NAMED_IAM"]},
        )

    # Add a s3 secure bucket in each region
    stack["eu"].add_construct([Bucket(name="e3-l1-example")])
    stack["us"].add_construct([Bucket(name="e3-l2-example")])

    # Define a new IAM-Roles that will be used to acces e3-l1-example bucket
    stack["eu"].add_construct(
        [
            Role(
                name="L1WriteRole",
                description="Role to write to l1 buckets",
                principal={"Service": "ecs-tasks.amazonaws.com"},
            )
        ]
    )

    # Define a new IAM-Policy to putObject in e3-l1-example bucket
    # and attach the L1WriteRole role to it
    stack["eu"].add_construct(
        [
            S3AccessManagedPolicy(
                name="S3WriteAccess",
                buckets=["e3-l1-example"],
                action=["s3:PutObject"],
                roles=[Ref(stack["eu"]["L1WriteRole"])],
            )
        ]
    )

    # Add AWS config rules to check S3 buckets security configuration.
    # This should only be defined in one region
    for region in ("eu",):
        stack[region].add_construct(
            [ConfigurationRecorder(bucket_name="config-bucket-example")]
        )

    for region in ("eu",):
        stack[region].add_construct(
            [
                S3BucketPublicWriteProhibited,
                S3BucketPublicReadProhibited,
                S3BucketServerSideEncryptionEnabled,
                S3BucketSSLRequestsOnly,
                IAMUserNoPoliciesCheck,
            ]
        )

    # Deploy stacks
    for region in ("eu", "us"):
        stack[region].deploy()
Пример #9
0
    def add_cache_invalidation(self, stack: Stack) -> list[AWSObject]:
        """Return resources invalidating cache when objects are pushed to s3.

        A lambda is called at each s3 object update to invalidate cloudformation
        cache for the updated object.
        """
        lambda_name = f"{self.name}-cache-invalidation-lambda"
        lambda_policy = ManagedPolicy(
            name=f"{lambda_name}-policy",
            description=f"managed policy used by {lambda_name}",
            path=f"/{stack.name}/",
            statements=[
                Allow(
                    action=["cloudfront:CreateInvalidation"],
                    resource=Join(
                        "",
                        [
                            "arn:aws:cloudfront::", AccountId,
                            ":distribution ", self.id
                        ],
                    ),
                )
            ],
        )
        lambda_role = Role(
            name=f"{lambda_name}-role",
            description=f"role assumed by {lambda_name}",
            path=f"/{stack.name}/",
            trust=Trust(services=["lambda"]),
            managed_policy_arns=[lambda_policy.arn],
        )

        # Get first part of invalidation lambda code from a file
        with open(
                os.path.join(
                    os.path.dirname(os.path.abspath(__file__)),
                    "data",
                    "lambda_invalidate_head.py",
                )) as lf:
            lambda_code = lf.read().splitlines()

        # Complete it with the part depending on the distribution id
        lambda_code.extend([
            "    client.create_invalidation(",
            Sub(
                "        DistributionId='${distribution_id}',",
                distribution_id=self.id,
            ),
            "        InvalidationBatch={",
            "            'Paths': {'Quantity': 1, 'Items': path},",
            "            'CallerReference': str(time.time()),",
            "        },",
            "    )",
        ])
        lambda_function = Function(
            name_to_id(lambda_name),
            description=(f"lambda invalidating cloudfront cache when "
                         f"{self.bucket.name} objects are updated"),
            handler="invalidate.handler",
            role=lambda_role,
            code_zipfile=Join("\n", lambda_code),
            runtime="python3.9",
        )

        sns_topic = Topic(name=f"{self.name}-invalidation-topic")
        sns_topic.add_lambda_subscription(
            function=lambda_function,
            delivery_policy={"throttlePolicy": {
                "maxReceivesPerSecond": 10
            }},
        )
        # Trigger the invalidation when a file is updated
        self.bucket.add_notification_configuration(event="s3:ObjectCreated:*",
                                                   target=sns_topic,
                                                   permission_suffix=self.name)

        result = [
            resource for construct in (lambda_policy, lambda_role,
                                       lambda_function, sns_topic)
            for resource in construct.resources(stack)
        ]
        return result