DNS Resolution in an Hub-And-Spoke network setup using Private Hosted Zones in AWS

March 8, 2024
brian-stark

Introduction

When setting up networks in AWS accounts using a Hub-and-spoke networking, it becomes important to provide DNS resolution as well as keeping traffic localised to a VPC, however with a hub-and-spoke setup there are multiple VPC’s and Route53 Private Hosted zones that can form part of the setup.

Challenges

This only works with Private Hosted Zones.

Setting it up manually can only be done via the AWS CLI, AWS SDK or Route53 API calls. The AWS documentation has the setup process here.

The AWS setup is a 2 step process which has to be done for every VPC and Route53 you want to associate.

  • Send an association authorisation(Invite) from the account that contains the hosted private zone.
  • Accept the association authorisation(invite) in the account you sent it too.

Example Setup

1 management account connected to multiple environments.

In the environment there can be multiple teams/accounts.

Each AWS account has its own Private Hosted zone e.g.

  • management.example.com
  • team1.example.com
  • team2.example.com

The management(hub) account has a centralised monitoring stack. Every Account will have to be able to resolve the DNS entry monitoring.management.example.com in the management Route53.

Management AWS account should also be able to resolve the Team AWS DNS entries for monitoring endpoints, e.g. service.team1.example.com.

Based on the above setup you will have 2 authorisation associations(invites) and 2 Association accepts.

Invite and accept from :

  • Management to Team1
  • Management to Team2
  • Team1 to Management
  • Team 2 to Management

Lets automate this using Terraform.

Step 1

  • Create file : main.tf
  • Setup the AWS Account Providers. Use aliases so you keep track of what account you are working with.
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.10"
    }
  }
}

# IMPORTANT!
# For simplicity, we are not using environment variables
# Setup your correct access_key and secret_key in your ~/.aws/credentials file

provider "aws" {
  alias  = "management"
  region  = "AWS_REGION"
  profile = "MANAGEMENT_AWS_ACCOUNT"
}

provider "aws" {
  alias  = "team1"
  region  = "AWS_REGION"
  profile = "TEAM1_AWS_ACCOUNT"
}

provider "aws" {
  alias  = "team2"
  region  = "AWS_REGION"
  profile = "TEAM2_AWS_ACCOUNT"
}

Step 2

  • Create file : vpc.tf
  • Get the VPC’s that need to be associated to Route53 zones.
  • Remember to keep track of the AWS accounts you are working with using specific provider aliases in Step 1.
data "aws_vpc" "management" {
  provider = "aws.management"
  filter {
    name   = "tag-value"
    values = ["THIS IS YOUR VPC NAME"]
  }
  filter {
    name   = "tag-key"
    values = ["Name"]
  }
}

data "aws_vpc" "team1" {
  provider = "aws.team1"
  filter {
    name   = "tag-value"
    values = ["THIS IS YOUR VPC NAME"]
  }
  filter {
    name   = "tag-key"
    values = ["Name"]
  }
}

data "aws_vpc" "team2" {
  provider = "aws.team2"
  filter {
    name   = "tag-value"
    values = ["THIS IS YOUR VPC NAME"]
  }
  filter {
    name   = "tag-key"
    values = ["Name"]
  }
}

Step 3

  • Create file : management_to_teams association.tf
  • Send associate authorisation(invite) to team account so the VPC can be associated with management Route53 (management.example.com)
data "aws_route53_zone" "management" {
  provider     = "aws.management"
  name         = "management.example.com."
  private_zone = true #Please remember to set this to true since we are working with Private Hosted Zones
}

//// Create and send association invites to associate the Team 1 VPC with the Management Route53
#----------------------------------------------#
resource "aws_route53_vpc_association_authorization" "management_to_team1" {
  provider = "aws.management"
  vpc_id   = data.aws_vpc.team1.id
  zone_id  = data.aws_route53_zone.managment.zone_id
}

//// Create and send association invites to associate the Team 2 VPC with the Management Route53
#----------------------------------------------#
resource "aws_route53_vpc_association_authorization" "prod_mgmt_share_to_prod_brokerage" {
  provider = "aws.management"
  vpc_id   = data.aws_vpc.team2.id
  zone_id  = data.aws_route53_zone.managment.zone_id
}

Step 4

  • Create file : team1_to_management_association.tf
  • Send associate authorisation(invite) to Management account so the VPC can be associated with Team 1 Route53 (team1.example.com)
data "aws_route53_zone" "team1" {
  provider     = "aws.team1"
  name         = "team1.example.com."
  private_zone = true #Please remember to set this to true since we are working with Private Hosted Zones
}

//// Create and send association invites to associate the Management VPC with the Team 1 Route53
#----------------------------------------------#
resource "aws_route53_vpc_association_authorization" "team1_to_management" {
  provider = "aws.team1"
  vpc_id   = data.aws_vpc.management.id
  zone_id  = data.aws_route53_zone.team1.zone_id
}

Step 5

  • Create file : team2_to_management_association.tf
  • Send associate authorisation(invite) to Management account so the VPC can be associated with Team 2 Route53 (team2.example.com)
data "aws_route53_zone" "team2" {
  provider     = "aws.team2"
  name         = "team2.example.com."
  private_zone = true #Please remember to set this to true since we are working with Private Hosted Zones
}

//// Create and send association invites to associate the Management VPC with the Team 2 Route53
#----------------------------------------------#
resource "aws_route53_vpc_association_authorization" "team2_to_management" {
  provider = "aws.team2"
  vpc_id   = data.aws_vpc.management.id
  zone_id  = data.aws_route53_zone.team2.zone_id
}

Step 6

  • Create file : accept_authorisations.tf
  • Once the invites have been sent they need to be accepted but the account that created/owns the Route53.
//// Accept associations
#----------------------------------------------#
// Accept Management VPC to Team 1 Route53 setup in Step 3
resource "aws_route53_zone_association" "accept_from_management_to_team1" {
  depends_on = [aws_route53_vpc_association_authorization.management_to_team1]
  provider   = "aws.team1"
  vpc_id     = aws_route53_vpc_association_authorization.management_to_team1.vpc_id
  zone_id    = aws_route53_vpc_association_authorization.management_to_team1.zone_id
}

// Accept Management VPC to Team 2 Route53 setup in Step 3
resource "aws_route53_zone_association" "accept_from_management_to_team2" {
  depends_on = [aws_route53_vpc_association_authorization.management_to_team2]
  provider   = "aws.team2"
  vpc_id     = aws_route53_vpc_association_authorization.management_to_team2.vpc_id
  zone_id    = aws_route53_vpc_association_authorization.management_to_team2.zone_id
}

// Accept Team 1 VPC to Mangement Route53 setup in Step 4
resource "aws_route53_zone_association" "accept_from_team1_to_management" {
  depends_on = [aws_route53_vpc_association_authorization.team1_to_management]
  provider   = "aws.mangement"
  vpc_id     = aws_route53_vpc_association_authorization.team1_to_management.vpc_id
  zone_id    = aws_route53_vpc_association_authorization.team1_to_management.zone_id
}

// Accept Team 1 VPC to Mangement Route53 setup in Step 5
resource "aws_route53_zone_association" "accept_from_team2_to_management" {
  depends_on = [aws_route53_vpc_association_authorization.team2_to_management]
  provider   = "aws.mangement"
  vpc_id     = aws_route53_vpc_association_authorization.team2_to_management.vpc_id
  zone_id    = aws_route53_vpc_association_authorization.team2_to_management.zone_id
}

Step 7 : Run

  • terraform plan
  • terraform apply

Conclusion

The above can get quite complex if you want to start adding more accounts to the hub-and-spoke networking and config. It is best to draw it out and then plan your terraform files and code.

If you don’t like doing things manually like most of us at Digitalis.io and AxonOps, automation should alway be the go-to solution.

If you need help, please get in touch.

Subscribe to newsletter

Subscribe to receive the latest blog posts to your inbox every week.

By subscribing you agree to with our Privacy Policy.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Ready to Transform 

Your Business?