Blog

How to deploy AWS SES Domain Identities and DKIM records using CloudFormation

14 Nov, 2019
Xebia Background Header Wave

In AWS CloudFormation there is no way to generate SES domain identities or obtain the DKIM tokens required to send and receive emails using AWS Simple Email Service. As we strive for 100% reproducibility, we created a custom provider for both the domain identity
and DKIM validation tokens. These custom providers return both the tokens and the required DNS record sets which are required
to validate the domain and email sender.

How do I add SES Domain Identity in CloudFormation?

It is quite easy: you specify a CloudFormation resource of type Custom::DomainIdentity:

Resources:
  DomainIdentity:
    Type: Custom::DomainIdentity
    Properties:
      Domain: !Ref 'ExternalDomainName'
      Region: !Ref 'EmailRegion'
      ServiceToken: !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:binxio-cfn-ses-provider'

This will create a domain identity in the specified region, and returns both the validation token and the DNS records as attributes. To proof to SES that you own the domain, you have to add a Route53 record set:

  DomainVerificationRecord:
    Type: AWS::Route53::RecordSetGroup
    Properties:
        Comment: !Sub 'SES identity for ${ExternalDomainName}'
        HostedZoneId: !Ref 'HostedZone'
        RecordSets: !GetAtt 'DomainIdentity.RecordSets'

How do I get DKIM tokens in CloudFormation?

It is quite easy: you specify a CloudFormation resource of type Custom::DkimTokens:

Resources:
  DkimTokens:
    Type: Custom::DkimTokens
    Properties:
      Domain: !GetAtt 'DomainIdentity.Domain'
      Region: !GetAtt 'DomainIdentity.Region'
      ServiceToken: !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:binxio-cfn-ses-provider'

This will return the DKIM tokens and the DNS records as attributes, for an existing domain identity. This allows the
receiver to validate that the messages were sent by the owner of the domain.
You can use this as follows:

  DkimRecords:
    Type: AWS::Route53::RecordSetGroup
    Properties:
      HostedZoneId: !Ref 'HostedZone'
      RecordSets: !GetAtt 'DkimTokens.RecordSets'

Installation

To install these custom resources, type:

git clone https://github.com/binxio/cfn-ses-provider.git
cd cfn-ses-provider
aws cloudformation deploy 
    --capabilities CAPABILITY_IAM 
    --stack-name cfn-ses-provider 
    --template-file ./cloudformation/cfn-resource-provider.yaml 

This CloudFormation template will use our pre-packaged provider from s3://binxio-public-{{your-region}}/lambdas/cfn-ses-provider-0.6.1.zip.

Demo

To install the demo of this Custom Resource, type:

aws cloudformation deploy 
    --stack-name cfn-ses-provider-demo 
    --template-file ./cloudformation/demo-stack.yaml

view the installed identity:

aws --region eu-west-1 ses list-identities

Conclusion

By using the Custom CloudFormation SES provider you can create Domain Identities and DKIM tokens. This ensures that your complete environment can be defined using CloudFormation and is fully reproducible without manual interventions.

Once you have your SES domain identity configured, you may also want to read about deploying your AWS SES access key and SMTP password to the parameter store using AWS CloudFormation.

If you have any questions, do not hesitate to contact me.

Mark van Holsteijn
Mark van Holsteijn is a senior software systems architect at Xebia Cloud-native solutions. He is passionate about removing waste in the software delivery process and keeping things clear and simple.
Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts