Coder Social home page Coder Social logo

ns1-terraform / terraform-provider-ns1 Goto Github PK

View Code? Open in Web Editor NEW
31.0 17.0 64.0 10.15 MB

Terraform NS1 provider

Home Page: https://www.terraform.io/docs/providers/ns1/

License: Mozilla Public License 2.0

Makefile 0.51% Go 96.40% Shell 0.59% HTML 0.76% HCL 1.74%
terraform terraform-provider nsone

terraform-provider-ns1's Introduction

NS1 Terraform Provider

This project is in active development.

Contents

  1. Upgrading from Terraform 0.12 - considerations when upgrading from previous versions of Terraform
  2. Requirements - lists the requirements for building the provider
  3. Building The Provider - lists the steps for building the provider
  4. Using The Provider - details how to use the provider
  5. Developing The Provider - steps for contributing back to the provider
  6. Known Isssues/Roadmap - check here for some of the improvements we are working on

Upgrading from Terraform 0.12

In preperation for the 0.13 release of Terraform, this repo has recently changed locations from the Hashicorp GitHub org to one owned by NS1.

As a result, in order to upgrade an existing config and state to Terraform 0.13 and use NS1 provider v1.8.5 and above, you'll need to update your config's required_providers block to point to the new location.

The 0.13upgrade tool will display a warning suggesting as much, but will not enforce this or automatically update your config.

Note that this block is only required if updating an existing state from 0.12 or below. Fresh deployments via Terraform 0.13 or above will automatically detect the new location of the provider.

Here is an example required_providers block enforcing the new location of this provider and Terraform 0.13 or greater:

terraform {
  required_providers {
    ns1 = {
      source = "ns1-terraform/ns1"
    }
  }
  required_version = ">= 0.13"
}

Requirements

  • Terraform 0.13+
  • Go 1.12+ (to build the provider plugin)

Building The Provider

Clone repository to: $GOPATH/src/github.com/ns1-terraform/terraform-provider-ns1

$ mkdir -p $GOPATH/src/github.com/ns1-terraform
$ cd $GOPATH/src/github.com/ns1-terraform
$ git clone [email protected]:ns1-terraform/terraform-provider-ns1.git

Enter the provider directory and build the provider

$ cd $GOPATH/src/github.com/ns1-terraform/terraform-provider-ns1
$ make build

Using The Provider

The documentation and examples for NS1 Resources and Data Sources is maintained as part of this repository, in the /website directory. This is published to registry.terraform.io/providers/ns1-terraform/ns1/latest/docs as part of the release process.

Developing The Provider

If you wish to work on the provider, you'll first need Go installed on your machine (version 1.12+ is required). You'll also need to correctly setup a GOPATH, as well as adding $GOPATH/bin to your $PATH.

To compile the provider, run make build. This will build the provider and put the provider binary in the $GOPATH/bin directory.

$ make bin
...
$ $GOPATH/bin/terraform-provider-ns1
...

In order to test the provider, you can simply run make test.

$ make test

In order to run the full suite of Acceptance tests, run make testacc.

Note: Acceptance tests create real resources, and often cost money to run.

$ make testacc

Some helpful things for debugging:

  • Set TF_LOG=DEBUG for verbose logging.
  • Additionally set NS1_DEBUG environment variable to include details of the API requests in the logs.

Contributions

Pull Requests and issues are welcome. See the NS1 Contribution Guidelines for more information.

Known Issues/Roadmap

  • Currently, some arguments marked as required in resource documentation are de-facto optional. A resource will be created/updated without error, but in general will lead to a "dirty terraform" state, since the defaulted attributes on the returned state may not match the resource descriptions. We're working on making these either truly Required or truly Optional as appropriate.
  • Currently, some resources do not return attributes for optional features that are unused. We are working on making the resource schemas fixed, with proper defaults returned for optional/unused features.

terraform-provider-ns1's People

Contributors

alistanis avatar appilon avatar caiofayres avatar cpontes-ns1 avatar decarvalhorobinson avatar dependabot[bot] avatar dghermanns1 avatar epelkey avatar eravin-ns1 avatar fformica avatar grubernaut avatar jcosta-ns1 avatar jfarrell-ns1 avatar mburtless avatar mioi avatar mobarzanek avatar natedaly avatar pashap avatar pburrows-ns1 avatar pcatalini avatar ponbiki avatar radeksimko avatar rupa avatar seddarj avatar siwyd avatar stack72 avatar tombuildsstuff avatar xaf avatar zach-johnson avatar zahiar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

terraform-provider-ns1's Issues

cant create mx record

Terraform Version

Terraform v0.11.14

  • provider.ns1 v1.5.0

Affected Resource(s)

  • ns1_record

Terraform Configuration Files

{
  "resource": {
    "ns1_record": {
      "foo": {
        "zone": "${ns1_zone.foo.zone}",
        "domain": "foo.com",
        "type": "MX",
        "ttl": 3600,
        "answers": [
          {
            "answer": "10 mail.foo.com"
          }
        ]
      }
    }
  }
}

Expected Behavior

MX record created and resource added to tf state.

Actual Behavior

MX record created and resource not added to tf state.

Steps to Reproduce

Record is created, but an error is encountered before the resource is added to the tf state.

$ terraform apply --target=ns1_record.foo
	* ns1_record.foo: json: cannot unmarshal number into Go struct field Answer.answer of type string

Record exists, but resource does not exist in tf state.

$ terraform state show ns1_record.foo
$

Subsequent tf apply encounters an error due to missing state.

$ terraform apply --target=ns1_record.foo
	* ns1_record.foo: record already exists

Feature request: ability to specify which network the zone belongs to

Terraform Version

Terraform v0.11.1
terraform-provider-ns1 (master)

Affected Resource(s)

  • ns1_zone

Terraform Configuration Files

resource "ns1_zone" "example_cn" {
  zone = "example.cn"
}

Debug Output

N/A

Panic Output

N/A

Expected Behavior

In the UI there is a way to enable to zone for the China network, but in the provider docs and source there is no way to have this changed through terraform. It would be nice if we could have that.

Actual Behavior

Terraform creates the zone, but only the UI has the option. When it is enabled in the UI terraform plan does not notice anything changed.

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. terraform apply
  2. Login to the UI, go to the newly created zone, go to Zone Settings, click China under "Networks"
  3. terraform apply

Important Factoids

Nothing that I can think of.

References

No

Terraform crash when working with NS1 feeds/sources

This issue was originally opened by @dangoldin as hashicorp/terraform#21065. It was migrated here as a result of the provider split. The original body of the issue is below.


Terraform Version

Terraform v0.11.13
+ provider.ns1 v1.3.0

Terraform Configuration Files

This is happening during the plan phase when I manually added a feed to a record and am trying to get Terraform to show the plan of removing it.

Debug Output

2019-04-21T23:31:38.432-0400 [DEBUG] plugin.terraform-provider-ns1_v1.3.0_x4: 2019/04/21 23:31:38 got meta:  &{<nil> map[feed:5cb8f7e5a632f60001771641] <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil>}
... and a few lines down ...
panic: expected v to be convertible to a string, got: map[feed:XXXXXXX], map[string]interface {}

Crash Output

I'm hesitant to post due to sensitive contents but can try to come up with a toy example if it's helpful. Generally seems the issue is due to NS1 feeds/sources being setup to support a different type (string vs map).

Expected Behavior

Terraform would be able to ingest the feed info from NS1.

Actual Behavior

Terraform crashed.

Steps to Reproduce

  1. Create a simple NS1 record using Terraform.
  2. Go into NS1 and add a filter chain to use that record.
  3. Run terraform plan.

Additional Context

Nope - pretty standard terraform.

References

NA

ns1_record regions attribute is missing required meta and feeds properties

The ns1_record resource's regions config is missing the meta and feeds properties. These two properties completely define what a region is and how it is used. Without them, there is absolutely no reason to define a region, nor assign a region to an answers config.

This also causes several filter types to be pointless as they require meta data attached to answers in order to function.

Updating a user isn't applying the permissions

Terraform Version

Terraform v0.11.1
+ provider.ns1 <master>

Affected Resource(s)

  • ns1_user

Terraform Configuration Files

resource "ns1_user" "Human_User" {
  name     = "Human User"
  username = "human_user"
  email    = "[email protected]"

  teams = ["${ns1_team.devops_users.id}"]

  notify {
    billing = true
  }
}

Debug Output

First terraform apply: https://gist.github.com/poblahblahblah/db9e304f6b17406fb4fde398b7efa57c
Second terraform apply: https://gist.github.com/poblahblahblah/a767b44722d71df65443d5959e739096

Panic Output

N/A

Expected Behavior

There should have been no permissions change to the user

Actual Behavior

The users permissions never get updated, so terraform plan/apply always thinks there are changes to be made.

Steps to Reproduce

  1. create a user with the above HCL snippet
  2. terraform apply
  3. terraform apply

Important Factoids

None

References

None

ns1_record answer meta field region not applied

Terraform Version

Terraform v0.11.2

  • provider.ns1 v1.0.0

Affected Resource(s)

ns1_record

Terraform Configuration Files

resource "ns1_record" "cname___example" {
     zone = "${ns1_zone.test-domain_net.zone}"
     domain = "example.${ns1_zone.test-domain_net.zone}"
     type = "CNAME"
     ttl = 10800

     answers = {
          answer = "a.example.com."
          meta = {
               region = "ExampleRegionA"
          }
     }

     answers = {
          answer = "b.example.com."
          meta = {
               region = "ExampleRegionB"
          }
     }

     regions = [
          {
               name = "ExampleRegionA"
               meta = {
                    country = "AS"
                    country = "AU"
               }
          },
          {
               name = "ExampleRegionB"
               meta = {
                    country = "US"
                    country = "CA"
                    us_state = "AL"
                    us_state = "NY"
               }
          }
     ]
}

terraform output

  answers.#:               "" => "2"
  answers.0.answer:        "" => "a.example.com."
  answers.0.meta.%:        "" => "1"
  answers.0.meta.region:   "" => "ExampleRegionA"
  answers.1.answer:        "" => "b.example.com."
  answers.1.meta.%:        "" => "1"
  answers.1.meta.region:   "" => "ExampleRegionB"
  domain:                  "" => "example.test-domain.net"
  regions.#:               "" => "2"
  regions.0.meta.%:        "" => "1"
  regions.0.meta.country:  "" => "AU"
  regions.0.name:          "" => "ExampleRegionA"
  regions.1.meta.%:        "" => "2"
  regions.1.meta.country:  "" => "CA"
  regions.1.meta.us_state: "" => "NY"
  regions.1.name:          "" => "ExampleRegionB"
  ttl:                     "" => "10800"
  type:                    "" => "CNAME"
  use_client_subnet:       "" => "true"

NS1 output

{
  "domain": "example.test-domain.net",
  "zone": "test-domain.net",
  "use_client_subnet": true,
  "answers": [
    {
      "answer": [
        "a.example.com."
      ],
      "meta": {},
      "id": "5"
    },
    {
      "answer": [
        "b.example.com."
      ],
      "meta": {},
      "id": "5"
    }
  ],
  "id": "5",
  "regions": {
    "ExampleRegionA": {
      "meta": {
        "country": [
          "AU"
        ]
      }
    },
    "ExampleRegionB": {
      "meta": {
        "country": [
          "CA"
        ]
      }
    }
  },
  "meta": {},
  "link": null,
  "filters": [],
  "ttl": 10800,
  "tier": 1,
  "type": "CNAME",
  "networks": [
    0
  ]
}

Expected Behavior

What should have happened?
Answers should have "region" metadata

Actual Behavior

What actually happened?
They don't.

ns1_zone does not support "primaries" or "secondaries" using IPv6 addresses

Terraform Version

Terraform v0.12.19
+ provider.ns1 v1.6.4

Affected Resource(s)

ns1_zone

Terraform Configuration Files

######### ROOT-LEVEL CONFIG ############
terraform {
  required_version = ">= 0.12"
  required_providers {
    ns1 = "~> 1.6"
  }
}

variable "secondary_zone_list" {
    description = "This is a list of secondary DNS zones implemented as a \"List of Objects\""
    default = [
        {
            the_zone_name      = "0.0.2.8.7.0.0.0.2.6.2.ip6.arpa"
            autogen_ns         = true
            enable_dnssec      = false
            ns1_networks       = [ 0 ]
            primary_nameserver = "2620:78:2000:0e00::ffff"
            more_primaries     = [
                "2620:78:2000:0e00::fffe",
            ]
        },
        {
            the_zone_name      = "0.0.0.0.0.0.2.8.7.0.0.0.2.6.2.ip6.arpa"
            autogen_ns         = true
            enable_dnssec      = false
            ns1_networks       = [ 0 ]
            primary_nameserver = "2620:78:2000:0e00::ffff"
            more_primaries     = [
                "2620:78:2000:0e00::fffe",
            ]
        },

module "secondary_zone_creation" {
    source = "./modules/zone/secondary_zone"

    # Inputs
    zone_name             = var.secondary_zone_list[*].the_zone_name
    primary_ns            = var.secondary_zone_list[*].primary_nameserver
    addl_primaries        = var.secondary_zone_list[*].more_primaries
    autogen_ns_records    = var.secondary_zone_list[*].autogen_ns
    dnssec_enabled        = var.secondary_zone_list[*].enable_dnssec
    ns1_network_id        = var.secondary_zone_list[*].ns1_networks
}

########## MODULE CONFIGURATION #############
variable "zone_name" {
    description = "The domain name of the zone"
    type = list(string)
    # There is no default defined, as this is required to be specified every time.
}

/******** Time-To-Live Values ********/
/* Reference for description fields: https://ns1.com/resources/understanding-ttl-values-in-dns-records */
variable "primary_ns" {
    description = "The authoritative (primary) name server IP Address where this zone will get updates"
    type = list(string)
     # There is no default defined, as this is required to be specified every time.
}

variable "addl_primaries" {
    description = "More authoritative (primary) name server IP Addresses where this zone will get updates"
    type = list(list(string))
    # There is no default defined, as this is required to be specified every time.
    # If there are no additional primaries, then 
}

variable "dnssec_enabled" {
    description = "Is DNSSEC enabled for this zone? (Requires account-level DNSSEC support)"
    type = list(bool)
    # NS1 Default is to not enable DNSSEC support
}

variable "ns1_network_id" {
    description = "List of network IDs for which the zone is available. If no network is provided, the zone will be created in network 0, the primary NS1 Global Network."
    type = list
    # NS1 Default value is "computed", which turns out to be "[ 0, ]"
}

variable "autogen_ns_records" {
    description = "If set to false, clears the autogenerated NS record on zone creation. This allows an automated workflow for creating zones with the NS record in terraform state. Note that this option only has an effect when a zone is being created."
    type = list(bool)
    # The default value is TRUE.  Set this to false only if you need to specify name servers.
}

resource "ns1_zone" "secondary_zone" {
    count = length(var.zone_name)

    # required values (per NS1's provider docs)
    zone                   = var.zone_name[count.index]     # must be defined every time!
    primary                = var.primary_ns[count.index]    # Must be defined every time!
    additional_primaries   = length(var.addl_primaries[count.index]) != 0    ? var.addl_primaries[count.index]     : []    # Leave empty if not defined

    # IF the variable is not NULL, use the value in the variable. ELSE, assign it the NS1 Default Values
    dnssec                 = var.dnssec_enabled[count.index]     != null ? var.dnssec_enabled[count.index]     : false
    networks               = var.ns1_network_id[count.index]     != null ? var.ns1_network_id[count.index]     : [ 0 ]
    autogenerate_ns_record = var.autogen_ns_records[count.index] != null ? var.autogen_ns_records[count.index] : true
}

// No outputs have been defined yet

Debug Output

I think the error message is pretty clear on this one, since it gives the error and why it failed (regex failure).

Panic Output

No crash output

Expected Behavior

The terraform apply would have succeeded and the secondary zones created with a primary NS that has an IPv6 address.

Actual Behavior

terraform init and terraform plan succeeded with no issues, but terraform apply failed with the following error (repeated for every secondary zone I defined):

Error: PUT https://api.nsone.net/v1/zones/0.2.3.0.0.0.2.8.7.0.0.0.2.6.2.ip6.arpa: 400 Input validation failed (Value u'2620:78:2000:0e00::dc01' for field '<obj>.secondary.primary_ip' does not match regular expression '^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$')

  on modules/zone/secondary_zone/main.tf line 4, in resource "ns1_zone" "secondary_zone":
   4: resource "ns1_zone" "secondary_zone" {

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. Use the config above and execute terraform apply

Important Factoids

  • I'm using IPv6 so I can avoid NAT-ting and to decrease the amount IPv4 addresses I am consuming. Some of my servers happen to be IPv6-only.
  • I'm actually trying to create 14 Zones programmatically so I don't have to do it by hand.
  • If this were Python, I'd actually have a routine for you that could be useful. But, I've never worked directly in Go. Sorry.

References

None that I know of.

Interface conversion error when specifying more than one country on a region

Hi there,

Thank you for opening an issue. Please note that we try to keep the Terraform issue tracker reserved for bug reports and feature requests. For general usage questions, please see: https://www.terraform.io/community.html.

Terraform Version

0.11.8

Affected Resource(s)

  • ns1_record

If this issue appears to affect multiple resources, it may be an issue with Terraform's core, so please mention this.

Terraform Configuration Files

resource "ns1_record" "endpointgroup" {
  zone              = "example.com"
  domain          = "record.example.com"
  type              = "A"

  ttl               = 300
  use_client_subnet = true

  answers = [
    {
      answer = "192.0.2.2"
      region = "SYD"

      meta = {
        up = true
      }
    },
    {
      answer = "192.0.2.1"
      region = "SYD"

      meta = {
        up = true
      }
    },
  ]

  regions = [
    {
      name = "SYD"
      meta = {
        up      = true
        country = "WF,WS,FJ,FM,PW,TV,NC,NF,TO,NZ,PF,TK,NR,PN,NU,PG,CK,GU,AS,AU,VU,KI,MH,MP,SB"
      }
    },
  ]

  filters {
    filter = "up"
  }

  filters {
    filter = "geotarget_country"
  }

  filters {
    filter = "select_first_n"
    config = {N=2}
  }
}

Debug Output

https://gist.github.com/glennslaven/9cf7721f9f608a9da5fcdf9e9c06b8b6

Expected Behavior

Create the record with the correct country meta values set

Actual Behavior

Crash

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. terraform apply

Not all records created during apply

Problem Description

When I am trying to build multiple zones with multiple records in a single run, most times, the run will partially fail with errors because one or more zones are not implemented at the time the records for implemented. This is because record creation does not wait for zone creation to be complete before beginning. If I wait a minute or two (or 5), then the zone will be there and the failed-to-be-created records will create just fine.

Terraform Version

$ terraform -v
Terraform v0.12.19
+ provider.ns1 v1.6.4

Affected Resource(s)

Please list the resources as a list, for example:

  • ns1_zone (4 zones total)
  • ns1_records (18 records total)

Terraform Configuration Files

This is a large config that would need to be zipped and encrypted.  Where can I find NS1's public GPG key?

Debug Output

  1. This is a link to the CLI output and, if you look at the order of operations, my Problem Description will make more sense.
    https://gist.github.com/chris-zenfolio/16d5dd35c61a3874faec3a72ae841ecc
  2. This is a link to the TRACE output from the 2 runs I needed to successfully complete the terraform apply.
    https://gist.github.com/chris-zenfolio/41583b21834ad1008b21679ab8483c40

Panic Output

No panic/crash was detected

Expected Behavior

terraform apply should create/modify all objects in one run

Actual Behavior

Two runs were needed because record creation did not verify zone existence prior to creation.

Steps to Reproduce

  1. Configure Terraform to create multiple zones and multiple records (of any type) for multiple zones.
  2. terraform apply

Important Factoids

This implementation is highly iterative. All of the specific information is contained inside the variables.tf file.

References

I ran similar, highly-iterative, configurations (creating resource groups, vnets, ip addresses, subnets, vpns, etc.) using the azurerm provider that had object-creation dependencies without this particular problem happening.

Add the ability to configure feeds for records up filter

Terraform Version

Terraform v0.11.7

Affected Resource(s)

Please list the resources as a list, for example:

  • ns1_record
  • ns1_datafeed

Terraform Configuration Files

resource "ns1_datafeed" "api" {
  name      = "${ns1_record.primary_api.domain}"
  source_id = "${module.notification_list.datasource_ns1_monitoring}"

  config = {
    jobid = "${ns1_monitoringjob.api.id}"
  }
}

resource "ns1_record" "api" {
  zone   = "${ns1_zone.example_com.zone}"
  domain = "api.${ns1_zone.example_com.zone}"
  type   = "CNAME"
  ttl    = 900

  answers = [
    {
      answer = "${ns1_record.primary_api.domain}"

      meta = {
        priority = 0
        up       = true
      }
    },
    {
      answer = "${ns1_record.secondary_api.domain}"

      meta = {
        priority = 1
        up       = true
      }
    },
  ]

  filters = {
    filter = "up"
  }

  filters = {
    filter = "priority"
  }
}

Expected Behavior

This configuration works find but I'd like to be able configure it as the following

  answers = [
    {
      answer = "${ns1_record.primary_api.domain}"

     feeds = [
                {
                    feed = "${ns1_datafeed.api.id}"
                    source = "${module.notification_list.datasource_ns1_monitoring}"
                }
            ],

      meta = {
        priority = 0
        up       = {
          feed = "${ns1_datafeed.api.id}"
         }
      }
    },
    {
      answer = "${ns1_record.secondary_api.domain}"

      meta = {
        priority = 1
        up       = true
      }
    },
  ]

Actual Behavior

Maybe there is another option to get this. I'd like to hear that

References

When adding the feeds manually from NS1 portal, im getting the same crash as GH-31 mentioned

Thanks

NS1 record to validate aws_acm_certificate fails - trailing dot

Terraform Version

Terraform v0.11.10
Provider: NS1 v1.0.0
Provider: AWS v1.39.0

Affected Resource(s)

  • ns1_record
  • aws_acm_certificate

Terraform Configuration Files

resource "ns1_record" "cert_validation" {
  zone                      = "${var.ns1-zone}"
  domain                    = "${aws_acm_certificate.certificate.domain_validation_options.0.resource_record_name}"
  type                      = "${aws_acm_certificate.certificate.domain_validation_options.0.resource_record_type}"
  ttl                       = 60
  answers = {
    answer                  = "${aws_acm_certificate.certificate.domain_validation_options.0.resource_record_value}"
  }
}

Debug Output

* ns1_record.cert_validation_0: 1 error(s) occurred:

* ns1_record.cert_validation_0: PUT https://api.nsone.net/v1/zones/<zone>/_a2f[...]3cd.<subdomain>.<domain><zone>..<zone>/CNAME: 400 "_a2f[...]3cd.<subdomain>.<domain><zone>..<zone>" not a valid domain in <zone>

Expected Behavior

The record should have been created based on the output of aws_acm_certificate

Actual Behavior

The output from aws_acm_certificate includes the trailing dot in the name. Acceptable inputs for ns1_record are either an FQDN including the zone (no trailing dot), or just the resource record and the zone will be appended automatically. When a trailing dot is included at the end the zone is appended, so you end up with <resource><zone>..<zone> which NS1 api fails to accept (correctly).

Steps to Reproduce

  • Have an aws_acm_certificate with one or more subject_alternative_names
  • Create an NS1 DNS record to complete validation using aws_acm_certificate.certificate.domain_validation_options.0.resource_record_name as the input for ns1_record.record.domain

Current workaround

Doing a replace() on the interpolated string allows for proper formatting. (replaces trailing dot with nothing)

"${replace(aws_acm_certificate.certificate.domain_validation_options.0.resource_record_name, "/\\.$/", "")}"

Rate Limit Exceeded

This issue was originally opened by @devinbernosky as hashicorp/terraform#15000. It was migrated here as part of the provider split. The original body of the issue is below.


Hi there,

Terraform Version

0.9.6

Affected Resource(s)

ns1_zone

Terraform Configuration Files

Actual Behavior

Rate Limits being hit

Steps to Reproduce

Create zone with 300+ records

image

provider "ns1" version attribute does not allow variables

### Terraform Version

$ terraform -v
Terraform v0.12.19
+ provider.ns1 v1.6.4

### Affected Resource(s)
provider "ns1" >> specifically the version attribute

### Terraform Configuration Files
Note: These two configuration blocks are normally in separate .tf files in our environment, but are combined here for readability. This doesn't make a difference in functionality.

variable "ns1_provider" {
    description = "These are all the values needed for the NS1 Provider block"
    default = {
            apikey                 = "SOME_API_KEY_VALUE_HERE"
            provider_version       = "1.6.4"
            api_endpoint           = "https://api.nsone.net/v1"  # default value
            ignore_ssl             = false                       # default value
            rate_limit_parallelism = 10                          # default value
    }
}

provider "ns1" {
    apikey                 = var.ns1_provider.apikey
    version                = var.ns1_provider.provider_version
    endpoint               = var.ns1_provider.api_endpoint
    ignore_ssl             = var.ns1_provider.ignore_ssl
    rate_limit_parallelism = var.ns1_provider.rate_limit_parallelism

### Debug Output
This is the failure observed when running terraform init with the version attribute interpolating a variable:
https://gist.github.com/chris-zenfolio/55955de18d22541a5387cda9806b8979

This is the success observed when running terraform init with the version attribute hard-coded:
https://gist.github.com/chris-zenfolio/b61c667647b0d7aff889ea2c06623e0d

This is the failure observed when running terraform plan (for example, if you started with a hard-coded value and changed to variable interpolation:
https://gist.github.com/chris-zenfolio/e9485923eda09d1df6470f3aeb7bd475

This is the success observed when running terraform plan after correcting the previous failure (by hard-coding the version attribute):
https://gist.github.com/chris-zenfolio/4a8702ef32aad730449becc950e8cf76

### Panic Output
No panic output

### Expected Behavior
The version attribute would interpolate the variable, just like for all the other attributes in the provider block.

### Actual Behavior
Both terraform init and terraform plan fail with a hard error "Variable not allowed." This requires hard-coding that attribute. We are only trying to hard-code values in a variables file (i.e., variables.tf or terraform.tfvars). Error output:

Error: Variables not allowed

  on providers.tf line 19, in provider "ns1":
  19:     version                = var.ns1_provider.provider_version

Variables may not be used here.

### Steps to Reproduce
Please list the steps required to reproduce the issue, for example:

  1. Use the variable and provider configuration above
  2. Run terraform init or terraform apply

### Important Factoids
Workaround for this bug:

provider "ns1" {
    apikey                 = var.ns1_provider.apikey
    version                = "1.6.4" . # or whatever version number it should be
    endpoint               = var.ns1_provider.api_endpoint
    ignore_ssl             = var.ns1_provider.ignore_ssl
    rate_limit_parallelism = var.ns1_provider.rate_limit_parallelism

### References
No references.

// EDIT: 1/10/2020: Corrected grammatical error in Expected Behavior section.

ns1_record regions seem unordered, undeterministic, cannot reliably run

Hi there,

Thank you for opening an issue. Please note that we try to keep the Terraform issue tracker reserved for bug reports and feature requests. For general usage questions, please see: https://www.terraform.io/community.html.

Terraform Version

Terraform v0.11.2
+ provider.ns1 v1.0.0

Affected Resource(s)

Please list the resources as a list, for example:

  • ns1_record

Terraform Configuration Files

module "tags_com" {
  zone   = "zone"
  domain = "tags.zone"
  type = "CNAME"
  ttl    = "600"

  answers = [
    {
      answer = "tags.edgekey.net"
      region = "Tier-II"

      meta = {
        note     = "Akamai"
        priority = "1"
        up       = "1"
      }
    },
  ]

  regions = [
    {
      name = "Tier-II"

      meta = {
        country = "BD,BF,BN,BO,JP,BI,BJ,BT,BV,BW,BR,RW,RE,LR,GW,GS,GQ,BH,GY,GF,GE,GA,GN,GM,KW,GH,OM,JO,HM,PS,PY,KP,PE,PK,PH,ZM,EH,EG,ZA,EC,AO,ET,ZW,ER,MG,UY,UZ,MM,ML,MO,MN,MU,MW,MV,MR,UG,MY,MZ,FK,NA,NE,NG,NP,CI,CO,CM,CL,CC,CG,CF,CD,CY,CX,MA,CV,SZ,SY,KG,KE,SR,KH,KM,ST,KR,SH,SO,SN,SL,SC,KZ,SA,SG,SD,DJ,YE,DZ,YT,LB,LA,TW,TR,LK,TN,TL,TM,TJ,LS,TH,TF,TG,TD,LY,AE,VE,AF,IQ,IR,AM,VN,AR,IL,IO,TZ,AZ,ID,QA"
      }
    },
    {
      name = "Cedexis"

      meta = {
        country = "BE,FR,BG,BA,HR,BM,DE,HU,US,UM,FI,SJ,JE,BY,FO,RU,NL,PT,RS,LT,NF,LI,LV,NZ,LU,GI,RO,CA,PL,PM,VA,CH,GR,EE,IS,AL,IT,GG,CZ,AU,AT,AX,AD,GL,IE,ES,ME,MD,MC,NO,MK,SK,MT,SI,SM,DK,IM,UA,SE,GB"
      }
    },
    {
      name = "EdgeCast-China"

      meta = {
        country = "CN"
      }
    },
    {
      name = "India"

      meta = {
        country = "IN"
      }
    },
    {
      name = "CatchAll"
      meta = {}
    },
  ]
}

Expected Behavior

terraform plan should be a repeatable function (as long the regions of the ns1_record in question are not changing in the background)

Actual Behavior

terraform plan for ns1_record with regions does not appear to be a repeatable/reliable function, regions in the list seems to switch positions all the time

Steps to Reproduce

terraform plan
terraform plan

Support Darwin Arm64 (apple silicon, Mac M1 chip)

Running terraform init with this provider present:

terraform {
  required_providers {
    ns1 = {
      source = "ns1-terraform/ns1"
    }
  }
}

โ€ฆetcโ€ฆ

I get this output, on an apple M1 mac:

โ•ท
โ”‚ Error: Incompatible provider version
โ”‚
โ”‚ Provider registry.terraform.io/ns1-terraform/ns1 v1.11.0 does not have a package available for your current
โ”‚ platform, darwin_arm64.
โ”‚
โ”‚ Provider releases are separate from Terraform CLI releases, so not all providers are available for all platforms.
โ”‚ Other versions of this provider may have different platforms supported.

I can confirm on the Releases page here: https://github.com/ns1-terraform/terraform-provider-ns1/releases that you haven't built an asset for Darwin Arm64 yet. Please can you do this ๐Ÿ™

Simpler answer format

Hey there,
I think it'd be a much simpler format for tf files if you didn't need multiple answers sections.

Instead of:

answers {
  answer = "asdf.com"
}
answers {
  answer = "jkl.com"
}

I think:

answers [ "asdf.com", "jkl.com" ]

or:

answers {
  answer = "asdf.com"
  answer = "jkl.com"
}

would be a bit saner.
If this is trivial, I'd be happy to help contribute.
Also maybe there are some edge-cases that this format doesn't handle well.

Intermittent errors refreshing state for datafeed

Terraform Version

terraform:0.11.1

- Downloading plugin for provider "ns1" (1.1.0)...

Affected Resource(s)

  • ns1_datafeed

Terraform Configuration Files

resource "ns1_datafeed" "bar" {
  name      = "bar"
  source_id = "f83b8420d35d7a740d91458cba65865f"
  config {
    alarm_name = "the_alarm"
  }
}

Output

ns1_datafeed.bar: Refreshing state... (ID: 5c3d855cc9c79d0001873391)

Error: Error refreshing state: 1 error(s) occurred:

* module.foo.ns1_datafeed.bar: 1 error(s) occurred:

* module.foo.ns1_datafeed.bar: ns1_datafeed.bar: invalid character '<' looking for beginning of value

Expected Behavior

What should have happened?
The reason (or at least the HTTP status code) why the NS1 API call failed should have been displayed instead of the error about <. For non-side-effect actions (like querying current state), failed API calls should be retried after a short pause before failing the entire terraform run.

Actual Behavior

What actually happened?
The NS1 API call failed and returned a HTML response body error instead of the expected JSON response. The provider attempted to JSON-parse the response body but failed due to the <html> tag. The provider then aborted the terraform run.

Steps to Reproduce

Since the NS1 API was failing intermittently, reproduction will likely require intercepting the HTTP requests to NS1 to inject these error responses.

Rate Limit Exceeded

Terraform Version

0.12.21

Affected Resource(s)

Likely all, but the one we're having problems with is ns1_user.

Expected Behavior

A successful run, regardless of the number of resources.

Actual Behavior

Receiving 429 Rate limit exceeded errors when doing runs with large number of resources.

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. Have hundreds of NS1 user resources managed by Terraform
  2. run tf refresh and wait for 429 Rate limit exceeded errors

References

Are there any other GitHub issues (open or closed) or Pull Requests that should be linked here? For example:

How to obfuscate the API key?

Terraform Version

Terraform v0.11.1, using master (sha: 68489a2) of the ns1 provider.

Affected Resource(s)

Please list the resources as a list, for example:

  • ns1_api_key

Terraform Configuration Files

provider "ns1" {
  apikey = "${var.prod_ns1_api_key}"
  version             = "8.4.0"
}

terraform {
  backend "s3" {
    bucket = "company-terraform-state"
    key    = "external-dns/zones/foobar.org.tfstate"
    region = "us-east-1"
  }
}

resource "ns1_zone" "foobar_org" {
  zone = "${var.zone_name}"
}

Debug Output

N/A

Panic Output

N/A

Expected Behavior

There should be a way to specify an API key that is not committed to a VCS. It would be very preferable if the provider could read a file on the file system or it could read an environment variable.

Actual Behavior

Error: variable "prod_ns1_api_key": default may not contain interpolations

Steps to Reproduce

  1. terraform init

Important Factoids

N/A

References

N/A

Unable to create notify list

Terraform Version

Terraform v0.11.7

Affected Resource(s)

Please list the resources as a list, for example:

  • ns1_notifylist

Terraform Configuration Files

resource "ns1_notifylist" "general" {
  name = "ns1-general-notifications"

  notifications = {
    type = "slack"

    config = {
      username = "ns1-bot"
      url          = "https://hooks.slack.com/services/xxx"
      channel  = "ns1-notifications"
    }
  }

  notifications = {
    type = "datafeed"

    config = {
      sourceid = "${ns1_datasource.nsone_monitoring.id}"
    }
  }
}

Expected Behavior

Create new notify list with Slack and data feed to managed dns metadata records

Actual Behavior

ns1_notifylist.general: PUT https://api.nsone.net/v1/lists: 500 Internal server error

Terraform crash on import of NS1 record

This issue was originally opened by @tenzone as hashicorp/terraform#18097. It was migrated here as a result of the provider split. The original body of the issue is below.


Terraform Version

Terraform v0.11.7
+ provider.ns1 v1.0.1

Terraform Configuration Files

resource "ns1_record" "test" {}
~/repos/nsonestage$  terraform import ns1_record.test eample.com/test.example.com/A

Crash Output

https://gist.github.com/tenzone/2fb49bb39bb341ef9c8deff50822e927

Expected Behavior

resoource/record import

Actual Behavior

crash

Steps to Reproduce

see above import command

Unable to create when record exists (when it shouldn't) due to missing overwrite feature

Terraform Version

`
Terraform v0.11.6

  • provider.ns1 v1.6.0
    `

Affected Resource(s)

Please list the resources as a list, for example:

  • ns1_record

Terraform Configuration Files

resource "ns1_record" "a___apex" {
     zone = "${var.zone_name}"
     domain = "${var.zone_name}"
     type = "ALIAS"
     ttl = 3600

     answers = {
          answer = "example.com."
     }
}

Debug Output

  • N/A

Panic Output

  • N/A

Expected Behavior

  1. I should have been able to specify something like OverwriteAllowed=true.
  2. Terraform should have then encountered the error on create and performed an update instead.
  3. Alternatively, terraform should perform a delete and create.

Actual Behavior

  1. Terraform stopped, threw an error and required manual intervention.

Steps to Reproduce

  1. Create DNS record manually, which mirrors a record in the tf configs.
  2. Run terraform apply
  3. Observe error 'record already exists'

References

Similar to issue #26 for which I submitted a pull request this morning. I'm creating this ticket so I can submit another pull request after I get lunch.

type conversion bug for filter config when importing record

Terraform Version

Terraform v0.12.29
+ provider.ns1 v1.8.4

Affected Resource(s)

Please list the resources as a list, for example:

  • ns1_record

Terraform Configuration Files

resource "ns1_record" "example" {
  zone   = "example.xyz"
  domain = "huh.example.xyz"
  type   = "CNAME"
  ttl    = 3600
}

Debug Output

https://gist.github.com/mjuarez/3d20f0efc53cf710d4265bb112735c11

Expected Behavior

I should be able to import an ns1_record

Actual Behavior

I receive an error about expecting string for a filter config, when I received a float64.

Error: [DEBUG] Error setting filters for: huh.example.xyz, error: &errors.errorString{s:"filters.1.config.N: '' expected type 'string', got unconvertible type 'float64'"}

Steps to Reproduce

  1. Create a record in a zone with a "Select First N" filter configured for 1 answer.
  2. terraform import ns1_record.example example.xyz/huh.example.xyz/CNAME

Important Factoids

I've replaced our domain with example.xyz

References

Potentially related to:

builtin/providers/ns1: Support "meta" in resource_record.go

This issue was originally opened by @sladkani as hashicorp/terraform#14920. It was migrated here as part of the provider split. The original body of the issue is below.


Terraform Version

Terraform v0.9.6

Affected Resource(s)

resource "ns1_record"

Seems NS1s "meta" field within "answers" or "regions" arguments ins't supported.
As code shows, all references to metaSchema are commented out,
see https://github.com/hashicorp/terraform/blob/master/builtin/providers/ns1/resource_record.go

Do note that in NS1's fork, there's a commit by @pashap attempting to support "meta",
see ns1/terraform@e9657de

Can you comment why "meta" was left out, and whether there are plan's to integrate @pashap 's work?

Thanks

Support CAA record type

NS1 supports CAA records now via the v2 web interface and via the API (but the API docs still need to be updated).

This is the info on CAA records and the NS1 API as provided to me by NS1 support:

We have supported CAA record management through our API already and will update our API doc soon.

In the meanwhile, you can use our Portal or follow this example:

$ curl -X PUT -H 'X-NSONE-KEY: <YOUR_API_KEY>' 'https://api.nsone.net/v1/zones/example.test/caa.example.test/CAA' -d @JSON_FILE

with JSON_FILE's content:

{
  "zone": "example.test",
  "domain": "caa.example.test",
  "answers": [
    {
      "answer": [
        0,
        "issue",
        "ca.example.test"
      ]
    }
  ],
  "type": "CAA"
}

GET, POST and DELETE requests are similar to other record types.

You can find more information about CAA record at https://ns1.com/articles/caa-records.

I've tried simply adding the CAA record type to the list of supported record types in the provider and rebuilding the provider. This allows me to create the following record perfectly, but as far as I can tell there is an issue retrieving the record info from NS1 and parsing it.

This is the resource:

resource "ns1_record" "wydooghe_com_caa" {
  zone = "wydooghe.com"
  domain = "wydooghe.com"
  type = "CAA"

  answers = {
    answer = "0 issue letsencrypt.org"
  }

  answers = {
    answer = "0 issuewild ;"
  }
}

This is the Terraform output:

Error applying plan:

1 error(s) occurred:

* module.ns1.ns1_record.wydooghe_com_caa: 1 error(s) occurred:

* ns1_record.wydooghe_com_caa: json: cannot unmarshal number into Go struct field Answer.answer of type string

Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.

The response when calling the API via curl is the following:

โฏ curl -X GET -H "X-NSONE-KEY: $NS1_APIKEY" 'https://api.nsone.net/v1/zones/siwyd.com/siwyd.com/CAA' | jq .
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   363    0   363    0     0    363      0 --:--:-- --:--:-- --:--:--   573
{
  "domain": "siwyd.com",
  "zone": "siwyd.com",
  "use_client_subnet": true,
  "answers": [
    {
      "answer": [
        0,
        "issuewild",
        ";"
      ],
      "meta": {},
      "id": "59a6e940c9c79d000120d3e3"
    },
    {
      "answer": [
        0,
        "issue",
        "letsencrypt.org"
      ],
      "meta": {},
      "id": "59a6e940c9c79d000120d3e4"
    }
  ],
  "id": "59a6e940c9c79d000120d3e5",
  "regions": {},
  "meta": {},
  "link": null,
  "filters": [],
  "ttl": 3600,
  "tier": 1,
  "type": "CAA",
  "networks": [
    0
  ]
}

The first element in the array is an integer, I'm guessing that might be the problem? MX records have a similar structure, but it seems NS1 returns those as all strings instead of the first element as integer:

โฏ curl -X GET -H "X-NSONE-KEY: $NS1_APIKEY" 'https://api.nsone.net/v1/zones/siwyd.com/siwyd.com/MX' | jq . 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   362    0   362    0     0    362      0 --:--:-- --:--:-- --:--:--   500
{
  "domain": "siwyd.com",
  "zone": "siwyd.com",
  "use_client_subnet": true,
  "answers": [
    {
      "answer": [
        "10",
        "mxb.mailgun.org"
      ],
      "meta": {},
      "id": "59517182a632f6000189aff8"
    },
    {
      "answer": [
        "10",
        "mxa.mailgun.org"
      ],
      "meta": {},
      "id": "59517182a632f6000189aff9"
    }
  ],
  "id": "59517182a632f6000189affa",
  "regions": {},
  "meta": {},
  "link": null,
  "filters": [],
  "ttl": 3600,
  "tier": 1,
  "type": "MX",
  "networks": [
    0
  ]
}

My Golang knowledge (and Terraform provider debugging) is pretty much nonexistent, so any help to get this working is much appreciated ;)

Unable to import MX record

Attempting to import an MX record results in a json marshaling error. I believe this is due to the priority data in the answer being a number. Ex:
"answer":[10, "mail2.example.com"]

Terraform Version

Terraform v0.11.7
+ provider.ns1 v1.0.0

Affected Resource(s)

  • ns1_record

Terraform Configuration Files

resource "ns1_zone" "example_com" {
  zone    = "example.com"
}

resource "ns1_record" "example_com_MX" {
  zone   = "${ns1_zone.example_com.zone}"
  domain = "example.com"
  type   = "MX"

  answers {
    answer = "10 mx.example.com"
  }
}

Expected Behavior

MX record is imported.

Actual Behavior

json: cannot unmarshal number into Go struct field Answer.answer of type string

Steps to Reproduce

  1. terraform import ns1_record.example_com_MX 'example.com/example.com/MX'

Plan generates phantom changes to apply (failed permission inheritance?)

Hi there,

Thank you for opening an issue. Please note that we try to keep the Terraform issue tracker reserved for bug reports and feature requests. For general usage questions, please see: https://www.terraform.io/community.html.

Terraform Version

Terraform v0.12.12
+ provider.ns1 v1.6.0

Affected Resource(s)

Please list the resources as a list, for example:

  • ns1_user.test

If this issue appears to affect multiple resources, it may be an issue with Terraform's core, so please mention this.

Terraform Configuration Files

resource "ns1_team" "test-team" {
  name = "test-team"

  dns_view_zones = true
  dns_manage_zones = true
  dns_zones_allow = [
    "t.testing.net",
  ]
  dns_zones_deny = []
  data_push_to_datafeeds = true
  data_manage_datasources = true
  data_manage_datafeeds = true

  account_manage_users = false
  account_manage_payment_methods = false
  account_manage_plan = false
  account_manage_teams = false
  account_manage_apikeys = false
  account_manage_account_settings = false
  account_view_activity_log = true
  account_view_invoices = false

  monitoring_manage_lists = true
  monitoring_manage_jobs = true
  monitoring_view_jobs = true
}

resource "ns1_user" "test" {
  name = "IaC Testing"
  username = "testing_org"
  email = "[email protected]"
  notify = {
    billing = false
  }
  teams = [ns1_team.test-team.id]
}

Debug Output

https://gist.github.com/oogali/1e230933e1200aa2aeb50d249830a509

Panic Output

No panic produced.

Expected Behavior

No changes/updates should be required as the user resource hasn't changed.

Actual Behavior

Every time a plan is run, the NS1 provider wishes to modify attributes inherited from the team permissions, and set them to null.

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. terraform plan
  2. terraform apply

Important Factoids

No important facts to mention here.

References

No references.

ns1_apikey ip_whitelist is updated in-place every run of apply

Terraform Version

Terraform v0.14.6
registry.terraform.io/ns1-terraform/ns1 v1.9.4

Affected Resource(s)

ns1_apikey

Terraform Configuration Files

resource "ns1_apikey" "keys" {
  for_each = var.apikeys

  name = each.key
  ip_whitelist = each.value.ip_whitelist 
  ip_whitelist_strict = each.value.ip_whitelist_strict

  dns_manage_zones = each.value.can_manage_domains
  dns_view_zones = each.value.can_view_domains
  dns_zones_allow = each.value.allowed_domains

}

variable "apikeys" {
  description = "Map of API keys"
  type        = map(object({
    ip_whitelist = list(string)
    ip_whitelist_strict = bool

    can_manage_domains = bool
    can_view_domains = bool
    allowed_domains = list(string)

  }))
  default     = {}
}

terraform {
  required_providers {
    ns1 = {
      source = "ns1-terraform/ns1"
    }
  }
}

terraform {
  required_version = "= 0.14.6"
}

provider "ns1" {
  rate_limit_parallelism = 120
}

Debug Output

n/a

Panic Output

n/a

Expected Behavior

Each run of apply will not modify the ip_whitelist list if the list of IPs is not changed.

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

Actual Behavior

Each run of apply refresh ip_whitelist list even when the list of IPs is not changed:

  # ns1_apikey.keys["internal-test"] will be updated in-place
  ~ resource "ns1_apikey" "keys" {
        id                               = "..."
      ~ ip_whitelist                     = [
          - "115.77.190.36/32",
          - "12.203.64.18/32",
          - "115.79.197.99/32",
          - "115.77.189.244/32",
          - "216.38.128.34/32",
            "88.146.255.106/32",
            "88.146.183.98/32",
          + "115.77.189.244/32",
          + "115.79.197.99/32",
          + "115.77.190.36/32",
          + "216.38.128.34/32",
          + "12.203.64.18/32",
        ]
        name                             = "internal-test"
...
Plan: 0 to add, 1 to change, 0 to destroy.

Steps to Reproduce

  1. define TF_VARS_apikeys variable
  2. run terraform apply

Important Factoids

n/a

References

n/a

ns1_team & ns1_user resource erring when adding permissions attribute.

The ns1_team / ns1_user resource throws error when permissions argument is included.

Terraform Version

  • Terraform v0.10.2

ns1 provider plugin version

  • terraform-provider-ns1_v0.1.0_x4

resources affected.

  • ns1_team1
  • ns1_user

Sample tf code

resource "ns1_team" "example" {
  name = "Example team"

  permissions = {
    dns_view_zones       = false
    account_manage_users = false
  }
}

resource "ns1_user" "example" {
  name     = "Example User"
  username = "example_user"
  email    = "[email protected]"
  permissions = {
    dns_view_zones       = false
    account_manage_users = false
  }

Error

2017/08/18 15:43:32 [ERROR] root: eval: *terraform.EvalValidateResource, err: Warnings: []. Errors: [: invalid or unknown key: permissions]
2017/08/18 15:43:32 [ERROR] root: eval: *terraform.EvalSequence, err: Warnings: []. Errors: [: invalid or unknown key: permissions]
2017/08/18 15:43:32 [TRACE] [walkValidate] Exiting eval tree: ns1_team.example
1 error(s) occurred:

* ns1_team.example: : invalid or unknown key: permissions

2017/08/18 16:24:00 [ERROR] root: eval: *terraform.EvalValidateResource, err: Warnings: []. Errors: [: invalid or unknown key: permissions]
2017/08/18 16:24:00 [ERROR] root: eval: *terraform.EvalSequence, err: Warnings: []. Errors: [: invalid or unknown key: permissions]
2017/08/18 16:24:00 [TRACE] [walkValidate] Exiting eval tree: ns1_user.example
1 error(s) occurred:

* ns1_user.example: : invalid or unknown key: permissions

Error: invalid character '<' looking for beginning of value

Hello,

I am facing the following issue when I try to create a simple type A record.

Terraform Version

terraform -v
Terraform v0.13.4

  • provider registry.terraform.io/ns1-terraform/ns1 v1.9.1

Tried also with terraform v0.14.5, situation is the same.

Affected Resource(s)

  • ns1_record

Terraform Configuration Files

terraform {
  required_providers {
    ns1 = {
      source = "ns1-terraform/ns1"
      version = "1.9.1"
    }
  }
}

provider "ns1" {
  # It gets api key from environment NS1_APIKEY
  endpoint = "http://172.30.200.10"
  ignore_ssl = true
}

resource ns1_record "record" {
  zone = "development.cloud"
  domain = "test.development.cloud"
  type = "A"
  answers {
    answer = "172.30.200.150"
  }
}

Debug Output

https://gist.github.com/socratesx/9eca6bb13ada32023048e624ea1eccfd

Expected Behavior

The record should have been applied to the ns1 zone.

Actual Behavior

Planning goes normal but when applying:

$ 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:

  # ns1_record.record will be created
  + resource "ns1_record" "record" {
      + domain            = "gdc-iac-ns101.development.cloud"
      + id                = (known after apply)
      + ttl               = (known after apply)
      + type              = "A"
      + use_client_subnet = true
      + zone              = "development.cloud"

      + answers {
          + answer = "172.30.200.150"
        }
    }

Plan: 1 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_record.record: Creating...

Error: invalid character '<' looking for beginning of value

  on main.tf line 19, in resource "ns1_record" "record":
  19: resource ns1_record "record" {

Steps to Reproduce

  1. terraform apply

Creating record from IP from provision in same terraform template

I am using this module along with the terraform libvirt module available here:https://github.com/dmacvicar/terraform-provider-libvirt

I am creating two vms using count=2 and then trying to reference the updated state data to create my A records for the IPs of the machines. In my libvirt templates I have the proper wait for and that works as it needs to as I can use the remote-exec and ssh into each of the machines as expected. My issue is when I attempt to create my A records since the resource of the base state does not exist initially I am not even able to run a plan without a failure occurring. This only occurs when when initially doing the plan when the VM is not created so the IP is not in the statefile. If I comment the resource out run the apply, let it complete, uncomment, and then run apply again it works fine since it's in the statefile. It very much seems like in the case where a loop over an array is occurring it's not allowing the data to be amended as the template runs and instead wants the data available at the plan step. Here is an example of what works, and what does not.

Works:

resource "ns1_record" "masterARecord" {
  zone   = "myzone.com"
  domain = "masternode.myzone.com"
  type   = "A"
  ttl    = 60

  answers = {
    answer = "${libvirt_domain.masternode.network_interface.0.addresses.0}"
  }

}

Does not work:

resource "ns1_record" "nodeRecords" {
  count = 2
  zone   = "myzone.com"
  domain = "node${count.index}.myzone.com"
  type   = "A"
  ttl    = 60

  answers = {
    answer = "${element(libvirt_domain.*.network_interface.0.addresses.0, count.index)}"

  }

}

[PROPOSAL] Switch to Go Modules

As part of the preparation for Terraform v0.12, we would like to migrate all providers to use Go Modules. We plan to continue checking dependencies into vendor/ to remain compatible with existing tooling/CI for a period of time, however go modules will be used for management. Go Modules is the official solution for the go programming language, we understand some providers might not want this change yet, however we encourage providers to begin looking towards the switch as this is how we will be managing all Go projects in the future. Would maintainers please react with ๐Ÿ‘ for support, or ๐Ÿ‘Ž if you wish to have this provider omitted from the first wave of pull requests. If your provider is in support, we would ask that you avoid merging any pull requests that mutate the dependencies while the Go Modules PR is open (in fact a total codefreeze would be even more helpful), otherwise we will need to close that PR and re-run go mod init. Once merged, dependencies can be added or updated as follows:

$ GO111MODULE=on go get github.com/some/module@master
$ GO111MODULE=on go mod tidy
$ GO111MODULE=on go mod vendor

GO111MODULE=on might be unnecessary depending on your environment, this example will fetch a module @ master and record it in your project's go.mod and go.sum files. It's a good idea to tidy up afterward and then copy the dependencies into vendor/. To remove dependencies from your project, simply remove all usage from your codebase and run:

$ GO111MODULE=on go mody tidy
$ GO111MODULE=on go mod vendor

Thank you sincerely for all your time, contributions, and cooperation!

record import Error

Terraform Version

terraform .11.8

Affected Resource(s)

importing A record

this is happening with multiple records. seems like they are all "intelligent" records

Terraform Configuration Files

resource "ns1_record" "example_test" {

}
terraform import ns1_record.example_test example.com/test.example.com/A

First attempt shows:

ns1_record.example_test: Importing from ID "example.com/test.example.com/A"...
ns1_record.example_test: Import complete!
  Imported ns1_record (ID: example.com/test.example.com/A)
ns1_record.example_test: Refreshing state... (ID: example.com/test.example.com/A)

Error: ns1_record.example_test (import id: example.com/test.example.com/A): 1 error(s) occurred:

* import ns1_record.example_test result: example.com/test.example.com/A: ns1_record.example_test: unexpected EOF

second attempt shows a panic :

ns1_record.example_test: Importing from ID "example.com/test.example.com/A"...
ns1_record.example_test: Import complete!
  Imported ns1_record (ID: example.com/test.example.com/A)
ns1_record.example_test: Refreshing state... (ID: example.com/test.example.com/A)

Error: ns1_record.example_test (import id: example.com/test.example.com/A): 1 error(s) occurred:

* import ns1_record.example_test result: example.com/test.example.com/A: ns1_record.example_test: unexpected EOF


panic: expected v to be convertible to a string, got: map[feed:581bb95a1c37270001ca2277], map[string]interface {}
2018-05-16T17:07:40.445-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4:
2018-05-16T17:07:40.445-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: goroutine 16 [running]:
2018-05-16T17:07:40.445-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: github.com/terraform-providers/terraform-provider-ns1/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data.FormatInterface(0x1682000, 0xc4205d6870, 0x194, 0x1682000)
2018-05-16T17:07:40.445-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: 	/opt/teamcity-agent/work/222ea50a1b4f75f4/src/github.com/terraform-providers/terraform-provider-ns1/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/meta.go:186 +0x66b
2018-05-16T17:07:40.445-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: github.com/terraform-providers/terraform-provider-ns1/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data.(*Meta).StringMap(0xc42061e000, 0x2)
2018-05-16T17:07:40.445-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: 	/opt/teamcity-agent/work/222ea50a1b4f75f4/src/github.com/terraform-providers/terraform-provider-ns1/vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/meta.go:155 +0x2da
2018-05-16T17:07:40.445-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: github.com/terraform-providers/terraform-provider-ns1/ns1.answerToMap(0xc42061e000, 0xc420146700, 0x1, 0x4, 0x0, 0x0, 0xc4204a9c90)
2018-05-16T17:07:40.445-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: 	/opt/teamcity-agent/work/222ea50a1b4f75f4/src/github.com/terraform-providers/terraform-provider-ns1/ns1/resource_record.go:246 +0x200
2018-05-16T17:07:40.445-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: github.com/terraform-providers/terraform-provider-ns1/ns1.recordToResourceData(0xc4202af260, 0xc420177900, 0x9, 0xc420017810)
2018-05-16T17:07:40.445-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: 	/opt/teamcity-agent/work/222ea50a1b4f75f4/src/github.com/terraform-providers/terraform-provider-ns1/ns1/resource_record.go:213 +0xa07
2018-05-16T17:07:40.445-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: github.com/terraform-providers/terraform-provider-ns1/ns1.RecordRead(0xc4202af260, 0x169ee00, 0xc420177860, 0x0, 0x1b88540)
2018-05-16T17:07:40.445-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: 	/opt/teamcity-agent/work/222ea50a1b4f75f4/src/github.com/terraform-providers/terraform-provider-ns1/ns1/resource_record.go:379 +0x1b3
2018-05-16T17:07:40.445-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: github.com/terraform-providers/terraform-provider-ns1/vendor/github.com/hashicorp/terraform/helper/schema.(*Resource).Refresh(0xc420066e40, 0xc420150a00, 0x169ee00, 0xc420177860, 0xc4201db5b0, 0xc4202bd401, 0x80000000018)
2018-05-16T17:07:40.445-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: 	/opt/teamcity-agent/work/222ea50a1b4f75f4/src/github.com/terraform-providers/terraform-provider-ns1/vendor/github.com/hashicorp/terraform/helper/schema/resource.go:321 +0x199
2018-05-16T17:07:40.445-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: github.com/terraform-providers/terraform-provider-ns1/vendor/github.com/hashicorp/terraform/helper/schema.(*Provider).Refresh(0xc4202ae4d0, 0xc4201509b0, 0xc420150a00, 0x1cf3000, 0x0, 0x18)
2018-05-16T17:07:40.445-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: 	/opt/teamcity-agent/work/222ea50a1b4f75f4/src/github.com/terraform-providers/terraform-provider-ns1/vendor/github.com/hashicorp/terraform/helper/schema/provider.go:284 +0x9a
2018-05-16T17:07:40.445-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: github.com/terraform-providers/terraform-provider-ns1/vendor/github.com/hashicorp/terraform/plugin.(*ResourceProviderServer).Refresh(0xc42000b3a0, 0xc4202fe0f0, 0xc4202fe2b0, 0x0, 0x0)
2018-05-16T17:07:40.446-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: 	/opt/teamcity-agent/work/222ea50a1b4f75f4/src/github.com/terraform-providers/terraform-provider-ns1/vendor/github.com/hashicorp/terraform/plugin/resource_provider.go:510 +0x4e
2018-05-16T17:07:40.446-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: reflect.Value.call(0xc420067a40, 0xc42000c5f0, 0x13, 0x1745793, 0x4, 0xc42027ff20, 0x3, 0x3, 0x0, 0x0, ...)
2018-05-16T17:07:40.446-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: 	/usr/local/go/src/reflect/value.go:434 +0x905
2018-05-16T17:07:40.446-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: reflect.Value.Call(0xc420067a40, 0xc42000c5f0, 0x13, 0xc42026af20, 0x3, 0x3, 0x0, 0x0, 0x0)
2018-05-16T17:07:40.446-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: 	/usr/local/go/src/reflect/value.go:302 +0xa4
2018-05-16T17:07:40.446-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: net/rpc.(*service).call(0xc42004f8c0, 0xc4201508c0, 0xc420017520, 0xc42014ea80, 0xc42000bf20, 0x1623660, 0xc4202fe0f0, 0x16, 0x16236a0, 0xc4202fe2b0, ...)
2018-05-16T17:07:40.446-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: 	/usr/local/go/src/net/rpc/server.go:381 +0x142
2018-05-16T17:07:40.446-0400 [DEBUG] plugin.terraform-provider-ns1_v1.0.0_x4: created by net/rpc.(*Server).ServeCodec

Expected Behavior

record imported

Actual Behavior

errors above

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. terraform import

mx record import error

Terraform Version

0.11.7

Affected Resource(s)

ns1_resource of MX type

Terraform Configuration Files

terraformimport ns1_record.example_mx example.com/example.com/MX

Expected Behavior

the record should be imported and managed by terraform

Actual Behavior

ns1_record.example_mx: Importing from ID "example.com/example.com/MX"...
ns1_record.example_mx: Import complete!
  Imported ns1_record (ID: abote.com/example.com/MX)
ns1_record.example_mx: Refreshing state... (ID: example.com/example.com/MX)

Error: ns1_record.example_mx (import id: example.com/example.com/MX): 1 error(s) occurred:

* import ns1_record.example_mx result: example.com/example.com/MX: ns1_record.example_mx: json: cannot unmarshal number into Go struct field Answer.answer of type string

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. import the MX record

Validator on IPv4 only fields

Terraform Version

All versions

Affected Resource(s)

ns1_zone

Terraform Configuration Files

resource "ns1_zone" "secondary_zone" {
    zone                   = "foo.com"
    primary                = "2620:78:2000:0e00::ffff"
    additional_primaries   = ["2620:78:2000:0e00::fffe"]
}

Debug Output

Panic Output

Expected Behavior

Config should fail with validation warning on IPv6 addresses in IPv4 only fields primary and additional_primaries. NS1 does not currently support IPv6 values for these fields.

Actual Behavior

Error: PUT https://api.nsone.net/v1/zones/0.2.3.0.0.0.2.8.7.0.0.0.2.6.2.ip6.arpa: 400 Input validation failed (Value u'2620:78:2000:0e00::ffff' for field '<obj>.secondary.primary_ip' does not match regular expression '^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$')

  on modules/zone/secondary_zone/main.tf line 4, in resource "ns1_zone" "secondary_zone":
   4: resource "ns1_zone" "secondary_zone" {

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. terraform apply

Important Factoids

References

Terraform does not create a zone before attempting to add a record

Terraform Version

Run terraform -v to show the version. If you are not running the latest version of Terraform, please upgrade because your issue may have already been fixed.

Affected Resource(s)

Please list the resources as a list, for example:

  • ns1_zone
  • ns1_record

Terraform Configuration Files

main.tf:

variable "ns1_apikey" {}

variable "zone_name" {
  default = "test-domain.net"
}

provider "ns1" {
  apikey  = "${var.ns1_apikey}"
  version = "1.0.0"
}

terraform {
  backend "s3" {
    bucket = "terraform-state"
    key    = "external-dns/zones/test-domain.net.tfstate"
    region = "us-east-1"
  }
}

resource "ns1_zone" "test-domain_net" {
  zone = "${var.zone_name}"
}

records.tf:

resource "ns1_record" "a___apex" {
  zone   = "${var.zone_name}"
  domain = "${var.zone_name}"
  type   = "A"

  answers = {
    answer = "10.90.10.1"
  }
}

Debug Output

Non Debug Output: https://gist.github.com/poblahblahblah/f5ee71bf6e2ff619824aa952964650b0

Panic Output

N/A

Expected Behavior

I would expect that the zone would be created first, then the records for the zone created next

Actual Behavior

Terraform tried to create the records first without creating the zone. This cause apply to fail. Running apply a 2nd time was successful.

Steps to Reproduce

  1. Create a brand new zone and record.
  2. terraform apply

Important Factoids

N/A

References

N/A

ns1_record refresh does not support resources disappearing

Terraform Version

Run terraform -v to show the version. If you are not running the latest version of Terraform, please upgrade because your issue may have already been fixed.

Terraform v0.11.6
+ provider.ns1 v1.0.0

Affected Resource(s)

Please list the resources as a list, for example:

  • ns1_record
  • possibly more

Terraform Configuration Files

resource "ns1_record" "a___apex" {
     zone = "${var.zone_name}"
     domain = "${var.zone_name}"
     type = "ALIAS"
     ttl = 3600

     answers = {
          answer = "example.com."
     }
}

Expected Behavior

On refresh, if a record does not exist, TF+ns1 should want to create it again.

Actual Behavior

On refresh (as part of terraform plan), the following errors are logged:

Error: Error refreshing state: 2 error(s) occurred:
* ns1_record.cname___www: 1 error(s) occurred:
* ns1_record.cname___www: ns1_record.cname___www: record does not exist
* ns1_record.a___example: 1 error(s) occurred:
* ns1_record.a___example: ns1_record.a___apex: record does not exist

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. run a terraform apply that creates an ns1_record resource
  2. from the web interface, delete the record
  3. run a terraform plan

Important Factoids

This doesn't seem like a terraform specific issue, I took a quick look (approx 30 seconds) at the resource in this repo and it looks like it's just mapping API output and returning it? It seems like RecordRead could be extended to catch "record doesn't exist" errors and instead signal that the record should be created, instead of exiting.

Release

@alistanis Hi; I've built this manually for now as I needed the meta attributes; is there a public roadmap for this stuff / hashicorp stuff in general, around release dates for builds (seeing there are no nightlies)?

Thanks for the effort pulling all the outstanding PRs in and the extra clean-ups, it's greatly appreciated.

ns1_user plan does not validate username

Terraform Version

0.12.15

Affected Resource(s)

  • ns1_user

Terraform Configuration Files

resource "ns1_user" "my_user" {
  name     = "My User"
  username = "my.user"
  email    = "[email protected]"
  teams = [
    ns1_team.manager.id
  ]
}

Debug Output

plan:

  # ns1_user.my_user will be created
  + resource "ns1_user" "my_user" {
      + account_manage_account_settings  = false
      + account_manage_apikeys           = true
      + account_manage_payment_methods   = false
      + account_manage_plan              = false
      + account_manage_teams             = false
      + account_manage_users             = false
      + account_view_activity_log        = false
      + account_view_invoices            = false
      + data_manage_datafeeds            = false
      + data_manage_datasources          = false
      + data_push_to_datafeeds           = false
      + dhcp_manage_dhcp                 = false
      + dhcp_view_dhcp                   = false
      + dns_manage_zones                 = false
      + dns_view_zones                   = false
      + dns_zones_allow_by_default       = false
      + email                            = "[email protected]"
      + id                               = (known after apply)
      + ipam_manage_ipam                 = false
      + ipam_view_ipam                   = false
      + monitoring_manage_jobs           = false
      + monitoring_manage_lists          = false
      + monitoring_view_jobs             = false
      + name                             = "My User"
      + security_manage_active_directory = false
      + security_manage_global_2fa       = false
      + teams                            = (known after apply)
      + username                         = "my.user"
    }

Panic Output

Failed Apply:

Error: PUT https://api.nsone.net/v1/account/users: 400 Input validation failed (Value u'my.user' for field '<obj>.username' does not match regular expression '^([a-zA-Z0-9_]+)$')

  on user_my_user.tf line 1, in resource "ns1_user" "my_user":
   1: resource "ns1_user" "my_user" {

Expected Behavior

I would expect the plan to throw an error.

Actual Behavior

The apply fails after a passing verify and plan.

Steps to Reproduce

  1. terraform plan
  2. terraform apply

Important Factoids

Using this provider completely within a CI/CD system, so plans/verifications need to happen on the feature branch before it merges to master. A failed apply means master is in a bad state.

ns1_zone: CIDR for Secondaries

Hi there,

Terraform Version

Run terraform -v to show the version. If you are not running the latest version of Terraform, please upgrade because your issue may have already been fixed.

# ./terraform -v
Terraform v0.11.7

Affected Resource(s)

Please list the resources as a list, for example:

  • ns1_zone

Terraform Configuration Files

resource "ns1_zone" "public_data_zone" {
  zone = "${var.public_data_ns1_zone}"
  ttl = "${var.dns_ttl}"
  secondaries {
    ip     = "10.10.10.10"
    port   = 53
    notify = true
  }
  secondaries {
    ip     = "10.10.10.20"
    port   = 53
    notify = true
  }
  secondaries {
    ip     = "10.10.20.0/27"
  }
}

Debug Output

ns1_zone.public_data_zone: Modifying... (ID: 5a984d9d0c13a400017f22c9)
  secondaries.257793059.ip:         "" => "10.10.20.0/27"
  secondaries.257793059.networks.#: "" => "<computed>"
  secondaries.257793059.notify:     "" => "false"
  secondaries.257793059.port:       "" => "53"
  secondaries.3238851087.ip:        "10.10.10.10" => "10.10.10.10"
  secondaries.3238851087.notify:    "true" => "true"
  secondaries.3238851087.port:      "53" => "53"
  secondaries.4276752053.ip:        "10.10.10.20" => "10.10.10.20"
  secondaries.4276752053.notify:    "true" => "true"
  secondaries.4276752053.port:      "53" => "53"
  secondaries.564337443.ip:         "10.10.20.0/27" => ""
  secondaries.564337443.notify:     "false" => "false"
  secondaries.564337443.port:       "0" => "0"

Error: Error applying plan:

1 error(s) occurred:

* ns1_zone.public_data_zone: 1 error(s) occurred:

* ns1_zone.public_data_zone: POST https://api.nsone.net/v1/zones/sub.domain.net: 400 port cannot be set with a subnet address

Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.

Expected Behavior

NS1 would have accepted a CIDR as a secondary, per NS1 Documentation

NS1 now allows you to configure inbound zone transfer requests from a subnet if you enter a CIDR notation (ex. 192.0.2.0/24) instead of a single IP address in the address field. Note that doing so automatically disables notification options. In order to notify individual servers within the subnet, enter their IP addresses as additional secondary servers explicitly.

Actual Behavior

There was an error from the API. The default port for a secondary per the provider is 53, which if not defined in the HCL it will be set and POST'd to the API.

Factoids

The JSON payload below works to set 2 by IP and 1 by CIDR when POSTing to the API directly

{
  "primary": {
    "enabled": true,
    "secondaries": [
      {
        "ip": "10.10.10.10",
        "notify": true,
        "port": 53
      },
      {
        "ip": "10.10.10.20",
        "notify": true,
        "port": 53
      },
      {
        "ip": "10.10.20.0/27"
      }
    ]
  }
}

Use of many ip_prefixes in an ns1_record results in broken change detection

Using many ip_prefixes is not idempotent. Every plan/apply shows changes even when the terraform is unchanged.

I believe this is because on the server side NS1 re-orders the ip prefix list, which you can see happen on their console. Note that you may need more than a couple ip prefixes to exhibit this behavior.

If NS1 will not guarantee consistent round-tripping on their api, then the terraform provider itself should compare the plan and actual lists using by breaking apart the attribute string and comparing the two sets of ip prefixes more directly.

Terraform Version

Terraform v0.12.9

Affected Resource(s)

  • ns1-record

Terraform Configuration Files

resource "ns1_record" "alias" {
  zone   = var.zone
  domain = var.domain
  type   = "ALIAS"
  ttl    = var.ttl

  answers {
    answer = "..."
    meta = {
      ...
      ip_prefixes = "join(",", [
        "3.248.0.0/13",
        "13.248.96.0/24",
        "13.248.113.0/24",
        "13.248.118.0/24",
        "13.248.119.0/24",
        "13.248.121.0/24",
        ...
      ])
    }
  }
  ...
}

Note that I'm only using join so that I can put each ip block on its own line; this makes it easy to detect when there are changes using the normal source control commands.

Expected Behavior

The expected behavior is that applying unchanged terraform (i.e., the list of ip_prefixes does not change) should be idempotent.

I should be able to deploy the terraform, and the next plan should show no changes.

Actual Behavior

Every plan / apply shows changes in the list of IP ranges.

The code that I wrote to generate this terraform is careful to sort the ip prefix list into a stable order (done by octet). I note that after I terraform apply and view the actual record in the NS1 console, the ip prefixes have been shuffled into a different order.

(My guess is that on the NS1 server side it passes through some kind of hash set, and gets re-ordered by their hashing function; again, this is a guess.)

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. Create a record with a number of ip prefixes; there needs to be enough to be subject to reordering.
  2. terraform apply
  3. Note in the console that the order has changed.
  4. terraform apply
  5. Verify that every apply shows a change in the ip prefixes, even though the terraform source has not changed.

Error: ns1: could not find api key

Terraform Version

0.12.24, 0.12.29, 0.14.0

Terraform Configuration Files

data "aws_secretsmanager_secret" "ns1" {
  name = "ns1_apikey"
}

data "aws_secretsmanager_secret_version" "ns1" {
  secret_id = data.aws_secretsmanager_secret.ns1.id
}

provider "ns1" {
  version = "= 1.9.4"
  apikey  = data.aws_secretsmanager_secret_version.ns1.secret_string
}

Debug Output

17:34:24         2021-03-25T00:34:24.403Z [DEBUG] plugin: waiting for RPC address: path=/home/jenkins/agent/workspace/TF_tf12-jarvis_PR-20/test/fixtures/.terraform/plugins/linux_amd64/terraform-provider-ns1_v1.9.4
17:34:24         2021-03-25T00:34:24.412Z [INFO]  plugin.terraform-provider-ns1_v1.9.4: configuring server automatic mTLS: timestamp=2021-03-25T00:34:24.412Z
17:34:24         2021-03-25T00:34:24.445Z [DEBUG] plugin.terraform-provider-ns1_v1.9.4: plugin address: address=/tmp/plugin148118970 network=unix timestamp=2021-03-25T00:34:24.445Z
17:34:24         2021-03-25T00:34:24.445Z [DEBUG] plugin: using plugin: version=5
17:34:24         2021/03/25 00:34:24 [ERROR] module.jarvis: eval: *terraform.EvalConfigProvider, err: ns1: could not find api key
17:34:24         2021/03/25 00:34:24 [ERROR] module.jarvis: eval: *terraform.EvalSequence, err: ns1: could not find api key
17:34:24         2021/03/25 00:34:24 [ERROR] module.jarvis: eval: *terraform.EvalOpFilter, err: ns1: could not find api key
17:34:24         2021/03/25 00:34:24 [ERROR] module.jarvis: eval: *terraform.EvalSequence, err: ns1: could not find api key
17:34:24         2021-03-25T00:34:24.649Z [DEBUG] plugin: plugin process exited: path=/home/terraform/.terraform.d/plugins/terraform-provider-aws_v2.61.0_x4 pid=6535
17:34:24         2021-03-25T00:34:24.649Z [DEBUG] plugin: plugin exited
17:34:24         
17:34:24         Error: ns1: could not find api key
17:34:24         
17:34:24           on ../../ns1.tf line 9, in provider "ns1":
17:34:24            9: provider "ns1" {

Expected Behavior

Should work

Actual Behavior

It fails some of the times, feels like it has something to do with a race condition when the provider tries to initialize before AWS SSM data source was refreshed.

Steps to Reproduce

  1. terraform destroy until it fails (the issue is with trying to destroy a module that has been already destroyed or never created - i.e. state file is empty).

Unable to link MonitoringJob to Record/Answers

Terraform Version

Terraform 0.11.11

Affected Resource(s)

  • ns1_monitoringjob

Terraform Configuration Files

resource "ns1_monitoringjob" "ftevif2_monitor_test" {
  name          = "FTE VIF #2"
  active        = true
  regions       = ["lga"]
  job_type      = "http"
  frequency     = 60
  rapid_recheck = true
  policy        = "quorum"
  notify_list   = "working_id"
  notify_failback = true

  config = {
    method = "GET"
    url = "http://example.com"
  }

  rules = {
    value      = "503"
    comparison = "=="
    key        = "status_code"
  }

}

Expected Behavior

There should be a data feed created that is linked to this new monitoring job, which then allows us to link the job to answer records - this can be observed when creating a monitoring job through the UI on NS1.

Actual Behavior

When a new monitoring job is created via terraform, it exists in the web UI and system , but no corresponding data feed is created, meaning the monitor job cannot then be linked to records.

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. Create a new monitoring job
  2. terraform plan
  3. terraform apply
  4. Observe created monitor job in UI
  5. Observe lack of data feed in UI

Error Strings contain capital letters or punctuation

Terraform Version

`
Terraform v0.11.6

  • provider.ns1 v1.6.0
    `

Affected Resource(s)

Issue exists throughout the code base.

Terraform Configuration Files

  • N/A

Debug Output

  • N/A

Panic Output

  • N/A

Expected Behavior

Error strings should not be capitalized (unless beginning with proper nouns or acronyms) or end with punctuation, since they are usually printed following other context. That is, use fmt.Errorf("something bad") not fmt.Errorf("Something bad"), so that log.Printf("Reading %s: %v", filename, err) formats without a spurious capital letter mid-message. This does not apply to logging, which is implicitly line-oriented and not combined inside other messages.
-- Quoting Golang Code Review Comments

Actual Behavior

  1. My IDE complains about various strings used in the code base, distracting me from debugging.

Steps to Reproduce

N/A

Important Factoids

If I've got the time to submit this issue, I've got the time to send a Pull Request and contribute to the community. It's in my queue of stuff for free time.

Support import of ns1_user and ns1_team resources

Terraform Version

Terraform 0.12.8
ns1 provider 1.9.4

Affected Resource(s)

  • ns1_user
  • ns1_team

Terraform Configuration Files

resource "ns1_user" "user" {
  provider                   = "ns1"
  name                       = "test"
  username                   = "custom_user_prefix_test"
  email                      = "[email protected]"
  teams                      = ["team-hash"]

  notify = {
    billing = false
  }

  # Because users can change their own name, we ignore changes to avoid unexpected drifts
  lifecycle {
    ignore_changes = ["name"]
  }
}

Debug Output

$ terraform import 'ns1_user.user' mytestuser
Acquiring state lock. This may take a few moments...
ns1_user.user: Importing from ID "mytestuser"...

Error: resource ns1_user doesn't support import

Panic Output

Does not apply

Expected Behavior

Provider should support importing users and teams

Actual Behavior

Provider does not support importing users and teams

Steps to Reproduce

  1. Use provided configuration file
  2. run terraform import 'ns1_user.user' mytestuser

Important Factoids

We have been told that when a user is deleted, the user is put on a deletion queue for 7 days. During this period, the username is reserved (as in-use), but not visible through the NS1 users API or the UI. Apparently, an NS1 support representative could recover the account from the deletion queue in case of accidental user deletion.

Nevertheless, nothing of this is useful under the following scenarios:

  • We delete a user, and we try to recreate it again. The username is in the deletion queue and API answers that user already exists
  • If we reach out to support for them to recover the username, it stays in the limbo, outside of our automation IaC strategy

These problems would go away if the provider would allow importing team and users. I guess it's a common scenario for folks that:

  • Don't use SAML integration
  • started with manual user creation
  • want to import the users into terraform IaC

References

N/A

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.