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:
- I have successfully managed to setup Route 53 alias resource record to the same Beanstalk Environments in the AWS console following the description To add an alias resource record set in Amazon Route 53, so it is "just" a question about transferring these configuration steps to the CloudFormation template.
- The stack is deployed in
eu-west-1
. - Instead of using the
AWS::Route53::RecordSetGroup
resource I have also tried to create two separateAWS::Route53::RecordSet
resources, but the stack update failed with the same error.