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-iam: Nested Stacks provide different Policies with equal, therefore conflicting names #23957

Open
ThomasSteinbach opened this issue Feb 1, 2023 · 2 comments
Labels
@aws-cdk/aws-iam Related to AWS Identity and Access Management bug This issue is a bug. documentation This is a problem with documentation. effort/medium Medium work item – several days of effort p2

Comments

@ThomasSteinbach
Copy link
Contributor

ThomasSteinbach commented Feb 1, 2023

Describe the bug

When CDK creates IAM Policies within different instances of the same nested stack, the PolicyNames are equal. Thus attaching these policies to a role in the parent stack, one policy replaces another. As a result only one policy becomes attached to the role. This is despite the instances of the nested stack class have disjunct construct id's.

Expected Behavior

Policies created within a nested stack should have distinct hashed appended to their name, depending on the construct id of the nested stack.

Current Behavior

Given a nested stack class with an IAM policy inside, each instance of the nested stack will provide a policy with equal names.

On deployment Cloud Formation does not care about the equal names and replaces one policy by another, when they were attached to the same IAM role.

Reproduction Steps

The following example can be downloaded and reproduced from:

https://gitlab.com/codexamples/aws-iam-policy-bug

The cdk.out folder is already pushed to this repository, so that no cdk synth is required to see the input source code as well as the output manifests.


This example stack (source link) ...

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

        role = aws_iam.Role(self, "role", assumed_by=aws_iam.AnyPrincipal())

        SubStack(self, "sub1", role)
        SubStack(self, "sub2", role)

... creating two instances of this nested stack (source link) ...

class SubStack(cdk.NestedStack):
    def __init__(self, scope: Construct, id: str, role: aws_iam.Role) -> None:
        super().__init__(scope, id)

        iam_policy = aws_iam.Policy(
            self,
            "ProblematicPolicy",
            statements=[
                aws_iam.PolicyStatement(
                    effect=aws_iam.Effect.ALLOW,
                    actions=[
                        "secretsmanager:GetSecretValue",
                    ],
                    resources=[id],
                ),
            ],
        )

        role.attach_inline_policy(iam_policy)

... will create two different policies with identical names ...

cdk.out/AwsIamPolicyBugStacksub1C2BE4621.nested.template.json

  "ProblematicPolicyB9AC90CA": {
   "Type": "AWS::IAM::Policy",
   "Properties": {
    "PolicyDocument": {
     "Statement": [
      {
       "Action": "secretsmanager:GetSecretValue",
       "Effect": "Allow",
       "Resource": "sub1"
      }
     ],
     "Version": "2012-10-17"
    },
    "PolicyName": "ProblematicPolicyB9AC90CA",

cdk.out/AwsIamPolicyBugStacksub25BE75079.nested.template.json

  "ProblematicPolicyB9AC90CA": {
   "Type": "AWS::IAM::Policy",
   "Properties": {
    "PolicyDocument": {
     "Statement": [
      {
       "Action": "secretsmanager:GetSecretValue",
       "Effect": "Allow",
       "Resource": "sub2"
      }
     ],
     "Version": "2012-10-17"
    },
    "PolicyName": "ProblematicPolicyB9AC90CA",

Possible Solution

Involving the nested stacks id when creating the hash postfix of the policies (resource) name should fix the problem.

Maybe there is more to consider than just including the nested stacks id. I assume CDK maintainers would know.

Additional Information/Context

I could imagine the current (buggy) behaviour also affects other resources. Especially when those resources are used within the parent stack, as the policy in the example given.

CDK CLI Version

2.55.1

Framework Version

No response

Node.js Version

v16.19.0

OS

MacOS Darwin 22.3.0

Language

Python

Language Version

3.10

Other information

No response

@ThomasSteinbach ThomasSteinbach added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Feb 1, 2023
@github-actions github-actions bot added the @aws-cdk/aws-iam Related to AWS Identity and Access Management label Feb 1, 2023
@ThomasSteinbach ThomasSteinbach changed the title aws-iam: Nested Stacks provide different Policies with equal thus colliding names aws-iam: Nested Stacks provide different Policies with equal therefore conflicting names Feb 1, 2023
@ThomasSteinbach ThomasSteinbach changed the title aws-iam: Nested Stacks provide different Policies with equal therefore conflicting names aws-iam: Nested Stacks provide different Policies with equal, therefore conflicting names Feb 1, 2023
@ThomasSteinbach
Copy link
Contributor Author

Workaround

Our workaround is to include the stack id into the policy id (source link):

        iam_policy = aws_iam.Policy(
            self,
            f"{cdk.Stack.of(self).node.id}ProblematicPolicy",

I have published the workaround and the synthesized manifests to a separate branch. Please see the diff:

https://gitlab.com/codexamples/aws-iam-policy-bug/-/compare/main...workaround?from_project_id=43104430&straight=false

However this workaround is rather rude and just works for this single policy and must be repeated for every construct that requires unique "unique" identifiers.

@peterwoodworth
Copy link
Contributor

Thanks for reporting this @ThomasSteinbach, I can confirm this bug will result in only creating one policy, with one overwriting the other.

It's going to be tricky for us to fix this bug, at the least it would require a feature flag because it would be a breaking change to change logical IDs or physical names, but I'm not sure we have a great solution for this problem in the first place even if we didn't have to worry about that.

You can also supply the policyName directly, the documentation seems to imply this issue can exist when the policy is created in different stacks. We should clarify this in the documentation

@peterwoodworth peterwoodworth added p1 effort/medium Medium work item – several days of effort documentation This is a problem with documentation. and removed needs-triage This issue or PR still needs to be triaged. labels Feb 3, 2023
@khushail khushail added p1.5 and removed p1 labels May 15, 2023
@otaviomacedo otaviomacedo added p2 and removed p1.5 labels May 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-iam Related to AWS Identity and Access Management bug This issue is a bug. documentation This is a problem with documentation. effort/medium Medium work item – several days of effort p2
Projects
None yet
Development

No branches or pull requests

4 participants