Panfactum LogoPanfactum
Bootstrapping StackDNS

DNS

Objective

Establish a domain name, setup subdomains, and delegate control of subdomains to AWS accounts.

Background

Domain Name Service (DNS) is what allows you to connect to networked services by human-readable names (e.g., panfactum.com) instead of IP addresses (1.2.3.4). It also plays an important role in X.509 certificate infrastructure which underpins security on the modern internet (e.g., TLS/SSL).

AWS Route 53 is AWS's suite of DNS utilities. It includes both a registrar (an organization that allows you to lease domain names) and a managed DNS server (Hosted Zones) for hosting individual DNS records.

Purchase Domain Name(s)

  1. Login to your production account in the AWS web console (or whichever account will host your client-facing infrastructure).

  2. Navigate to Route 53 > Registered domains.

  3. Select "Register domains."

  4. Search for the domain(s) you want to purchase and add them to your cart.

  5. Checkout and ensure you enable auto-renew.

Deploy the AWS Registered Domains Module

To use your domain registrations in IaC and to align them with best practices, we will now deploy the aws_registered_domains module. 1

This module will not register / unregister domains, only update the registration settings. In addition, it will set up the root hosted zones and enable DNSSEC to prevent domain hijacking.

Let's deploy the module now:

  1. When you purchased your domain name, AWS may have automatically set up a hosted zone for you. You should delete the automatically generated zone as this module will create one for you. 2

  2. Add a new aws_registered_domains folder to your production environment in the global region.

  3. Add a new terragrunt.hcl file that looks like this.

    Note that we use sops-encrypted values here as we did in the aws_account module. It is up to you what you leave encrypted / unencrypted throughout this guide. However, if you choose to use encrypted values, ensure that you create an encrypted secrets.yaml.

  4. Run pf-tf-init to enable the required providers.

  5. Run terragrunt apply.

Verify DNS Resolution Works

To verify that everything is working as expected:

  1. Navigate to the hosted zone via the AWS web console (Route 53 > Hosted Zone).

  2. View the DNSSEC signing section. It should appear as follows:

    DNSSEC enabled
  3. Add a new A record under test pointing to 1.1.1.1 to your hosted zone via the AWS management console.

    Test A record
  4. Run delv @1.1.1.1 test.panfactum.com (replace panfactum.com with your domain name). 3 You should see a result that looks as follows:

    ; fully validated
    test.panfactum.com.	300	IN	A	1.1.1.1
    test.panfactum.com.	300	IN	RRSIG	A 13 3 300 20240322220955 20240322200455 11333 panfactum.com. NX8hwISu5w6ZhHKPsawBMeb3XarIMZiDzv1Rxlb584vQgziAx67aX8KK xPS6vQlMtW6jwfWOrhNYLHTrEpIKww==
    

    The presence of ; fully validated verifies that DNSSEC is working as intended. The RRSIG record is the digital signature for the record set.

  5. Remove the test record.

Set Up Delegated Zones

Each environment will have its own subdomain for each root domain (e.g., dev.panfactum.com). This subdomain will be managed by its own hosted zone (not the root hosted zone). This provides the following benefits:

  • Limits the blast radius if something is misconfigured. At most, a configuration problem will impact only a single environment without the possibility of impacting other environments (or worse, your entire DNS infrastructure).

  • Limits the permissions needed to be granted to users and services in each environment. To add records to the subdomain dev.panfactum.com, a user would not need any access to records in other environments. This would not be possible if all records were stored in a single, global hosted zone.

This is accomplished via a concept called subdomain delegation. Panfactum's aws_delegated_zones will provide the relevant setup for this to work.

Let's do this now for every environment:

  1. Choose a set of subdomain identifiers. For example, for production you might use the subdomains prod and production.

  2. Add a new directory in production/global called aws_delegated_zones_<environment> where <environment> is replaced with the environment name for this set of subdomains.

  3. Create a terragrunt.hcl that looks like this. 4 Use the appropriate subdomain_identifiers for your environment.

  4. Create a module.yaml.

    1. Run pf-tf-init to generate the module.yaml and enable the required providers.

    2. Set the aws_account_id and aws_profile to the appropriate values for the target environment.

      For example, if setting up aws_delegated_zones_development, the aws_account_id should be set to your development account and the aws_profile should be set to your profile for creating resources in the development account (e.g., development-superuser).

      Note that this module deploys resources in multiple accounts: it uses the primary aws provider to deploy the hosted zones in the target environment account and the secondary aws provider to deploy the appropriate DNS records in root hosted zone inside the production environment.

    3. Set aws_secondary_region to your primary region.

    4. Set module to aws_delegated_zones since we are using a directory name aws_delegated_zones_<environment> that is different from the Panfactum module aws_delegated_zones.

  5. Run terragrunt apply.

Verify DNS Resolution Works (Subdomains)

To verify that everything is working as expected, follow the guide from the previous section but for the subdomain zone. This will require you to log in to the respective AWS account.

You would test via delv @1.1.1.1 test.<your_subdomain_identifier>.<your_root_domain>. Ensure that this shows both the return A record and the dnssec signature.

Deploy Records

If you have static records to deploy, you can use our aws_dns_records module to deploy them to the appropriate hosted zone.

Specifically, now would be a good time to migrate and/or set up your MX records for your primary email provider.

In the future, we will set up a mechanism to ensure that DNS records for all of our Panfactum stack infrastructure is automatically deployed and updated without manual intervention.

Next Steps

Now that you have prepared your DNS configuration, we are ready to begin setting up the Panfactum stack. Our next step is to configure AWS networking by creating a Virtual Private Cloud (VPC).

PreviousNext
Panfactum Bootstrapping Guide:
Step 6 /21

Footnotes

  1. The domains will have the following defaults you can override if desired: privacy protection, auto-renewal, and transfer lock. For more information, refer to the module documentation.

  2. If the zone does not exist, you may skip this step. If you want to keep this zone, follow the import instructions above.

  3. Note that @1.1.1.1 instructs delv to use Cloudflare's DNS servers instead of your network's default. Some intermediate DNS servers do not support DNSSEC and will actually strip the relevant information from the returned responses. This is particularly prevalent for consumer hardware and ISPs.

  4. Note that this is the first time we will take advantage of terragrunt's dependency blocks to use the outputs of one module as inputs into another.