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

CodePipeline: when providing custom Pipeline Role, cross-region support stacks cannot be deployed #19881

Closed
cprice404 opened this issue Apr 12, 2022 · 20 comments · Fixed by #21143
Assignees
Labels
@aws-cdk/aws-iam Related to AWS Identity and Access Management @aws-cdk/pipelines CDK Pipelines library bug This issue is a bug. effort/medium Medium work item – several days of effort p1

Comments

@cprice404
Copy link

cprice404 commented Apr 12, 2022

Describe the bug

When trying to come up with a workaround for the maximum policy size bug mentioned here and elsewhere, I created my own IAM role to explicitly pass in to my Pipelines.

As soon as I did this, the cross-region support stacks for my Pipelines were changed slightly; their KMS KeyPolicy got a new PolicyStatement that looks like this:

            {
              "Action": [
                "kms:Decrypt",
                "kms:DescribeKey",
                "kms:Encrypt",
                "kms:GenerateDataKey*",
                "kms:ReEncrypt*"
              ],
              "Effect": "Allow",
              "Principal": {
                "AWS": {
                  "Fn::Join": [
                    "",
                    [
                      "arn:",
                      {
                        "Ref": "AWS::Partition"
                      },
                      ":iam::123456789012:role/my-new-pipeline-role"
                    ]
                  ]
                }
              },
              "Resource": "*"
            },

The policy now explicitly references the new IAM role that I created for my Pipeline.

However, that role does not exist until the Pipeline stack itself is deployed, and the order of the actions created by CodePipeline attempts to deploy the support stacks first. So the support stacks fail to deploy because this IAM role does not exist yet.

Expected Behavior

Explicitly passing in an IAM role to the constructor of my Pipelines will allow me to avoid the maximum IAM policy size bugs, while still deploying my Pipeline stacks and support stacks.

Current Behavior

The support stacks fail to deploy with Resource handler returned message: "Policy contains a statement with one or more invalid principals. (Service: Kms, Status Code: 400, Request ID: ..., Extended Request ID: null)" (RequestToken: ..., HandlerErrorCode: InvalidRequest), because they reference an IAM role arn that has not been created yet.

Reproduction Steps

Create an IAM role, pass it in to the constructor of a Pipeline object, observe that the support stacks that are generated now explicitly reference the ARN of this IAM role in their KeyPolicy.

Possible Solution

Do not add the Role to the KeyPolicy. It is unnecessary, as the Role is in the same account as the Key, and the KeyPolicy already grants permission to the account:

            {
              "Action": "kms:*",
              "Effect": "Allow",
              "Principal": {
                "AWS": {
                  "Fn::Join": [
                    "",
                    [
                      "arn:",
                      {
                        "Ref": "AWS::Partition"
                      },
                      ":iam::123456789012:root"
                    ]
                  ]
                }
              },
              "Resource": "*"
            },

Additional Information/Context

No response

CDK CLI Version

2.19.0

Framework Version

2.19.0

Node.js Version

v16.5.0

OS

Amazon Linux 2

Language

Typescript

Language Version

TypeScript 4.4.2

Other information

No response

@cprice404 cprice404 added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Apr 12, 2022
@github-actions github-actions bot added the @aws-cdk/aws-codepipeline Related to AWS CodePipeline label Apr 12, 2022
@cprice404
Copy link
Author

related to #19835

@skinny85
Copy link
Contributor

Thanks for reporting @cprice404. Yes, you're right that we shouldn't add Role to the Resource Policy of the Key in this case.

I wonder what triggers this behavior though! The CodePipeline construct just constructs the Role itself if you don't pass it, so it shouldn't be any different.

Can you show how you create the Role, and how do you pass it to CodePipeline?

Thanks,
Adam

@skinny85 skinny85 added the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Apr 12, 2022
@cprice404
Copy link
Author

cprice404 commented Apr 12, 2022

@skinny85 I'm creating it with code very similar to what I pasted in my comment on the other ticket:

#19835 (comment)

I did have to add this because CFN wasn't waiting for the policy to be created before it started trying to create the pipeline:

      const pipelineCfnResource = pipeline.node.defaultChild as CfnResource;
      pipelineCfnResource.addDependsOn(
        pipelineRolePolicy.node.defaultChild as CfnResource
      );

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Apr 12, 2022
@skinny85
Copy link
Contributor

That might be a different bug in the Pipeline construct...

What's childPipelinePolicy?

@skinny85 skinny85 added the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Apr 12, 2022
@cprice404
Copy link
Author

That might be a different bug in the Pipeline construct...

What's childPipelinePolicy?

Sorry, edited it to match the code from the snippet on the other ticket. It's just the policy that I build up with the s3/kms/assumerole permissions, which I had to do because the auto-generated policy exceeds the max IAM policy size.

@cprice404
Copy link
Author

cprice404 commented Apr 12, 2022

So basically it's this:

  // We need to create a policy statement that grants access to the
  // KMS key that CDK generated for accessing the pipeline's s3 artifact
  // buckets.  To do this, we will need to know CDK's "uniqueId" for the
  // key, so that we can reference it in the policy.  Here we are calling
  // a vendored copy of their function that creates the unique id, because
  // the function isn't exported in the CDK library.
  const artifactBucketEncryptionKeyCdkUniqueId = makeUniqueId([
    `pipeline-${pipelineName}`,
    'ArtifactsBucketEncryptionKey',
    'Resource',
  ]);

  const pipelineRolePolicyName = `pipelinepolicy-${pipelineName}`;
  const pipelineRolePolicy = new iam.Policy(
    scope,
    pipelineRolePolicyName,
    {
      policyName: pipelineRolePolicyName,
      // These policy statements were built up by hand after examining the
      // statements in the CDK-generated policy for several pipelines.
      statements: [
        // Grants the pipeline access to the s3 artifact buckets.
        new iam.PolicyStatement({
          effect: iam.Effect.ALLOW,
          actions: [
            's3:Abort*',
            's3:DeleteObject*',
            's3:GetBucket*',
            's3:GetObject*',
            's3:List*',
            's3:PutObject',
            's3:PutObjectLegalHold',
            's3:PutObjectRetention',
            's3:PutObjectTagging',
            's3:PutObjectVersionTagging',
          ],
          resources: [`arn:aws:s3:::${pipelineName}-pipeline*`],
        }),
        // Grants the pipeline access to the KMS key that is used for the s3 artifact buckets.
        new iam.PolicyStatement({
          effect: iam.Effect.ALLOW,
          actions: [
            'kms:Decrypt',
            'kms:DescribeKey',
            'kms:Encrypt',
            'kms:GenerateDataKey*',
            'kms:ReEncrypt*',
          ],
          resources: [
            Fn.getAtt(artifactBucketEncryptionKeyCdkUniqueId, 'Arn').toString(),
          ],
        }),
        // Grants the pipeline AssumeRole permissions into the various CDK-generated roles, for
        // cross-account / cross-region deploys etc.
        new iam.PolicyStatement({
          effect: iam.Effect.ALLOW,
          actions: ['sts:AssumeRole'],
          resources: targetAccounts.map(targetAccount => {
            // Here we are granting permissions to assume some roles that are generated by CDK
            // for use in pipelines.  We need to wild-card them so that the policy doesn't get
            // too large for IAM.  The roles will begin with a string like `cacheadmin-pipeline`,
            // unless the name of the pipeline is too long; CDK will truncate the prefix portion
            // after 25 chars, and the suffix varies per role, so we just use the first 25 chars.
            const pipelineRoleNamePrefix = `${pipelineName}-pipeline`.substr(
              0,
              25
            );
            return `arn:aws:iam::${targetAccount}:role/${pipelineRoleNamePrefix}*`;
          }),
        }),
      ],
    }
  );

  const pipelineRoleName = `pipelinerole-${pipelineName}`;
  const pipelineRole = new iam.Role(scope, pipelineRoleName, {
    roleName: pipelineRoleName,
    assumedBy: new iam.ServicePrincipal('codepipeline.amazonaws.com'),
  });
  pipelineRolePolicy.attachToRole(pipelineRole);

      
      const pipeline = new codepipeline.Pipeline(
        this,
        `pipeline-foo`,
        {
          pipelineName: 'foo',
          crossAccountKeys: true,
      
          // passing the role via `withoutPolicyUpdates` prevents CDK from trying to manually manage the policy.  See:
          role: pipelineRole.withoutPolicyUpdates()
        }
      );

      const pipelineCfnResource = pipeline.node.defaultChild as CfnResource;
      pipelineCfnResource.addDependsOn(
        pipelineRolePolicy.node.defaultChild as CfnResource
      );


@skinny85
Copy link
Contributor

OK, thanks.

Can you explain more about your Pipeline? What makes it cross-region? Is it also cross-account at the same time?

@skinny85
Copy link
Contributor

Also, pipelineRolePolicy is a Policy in your code, but you pass it as the role property...?

@cprice404
Copy link
Author

Also, pipelineRolePolicy is a Policy in your code, but you pass it as the role property...?

Agh! Sorry. I manually edited the code to sanitize/simplify it before posting and I made a typo there. It's fixed now, it should have been role: pipelineRole.withoutPolicyUpdates().

Can you explain more about your Pipeline? What makes it cross-region? Is it also cross-account at the same time?

Yes. The pipeline has several stages in it, which deploy CFN stacks to our different accounts. We have a separate account for each region that we deploy to, so it is both cross-account and cross-region.

Thanks very much for looking into this! Sorry for the typos.

@skinny85
Copy link
Contributor

No worries 🙂.

Can you show the entire Key resource in the support Stack - once before using your Role (so using the Role CDK generates), and then again, after passing your Role to the Pipeline?

Thanks,
Adam

@cprice404
Copy link
Author

Before (using auto-generated role):

    "CrossRegionCodePipelineReplicationBucketEncryptionKey70216490": {
      "Type": "AWS::KMS::Key",
      "Properties": {
        "KeyPolicy": {
          "Statement": [
            {
              "Action": [
                "kms:*",
                "kms:Decrypt",
                "kms:DescribeKey",
                "kms:Encrypt",
                "kms:GenerateDataKey*",
                "kms:ReEncrypt*"
              ],
              "Effect": "Allow",
              "Principal": {
                "AWS": {
                  "Fn::Join": [
                    "",
                    [
                      "arn:",
                      {
                        "Ref": "AWS::Partition"
                      },
                      ":iam::111111111111:root"
                    ]
                  ]
                }
              },
              "Resource": "*"
            },
            {
              "Action": [
                "kms:Decrypt",
                "kms:DescribeKey"
              ],
              "Effect": "Allow",
              "Principal": {
                "AWS": [
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::222222222222222:role/core-infrastructure-pipelesdeploymentrole0f05f65d4b3029ee86f8"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::222222222222222:role/core-infrastructure-pipelesdeploymentrole1f174e528c315ee82b87"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::222222222222222:role/core-infrastructure-pipelesdeploymentroleb02d5222abc264efc063"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::222222222222222:role/core-infrastructure-pipelesdeploymentroleea21c8fe63d48c899641"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::222222222222222:role/core-infrastructure-pipelhangesactionrole19bdae0b7c00bbf6d718"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::222222222222222:role/core-infrastructure-pipelhangesactionrole65586e1094cee5f22d21"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::222222222222222:role/core-infrastructure-pipelhangesactionrole8c59bd647e1f00203e62"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::222222222222222:role/core-infrastructure-pipelhangesactionrole931300cfe72d996a772b"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::33333333333333:role/core-infrastructure-pipelesdeploymentrole33db272d83b5af51feae"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::33333333333333:role/core-infrastructure-pipelesdeploymentrole7ba9a73d7425c5836be5"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::33333333333333:role/core-infrastructure-pipelesdeploymentrole82502211759d325f2af1"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::33333333333333:role/core-infrastructure-pipelesdeploymentrolefb95aee7d0b79fb87499"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::33333333333333:role/core-infrastructure-pipelhangesactionrole446ff9efa7fe0a893a8e"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::33333333333333:role/core-infrastructure-pipelhangesactionroleb030a104f8c518643c2d"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::33333333333333:role/core-infrastructure-pipelhangesactionroleb355ae8d7595154ac81b"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::33333333333333:role/core-infrastructure-pipelhangesactionrolebc4bdb4ca37ae4348524"
                      ]
                    ]
                  }
                ]
              },
              "Resource": "*"
            }
          ],
          "Version": "2012-10-17"
        }
      },
      "UpdateReplacePolicy": "Delete",
      "DeletionPolicy": "Delete",
      "Metadata": {
        "aws:cdk:path": "pipeline-of-pipelines-stack/core-infrastructure/cross-region-stack-111111111111111111:us-east-1/Default/CrossRegionCodePipelineReplicationBucketEncryptionKey/Resource"
      }
    }

@cprice404
Copy link
Author

After (passing custom role):

    "CrossRegionCodePipelineReplicationBucketEncryptionKey70216490": {
      "Type": "AWS::KMS::Key",
      "Properties": {
        "KeyPolicy": {
          "Statement": [
            {
              "Action": "kms:*",
              "Effect": "Allow",
              "Principal": {
                "AWS": {
                  "Fn::Join": [
                    "",
                    [
                      "arn:",
                      {
                        "Ref": "AWS::Partition"
                      },
                      ":iam::111111111111:root"
                    ]
                  ]
                }
              },
              "Resource": "*"
            },
            {
              "Action": [
                "kms:Decrypt",
                "kms:DescribeKey",
                "kms:Encrypt",
                "kms:GenerateDataKey*",
                "kms:ReEncrypt*"
              ],
              "Effect": "Allow",
              "Principal": {
                "AWS": {
                  "Fn::Join": [
                    "",
                    [
                      "arn:",
                      {
                        "Ref": "AWS::Partition"
                      },
                      ":iam::111111111111:role/pipelinerole-core-infrastructure"
                    ]
                  ]
                }
              },
              "Resource": "*"
            },
            {
              "Action": [
                "kms:Decrypt",
                "kms:DescribeKey"
              ],
              "Effect": "Allow",
              "Principal": {
                "AWS": [
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::2222222222222:role/core-infrastructure-pipelesdeploymentrole0f05f65d4b3029ee86f8"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::2222222222222:role/core-infrastructure-pipelesdeploymentrole1f174e528c315ee82b87"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::2222222222222:role/core-infrastructure-pipelesdeploymentroleb02d5222abc264efc063"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::2222222222222:role/core-infrastructure-pipelesdeploymentroleea21c8fe63d48c899641"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::2222222222222:role/core-infrastructure-pipelhangesactionrole19bdae0b7c00bbf6d718"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::2222222222222:role/core-infrastructure-pipelhangesactionrole65586e1094cee5f22d21"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::2222222222222:role/core-infrastructure-pipelhangesactionrole8c59bd647e1f00203e62"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::2222222222222:role/core-infrastructure-pipelhangesactionrole931300cfe72d996a772b"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::3333333333333:role/core-infrastructure-pipelesdeploymentrole33db272d83b5af51feae"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::3333333333333:role/core-infrastructure-pipelesdeploymentrole7ba9a73d7425c5836be5"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::3333333333333:role/core-infrastructure-pipelesdeploymentrole82502211759d325f2af1"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::3333333333333:role/core-infrastructure-pipelesdeploymentrolefb95aee7d0b79fb87499"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::3333333333333:role/core-infrastructure-pipelhangesactionrole446ff9efa7fe0a893a8e"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::3333333333333:role/core-infrastructure-pipelhangesactionroleb030a104f8c518643c2d"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::3333333333333:role/core-infrastructure-pipelhangesactionroleb355ae8d7595154ac81b"
                      ]
                    ]
                  },
                  {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::3333333333333:role/core-infrastructure-pipelhangesactionrolebc4bdb4ca37ae4348524"
                      ]
                    ]
                  }
                ]
              },
              "Resource": "*"
            }
          ],
          "Version": "2012-10-17"
        }
      },
      "UpdateReplacePolicy": "Delete",
      "DeletionPolicy": "Delete",
      "Metadata": {
        "aws:cdk:path": "pipeline-of-pipelines-stack/core-infrastructure/cross-region-stack-111111111111:us-east-1/Default/CrossRegionCodePipelineReplicationBucketEncryptionKey/Resource"
      }
    }

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Apr 13, 2022
@skinny85
Copy link
Contributor

Thanks for the info. I can reproduce the issue. I have a hunch of what it might be, but I'll confirm tomorrow.

@skinny85
Copy link
Contributor

skinny85 commented Apr 13, 2022

But definitely the problem is not the custom Role, but Role.withoutPolicyUpdates() there.

Can you try passing pipelineRole there without the call to withoutPolicyUpdates(), and see if that helps? (Make sure the "@aws-cdk/aws-iam:minimizePolicies" feature flag in your cdk.json is set to true).

@cprice404
Copy link
Author

cprice404 commented Apr 13, 2022

I tried without withoutPolicyUpdates previously, and CDK then attempted to generate the policy to add to my role. The generated policy still exceeded the max IAM policy size, so that wasn't workable. Even with minimizePolicies set to true.

@skinny85
Copy link
Contributor

Yes, but does removing withoutPolicyUpdates() get rid of the bug here? (By which I mean this:

            {
              "Action": [
                "kms:Decrypt",
                "kms:DescribeKey",
                "kms:Encrypt",
                "kms:GenerateDataKey*",
                "kms:ReEncrypt*"
              ],
              "Effect": "Allow",
              "Principal": {
                "AWS": {
                  "Fn::Join": [
                    "",
                    [
                      "arn:",
                      {
                        "Ref": "AWS::Partition"
                      },
                      ":iam::111111111111:role/pipelinerole-core-infrastructure"
                    ]
                  ]
                }
              },
              "Resource": "*"
            },

statement from the Key policy)

@cprice404
Copy link
Author

Yes, it appears that the statement above does not get added if we don't use withoutPolicyUpdates.

I would guess that most folks who are opting-in to managing their own Role, though, are doing it because of the IAM policy size issue, and withoutPolicyUpdates is necessary for that use case. Just my guess, though.

@skinny85
Copy link
Contributor

So the problem is here:

return principal instanceof iam.Role ||
principal instanceof iam.User ||
principal instanceof iam.Group;

So, as long as you're using the Role generated by the CodePipeline construct, the above expression returns true, and everything works. However, the moment you use withoutPolicyUpdates(), suddenly that returns an IRole implementation that isn't the Role class, and the above expression returns false, and that's why that IAM Statement for the pipeline's Role is (incorrectly) generated.

Now, the simplest solution would be to add ImmutableRole to the above expression, alongside Group, Role and User (yes, it's private in the IAM module, but we can hack into it with a deep import in the KMS module). However, there's a problem with that simple solution, and that is the fact that the ImmutableRole class is also used in the fromRoleArn() method - and since that refers to an existing Role, the principalIsANewlyCreatedResource() method should return false for it, obviously.

@rix0rrr any ideas here? Looks like the hackiness of principalIsANewlyCreatedResource() is coming back to bite us... Should we somehow model the concept of a "new" resource properly, and use it from the KMS module?

@peterwoodworth peterwoodworth removed the needs-triage This issue or PR still needs to be triaged. label Apr 22, 2022
@skinny85 skinny85 added p1 effort/medium Medium work item – several days of effort labels May 4, 2022
@skinny85 skinny85 assigned rix0rrr and unassigned skinny85 May 4, 2022
@skinny85
Copy link
Contributor

skinny85 commented May 4, 2022

Re-assigning Rico, so he has a chance to see and comment on this one.

@rix0rrr rix0rrr added @aws-cdk/aws-iam Related to AWS Identity and Access Management @aws-cdk/pipelines CDK Pipelines library and removed @aws-cdk/aws-codepipeline Related to AWS CodePipeline labels May 23, 2022
@rix0rrr rix0rrr removed their assignment May 23, 2022
@comcalvi comcalvi self-assigned this Jul 12, 2022
@mergify mergify bot closed this as completed in #21143 Jul 14, 2022
mergify bot pushed a commit that referenced this issue Jul 14, 2022
`principalIsANewlyCreatedResource()` was an imperfect solution to determining whether or not a principal already existed or if it was managed by CDK. This caused a deployment error, so this PR replaces it with `Resource.isOwnedResource()` which returns true iff a resource was created by CDK. This also updates the return type of `isResource()` to `is Resource`, because we already have a `is CfnResource` in `CfnResource`. 

Closes #19881.

----

### All Submissions:

* [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@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-iam Related to AWS Identity and Access Management @aws-cdk/pipelines CDK Pipelines library bug This issue is a bug. effort/medium Medium work item – several days of effort p1
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants