question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

aws-ses: DKIM records are created with incorrect name from EmailIdentity

See original GitHub issue

Describe the bug

When creating a new ses.EmailIdentity construct, the names of the DKIM records that get created in Route53 are incorrect.

Expected Behavior

If the DKIM record name is x.y.example.com, and the hosted zone is y.example.com, the name of the record that gets set in Route53 should be x.y.example.com

Current Behavior

If the DKIM record name is x.y.example.com, and the hosted zone is y.example.com, the name of the record that gets set in Route53 should is x.y.example.com.y.example.com

Reproduction Steps

Here is a simple reproduction case:

const myHostedZone = ...; // However you're grabbing or creating your hosted zone

const sesIdentity = new ses.EmailIdentity(this, "ses-identity", {
  identity: ses.Identity.publicHostedZone(hostedZone),
  mailFromDomain: `mail.${hostedZoneDomain}`,
});

Possible Solution

The reason for the incorrect record names is because of the function here in the source code:.

https://github.com/aws/aws-cdk/blob/ac323408383b6eb40c3d08a7537a117227370d99/packages/%40aws-cdk/aws-ses/lib/email-identity.ts#L220-L237

It calls route53.CnameRecord, which accepts a record name excluding the hosted zone suffix - eg. for x.y.example.com where the hosted zone is y.example.com, the record name should just be x.

However, it’s passing in dkimDnsTokenName1 etc, which according to the Cloudformation docs, is the entire host for the record, including the hosted zone.

This means that route53.CnameRecord tried to append the hosted zone name onto the end of the record name which already includes the hosted zone name, leading to the duplication.

This can be seen in a cdk synth:

...
    Type: AWS::Route53::RecordSet
    Properties:
      Name:
        Fn::Join:
          - ""
          - - Fn::GetAtt:
                - <Our SES Entity ID>
                - DkimDNSTokenName1
            - .y.example.com.
      Type: CNAME
...

There are 2 fixes that I can think of:

  1. Call CfnRecordSet rather than CnameRecord - eg:
new route53.CfnRecordSet(emailIdentity, "DkimDnsToken1", {
  hostedZoneName: hostedZone.zoneName + ".",
  name: Lazy.string({ produce: () => emailIdentity.dkimDnsTokenName1 }),
  type: "CNAME",
  resourceRecords: [Lazy.string({ produce: () => emailIdentity.dkimDnsTokenValue1 })],
  ttl: "1800",
})
  1. Use a hacky workaround to lop off the suffix before passing to CnameRecord - by combining cdk.Fn.select and cdk.Fn.split to remove the last part of the string. Here’s how that would look:
// This function removes a string from the end of another string using Cfn functions.
// For example, calling it on "abcd" with suffix "cd" would return "ab".
// We accomplish this by splitting by the suffix (which gives ["ab"]), then selecting the 0th value.
const hackyCfnRemoveSuffix = (sourceString: string, suffixToRemove: string) =>
  cdk.Fn.select(0, cdk.Fn.split(suffixToRemove, sourceString));

// Then use it in the bind function
new route53.CnameRecord(emailIdentity, 'DkimDnsToken1', {
  zone: hostedZone,
  recordName: hackyCfnRemoveSuffix(Lazy.string({ produce: () => emailIdentity.dkimDnsTokenName1 }), "." + hostedZone.zoneName),
  domainName: Lazy.string({ produce: () => emailIdentity.dkimDnsTokenValue1 }),
});

Additional Information/Context

No response

CDK CLI Version

2.29.0 (build 47d7ec4)

Framework Version

2.33.0

Node.js Version

v16.15.1

OS

MacOS

Language

Typescript

Language Version

No response

Other information

Workaround

For anyone else experiencing this issue - we’ve opted to go with the CfnRecordSet option as it’s a bit simpler to see what’s going on. Simply map through each of the dkimRecords after creating the EmailIdentity and create the correct records - note that this won’t remove the incorrect ones unfortunately.

Code below:

// Create SES email identity based on Route53 hosted zone
const sesIdentity = new ses.EmailIdentity(this, "ses-identity", {
  identity: ses.Identity.publicHostedZone(hostedZone),
  mailFromDomain: `mail.${hostedZone.zoneName}`,
});

// Temporary workaround: There is a bug with the EmailIdentity construct where if the DKIM record is x.y.example.com,
// and the hosted zone is y.example.com, the record that gets set is x.y.example.com.y.example.com. For now, we are
// manually creating the correct records.
const dkimCnameRecords = sesIdentity.dkimRecords.map(
  (dkimRecord, index) =>
    new route53.CfnRecordSet(this, `dkim-record-${index}`, {
      hostedZoneName: hostedZone.zoneName + ".",
      name: dkimRecord.name,
      type: "CNAME",
      resourceRecords: [dkimRecord.value],
      ttl: "1800",
    })
);

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:4
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
Booligooshcommented, Sep 27, 2022

Thanks for the fix! Just a note for @derekmurawsky and anyone else that was using the workaround I mentioned in the original issue and is wanting to upgrade to the fixed version of CDK.

When upgrading the version to get rid of the need for the workaround, we weren’t able to do it all in 1 deployment, as the DKIM records created by the workaround got deleted, but did not get re-created by the now fixed EmailIdentity.

We had to do the following:

  1. Remove the workaround of manually creating the CfnRecordSets (see above) and deploy. This will temporarily remove your correct DKIM records.
  2. Upgrade the CDK version and deploy. This will remove the incorrect DKIM records, and re-create the correct ones (but as part of the EmailIdentity).
2reactions
jogoldcommented, Jul 25, 2022

OK, got it, I see the duplication in the record.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Managing Easy DKIM and BYODDKIM - AWS Documentation
Obtaining DKIM Records for an identity · At the command line, type the following command: aws ses get-identity-dkim-attributes --identities " example.com " ·...
Read more >
How to remove a verified domain from AWS SES?
Either remove DKIM settings from the domain, which will mean disabling DKIM for the email address and removing the DKIM CNAME records from ......
Read more >
How to replace "via amazonses.com" with my apps branding ...
If the DKIM/SPF DNS records are set properly - it works well. But with email identities - AWS SES adds something like "via...
Read more >
Logging and Monitoring AWS SES Email Delivery Metrics
Create a DynamoDB table to store records written by the Lambda function ... aws ses verify-email-identity --email-address $ ...
Read more >
SESV2 — Boto3 Docs 1.26.36 documentation - Amazon AWS
If false , email sending is disabled for the configuration set. ... This typically occurs when Amazon SES fails to find the DKIM...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found