为什么在Terraform aws_route53_record中会出现错误“别名目标名称不在目标区域内”?

24

使用 Terraform 0.12,在 S3 存储桶中创建静态网站:

...

resource "aws_s3_bucket" "www" {
  bucket = "example.com"
  acl    = "public-read"
  policy = <<-POLICY
    {
      "Version": "2012-10-17",
      "Statement": [{
        "Sid": "AddPerm",
        "Effect": "Allow",
        "Principal": "*",
        "Action": ["s3:GetObject"],
        "Resource": ["arn:aws:s3:::example.com/*"]
      }]
    }
    POLICY
  website {
    index_document = "index.html"
    error_document = "404.html"
  }

  tags = {
    Environment = var.environment
    Terraform = "true"
  }
}

resource "aws_route53_zone" "main" {
  name = "example.com"

  tags = {
    Environment = var.environment
    Terraform = "true"
  }
}

resource "aws_route53_record" "main-ns" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "example.com"
  type    = "A"
  alias {
    name                   = aws_s3_bucket.www.website_endpoint
    zone_id                = aws_route53_zone.main.zone_id
    evaluate_target_health = false
  }
}

我遇到了错误:

Error: [ERR]: Error building changeset: InvalidChangeBatch:
[Tried to create an alias that targets example.com.s3-website-us-west-2.amazonaws.com., type A in zone Z1P...9HY, but the alias target name does not lie within the target zone, 
 Tried to create an alias that targets example.com.s3-website-us-west-2.amazonaws.com., type A in zone Z1P...9HY, but that target was not found]
    status code: 400, request id: 35...bc

  on main.tf line 132, in resource "aws_route53_record" "main-ns":
 132: resource "aws_route53_record" "main-ns" {

有什么问题吗?

3个回答

39

alias 中的 zone_id 是 S3 存储桶区域 ID,而不是 Route 53 区域 ID。正确的 aws_route53_record 资源如下:

resource "aws_route53_record" "main-ns" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "example.com"
  type    = "A"
  alias {
    name                   = aws_s3_bucket.www.website_endpoint
    zone_id                = aws_s3_bucket.www.hosted_zone_id    # Corrected
    evaluate_target_health = false
  }
}

这里是 CloudFront 的示例。变量如下:

base_url = example.com
cloudfront_distribution = "EXXREDACTEDXXX"
domain_names = ["example.com", "www.example.com"]

Terraform代码如下:

data "aws_route53_zone" "this" {
  name = var.base_url
}

data "aws_cloudfront_distribution" "this" {
  id = var.cloudfront_distribution
}

resource "aws_route53_record" "this" {
  for_each = toset(var.domain_names)
  zone_id = data.aws_route53_zone.this.zone_id
  name = each.value
  type = "A"
  alias {
    name    = data.aws_cloudfront_distribution.this.domain_name
    zone_id = data.aws_cloudfront_distribution.this.hosted_zone_id
    evaluate_target_health = false
  }
}

许多用户指定CloudFront zone_id = "Z2FDTNDATAQYW2",因为它总是Z2FDTNDATAQYW2,直到某一天它可能不再是。 我喜欢通过使用数据源aws_cloudfront_distribution来计算避免文字字符串。


3
将此放在这里,以便寻找此内容的任何人: https://docs.aws.amazon.com/Route53/latest/APIReference/API_AliasTarget.html对于Cloudfront,它是一个标准的HostedZoneID: Z2FDTNDATAQYW2 - Schalton
1
你在我刚要添加一个CloudFront示例的时候发表了评论! - John McGehee
1
Terraform 在他们的文档中有一个不错的示例:https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/s3_bucket#route53-record - Karl Anka
谢谢Karl,这正是我想要的(S3存储桶Route53记录示例)。 - Dylan Hogg

2

对于像我这样从谷歌搜索云编排和YML语法的人,以下是如何为您的子域实现它的方法。

在这里,我们向Route53添加DNS记录,并将example.com的所有子网重定向到此ALB:

AlbDnsRecord:
    Type: "AWS::Route53::RecordSet"
    DependsOn: [ALB_LOGICAL_ID]
    Properties:
      HostedZoneName: "example.com."
      Type: "A"
      Name: "*.example.com."
      AliasTarget:
        DNSName: !GetAtt [ALB_LOGICAL_ID].DNSName
        EvaluateTargetHealth: False
        HostedZoneId: !GetAtt [ALB_LOGICAL_ID].CanonicalHostedZoneID
      Comment: "A record for Stages ALB"

我的错误是:

  • 没有在我的HostedZoneName的结尾添加.
  • AliasTarget.HostedZoneId下的ID在CanonicalHostedZoneID的末尾全是大写字母
  • 用你的ALB的实际名称替换[ALB_LOGICAL_ID],对我来说像这样:ALBStages.DNSName
  • 你应该在Route53中拥有该区域。

因此,所有以下地址都将进入此ALB:

  • dev01.example.com
  • dev01api.example.com
  • dev02.example.com
  • dev02api.example.com
  • qa01.example.com
  • qa01api.example.com
  • qa02.example.com
  • qa02api.example.com
  • uat.example.com
  • uatapi.example.com

0
对于任何试图为VPC端点创建PHZ和'A'记录集的人,使用CloudFormation的下面代码将会很有用。
AWSTemplateFormatVersion: "2010-09-09"
Resources:
  EC2Endpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ec2'
      SubnetIds: 
        - subnet-1
        - subnet-2
        - subnet-3
      VpcEndpointType: Interface
      VpcId: vpc-id
      Tags:
        - Key: Name
          Value: EC2-Endpoint
  EC2PHZ:
    Type: "AWS::Route53::HostedZone"
    Properties: 
      HostedZoneConfig: 
        Comment: 'PHZ for ec2 vpc endpoint'
      Name: !Sub 'ec2.${AWS::Region}.amazonaws.com'
      VPCs: 
        - 
          VPCId: vpc-id
          VPCRegion: !Ref "AWS::Region"
  EC2ARecord:
    Type: AWS::Route53::RecordSet
    Properties:
      Name: !Sub 'ec2.${AWS::Region}.amazonaws.com'
      HostedZoneId: !Ref EC2PHZ
      Type: A
      AliasTarget:
       HostedZoneId: !Select [0, !Split [":", !Select [0, !GetAtt EC2Endpoint.DnsEntries]]]
       DNSName: !Select [1, !Split [":", !Select [0, !GetAtt EC2Endpoint.DnsEntries]]]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接