GuideReference
TrainingSupportCommunity
Guide

Configure DNS zones

Automate setting up, deploying, and managing your Edge DNS zones and the record sets of your primary zones. Use them to integrate with your existing DNS infrastructure and manage your DNS namespace more easily.

1. Prep

If using the Edge DNS or GTM subprovider, you may also need to configure Property Manager to serve traffic via Akamai. This mostly applies when configuring an AKAMAICDN record.

2. Create DNS zone

Create a DNS zone resource first. It provides an operating context for all other record set resources.

By default, your Edge DNS contracts can have up to 2,000 configured zones, including aliases. Contact your service representative if you need to increase the limit.

Use the akamai_dns_zone resource to create a new DNS zone:

  1. Add your contract ID, domain zone name, and specify the zone type, either primary, secondary, or alias. Depending on the zone type, provide additional details in the body of the resource declaration.

    • When there's more than one group available to you, you're required to provide the group ID.
    • The sign_and_serve argument is required for both primary and secondary zones.
    • The masters and tsig_key arguments are required only for secondary zones.
    • The target argument is required only for alias zones.

    resource "akamai_dns_zone" "my_dns_zone" {
      contract       = "C-0N7RAC7"
      zone           = "my_dns_zone.com"
      type           = "primary"
      comment        = "This is my dns zone"
      group          = 123456
      sign_and_serve = false
    }
    
  2. Run terraform plan to check syntax and terraform apply to create a new DNS zone.

  3. After creating a zone, Terraform doesn't wait for the zone to be fully activated. Instead, it returns with activation_state as PENDING in your state file. Thus, you need to manually update the state:

    • After 1–2 minutes when the processing finishes, run terraform plan -refresh-only to review how Terraform would update your state file.
    • Then run terraform apply -refresh-only to apply the update of the zone's activation_state in your state file.

When creating a primary zone, Akamai automatically creates the SOA (start of authority) and NS (name server) records for you in the Control Center UI. However, they aren't added to your configuration file. To add them, follow the steps in the Import DNS zone and records section.

Sometimes due to a network error, a primary zone is only partially created without the SOA and NS records. As a result, you won't be able to manage the record sets for this zone. To fix this, manually create these records before you manage the zone. See the akamai_dns_record resource for the examples of setting up the SOA and NS records in Terraform.

📘

Terraform doesn't currently support deleting DNS zones. You can do this using the Control Center UI.

3. Create DNS record

After creating a DNS zone, add records to create record sets. Initially, the record set is empty for secondary and alias zones.

Each primary zone record set must contain one start of authority (SOA) record and at least one name server (NS) record.

Secondary zones support only AKAMAICDN and AKAMAITLC records. Additionally, an AKAMAITLC record is read-only in Terraform, you can create it only via the Control Center UI. If you try to add other record types to secondary zones, you get an error.

Use the akamai_dns_record resource to create a new DNS record:

  1. Specify your domain zone name, DNS record name, DNS record type, time-to-live (TTL), and other required or optional arguments depending on the record type.

    • See the arguments table of the DNS record resource for details of the supported record types and their arguments.

     resource "akamai_dns_record" "my_record_type_a" {
       zone       = "my_dns_zone.com"
       name       = "www.my_dns_zone.com"
       recordtype = "A"
       ttl        = 86400
       target     = ["123.4.5.67"]
     }
    
  2. Run terraform plan to check syntax and terraform apply to create a new DNS record.

  3. After creating a record for a zone, the zone's activation_state changes back to PENDING in the background, but it doesn't get updated in your state file. As a result, its activation_state stays ACTIVE. If you want to keep track of the zone's activation_state, you can update it manually:

    • Run terraform plan -refresh-only to review how Terraform would update your state file.
    • Then run terraform apply -refresh-only to apply the update of the zone's activation_state in your state file.

    The DNS record configuration and state files also include a computed record_sha attribute that represents the current resource state to compare the local and remote DNS record configuration. When a change happens outside of Terraform, this attribute also gets updated when you refresh your state.


🚧

It's recommended that you don't create multiple DNS records with the same values in the name and recordtype arguments. This is to avoid issues with deleting or updating such records. Otherwise, you'll need to fix them manually to reconcile your state file.

Configure AKAMAICDN record

You can set an AKAMAICDN record for a zone only if an AKAMAITLC record doesn't already exists for the given zone.

Before you create an AKAMAICDN record, first configure an edge hostname via a Property Manager subprovider.

When adding this record:

  • In the target argument, provide a DNS name representing the selected edge hostname and domain. You need to have at least viewer permissions to that hostname to create this record.
  • The value of the ttl argument needs to be 20 seconds.

If you don't fulfill these requirements when creating this record, you get an error.

resource "akamai_dns_record" "my_cdn_record" {
  zone       = "my_cdn_record.org"
  name       = "www.my_cdn_record.org"
  recordtype = "AKAMAICDN"
  target     = ["www.example.com.edgekey.net"]
  ttl        = 20
}

Configure SPF or TXT record

The target argument for the SPF (sender policy framework) or TXT (text) record accepts one or more character-strings. You can provide a string using one of these methods:

  • As an adjacent set of characters without interior spaces.
    resource "akamai_dns_record" "my_txt_record" {
      zone       = "my_txt_zone.com"
      name       = "my_txt_zone.com"
      recordtype = "TXT"
      target     = ["\"Ab1cDE2f3G4h5iJKl67MnopQrs8tUwxY9\""]
      ttl        = 3600
    }
    
  • As a string beginning and ending with a double quote ("). Inside a double-quote-delimited string, you can add any character, except for a double quote itself, which needs to be quoted using a backslash (\).
    resource "akamai_dns_record" "my_txt_record" {
      zone       = "my_txt_zone.com"
      name       = "my_txt_zone.com"
      recordtype = "TXT"
      target     = ["\"v=spf1 redirect=example1.com\"", "\"v=spf2 redirect=example2.com\""]
      ttl        = 3600
    }
    

If a given SPF or TXT record data in the target argument has multiple strings and exceeds 255 characters, then you can split those strings into sections to avoid any errors with displaying this record on the UI. To do that:

  • Contain each section within double quotes and add a space character between them to separate them.
  • Also, add a space character before a closing quote of a given section as well as a backslash (\) to quote a double quote.
  • Don't include a space character before the closing quote of the last section.
  • Don't separate the sections of such a record with a comma, as the system will process them as two separate records.
resource "akamai_dns_record" "my_spf_record" {
  zone       = "my_spf_zone.com"
  name       = "mailhost.my_spf_zone.com"
  recordtype = "SPF"
  target     = ["\"v=spf1 a mx ip4:13.71.20.6 ip4:13.71.25.91 ip4:52.172.143.60 ip4:13.71.19.14 ip4:103.74.181.16 ip4:103.74.181.17 ip4:180.179.158.193 \" \"ip4:180.179.158.196 ip4:180.179.36.129 ip4:180.179.36.130 ip4:123.456.78.90 include:_spf.example.com include:_spf.example2.com include:_spf.example3.com -all\""]
  ttl        = 1800
}

Configure MX record

You can instantiate an MX (mail exchanger) record configuration using one of these methods:

Method Description
Couple priority and host

Include both the priority and host in each target entry.

  resource "akamai_dns_record" "mx_record_self_contained" {
    zone       = "mx_record_self_contained_example.com"
    name       = "mailhost.mx_record_self_contained_example.com"
    target     = [
      "0 smtp-0.example.com.",
      "10 smtp-1.example.com."
    ]
    recordtype = "MX"
    ttl        = 300
  }

This configuration will generate these record data values:

  [
    "0 smtp-0.example.com.",
    "10 smtp-1.example.com."
  ]
Assign priority to hosts via start and increment parameters

Define a number of hosts in the target argument as a list along with a starting priority and priority_increment.

  resource "akamai_dns_record" "mx_record_pri_increment" {
    zone               = "mx_pri_increment_example.com"
    name               = "mailhost.mx_pri_increment_example.com"
    target             = [
      "smtp-1.example.com.",
      "smtp-2.example.com.",
      "smtp-3.example.com."
    ]
    priority           = 10
    priority_increment = 10
    recordtype         = "MX"
    ttl                = 900
  }

Edge DNS will generate the record data values by incrementally pairing and incrementing the priority by the priority_increment.

  [
    "10 smtp-1.example.com.",
    "20 smtp-2.example.com.",
    "30 smtp-3.example.com."
  ]
Generate instances

Generate a number of host instances using Terraform's count or for/each construct.

  resource "akamai_dns_record" "mx_record_instances" {
    zone       = "mx_record_example.com"
    name       = "mailhost.mx_record_example.com"
    recordtype = "MX"
    ttl        = 500
    count      = 3
    target     = ["smtp-${count.index}.example.com."]
    priority   = count.index * 10
  }

This configuration will generate three distinct resource instances, each with a single target and priority, and aggregated record data values.

  [
    "0 smtp-0.example.com.",
    "10 smtp-1.example.com.",
    "20 smtp-2.example.com."
  ]
Note: When deleting a record resource with multiple instances or a single instance, it'll remove the entire remote record set resource.

Import DNS zone and records

To check what DNS zones are available to you, run the List zones operation.

To check what DNS records are available for your zone, run the Get a zone's record sets operation. It works only for primary and secondary zones.

  1. Run the export command with the --resources flag to create a list of your zone's current record sets.

    • Even if the zone doesn't have any record sets, the --resources flag is required in this command to generate a config file. Otherwise, you get an error.
    akamai terraform export-zone --resources {your_dns_zone_name}
    

    The command will generate a JSON file, for example, my_dns_zone_com_resources.json.

     {
         "Zone": "my_dns_zone.com",
         "Recordsets": {
             "my_dns_zone.com": [
                "NS",
                "SOA"
             ]
         }
     }
    
  2. Then update your configuration file using the generated JSON file as an input.

    akamai terraform export-zone --createconfig {your_dns_zone_name}
    

    As a result, your configuration file gets updated with the zone and record set resources. For example:

     locals {
       zone = "my_dns_zone.com"
     }
    
     resource "akamai_dns_zone" "my_dns_zone.com" {
       contract                 = var.contractid
       group                    = var.groupid
       zone                     = local.zone
       type                     = "PRIMARY"
       masters                  = []
       comment                  = "My dns zone"
       sign_and_serve           = false
       sign_and_serve_algorithm = ""
       target                   = ""
       end_customer_id          = ""
     }
    
     resource "akamai_dns_record" "my_dns_zone_com_NS" {
       zone       = local.zone
       name       = "my_dns_zone.com"
       recordtype = "NS"
       target = [
         "a1-23.akam.net.",
         "a2-34.akam.net.",
         "a3-45.akam.net.",
         "a4-56.akam.net.",
         "a5-67.akam.net.",
         "a6-78.akam.net."
       ]
       ttl = 86400
     }
    
     resource "akamai_dns_record" "my_dns_zone_com_SOA" {
       zone          = local.zone
       email_address = "hostmaster.my_dns_zone.com"
       expiry        = 604800
       name          = "my_dns_zone.com"
       name_server   = "a1-23.akam.net."
       nxdomain_ttl  = 300
       recordtype    = "SOA"
       refresh       = 3600
       retry         = 600
       target        = []
       ttl           = 86400
     }
    
  3. Generate an import script for the zone's resources using a previously generated output.

    akamai terraform export-zone --importscript {your_dns_zone_name}
    

    The generated script file contains the import statements for the zone and its records:

    terraform init
    terraform import akamai_dns_zone.{your_dns_zone_resource_name} {your_dns_zone_name}
    terraform import akamai_dns_record.{your_dns_record_resource_name} {your_dns_zone_name}#{your dns recordset_name}#{record_type}
    
  4. If you previously created a primary zone and want to import just its NS and SOA records, then remove the terraform import akamai_dns_zone.{your_dns_zone_resource_name} {your_dns_zone_name} line from the script file to avoid creating a duplicate.

  5. Run the generated import script file to populate your Terraform state and prevent Terraform from attempting to recreate your assets.

    Terraform doesn't have access to the zone resource configuration when processing the import. Thus, it can't populate the group attribute's value for that resource in your state after import. Update the group locally and then run terraform apply to reconcile your configuration and state.