Create Hosted Zone

In this section you will create an Amazon Route 53 public hosted zone for your desired domain. ExternalDNS will dynamically update the records of this zone based on the Ingress resources in your EKS cluster.

Choose one of the following options to create a hosted zone for your desired domain:

Check Your Environment

To create an Amazon Route 53 public hosted zone for your desired domain, you are going to deploy a CloudFormation stack. When working with AWS CloudFormation stacks to manage resources, not only do you need sufficient permissions on AWS CloudFormation, but also on the underlying resources that are defined in the template.

In order to create an Amazon Route 53 public hosted zone using AWS CloudFormation you need permissions for the following actions:

  • Deploy AWS CloudFormation stacks.
  • Create a public Route53 Hosted Zone.

Note

If you do not have the above permissions, contact your AWS administrator to grant sufficient permissions to your IAM user or deploy the below AWS CloudFormation stack for you.

Option 1: Create Hosted Zone Automatically (preferred)

Create a hosted zone by following the on-screen instructions on the rok-deploy user interface.

If rok-deploy is not already running, start it with:

root@rok-tools:~# rok-deploy --run-from eks-alb-zone
../../../../_images/eks-alb-zone1.png

Proceed to the Summary section.

Option 2: Create Hosted Zone Manually

If you want to create a hosted zone manually, follow the instructions below.

Procedure

  1. Go to your GitOps repository, inside your rok-tools management environment:

    root@rok-tools:~# cd ~/ops/deployments
  2. Restore the required context from previous sections:

    root@rok-tools:~/ops/deployments# source <(cat deploy/env.{envvars-aws,eks-cluster})
    root@rok-tools:~/ops/deployments# export AWS_DEFAULT_REGION EKS_CLUSTER
  3. Specify the DNS name suffix (domain) for the hosted zone:

    root@rok-tools:~/ops/deployments# export EKS_ALB_ZONE_DOMAIN=<DOMAIN>

    Replace <DOMAIN> with your desired domain. For example:

    root@rok-tools:~/ops/deployments# export EKS_ALB_ZONE_DOMAIN=apps.example.com
  4. List the hosted zones of your desired domain and ensure that there are no hosted zones for this domain, that is, the output of the following command is empty:

    root@rok-tools:~/ops/deployments# aws route53 list-hosted-zones \ > --query 'HostedZones[?Name==`'${EKS_ALB_ZONE_DOMAIN?}.'`].{ID:Id,Name:Name,Private:Config.PrivateZone}' \ > --output table

    Troubleshooting

    A hosted zone for the domain already exists

    If your desired domain already has one or more hosted zones, then go back to step 3 and select a new domain.

  5. Set the name of the CloudFormation stack you will deploy:

    root@rok-tools:~/ops/deployments# export EKS_ALB_ZONE_CF=rok-${AWS_DEFAULT_REGION?}\ > -${EKS_CLUSTER?}-zone
  6. Verify that the CloudFormation stack name you specified is not longer than 128 characters:

    root@rok-tools:~/ops/deployments# [[ ${#EKS_ALB_ZONE_CF} -le 128 ]] && echo OK || echo FAIL OK

    Troubleshooting

    The output of the command is FAIL

    Go back to step 5 and specify a shorter name. Ensure the new name is not already in use.

  7. Generate the AWS CloudFormation stack:

    root@rok-tools:~/ops/deployments# j2 rok/eks/eks-alb-hosted-zone.yaml.j2 \ > -o rok/eks/eks-alb-hosted-zone.yaml

    Alternatively, download the eks-alb-hosted-zone CloudFormation template provided below and use it locally.

    eks-alb-hosted-zone.yaml.j2
    1AWSTemplateFormatVersion: "2010-09-09"
    2
    3Description: Amazon EKS - Route53 Hosted Zone
    4-11
    4
    5Metadata:
    6 Rok::StackName: {{EKS_ALB_ZONE_CF}}
    7
    8Resources:
    9 HostedZone:
    10 Type: AWS::Route53::HostedZone
    11 Properties:
    12 HostedZoneConfig:
    13 Comment: Hosted Zone for EKF
    14 Name: {{EKS_ALB_ZONE_DOMAIN}}
  8. Commit your changes:

    root@rok-tools:~/ops/deployments# git commit -am "Create Hosted Zone"
  9. Deploy the CloudFormation stack:

    root@rok-tools:~/ops/deployments# aws cloudformation deploy \ > --stack-name ${EKS_ALB_ZONE_CF?} \ > --template-file rok/eks/eks-alb-hosted-zone.yaml Waiting for changeset to be created.. Waiting for stack create/update to complete Successfully created/updated stack - rok-us-west-2-arrikto-cluster-zone

    Troubleshooting

    AccessDenied

    If the above command fails with an error message similar to the following:

    An error occurred (AccessDenied) when calling the DescribeStacks operation: User: arn:aws:iam::123456789012:user/user is not authorized to perform: cloudformation:DescribeStacks on resource: arn:aws:cloudformation:us-west-2:123456789012:stack/rok-us-west-2-arrikto-cluster-zone

    it means that your IAM user does not have sufficient permissions to perform an action necessary to deploy an AWS CloudFormation stack.

    To proceed, Check Your Environment and contact your AWS administrator to grant sufficient permissions to your IAM user or deploy the AWS CloudFormation stack for you.

    Failed to create/update the stack

    If the above command fails with an error message similar to the following:

    Failed to create/update the stack. Run the following command to fetch the list of events leading up to the failure aws cloudformation describe-stack-events --stack-name rok-us-west-2-arrikto-cluster-zone

    describe the events of the CloudFormation stack to identify the root cause of the failure:

    root@rok-tools:~/ops/deployments# aws cloudformation describe-stack-events --stack-name ${EKS_ALB_ZONE_CF?}
    • A stack event like the following:

      { "StackId": "arn:aws:cloudformation:eu-west-2:123456789012:stack/rok-us-west-2-arrikto-cluster-zone/143da550-3374-11ec-bfb3-025974fba520", "EventId": "HostedZone-CREATE_FAILED-2021-10-22T20:10:29.320Z" "StackName": "rok-us-west-2-arrikto-cluster-zone", "LogicalResourceId": "HostedZone", "PhysicalResourceId": "", "ResourceType": "AWS::Route53::HostedZone", "Timestamp": "2021-10-22T20:10:29.320000+00:00", "ResourceStatus": "CREATE_FAILED", "ResourceStatusReason": "Resource handler returned message: \"User: arn:aws:iam::123456789012:user/user is not authorized to perform: route53:CreateHostedZone (Service: Route53, Status Code: 403, Request ID: fa4d580f-3760-4bf6-b1c1-c897cf8697a6, Extended Request ID: null)\" (RequestToken: f6606ab1-14da-a6bd-012e-78ae70061159, HandlerErrorCode: GeneralServiceException)", "ResourceProperties": "{\"HostedZoneConfig\":{\"Comment\":\"Hosted Zone for EKF\"},\"Name\":\"apps.example.com\"}" }

      means that your IAM user does not have sufficient permissions to create the hosted zone that the AWS CloudFormation stack defines.

      To proceed, Check Your Environment and contact your AWS administrator to grant your IAM user sufficient permissions or deploy the AWS CloudFormation stack for you.

    ValidationError

    If the above command fails with an error message similar to the following:

    An error occurred (ValidationError) when calling the CreateChangeSet operation: Stack:arn:aws:cloudformation:us-west-2:123456789012:stack/rok-us-west-2-arrikto-cluster-zone/671606f0-eb2b-11eb-8afb-0217413c9ed2 is in ROLLBACK_COMPLETE state and can not be updated.

    delete the stack and deploy it again.

  10. Obtain the zone ID:

    root@rok-tools:~/ops/deployments# export EKS_ALB_ZONE_ID=$(aws route53 list-hosted-zones \ > | jq -r '.HostedZones[] | select(.Name=="'${EKS_ALB_ZONE_DOMAIN?}.'") | .Id')
  11. Save your state:

    root@rok-tools:~/ops/deployments# rok-j2 deploy/env.eks-alb-zone.j2 \ > -o deploy/env.eks-alb-zone
  12. Commit your changes:

    root@rok-tools:~/ops/deployments# git commit -am "Create Hosted Zone - context"
  13. Mark your progress:

    root@rok-tools:~/ops/deployments# export DATE=$(date -u "+%Y-%m-%dT%H.%M.%SZ")
    root@rok-tools:~/ops/deployments# git tag \ > -a deploy/${DATE?}/release-2.0/eks-alb-zone \ > -m "Create Hosted Zone"
  14. Obtain the Amazon nameservers for your hosted zone:

    root@rok-tools:~/ops/deployments# aws route53 list-resource-record-sets \ > --output json \ > --hosted-zone-id ${EKS_ALB_ZONE_ID?} \ > --query "ResourceRecordSets[?Type == 'NS']" \ > | jq -r '.[0].ResourceRecords[].Value' ns-2048.awsdns-64.com ns-2049.awsdns-65.net ns-2050.awsdns-66.org ns-2051.awsdns-67.co.uk
  15. Update your nameservers to forward DNS queries for EKS_ALB_ZONE_DOMAIN to the Amazon nameservers found above.

Verify

  1. Go to your GitOps repository, inside your rok-tools management environment:

    root@rok-tools:~# cd ~/ops/deployments
  2. Restore the required context from previous sections:

    root@rok-tools:~/ops/deployments# source <(cat deploy/env.eks-alb-zone)
    root@rok-tools:~/ops/deployments# export EKS_ALB_ZONE_DOMAIN EKS_ALB_ZONE_ID
  3. Ensure that the hosted zone exists and is associated with your desired domain, that is, the output of the following command is not empty:

    root@rok-tools:~/ops/deployments# aws route53 list-hosted-zones \ > --query 'HostedZones[?(Id==`'${EKS_ALB_ZONE_ID?}'` && Name==`'${EKS_ALB_ZONE_DOMAIN?}.'`)].{ID:Id,Name:Name,Private:Config.PrivateZone}' \ > --output table -------------------------------------------------------------------------- | ListHostedZones | +------------------------------------+------------------------+----------+ | ID | Name | Private | +------------------------------------+------------------------+----------+ | /hostedzone/Z08893681AKMCJZ2MRWZ4 | apps.example.com | False | +------------------------------------+------------------------+----------+
  4. Obtain the Amazon nameservers for your hosted zone:

    root@rok-tools:~/ops/deployments# aws route53 list-resource-record-sets \ > --output json \ > --hosted-zone-id ${EKS_ALB_ZONE_ID?} \ > --query "ResourceRecordSets[?Type == 'NS']" \ > | jq -r '.[0].ResourceRecords[].Value' ns-2048.awsdns-64.com ns-2049.awsdns-65.net ns-2050.awsdns-66.org ns-2051.awsdns-67.co.uk
  5. Ensure that the domain is delegated to the exact same nameservers found above:

    root@rok-tools:~/ops/deployments# host -t ns ${EKS_ALB_ZONE_DOMAIN?} apps.example.com name server ns-2048.awsdns-64.com. apps.example.com name server ns-2049.awsdns-65.net. apps.example.com name server ns-2050.awsdns-66.org. apps.example.com name server ns-2051.awsdns-67.co.uk.

Summary

You have successfully created an Amazon Route 53 public hosted zone.

What’s Next

The next step is to create an IAM role for ExternalDNS.