Terraform toolkit for IBM NS1 Connect®

Terraform is an infrastructure-as-code (IaC) solution for DNS management and automation across multiple providers. The IBM® NS1 Connect® + Terraform toolkit provides the tools needed to sync DNS zones and records across all of your DNS providers to create a single source of truth and to centralize resource management.

Refer to Terraform's NS1 provider documentation to learn more. Additionally, to work effectively with the NS1 provider for Terraform, it is helpful to understand NS1's API data structures and concepts. Refer to the API documentation for details.

Below is an example demonstrating how to use the Terraform toolkit to create a DNS zone on the IBM NS1 Connect® platform.

Instructions: Using Terraform to create an NS1 zone

Step 1 - Create a configuration

Below are the contents of a Terraform configuration file (terraform_example.tf) for the zone, terraform.example:

terraform { 
  required_providers { 
    ns1 = { 
      source = "ns1-terraform/ns1" 
    } 
  } 
  required_version = ">= 0.13" 
} 
provider "ns1" { 
   apikey = "API_KEY" 
   rate_limit_parallelism = 60 
}

resource "ns1_zone" "terraform_example" {
 zone = "terraform.example"
}

resource "ns1_record" "first_terraform_example_A" {
 zone = ns1_zone.terraform_example.zone
 domain = "first.${ns1_zone.terraform_example.zone}"
 type = "A"
 answers {
 answer = "192.0.2.1"
 }
}

resource "ns1_record" "second_terraform_example_A" {
 zone = ns1_zone.terraform_example.zone
 domain = "second.${ns1_zone.terraform_example.zone}"
 type = "A"
 answers {
 answer = "192.0.2.2"
 }
}

Below is a breakdown of each resource block.

The first block declares the NS1 provider with the following arguments:

API_KEY
A valid API key generated within the IBM NS1 Connect® platform.
Rate_limit_parallelism
The value recommended by NS1’s Terraform provider documentation.
Attention: If you receive rate-limiting errors or an error message of "invalid character 'u' looking for the beginning of value," check the parallelism value and set it to 60. Setting this to a value of 60 provides a good balance between optimizing for performance and reducing the risk of a 429 response. If you still encounter issues, you can increase this value — NS1 recommends you do so in increments of 20.

The second block defines a resource block of type ns1_zone. NS1 recommends using the domain name of the zone. Note that resource names cannot include periods, so replace the period(s) of the domain name with an underscore. For this example, only the zone's domain name is declared.

The third block defines an ns1_record. Note that a Terraform resource is created for a DNS resource record, and it is important that the two are not confused. NS1 recommends combining the domain name and resource record type to form the resource's name. Also, consider the following:

zone
A reference to the zone attribute of the zone resource block that has already been declared. This creates an implicit dependency on the zone resource to avoid issues whereby a resource record is created before the parent zone.
domain
The domain name of the resource record. Again there is a reference to the zone attribute, but the configuration is more complicated due to interpolation. The alternative is to use first.terraform.example, but this approach is error-prone because you could accidentally create a resource record in another zone. Note there is no explicit relationship between the different types of declared Terraform resources, which means a configuration file could contain unrelated zone and resource records.
type
The resource record type.
answers
A list of IP addresses.

Lastly, a second resource record is defined in the same way as above.

Step 2 - Initialize the working directory

The next step is to initialize the Terraform working directory. This is the place where the configuration file will reside. You should create a new folder for this purpose. You can have multiple configuration files in the same directory, but that means they all get applied at the same time.

Throughout the next few sections, the output of Terraform is shortened for brevity’s sake. This is indicated by an ellipsis in square brackets: [...].

$ terraform init

Initializing the backend...

Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "ns1" (terraform-providers/ns1) 1.8.3...

[...]

* provider.ns1: version = "~> 1.8"

Terraform has been successfully initialized!
Step 3 - Review changes

The Terraform state is now refreshed to indicate what will change. In this case, the resources do not yet exist in Terraform’s state, so new resources will be created.

$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage.


------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
 + create

Terraform will perform the following actions:

[...]

Plan: 3 to add, 0 to change, 0 to destroy.

[...]
Step 4 - Apply the configuration

Once verified, the changes can now be applied.

$ terraform apply

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
 + create

Terraform will perform the following actions:

[...]

Plan: 3 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
 Terraform will perform the actions described above.
 Only 'yes' will be accepted to approve.

Enter a value: yes

ns1_zone.terraform_example: Creating...
ns1_zone.terraform_example: Creation complete after 1s [id=5ec819124f59db008e3836a5]
ns1_record.first_terraform_example_A: Creating...
ns1_record.second_terraform_example_A: Creating...
ns1_record.first_terraform_example_A: Creation complete after 0s [id=5ec819120eafb9008cf45de1]
ns1_record.second_terraform_example_A: Creation complete after 0s [id=5ec8191306e7170090c76d4a]

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

The change is complete. Terraform used the IBM NS1 Connect® API to create the zone with two records.