aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.72k stars 3.94k forks source link

(route53): CustomDeleteExistingRecordSetCustomResourceProviderRole fails with Maximum policy size of 10240 bytes exceeded for role #23279 #23424

Open andresionek91 opened 1 year ago

andresionek91 commented 1 year ago

Describe the bug

When deploying many records using route53.RecordSet and having delete_existing=True the deployment fails due to exceeding the maximum policy size for the custom role that allows the lambda to delete the records.

Expected Behavior

The role and function to delete records should be created normally.

Current Behavior

Error is raised when deploying:

Maximum policy size of 10240 bytes exceeded for the role [redacted]-CustomDeleteExistingReco-1OGW8OMHV7Y0G

Reproduction Steps

Create at least 50 (I don't know what the exact critical number that makes this fail is) route53.RecordSet objects in a stack with delete_existing=True.

The same happens for more specific objects, such as CnameRecord or ARecord, even if there is a mix of record types.

@dataclass
class Record:
    name: str
    type: RecordType
    target_values: list[str]
    ttl_seconds: int = 1800
    comment: str = ""
    zone: route53.IHostedZone = hosted_zone

records = [ # have at least 50 different records here.
    Record(
        name="test.com",
        type=RecordType.A,
        target_values=[
            "0.0.0.0",
        ],
        ttl_seconds=300,
        comment="website",
    ),
    Record(
        name="test.com",
        type=RecordType.MX,
        target_values=[
            "1\tASPMX.L.GOOGLE.COM.",
            "5\tALT1.ASPMX.L.GOOGLE.COM.",
            "5\tALT2.ASPMX.L.GOOGLE.COM.",
            "10\tALT3.ASPMX.L.GOOGLE.COM.",
            "10\tALT4.ASPMX.L.GOOGLE.COM.",
        ],
        comment="email",
        ttl_seconds=300,
    ),
]

for idx, record in enumerate(records):
    route53.RecordSet(
        scope=self,
        id=f"Record{idx}",
        record_name=record.name,
        record_type=record.type,
        target=RecordTarget(values=record.target_values),
        ttl=cdk.Duration.seconds(amount=record.ttl_seconds),
        comment=record.comment,
        zone=record.zone,
        delete_existing=True
    )

Possible Solution

No response

Additional Information/Context

The current implementation will add a new inline Policy Statement for each record with repeated statements. In the end the policy ends up huge and above the minimum amount.

I tried activating the @aws-cdk/aws-iam:minimizePolicies feature flag set to true in cdk.json, but after activating the flag the generated policy is still ~1800 lines long.

❯ cdk --version
2.55.1 (build 30f1ae4)

cdk.json:

{
  "app": "python3 app.py",
  "requireApproval": "never",
  "watch": { "include": [ "**" ] },
  "context": {
    "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true,
    "@aws-cdk/core:stackRelativeExports": true,
    "@aws-cdk/aws-rds:lowercaseDbIdentifier": true,
    "@aws-cdk/aws-lambda:recognizeVersionProps": true,
    "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true,
    "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
    "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
    "@aws-cdk/aws-iam:minimizePolicies": true,
    "@aws-cdk/core:target-partitions": [
      "aws",
      "aws-cn"
    ]
  }
}

For example, this particular policy below is repeated 24 times in the policy statement:

        {
         "Effect": "Allow",
         "Action": "route53:ChangeResourceRecordSets",
         "Resource": {
          "Fn::Join": [
           "",
           [
            "arn:",
            {
             "Ref": "AWS::Partition"
            },
            ":route53:::hostedzone/",
            {
             "Ref": "PublicDnsPublicHostedZoneEAEBE413"
            }
           ]
          ]
         },
         "Condition": {
          "ForAllValues:StringEquals": {
           "route53:ChangeResourceRecordSetsRecordTypes": [
            "CNAME"
           ],
           "route53:ChangeResourceRecordSetsActions": [
            "DELETE"
           ]
          }
         }
        },

Could it be that the flag is not merging the statements because the policy has a Condition?

Looking at the docs I don't see any mentions to what the flag does when there is a Condition: https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyDocumentProps.html#minimize

CDK CLI Version

2.55.1 (build 30f1ae4)

Framework Version

No response

Node.js Version

v16.14.0

OS

ubuntu / macOs

Language

Python

Language Version

Python 3.9.11

Other information

No response

riskersen commented 1 year ago

I have the same issue with a bunch of cname records for interface endpoints in a shared service vpc..