Terraform toolkit for IBM NS1 Connect®
Terraform is an infrastructure-as-code (IaC) solution for DNS management and automation across multiple providers. The 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 provider documentation for NS1 Connect to learn more. Additionally, to work effectively with the provider for Terraform, it is helpful to understand NS1 Connect's API data structures and concepts. Refer to the API documentation for details.
The following example demonstrates how to use the Terraform toolkit to create a DNS zone in NS1 Connect.
Instructions: Using Terraform to create an NS1 Connect zone
Following 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"
}
}
Following 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 NS1 Connect.
- Rate_limit_parallelism
- The value recommended by NS1’s Terraform provider documentation.
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 in increments of 20.The second block defines a resource block of type
ns1_zone
. You can use 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. You can combine 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.
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!
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.
[...]
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 NS1 Connect API to create the zone with two records.