Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(aws-s3-deployment): Policy Resource Created Despite Providing a Role #12375

Closed
joel-aws opened this issue Jan 6, 2021 · 4 comments
Closed
Assignees
Labels
@aws-cdk/aws-s3-deployment guidance Question that needs advice or information. response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.

Comments

@joel-aws
Copy link
Contributor

joel-aws commented Jan 6, 2021

When passing a role to aws_s3_deployment.BucketDeployment, a DefaultPolicy resource is still created in addition to the supplied role (e.g., uploadsupportfilesDefaultPolicy6089F180 results from the code below).

This interferes with my corporate policy, where policies are provisioned and referenced, not created. (I.e., in prod, an existing role would be imported and passed to BucketDeployment for use; if it created an additional Policy, then an error would be thrown.

Reproduction Steps

from aws_cdk import (
    core,
    aws_iam as iam,
    aws_s3 as s3,
    aws_s3_deployment as s3_deploy,
)

class SupportFilesStack(core.Stack):
    def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        support_files_bucket = s3.Bucket(
            self,
            "support-files",
            removal_policy=core.RemovalPolicy.DESTROY,
            auto_delete_objects=True,
        )

        default_lambda_policy = iam.PolicyStatement(
            effect=iam.Effect.ALLOW,
            actions=[
                "logs:CreateLogStream",
                "logs:CreateLogGroup",
                "logs:PutLogEvents",
            ],
            resources=["*"],
        )

        read_bootstrap_bucket_policy = iam.PolicyStatement(
            effect=iam.Effect.ALLOW,
            actions=["s3:GetObject*", "s3:GetBucket*", "s3:List*"],
            resources=[
                self.create_s3_arn(
                    f"cdk-hnb659fds-assets-{self.account}-{self.region}"
                ),
                self.create_s3_arn(
                    f"cdk-hnb659fds-assets-{self.account}-{self.region}/*"
                ),
            ],
        )
        crud_support_files_bucket_policy = iam.PolicyStatement(
            effect=iam.Effect.ALLOW,
            actions=[
                "s3:GetObject*",
                "s3:GetBucket*",
                "s3:List*",
                "s3:DeleteObject*",
                "s3:PutObject*",
                "s3:Abort*",
            ],
            resources=[
                support_files_bucket.bucket_arn,
                f"{support_files_bucket.bucket_arn}/*",
            ],
        )
        support_role = iam.Role(
            self,
            "support-files-role",
            assumed_by=iam.ServicePrincipal("lambda"),
            inline_policies={
                "upload-support-files": iam.PolicyDocument(
                    statements=[
                        default_lambda_policy,
                        read_bootstrap_bucket_policy,
                        crud_support_files_bucket_policy,
                    ]
                )
            },
        )

        s3_deploy.BucketDeployment(
            self,
            "support_files_deployment",
            sources=[s3_deploy.Source.asset("./support_files/")],
            destination_bucket=support_files_bucket,
            retain_on_delete=True,
            role=support_role,
        )

    def create_s3_arn(self, bucket_name: str) -> str:
        return self.format_arn(
            service="s3", resource=bucket_name, region="", account=""
        )

What did you expect to happen?

BucketDeployment to accept a Role (support_role in this example) and not create an additional Policy.

What actually happened?

A "DefaultPolicy" Policy resource was created in addition to the supplied role that contained the same policy.

Environment

CDK CLI Version: 1.82.0
Framework Version:
Node.js Version: v15.3.0
OS: Mac OS 10.15.7
Language (Version): Python 3.7.9

Other

Might be related-to/duplicate-of #9989.


This is 🐛 Bug Report

@joel-aws joel-aws added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Jan 6, 2021
@joel-aws
Copy link
Contributor Author

joel-aws commented Jan 9, 2021

My work around for now is to apply the following Aspect to the Construct that removes any DefaultPolicy node:

import jsii
from aws_cdk import core, aws_iam as iam

@jsii.implements(core.IAspect)
class RemoveDefaultPolicyAspect:
    """Removes any DefaultPolicy (`IAM::Policy`) created by a construct."""

    def visit(self, node):
        if isinstance(node, iam.Policy):
            if "DefaultPolicy" in node.node.id:
                parent = node.node.scope
                parent.node.try_remove_child(node.node.id)

@iliapolo
Copy link
Contributor

@joel-aws You mentioned:

in prod, an existing role would be imported and passed to BucketDeployment for use

When you do that, the created role will be an instance of IRole (as opposed to Role) - which you can define to be immutable. So in production you would do:

production_role = iam.Role.from_role_arn(self, 'Role', mutable=False)

This will cause CDK to skip the creation of an IAM policy for that role. Instead, it will attach an inline policy on the destination bucket to allow this role to put objects. This means you can skip the manual destination bucket permissions I see you configure.

If your corporate policy prevents creating bucket policies as well, you'll need to also import the bucket (using Bucket.fromXXX). In this case, you have to take care of all necessary permissions, like you already do.

Let me know if that addresses you issue.

@iliapolo iliapolo added guidance Question that needs advice or information. response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. and removed bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Jan 10, 2021
@joel-aws
Copy link
Contributor Author

That worked perfectly, @iliapolo -- thank you!

@github-actions
Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-s3-deployment guidance Question that needs advice or information. response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.
Projects
None yet
Development

No branches or pull requests

2 participants