John McGehee
John McGehee

Reputation: 10309

Why error, "alias target name does not lie within the target zone" in Terraform aws_route53_record?

With Terraform 0.12, I am creating a static web site in an S3 bucket:

...

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

I get the error:

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

What is wrong?

Upvotes: 26

Views: 25491

Answers (3)

satish.k
satish.k

Reputation: 56

For anyone who is trying to create a PHZ and 'A' recordset for a VPC endpoint, using cloudformation then below code will be useful.

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]]]

Upvotes: 0

Mohamad
Mohamad

Reputation: 1065

For anyone like me that came here from Google in hope to find the syntax for the CloudFormation and YML, Here is how you can achieve it for your sub-domains.

Here we add a DNS record into the Route53 and redirect all the subnets of example.com to this 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"

My mistakes was:

  • not adding . at the end of my HostedZoneName
  • under AliasTarget.HostedZoneId ID is al uppercase in the end of CanonicalHostedZoneID
  • replace the [ALB_LOGICAL_ID] with the actual name of your ALB, for me it was like: ALBStages.DNSName
  • You should have the zone in your Route53.

So for us all the below addresses will come to this 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

Upvotes: 2

John McGehee
John McGehee

Reputation: 10309

The zone_id within alias is the S3 bucket zone ID, not the Route 53 zone ID. The correct aws_route53_record resource is:

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

Here is an example for CloudFront. The variables are:

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

The Terraform code is:

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

Many users specify CloudFront zone_id = "Z2FDTNDATAQYW2" because it's always Z2FDTNDATAQYW2...until some day maybe it isn't. I like to avoid the literal string by computing it using data source aws_cloudfront_distribution.

Upvotes: 48

Related Questions