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-codepipeline: cross region support creates huge inline policy document for the pipeline role #16244
Comments
Thanks for reporting @adigopv. I think this is another need for #14713; I'm not sure there's much the CodePipeline module itself can do here. One way you can try to unblock yourself is to create a Role explicitly, add it all of the permissions (in a more efficient way), and then pass an immutable copy of it into the CodePipeline construct(s): https://docs.aws.amazon.com/cdk/api/latest/docs/aws-iam-readme.html#opting-out-of-automatic-permissions-management Thanks, |
Hi Adam, thanks for the suggestion ! But, we do not have knowledge about some of the resource ARNs like the Thanks, |
@adigopv any chance you could supply me with a small CDK app (maybe hosted in a GitHub public repository) that reproduces this error? It would really help me trying to devise a workaround for this problem. |
…size limit When we generate CodePipelines, we need to add an `sts:AssumeRole` statement for each Action in the pipeline, and a `Bucket.grantReadWrite()` statement for each region the pipeline is in, to the policy statement of the pipeline's Role. For pipelines with many Actions and/or regions, this makes the policy exceed IAM limit of 10240 bytes. Extract a new class from the CodePipeline CloudFormation Actions that caches the statements added to a given Principal by the 'Action' field, and groups the statements with the same 'Actions' by adding elements to the 'Resource' field. This dramatically reduces the duplication in the statement, and increases the chances of it being smaller than the limit. Use this new class in the `Pipeline` construct. Fixes aws#16244
…size limit When we generate CodePipelines, we need to add an `sts:AssumeRole` statement for each Action in the pipeline, and a `Bucket.grantReadWrite()` statement for each region the pipeline is in, to the policy statement of the pipeline's Role. For pipelines with many Actions and/or regions, this makes the policy exceed IAM limit of 10240 bytes. Extract a new class from the CodePipeline CloudFormation Actions that caches the statements added to a given Principal by the 'Action' field, and groups the statements with the same 'Actions' by adding elements to the 'Resource' field. This dramatically reduces the duplication in the statement, and increases the chances of it being smaller than the limit. Use this new class in the `Pipeline` construct. Fixes aws#16244
…size limit When we generate CodePipelines, we need to add an `sts:AssumeRole` statement for each Action in the pipeline, and a `Bucket.grantReadWrite()` statement for each region the pipeline is in, to the policy statement of the pipeline's Role. For pipelines with many Actions and/or regions, this makes the policy exceed IAM limit of 10240 bytes. Extract a new class from the CodePipeline CloudFormation Actions that caches the statements added to a given Principal by the 'Action' field, and groups the statements with the same 'Actions' by adding elements to the 'Resource' field. This dramatically reduces the duplication in the statement, and increases the chances of it being smaller than the limit. Use this new class in the `Pipeline` construct. Fixes aws#16244
This is a real blocker! The whole idea of infra-as-code is that it can be scaled and generated. But this becomes an impediment and an antithesis to infra-as-code. We were testing on a small set of stages to make sure it all worked. When we added other stages, everything crumbled and the pipeline is now broken. |
@moltar how about destroying and redeploying your pipeline with alle needed stages included? A pipeline should be loosly coupled to the "golden" cdk stacks |
That's not always possible, as we add new stages. Also, I am not sure how it'd help? The problem is the pipeline generates a policy that is unnecessarily large. It lists permissions for every single asset, which there can be many of. {
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::11111111:role/ProjectPipelineSourceaatlanti-17INJW07P0N4J",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::11111111:role/ProjectPipelineBuildSynthShellStepCod-1JX5K4YAETR30",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::11111111:role/ProjectPipelineUpdatePipelineSelfMuta-4OFIXOVQVY50",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::11111111:role/ProjectPipelineAssets1DockerAsset1Cod-NJA8YN3R8EW1",
"Effect": "Allow"
} and on and on and on These assets aren't stage-specific. If we have 1 or 3 stages, the assets do not change. 80% of the policy could be replaced with: {
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::11111111:role/ProjectPipeline*",
"Effect": "Allow"
}, |
Hey, I don't have a repo, but a simple repro maybe is to loop over lambda function construct and create 50 lambdas with some dummy asset (but new asset for each). This will produce insanely long policy which sets a new role for each asset, and then grants |
Here's the full (sanitized) policy: {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:GetObject*",
"s3:GetBucket*",
"s3:List*",
"s3:DeleteObject*",
"s3:PutObject*",
"s3:Abort*"
],
"Resource": [
"arn:aws:s3:::ad-mainline-mainlinepipelineartifactsbucket32b9fb-xyz",
"arn:aws:s3:::ad-mainline-mainlinepipelineartifactsbucket32b9fb-xyz/*"
],
"Effect": "Allow"
},
{
"Action": [
"kms:Decrypt",
"kms:DescribeKey",
"kms:Encrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*"
],
"Resource": "arn:aws:kms:eu-west-1:111111111111:key/00000000-0000-0000-0000-000000000000",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineSourceScaleLeapatlanti-17INJW07P0N4J",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineBuildSynthShellStepCod-1JX5K4YAETR30",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineUpdatePipelineSelfMuta-4OFIXOVQVY50",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1DockerAsset1Cod-NJA8YN3R8EW1",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1DockerAsset2Cod-11OHUPSDDCAOZ",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset1CodeP-1DT95S0C165LP",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset10Code-1PTENGEIA6IGN",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset11Code-3SID6KWFXP4S",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset12Code-HASQGQSED9L8",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset13Code-10NEHGGVXQ07O",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset14Code-H4V83IMXBFH",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset15Code-1SZJY4YGP1Z9N",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset16Code-1FDTTZBNXIHNY",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset17Code-7ZEOMOE4FDLL",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset18Code-DGD5JWHHVVT4",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset19Code-100WNYVJLJF4U",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset2CodeP-194SY99PL17D1",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset20Code-5441XLBRNDZS",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset21Code-QF6TINYYHRL2",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset22Code-OUNVGMQ7TMSC",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset23Code-1UD2HYLSYXKNV",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset24Code-664Y8WHH7JZ9",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset25Code-AUVHQCS529T1",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset26Code-RV8CCCNDZDO6",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset27Code-XNU1I9IQRC30",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset28Code-1G05MOM2IF9QS",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset29Code-1D2F1LBMS773H",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset3CodeP-USV2ATZ3VAV1",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset30Code-BBKO6T4MZN8J",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset31Code-9XQBKA45886R",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset32Code-1VOHI3BAKRZZT",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset33Code-D1YDOXD4VB59",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset34Code-17HGFP2KLBNP7",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset35Code-LRF74E107MG5",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset36Code-1SZIOI7KG0KKR",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset37Code-7IBADQWRWOHE",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset38Code-KZS13S4OV0M5",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset39Code-IL8N1ZSU0ULL",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset4CodeP-1X172A6SCOVKE",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset40Code-TPAUSL1GFGD8",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset41Code-AXBUOGR42Z0",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset42Code-1I1USSIDU605G",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset43Code-1FTYT0NU8CVOV",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset44Code-2H0PIC97UOWQ",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset45Code-XJ5LHVI7WD8U",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset46Code-74644R1KCC6V",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset47Code-1OEKGUKDNVPIY",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset48Code-KIZEO8Y5F7ZI",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset49Code-3MF3M1C0MRS5",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset5CodeP-ULQ1QL1DBXAP",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset6CodeP-1JYS6M3MOWBQ9",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset7CodeP-1T53GD4PRG3J7",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets1FileAsset8CodeP-LUNA0SYKXWCP",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/AD-Mainline-MainlinePipelineAssets2FileAsset9CodeP-1BISQRL8S9XVK",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/cdk-hnb659fds-deploy-role-111111111111-eu-west-1",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::222222222222:role/cdk-hnb659fds-deploy-role-222222222222-eu-west-1",
"Effect": "Allow"
},
{
"Action": [
"s3:GetObject*",
"s3:GetBucket*",
"s3:List*",
"s3:DeleteObject*",
"s3:PutObject*",
"s3:Abort*"
],
"Resource": [
"arn:aws:s3:::ad-mainline-support-ap-soeplicationbucket11c23xyz",
"arn:aws:s3:::ad-mainline-support-ap-soeplicationbucket11c23xyz/*"
],
"Effect": "Allow"
},
{
"Action": [
"kms:Decrypt",
"kms:DescribeKey",
"kms:Encrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*"
],
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::333333333333:role/cdk-hnb659fds-deploy-role-333333333333-ap-southeast-1",
"Effect": "Allow"
},
{
"Action": [
"s3:GetObject*",
"s3:GetBucket*",
"s3:List*",
"s3:DeleteObject*",
"s3:PutObject*",
"s3:Abort*"
],
"Resource": [
"arn:aws:s3:::ad-mainline-support-ap-noeplicationbucket590d26xyz",
"arn:aws:s3:::ad-mainline-support-ap-noeplicationbucket590d26xyz/*"
],
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::44444444444444:role/cdk-hnb659fds-deploy-role-44444444444444-ap-northeast-1",
"Effect": "Allow"
}
]
} |
Could the CodePipeline construct run an aspect on itself to do the optimization on its end? It seems there's reluctance to make sweeping IAM optimization changes based on comments in #14713, but this is a real show-stopper for production usage of CDK. |
We just ran into this. Glad to see it has recent attention in #18549 and #16350. It'd be great if we could pass a parameter like |
We are running into similar issues with the bucket policy in cross region support stacks. |
@gottkanzler-rgb can you specify your exact problem with passing |
Initializing the Pipeline myself seems to have no effect. I have an artifact Bucket with a suitable resource policy, same for the KMS key, but when synthesizing the stack it automatically creates the redundant policy statements nevertheless. |
I stopped using CDK Pipelines, not so much because of this issue, but rather because of the non-adjustable AWS CodePipeline limits. In particular, the "50 actions per stage" and "50 stages per pipeline" limits are troublesome for deployments targeting hundreds or thousands of environments since multiple actions are created per environment. I'm currently using the L2 CodePipeline and CodeBuild constructs and just running |
@meeber Yes some limits seem very arbitrary. I'm sure it's defined for a reason but leaves a bad taste and doesn't generate a ton of confidence developing solutions relying on this service/tooling. |
Hey guys, I recently had the same issue #20565 when deploying to all AWS regions and luckily there was a recent fix to prevent 10k exceed limit for IAM policies. In addition, adding |
@am29d It does not help. I have that directive active. Indeed it does minimize IAM policy documents but the issue is much more widespread. There are many open issues in this project regarding the 10K limit being exceeded under what appear to be many scenarios. |
I see, I am not aware of all the cases, are there any other cases for 10k limit? I could only find three issues. At least the recent PR 75bfce7 helped to reduce the policy size by creating overflow policies for cross region support stacks. Can you point me to other issues, curious to see what blockers I might encounter further down the road. |
#19835 lists a few issues. The main issue is closed but it references other issues some of which are probably still open. https://github.com/aws/aws-cdk/issues?q=is%3Aissue+10240+is%3Aopen are open cases but I seriously doubt it covers all issues. here's an issue I opened up back in Dec #18167 which won't show up in a search for 10240. Issue is due to pipelines/CodePipeline constructs not enforcing or honoring the withoutPolicyUpdates method (and therefore still generating policy documents that exceed the limit). So, different issue but still same underlying root cause. Somewhere (maybe even in this ticket?) @rix0rrr mentions the challenge involved which has to do with the fact that the policy document is inline and not managed. I've kinda always wondered why someone can't split the policy up into multiple managed policies and then attach those multiple policies to the role in question. I'm sure it's easier said than done so I don't want to sound flippant or anythign. Just kinda wondered that's all. And no I'm not about to take a break from my multiple clients and 55 hours / week to help fix this issue (even though i sort of want to) :-) I just don't have time and I'm pretty sure you folks at AWS have the resources if you really wanted to figure it out ;-) |
Hey @ekeyser , thanks for the pointers and the clarification, this helps to see the broader picture and other issues I might run into later. I agree that it's probably not a trivial challenge to solve, and with the recent PR the policies are chunked into an overflow policy document and are attached to the role. I will take a look at your mentioned issue and check if the recent changes fixed the problem. |
@am29d not to put too fine a point on it but the broader picture is this project and aws is failing users. You all have put v1 into maintenance mode without resolving problems that allow people to migrate to v2. Not sure what kind of logic that is but doesn't seem like very good logic. |
We have a code pipeline setup with cross region support. The pipeline creates replication buckets in cross regions and pipeline internally adds permissions for these s3 buckets in the pipeline role here.
Something like this for each cross region:
Since an
addAction
is called for each region, we add a new policy statement every time with the same permissions, which is causing the pipeline role inline policy to exceed the iam policy size limit causing below error.Similar issue is seen for the
sts:AssumeRole
permissions added here.Reproduction Steps
Create a codepipeline with multiple stages and ~ 15 regions.
What did you expect to happen?
The role that pipeline created should be reduced / compacted. Since there are many duplicate actions for each resource, we can have a single policy statement with all resources.
We were adding new stages and regions in our pipeline when we observed this.
What actually happened?
Got this error when deploying the stack.
Environment
This is 🐛 Bug Report
The text was updated successfully, but these errors were encountered: