CDK permissions not created correctly after updating Amazon.CDK.Lib (not authorized to perform: route53:ChangeResourceRecordSets on resource)

0

Hello, We have the following situation:

  • The entire AWS infrastructure deployed through a DOTNET CDK solution.
  • Everything worked fine, but we were using AWS.CDK 1.204.0 packages, and had to update to Amazon.CDK.Lib (Version="2.150.0")
  • We are using Route53, and add some records through CDK

After the update, the CDK deployment fails with the records not being able to be added because of this error:

AppStack | 12:21:12 PM | CREATE_FAILED | AWS::CloudFormation::CustomResource | eu-west-1_***_Certificate/CertificateRequestorResource/Default (euwest1***CertificateRequestorResource7E52A588) Received response status [FAILED] from custom resource. 
Message returned: User: arn:aws:sts::123456789012:assumed-role/***-euwest1***Certifica-*** is not authorized to perform: route53:ChangeResourceRecordSets on resource: arn:aws:route53:::hostedzone/***
because no identity-based policy allows the route53:ChangeResourceRecordSets action (RequestId: 34541f0d-f625-413d-906a-58d4f5dd40ab)

At this time I can not test with the old version (as the 1.2 CDK generates some certificate lambdas with nodejs14, that refuse to deploy), so I only can assume that is something due to the update.

Does anyone know what could cause this, or had experienced a similar problem? Any input is much appreciated, thank you!

The code creating the hosted zone, domain and then add the records, look like this:

            var subDomain = $"{functionName}.example.com";
            IHostedZone hostedZone = HostedZone.FromHostedZoneAttributes(this, $"{Region}_{functionName}_HZ", new HostedZoneAttributes
            {
                HostedZoneId = "Z020000000000000000000", // Route53 Zone ID
                ZoneName = subDomain,
            });

            DnsValidatedCertificate certificate = new DnsValidatedCertificate(this, $"{Region}_{functionName}_Certificate", new DnsValidatedCertificateProps
            {
                DomainName = subDomain,
                HostedZone = hostedZone,
                Region = Region,
                Validation = CertificateValidation.FromDns(hostedZone),
            });

            IDomainName domain = new DomainName(this, $"{Region}_{functionName}_DomainName", new DomainNameProps
            {
                DomainName = subDomain,
                Certificate = certificate,
                SecurityPolicy = SecurityPolicy.TLS_1_2,
            });

            var dnsCfnRecordSet = new CfnRecordSet(this, $"{Region}_{functionName}_CfnRecordSet", new CfnRecordSetProps
            {
                HostedZoneId = hostedZone.HostedZoneId,
                Region = Region,
                Type = "A",
                Name = subDomain,
                AliasTarget = new CfnRecordSet.AliasTargetProperty
                {
                    DnsName = domain.RegionalDomainName,
                    HostedZoneId = domain.RegionalHostedZoneId,
                    EvaluateTargetHealth = false,
                },
                SetIdentifier = $"{functionName}_{Region}_id"
            });
2 Answers
2
Accepted Answer

Hello,

This issue mostly caused by caused the permission issue with Route53.

Attach IAM Policy to the Role:

  • Identify the IAM role used by your CDK application for deployments.
  • Attach an IAM policy to this role that grants permission for route53:ChangeResourceRecordSets on the specific hosted zone. You can use the AWS Management Console or the CDK code itself.

an example using CDK:

import * as iam from '@aws-cdk/aws-iam';

const role = new iam.Role(this, 'MyCDKDeploymentRole', {
    // ... other role properties
});

role.addToPolicy(new iam.PolicyStatement({
    effect: iam.Effect.ALLOW,
    actions: ['route53:ChangeResourceRecordSets'],
    resources: [hostedZone.hostedZoneId],
}));

Replace hostedZone.hostedZoneId with the actual ID of your Route53 hosted zone.

Verify Permissions:

  • After attaching the policy, try deploying your CDK application again.
  • If the issue persists, double-check the IAM policy attachment to the correct role and ensure there are no typos in the resource ID.

Review the documentation for IAM permissions in CDK v2: https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Policy.html

profile picture
EXPERT
answered 3 months ago
  • Thank you very much for the answer! But (as far as i understand at least) the IAM policy is generated when deploying / bootstrapping the stack, so i am not sure how to change it. Also didn't find a way to get the iam "current" role inside the stack code, to update the role's policy (if possible).

    Following your answer I inspected the stack template (output by "cdk synth" command) and i noticed that the AWS::IAM::Policy that (probably) should do the route53 change, has this declaration: - Action: route53:changeResourceRecordSets Condition: ForAllValues:StringEquals: route53:ChangeResourceRecordSetsRecordTypes: - CNAME route53:ChangeResourceRecordSetsActions: - UPSERT ForAllValues:StringLike: route53:ChangeResourceRecordSetsNormalizedRecordNames: - "*.<edited_name>.com" Effect: Allow while i try to add a Type="A" record set, i can see in the declaration specified the "CNAME" condition.

    Could this condition could be the cause of the operation failing? And if so, is there a way to change the generated template?

  • The CNAME condition in your IAM policy is indeed preventing the creation of A record sets. The route53:ChangeResourceRecordSetsRecordTypes condition is explicitly set to "CNAME", which limits the allowed record types.

    1. Try to create a new IAM policy.
    2. try this CDK Typescript.

    import * as route53 from 'aws-cdk-lib/aws-route53';

    const hostedZone = route53.HostedZone.fromHostedZoneAttributes(this, 'MyHostedZone', { hostedZoneId: 'Z0123456789ABCDEF0', zoneName: 'example.com', });

    new route53.ARecord(this, 'AliasRecord', { zone: hostedZone, recordName: 'www', target: route53.RecordTarget.fromAlias(new route53.AliasTarget( hostedZoneId: 'Z234567890ABCDEF0', // Replace with the target zone ID dnsName: 'my-load-balancer.us-east-1.elb.amazonaws.com', )), });

0

following up with an answer, as i can not paste images in the comment.

unfortunately my problem is that the IAM user and policy are auto-generated by CDK, and when failing they are rolled back so I can't edit them in AWS Console, also don't know how they are generated, as i can see that the CDK add these conditions to the created policies (Also briefly catching the policy alive before being rolled back, i can confirm it is created ok, but with the condition attached): Enter image description here

While inspecting such a policy in a production environment (produced with the same code before the update, last year) does not have that condition associated. Enter image description here

So it looks to be like AWS added a bit more restrictions, but my impression is that in this case it is more of a bug, as the condition is more restrictive than it needs be.

Thank you a lot for the help, Narravula, your input helped me a lot narrowing down the issue!

P.S. If you know how or if i can add/remove permissions to these IAM policies auto-generated by the CDK would also help me a big deal. Right now I can only think of some sort of workaround ugly solution.

answered 3 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions