What is the correct Route 53 CloudFormation configuration to alias sub-domain names to an Elastic Beanstalk Environment ELBs?
I have copied the HostedZoneId
s from the Amazon Route 53 Hosted Zone ID table to mappings:
"Beanstalk2Route53HostedZoneId" : {
"us-east-1" : { "HostedZoneId": "Z117KPS5GTRQ2G" },
"us-west-1" : { "HostedZoneId": "Z1LQECGX5PH1X" },
"us-west-2" : { "HostedZoneId": "Z38NKT9BP95V3O" },
"eu-west-1" : { "HostedZoneId": "Z2NYPWQ7DFZAZH" },
"eu-central-1" : { "HostedZoneId": "Z1FRNW7UH4DEZJ" },
"ap-northeast-1" : { "HostedZoneId": "Z1R25G3KIG2GBW" },
"ap-northeast-2" : { "HostedZoneId": "Z3JE5OI70TWKCP" },
"ap-southeast-1" : { "HostedZoneId": "Z16FZ9L249IFLT" },
"ap-southeast-2" : { "HostedZoneId": "Z2PCDNR3VC2G1N" },
"sa-east-1" : { "HostedZoneId": "Z10X7K2B4QSOFV" }
}
My resources have two Beanstalk Environments:
"MyBeanstalkConfig": {
"Type": "AWS::ElasticBeanstalk::ConfigurationTemplate",
"Properties": {
"OptionSettings": {
{ "Namespace": "aws:elb:listener:80", "OptionName": "ListenerEnabled", "Value" : "false" },
{ "Namespace": "aws:elb:listener:443", "OptionName": "ListenerEnabled", "Value" : "true" },
{ "Namespace": "aws:elb:listener:443", "OptionName": "InstancePort", "Value" : "8081" },
{ "Namespace": "aws:elb:listener:443", "OptionName": "ListenerProtocol", "Value" : "HTTPS" },
{ "Namespace": "aws:elb:listener:443", "OptionName": "SSLCertificateId", "Value" : "arn:aws:iam::[accountNbr]:server-certificate/example-cert-name" },
[...]
}
}
},
"MyStageBeanstalkEnv": {
"Type": "AWS::ElasticBeanstalk::Environment",
"Properties": {
"Description": "Stage Environment",
"TemplateName": { "Ref": "MyBeanstalkConfig" },
[...]
}
},
"MyProdBeanstalkEnv": {
"Type": "AWS::ElasticBeanstalk::Environment",
"Properties": {
"Description": "Production Environment",
"TemplateName": { "Ref": "MyBeanstalkConfig" },
[...]
}
},
Outputs:
"StageEndpoint" : {
"Description" : "endpoint of the stage environment",
"Value" : { "Fn::GetAtt" : [ "MyStageBeanstalkEnv", "EndpointURL" ] }
},
"ProdEndpoint" : {
"Description" : "endpoint of the production environment",
"Value" : { "Fn::GetAtt" : [ "MyProdBeanstalkEnv", "EndpointURL" ] }
}
Both the stage and the prod Beanstalk Environments are working, i.e. they respond to calls to MyStageBeanstalkEnv.eu-west-1.elasticbeanstalk.com
as well as the endpoints returned by { "Fn::GetAtt" : [ "MyStageBeanstalkEnv", "EndpointURL" ] }
(which look like awseb-[abc-123-xyz].eu-west-1.elb.amazonaws.com
).
Unsurprisingly, the cert is not valid since it expects the domain name to be either stage.example.com
or prod.example.com
.
Now I attempt to add Route 53 configuration:
"ExampleDomainHostedZone": {
"Type" : "AWS::Route53::HostedZone",
"Properties" : {
"Name" : "example.com"
}
},
"ExampleDomainRecordSetGroup" : {
"Type" : "AWS::Route53::RecordSetGroup",
"Properties" : {
"HostedZoneId" : { "Ref": "ExampleDomainHostedZone" },
"RecordSets" : [{
"AliasTarget" : {
"DNSName" : { "Fn::GetAtt" : ["MyStageBeanstalkEnv", "EndpointURL"] },
"EvaluateTargetHealth" : false,
"HostedZoneId" : { "Fn::FindInMap" : [ "Beanstalk2Route53HostedZoneId", {"Ref" : "AWS::Region"}, "HostedZoneId" ]}
},
"Name" : "stage.example.com",
"Type": "A"
},
{
"AliasTarget" : {
"DNSName" : { "Fn::GetAtt" : ["MyProdBeanstalkEnv", "EndpointURL"] },
"EvaluateTargetHealth" : false,
"HostedZoneId" : { "Fn::FindInMap" : [ "Beanstalk2Route53HostedZoneId", {"Ref" : "AWS::Region"}, "HostedZoneId" ]}
},
"Name" : "prod.example.com",
"Type": "A"
}]
}
},
When I attempt to update the CloudFormation stack I get the following error in the AWS console:
16:12:00 UTC+0200 CREATE_FAILED AWS::Route53::RecordSetGroup ExampleDomainRecordSetGroup Tried to create an alias that targets awseb-[abc-123-xyz].eu-west-1.elb.amazonaws.com., type A in zone Z2NYPWQ7DFZAZH, but the alias target name does not lie within the target zone
In this context, awseb-[abc-123-xyz].eu-west-1.elb.amazonaws.com
is the same URL as provided by the Beanstalk ELB.
Comments:
eu-west-1
.AWS::Route53::RecordSetGroup
resource I have also tried to create two separate AWS::Route53::RecordSet
resources, but the stack update failed with the same error.Elastic Beanstalk automatically handles the deployment, from capacity provisioning, load balancing, auto-scaling to application health monitoring based on the code you upload to it, where as CloudFormation is an automated provisioning engine designed to deploy entire cloud environments via a JSON script.
CloudFormation supports Elastic Beanstalk application environments. This allows you, for example, to create and manage an AWS Elastic Beanstalk–hosted application along with an RDS database to store the application data.
Open the Elastic Beanstalk console , and in the Regions list, select your AWS Region. In the navigation pane, choose Environments, and then choose the name of your environment from the list.
Some Googling hinted that (1, 2) the Amazon Route 53 Hosted Zone ID cannot be used when configuring alias. It is stated that eu-west-1
has the Hosted Zone ID Z2NYPWQ7DFZAZH
for the elasticbeanstalk.eu-west-1.amazonaws.com
endpoint. However, when double-checking the ELB configuration of what Beanstalk actually generated by using the AWS CLI I found that:
$ aws elb describe-load-balancers --region eu-west-1
{
"LoadBalancerDescriptions": [
{
[...]
"CanonicalHostedZoneNameID": "Z3NF1Z3NOM5OY2",
"CanonicalHostedZoneName": "awseb-[abc-123-xyz].eu-west-1.elb.amazonaws.com",
}
]
}
In other words, the hosted zone name id is different. Moreover, the CanonicalHostedZoneName
is equal to the DNSName
in the AliasTarget
, i.e. awseb-[abc-123-xyz].eu-west-1.elb.amazonaws.com
, which is not the same endpoint as elasticbeanstalk.eu-west-1.amazonaws.com
used in Amazon Route 53 Hosted Zone ID. Consequently, I changed the mappings to include the CanonicalHostedZoneNameID
provided from the CLI output:
"Beanstalk2Route53HostedZoneId" : {
"eu-west-1" : { "HostedZoneId": "Z3NF1Z3NOM5OY2" }
}
Now the stack could be updated successfully. Regrettably only for eu-west-1
, but the procedure can be updated if / when I deploy the stack to other regions.
After the stack was updated, there was still no response from the DNS names (stable.example.com
and unstable.example.com
). Updating Your Registrar's Name Servers solved that problem.
I had same problem with Route53 Alias for CloudFront. I build HostedZOneId mapping but it never worked for me, by searching AWS documentation I find this:
The hosted zone ID.
For load balancers, use the canonical hosted zone ID of the load balancer.
For Amazon S3, use the hosted zone ID for your bucket's website endpoint.
For CloudFront, use Z2FDTNDATAQYW2.
For a list of hosted zone IDs of other services, see the relevant service in the AWS Regions and Endpoints.
So I just hard-coded it:
"AliasTarget": {
"HostedZoneId": "Z2FDTNDATAQYW2",
"DNSName": {
"Fn::GetAtt": ["MyCloudFrontDistribution", "DomainName"]
}
}
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-aliastarget.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With