Route53 configuration for Elastic Beanstalk

The AWS documentation is extensive, yet I find it both incomprehensible and overwhelming from time to time. Recently, I struggled to configure a HostedZoneId in a Route53 AliasTarget targeting an Elastic Beanstalk environment using CloudFormation.

Challenge

I had an ElasticBeanstalk environment with an ELB (such as the Elastic Beanstalk Node.js sample application available at the AWS site). Now, the task was to configure DNS based on a Route53 Alias Resource Record Set (see Choosing Between Alias and Non-Alias Resource Record Sets for an explanation).

Configuration

I started by adding a parameter for the domain name:

Next, I added two resources for the HostedZone and the RecordSet:

HostedZoneId for AliasTarget?

The most difficult obstacle was to find the correct value for the HostedZoneId for the AliasTarget configuration (marked as ??? above) . Normally, when configuring an ELB using the AWS::ElasticLoadBalancing::LoadBalancer resource, one can use { "Fn::GetAtt" : ["myELB", "CanonicalHostedZoneNameID"] } to get the id of the hosted zone. Unfortunately, this option is not available for Beanstalk environments so that does not work.

Next, I found a table in the AWS documentation that maps AWS regions to Amazon Route 53 Hosted Zone ID. According to the table, the HostedZoneId for eu-west-1 where my stack resides should be Z2NYPWQ7DFZAZH. However, the stack update failed miserably:

20:31:03 UTC+0200 CREATE_FAILED AWS::Route53::RecordSet SampleRecordSet Tried to create an alias that targets awseb-e-n-AWSEBLoa-[ABCDEFGHIJKLK-1234567890].eu-west-1.elb.amazonaws.com., type A in zone Z2NYPWQ7DFZAZH, but the alias target name does not lie within the target zone

What to do? By deploying just the Beanstalk configuration (before adding Route53) it is possible to lookup the Hosted Zone Id, either by looking at the “Load Balancers” in the EC2 service in the AWS console, or by calling the CLI:

I updated the HostedZoneId in the CloudFormation template to Z3NF1Z3NOM5OY2 and it worked.

Solution

Now that I knew what to look for, it was easier to find relevant hits. Some Googling revealed this issue that contains a list of AWS regions mapped to Beanstalks HostedZoneIds. The author claims that the mapping can be used for all accounts. Consequently, I added the following mapping to the template:

And updated the configuration of the AWS::Route53::RecordSet accordingly:

What’s next?

By now, Route53 should be successfully configured, however that does not mean that DNS is working. Depending on where you have registered your domain, you need to Configuring Amazon Route 53 as Your DNS Service (specifically, take a closer look at Updating Your Registrar’s Name Servers).
It may also interest you that Route 53 can also be used for registering and transferring domain names to AWS.

Resources

12 Comments

  1. Since January 2016 Route53 supports Alias records that point directly to your environments CNAME. This should be more stable than pointing to the ELB as the ELB may be replaced for certain updates.

    More here: https://aws.amazon.com/about-aws/whats-new/2016/01/aws-elastic-beanstalk-adds-support-for-amazon-route-53-aliasing/

    And a complete list of EB HostedZones: http://docs.aws.amazon.com/general/latest/gr/rande.html#elasticbeanstalk_region (this page has all HostedZone IDs for Route53, useful page to bookmark :) )

    • @Carl: Thank you for your comments.

      You wrote “This should be more stable than pointing to the ELB as the ELB may be replaced for certain updates.”. Do you know if this is a problem? I got the impression that using Alias resource record sets are robust enough to handle changes of the Beanstalk’s ELB. Copied from the AWS docs:

      Alias resource record sets can save you time because Amazon Route 53 automatically recognizes changes in the resource record sets that the alias resource record set refers to. For example, suppose an alias resource record set for example.com points to an ELB load balancer at lb1-1234.us-east-1.elb.amazonaws.com. If the IP address of the load balancer changes, Amazon Route 53 will automatically reflect those changes in DNS answers for example.com without any changes to the hosted zone that contains resource record sets for example.com.

      As I described above, I tried to use the values from the very same table that you mentioned with EB HostedZone Ids for mapping HostedZone Ids to Route 53 Alias target without success (this was when I experienced the error Tried to create an alias that targets [...], type A [...], but the alias target name does not lie within the target zone described in the blog). I guess they work much better when working with CNAMEs…

  2. Shakeel

    Thank you so much for writing this up! There are times where I really want to find a product manager over at Amazon and slap them and ask them what they were thinking! If you can get the elasticbeanstalk name that they talk about in the cloudformations script, you could use the hostedzoneid that they present to you. Unfortunately, a GetAtt for EndpointURL on the EB gives you the LB url, and there doesn’t seem to be a way to get the EB CName. :( So, without your article, I might have spent many many hours trying to figure out how the heck to create that damn alias, so thank you very much, specifically for the mapping, that’s what I really needed. Saved me a bunch of time

    • @Shakeel: You are welcome. I had similar thoughts but failed to find a working solution, hence this blog post.

    • John Aitchison

      Thanks for the great article and comment here, I was facing the same issue of not having a way to Ref an Elastic Beanstalk CNAME URL in CloudFormation. There is a way to accomplish it though. First, in AWS::ElasticBeanstalk::Environment you can set a CNAMEPrefix, for example “prod-mysite”. This will cause Elastic Beanstalk to create your environment with a CNAME of something like “prod-mysite.us-west-2.elasticbeanstalk.com” The ending of the URL will be different based on what AWS region you are in, that example is for US Oregon.

      Now you have a known CNAME for your EB environment, which you can then reference in your DNS Record set simply:
      “DNSName”: “prod-mysite.us-west-2.elasticbeanstalk.com”

      As a side note, I highly recommend using a templating engine like Nunjucks for creating Cloudformation Templates. It will save you a lot of time and uncessary repition of code.

  3. You rock. Thanks so much for posting this!

    • @Paco: Thank you for comment. Have you tried using the documented hosted zone ids on the page that you linked to in a similar context like mine? The reason I ask is that the link that you provided is the very same one that I mentioned in the blog post where I found HostedZoneId Z2NYPWQ7DFZAZH. As explained above, this did not work when I wrote the blog post.

  4. Harish Gautam

    Thanks you hit the mark this is what i was looking

Leave a Reply