如何使用CloudFormation将域名别名为Elastic Beanstalk环境?

时间:2016-05-03 15:38:11

标签: amazon-web-services elastic-beanstalk amazon-cloudformation amazon-route53 amazon-elastic-beanstalk

正确的Route 53 CloudFormation配置是什么将子域名别名别名为Elastic Beanstalk环境ELB?

我已将HostedZoneIdAmazon Route 53 Hosted Zone ID表复制到映射:

"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" }
}

我的资源有两个Beanstalk环境:

"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" },
    [...]
  }
},

输出:

"StageEndpoint" : {
  "Description" : "endpoint of the stage environment",
  "Value" : { "Fn::GetAtt" : [ "MyStageBeanstalkEnv", "EndpointURL" ] }
},
"ProdEndpoint" : {
  "Description" : "endpoint of the production environment",
  "Value" : { "Fn::GetAtt" : [ "MyProdBeanstalkEnv", "EndpointURL" ] }
}

舞台和prod Beanstalk环境都在工作,即它们响应对MyStageBeanstalkEnv.eu-west-1.elasticbeanstalk.com的调用以及{ "Fn::GetAtt" : [ "MyStageBeanstalkEnv", "EndpointURL" ] }返回的端点(看起来像awseb-[abc-123-xyz].eu-west-1.elb.amazonaws.com)。 不出所料,该证书无效,因为它希望域名为stage.example.comprod.example.com

现在我尝试添加Route 53配置:

"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"
    }]
  }
},

当我尝试更新CloudFormation堆栈时,我在AWS控制台中收到以下错误:

  

16:12:00 UTC + 0200 CREATE_FAILED AWS :: Route53 :: RecordSetGroup ExampleDomainRecordSetGroup尝试创建一个目标为awseb- [abc-123-xyz] .eu-west-1.elb.amazonaws.com。的别名。在区域Z2NYPWQ7DFZAZH中输入A,但别名目标名称不在目标区域内

在此上下文中,awseb-[abc-123-xyz].eu-west-1.elb.amazonaws.com与Beanstalk ELB提供的URL相同。

评论:

  • 我已成功设法将Route 53别名资源记录设置为遵循描述To add an alias resource record set in Amazon Route 53的AWS控制台中的相同Beanstalk环境,因此这只是关于将这些配置步骤传输到CloudFormation模板的问题。
  • 堆栈部署在eu-west-1
  • 我没有使用AWS::Route53::RecordSetGroup资源,而是尝试创建两个单独的AWS::Route53::RecordSet资源,但堆栈更新失败并出现相同的错误。

3 个答案:

答案 0 :(得分:9)

一些Google搜索提示,在配置别名时,12Amazon Route 53 Hosted Zone ID无法使用。据称,eu-west-1具有Z2NYPWQ7DFZAZH端点的托管区域ID elasticbeanstalk.eu-west-1.amazonaws.com。但是,当仔细检查使用AWS CLI实际生成的Beanstalk的ELB配置时,我发现:

$ aws elb describe-load-balancers --region eu-west-1
{
    "LoadBalancerDescriptions": [
        {
            [...]
            "CanonicalHostedZoneNameID": "Z3NF1Z3NOM5OY2",
            "CanonicalHostedZoneName": "awseb-[abc-123-xyz].eu-west-1.elb.amazonaws.com",
        }
    ]
}

换句话说,托管区域名称ID是不同的。此外,CanonicalHostedZoneName等于DNSName中的AliasTarget,即awseb-[abc-123-xyz].eu-west-1.elb.amazonaws.com,这与Amazon Route 53 Hosted Zone ID中使用的elasticbeanstalk.eu-west-1.amazonaws.com不同}。因此,我更改了映射以包含CLI输出提供的CanonicalHostedZoneNameID

"Beanstalk2Route53HostedZoneId" : {
  "eu-west-1" : { "HostedZoneId": "Z3NF1Z3NOM5OY2" }
}

现在可以成功更新堆栈。遗憾的是,只有eu-west-1,但是如果/当我将堆栈部署到其他区域时,可以更新该过程。

更新堆栈后,DNS名称(stable.example.comunstable.example.com)仍然没有响应。 Updating Your Registrar's Name Servers解决了这个问题。

答案 1 :(得分:6)

CloudFront的Route53 Alias也遇到了同样的问题。 我构建了HostedZOneId映射,但它从来没有对我有用, 通过搜索AWS文档,我发现了这个:

  

托管区域ID。

     

对于负载均衡器,请使用负载均衡器的规范托管区域ID。

     

对于Amazon S3,请使用托管网站端点的托管区域ID。

     

对于CloudFront,请使用Z2FDTNDATAQYW2。

     

有关其他服务的托管区域ID的列表,请参阅AWS区域和端点中的相关服务。

所以我只是硬编码:

"AliasTarget": {
    "HostedZoneId": "Z2FDTNDATAQYW2",
    "DNSName": {
        "Fn::GetAtt": ["MyCloudFrontDistribution", "DomainName"]
    }
}

http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-aliastarget.html

答案 2 :(得分:0)

有两种方法可以通过别名从Route53连接到ElasticBeanstalk:

  1. 使用ElasticBeanstalk端点,例如foobar.u8k2abcm4.eu-central-1.elasticbeanstalk.com/
  2. 使用ElasticBeanstalk环境中的LoadBalancer的端点,例如awseb-[abc-123-xyz].eu-west-1.elb.amazonaws.com

"Fn::GetAtt" : ["BeanstalkEnvironment", "EndpointURL"]返回的值是LoadBalancer端点(docs),因此必须使用LoadBalancer映射表,请参见here(而不是ElasticBeanstalk的那个)。

不确定在ElasticBeanstalk Env负载不平衡的情况下是否/如何工作。