Coder Social home page Coder Social logo

terraform-provider-nsone's Introduction

Synopsis

This is an experimental provider which allows Terraform to create and update DNS zones, records, monitoring jobs, data sources and feeds, and other resources with the NSONE API.

Example use

provider "nsone" {
  api_key = "xxxxxxx" # Or set NSONE_APIKEY environment variable
}

resource "nsone_datasource" "api" {
  name = "terraform test"
  sourcetype = "nsone_v1"
}

resource "nsone_datafeed" "exampledc1" {
  name = "exampledc1"
  source_id = "${nsone_datasource.api.id}"
  config {
    label = "exampledc1"
  }
}

resource "nsone_datafeed" "exampledc2" {
  name = "exampledc2"
  source_id = "${nsone_datasource.api.id}"
  config {
    label = "exampledc2"
  }
}

resource "nsone_zone" "example" {
  zone = "mycompany.com"
  ttl = 60
}

resource "nsone_record" "www" {
  zone = "${nsone_zone.example.zone}"
  domain = "www.${nsone_zone.example.zone}"
  type = "A"
  answers {
    answer = "1.1.1.1"
    meta {
      field = "up"
      feed = "${nsone_datafeed.exampledc1.id}"
    }
    region = "useast"
  }
  answers {
    answer = "2.2.2.2"
    meta {
      feed = "${nsone_datafeed.exampledc2.id}"
      field = "up"
    }
    region = "uswest"
  }
  regions {
    name = "useast"
    georegion = "US-EAST"
  }
  regions {
    name = "uswest"
    georegion = "US-WEST"
  }
  filters {
    filter = "up"
  }
  filters {
    filter = "select_first_n"
    config {
      N = 1
    }
  }
}

resource "nsone_record" "star" {
  link = "www.${nsone_zone.example.zone}"
}

resource "nsone_zone" "co_uk" {
  zone = "mycompany.co.uk"
  link = "${nsone_zone.example.zone}"
}

resource "nsone_monitoringjob" "useast" {
  name = "useast"
  active = true
  regions = [ "lga" ]
  job_type = "tcp"
  frequency = 60
  rapid_recheck = true
  policy = "all"
  config {
    send = "HEAD / HTTP/1.0\r\n\r\n"
    port = 80
    host = "1.1.1.1"
  }
}

See the examples/ folder in the repository for more detailed examples.

Installing

make install

Should do the right thing assuming that you have terraform already installed, and this code is placed in the right place in your $GOPATH.

Supported features

Create and manage DNS zones

* Normal primary zones supported
* Linked zones supported
* Secondary (slave) zones supported

Manage records in your zones

* A, MX, ALIAS and CNAME record types are supported.
* Other record types MAY work, but are untested.
* Supports NSONE's Linked Records
* Supports multiple answers, each of which can be connected to data feeds
* Add filter chains to records, with config
* Add regions to answers, and the record. Some (not all!) region metadata types are supported.

Data sources

* Can create datasources with arbitrary config
* This *should* work for all datasource types, but only nsone_v1 and nsone_monitoring are tested

Data feeds

* Create data feeds connected to a data source with a label

NSONE monitoring

* Create and manage monitoring jobs.
* Connect monitoring notifications to data feeds and use monitors to control record up/down status.

Users / Account management / API keys

  • Creation of users, API keys and teams is fully supported

Unsupported features

Zones

  • Whitelisting of secondary servers to allow AXFR is currently unsupported

Records

  • Metadata support in regions is limited
  • Record-wide metadata is unsupported

NSONE monitoring

  • Notification list management is not supported

Resources provided

nsone_zone

Creates a DNS zone in NSONE.

Inputs

  • zone - The name of the zone to define [Required]
  • link - The name of another zone to link this zone to (so that they serve the same DNS records) [Optional]
  • ttl - The TTL for the SOA record for this zone [Optional]
  • nx_ttl - The TTL for NXDOMAIN answers in this zone [Optional]
  • refresh - Frequency for slaves to try to refresh this zone [Optional]
  • retry - Time between slave retries if "refresh" has expired [Optional]
  • expiry - Time after an expired "refresh" to keep "retrying" before giving up [Optional]
  • primary - The master nameserver hostname to AXFR this zone from, creates a secondary zone. [Optional]

Outputs

  • id - The internal ID for the zone in the NSONE API
  • hostmaster - The hostmaster for the zone

nsone_record

Creates a DNS record and optional traffic management config in NSONE.

Inputs

  • zone - The name of the zone that this record lives in [Required]
  • domain - The full domain name of this record [Required]
  • ttl - A TTL specific to this record [Optional]
  • type - The type of the record [Required]
  • meta - Record wide metadata [Currently unsupported]
  • link - The domain of a record to link this record to (so that they serve the same answers) [Optional]
  • answers - The set of answers that it's possible to return. This stanza can be repeated.
    • answer - The DNS RDATA of the answer to return (e.g. "1.2.3.4" for an A record, or "some.example.com" for a CNAME). FIXME - Test/fix other record types. [Required]
    • region - The name of the region (from 'regions', below) to assign this answer to. Regions may be used to specify metadata that should apply across all answers in the region. [Optional]
    • meta - Add metadata key/value pairs to this answer, used for filtering. This stanza can be repeated. Get the current set of supported metadata types from the /metatypes NSONE API endpoint. [Optional]
      • field - The metadata field name to update from a feed. [Required]
      • feed - The id of the data feed which updates this field. [Optional, conflicts with value]
      • value - The static value to set for this metadata field. [Optional, conflicts with feed]
  • regions - The set of regions into which answers may be grouped. Each region has its own metadata. This stanza can be repeated. [Optional]
    • name - The name of this region (the name provided in an answer) [Required]
    • georegion - The name of the geographic region which corresponds to this region. Allowed values are: US-WEST, US-EAST, US-CENTRAL, EUROPE, AFRICA, ASIAPAC, SOUTH-AMERICA. [Optional]
    • country - The name of the country which corresponds to this region. FIXME countries? [Optional]
    • us_state - The name of the US state which corresponds to this region. FIXME states? [Optional]
    • FIXME - Add the rest!
    • FIXME - Add support for having feeds at the region level!
  • filters - The Filter Chain to apply to the answers, consisting of a list of filter algorithms. This stanza can be repeated. Order matters when creating a Filter Chain. [Optional]
    • filter - The type of this filter. Get possible filters from the /filtertypes NSONE API endpoint. [Required]
    • disabled - If this filter should be disabled. [Optional]
    • config - A map of configuration key/value pairs specific to this filter. Get the possible/required keys and values from the /filtertypes NSONE API endpoint. [Optional]

Outputs

  • id - The internal NSONE ID for this record
  • ttl - The record's TTL

nsone_datasource

NSONE Data Sources are conduits for pushing updates to DNS record/answer metadata through individual data feeds to NSONE's platform.

Inputs

  • name - The name to associate with this data source. [Required]
  • sourcetype - The type of data source to create. Get the current set of supported data source types from the /data/sourcetypes NSONE API endpoint. nsone_v1, nsone_monitoring are currently tested. [Required]

Outputs

  • id - The internal NSONE id of this data source. This is used when associating feeds with this source (nsone_datafeed's source_id).

nsone_datafeed

Multiple data feeds may be associated with an NSONE Data Source -- for example, feeds keyed to individual servers, monitoring jobs, etc.

Inputs

  • source_id - The internal NSONE id of the data source this feed is attached to. [Required]
  • name - The user friendly name for this feed [Required]
  • config - A map of configuration key/value pairs for this data feed. The keys and values required vary depending on the type of source. Get the current set of supported config keys from the /data/sourcetypes NSONE API endpoint. [Optional]

Outputs

  • id - The internal NSONE id of this data feed. This is passed into resource_record's answer.meta.feed field

nsone_monitoringjob

NSONE's Monitoring jobs enable up/down monitoring of your different service endpoints, and can feed directly into DNS records to drive DNS failover.

Inputs

  • name - The friendly name of this monitoring job [Required]
  • active - If the job is active [Bool, Required]
  • regions - NSONE Monitoring regions to run the job in. List of valid regions is available from the /monitoring/regions NSONE API endpoint. [Required]
  • job_type - One of the job types from the /monitoring/jobtypes NSONE API endpoint. [Required]
  • frequency - How often to run the job in seconds [Int, Required]
  • rapid_recheck - If the check should be immediately re-run if it fails [Bool, Required]
  • policy - The policy of how many regions need to fail to make the check fail, this is one of: quorum, one, all. [Required]
  • notes - Operator notes about what this monitoring job does. [Optional]
  • config - A map of configuration for this job_type, see the /monitoring/jobtypes NSONE API endpoint for more info. [Required]
  • notify_delay - How long this job needs to be failing for before notifying [Int, Optional]
  • notify_repeat - How often to repeat the notification if unfixed [Int, Optional]
  • notify_failback - Notify when fixed [Bool, Optional]
  • notify_regional - Notify (when using multiple regions, and quorum or all policies) if an individual region fails checks [Bool, Optional]
  • notify_list - Notification list id to send notifications to when this monitoring job fails [Optional]
  • rules - List of rules determining failure conditions. Each entry must have the following inputs: [Optional]
    • value - Value to compare to [Required]
    • comparison - Type of comparison to perform [Required]
    • key - The output key from the job, to which the value will be compared - see the /monitoring/jobtypes NSONE API endpoint for list of valid keys for each job type [Required]

Outputs

  • id - The internal NSONE id of this monitoring job. This is passed into resource_datafeed's config.jobid

nsone_user

Inputs

N.B. This also has all the inputs from the nsone_team resource, which you can use instead of assigning to key to one or more teams.

  • username - The user's login username [Required]
  • email - The user's email address [Required]
  • name - The user's full name [Required]
  • notify
    • billing - Whether the user should receive billing notifications [Bool, Optional]
  • teams - List of the nsone_team ids to attach to this user's permissions. [Optional]

Outputs

  • id - The internal NSONE id of this user.
  • FIXME - Add current registration/login status?

nsone_apikey

Inputs

N.B. This also has all the inputs from the nsone_team resource, which you can use instead of assigning to key to one or more teams.

  • teams - List of the nsone_team ids to attach to this API key's permissions.

Outputs

  • key - The API key that has been generated.
  • id - The internal NSONE id of this api key.

nsone_team

Permissions are all optional -- by default, a user is granted an unspecified permission.

Inputs

  • name - The name of this team. [Required]
  • dns_view_zones [Bool]
  • dns_manage_zones [Bool]
  • dns_zones_allow_by_default [Bool]
  • dns_zones_deny - List of zones [Optional]
  • dns_zones_allow - List of zones [Optional]
  • data_push_to_datafeeds [Bool]
  • data_manage_datasources [Bool]
  • data_manage_datafeeds [Bool]
  • account_manage_users [Bool]
  • account_manage_payment_methods [Bool]
  • account_manage_plan [Bool]
  • account_manage_teams [Bool]
  • account_manage_apikeys [Bool]
  • account_manage_account_settings [Bool]
  • account_view_activity_log [Bool]
  • account_view_invoices [Bool]
  • monitoring_manage_lists [Bool]
  • monitoring_manage_jobs [Bool]
  • monitoring_view_jobs [Bool]

Outputs

  • id - The internal NSONE id of this team.

Support / contributions

I'm planning to continue developing and supporting this code for my use-cases, and I'll do my best to respond to issues and pull requests (and I'm happy to take patches to improve the code or add missing feaures!).

Also, please be warned that I am not a competent Go programmer, so please expect to find hideous / insane / non-idiomatic code if you look at the source. I'd be extremely happy to accept patches or suggestions from anyone more experience than me:)

Please feel free to contact me via github issues or Twitter or irc in #terraform (t0m) if you have any issues with, or would like advice on using this code.

Copyright

Copyright (c) Tomas Doran 2015

LICENSE

Apache2 - see the included LICENSE file for more information

terraform-provider-nsone's People

Contributors

asottile avatar beevek avatar bobtfish avatar oholiab avatar sarguru avatar supermatt avatar thomasco avatar vulpine avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar

terraform-provider-nsone's Issues

markdown error.

Parens and brackets are swapped in the md link.

screen shot 2016-02-10 at 4 27 41 pm

p.s. thank you for this sweet sweet project.

Support New Terraform API Version 2 and Terraform 0.7

When I try to run this, using Terraform v0.6.16 I get the following error message about the API version.

Is there a work around or branch that resolves this problem?

$ terraform plan
Error configuring: 1 error(s) occurred:

* Incompatible API version with plugin. Plugin version: 1, Ours: 2

What are resource IDs used for?

I'm trying to figure out how to use terraform-provider-nsone to download our current NS1 configuration into a Terraform state file. It looks like I need to implement Importers for the different NS1 resources.

As part of doing that, I'm trying to understand how Terraform resource IDs work. It looks like maybe terraform-provider-nsone doesn't actually use Terraform resource IDs when communicating with the NS1 API. Is that true?

resource nsone_user crashes when trying to set billing

For a sample resource which goes like

  resource "nsone_user" "test_sarguru" {
  name = "sarguru2"
  username = "sarguru99"
  email = "[email protected]"
  notify {
    billing = true
  }
}

the terraform provider crashes with the following error.

!!!!!!!!!!!!!!!!!!!!!!!!!!! TERRAFORM CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!!
nsone_user.test_sarguru: Creating...
  email:          "" => "[email protected]"
  name:           "" => "sarguru2"
  notify.#:       "0" => "1"
  notify.billing: "" => "1"
  username:       "" => "sarguru99"
Error applying plan:

1 error(s) occurred:

* nsone_user.test_sarguru: unexpected EOF
.
panic: interface conversion: interface is string, not bool

It seems to be because notify.billing: "" => "1" is rendered as a string rather than boolean for some reason.

ip_prefixes record meta data should support lists

Currently ip_prefixes expects a string. NS1 api suggests we should pass something like [1.2.3.0/24,5.6.7.0/24] but if we pass this as a string , nsone throws an error saying its not a valid IPV4 address. '1.2.3.0/24, 5.6.7.0/24.' is considered a valid input but only the first range is set in the ip prefixes. It would be nice to pass a comma or space separated list.

Terraform applies even when there is no change

If we run exactly the same code multiple times, even when there is no actual change, terraform plan says there is a change.

Digging a little deeper it seems to happen only in places where we have a meta field with a value, if we have answers with just meta field that just has feed then it works fine.

It looks like nsone returns answers differently for both the meta types which might be causing issue with the hash generated.

For. eg

[{Region:uswest Answer:[2.2.2.2] Meta:map[weight:10]} {Region:useast Answer:[1.1.1.1] Meta:map[weight:10]}]

vs

[{Region:useast Answer:[1.1.1.1] Meta:map[up:map[feed:5662dd929f782d027ede0b85]]} {Region:uswest Answer:[2.2.2.2] Meta:map[up:map[feed:5662dd929f782d027ede0b84]]}]

which leads to

Generated metaToHash %d from %+v 2516651947 map[feed: value: field:weight]

instead of

Generated metaToHash %d from %+v 723701776 map[field:up feed:5662dd929f782d027ede0b84]

Ability to get name servers assigned by nsone in an output.

We should be able to get this back from the API, and output it in a terraform output, so that this info can be displayed to users and/or used elsewhere.

Due to Terraform's terrible handling of structured data, this will probably need to be a comma separated list.

Filter Config JSON /

Been trying to set netfence_prefix to do split horizon DNS. There's something defining filters when a bool like netfence_prefix is converted into JSON. I'm not really sure how to fix it. Almost like when schema.TypeMap is turned into JSON nothing is defining remove_no_ip_prefixes as a bool

I get errors like

nsone_record.www_priv: 400 Bad Request: {"message":"filter declaration incorrect: \"1\" invalid for option \"remove_no_ip_prefixes\""}

In a test record

  filters {
    filter = "netfence_prefix"
    config = {
      remove_no_ip_prefixes = true
    }
  }

Gets translated into

  "filters": [{
    "filter": "netfence_prefix",
    "config": {
      "remove_no_ip_prefixes": 1
    }
  }]

I also tried

  filters {
    filter = "netfence_prefix"
    config = {
      remove_no_ip_prefixes = "true"
    }
  }

Which translates into

  "filters": [{
    "filter": "netfence_prefix",
    "config": {
      "remove_no_ip_prefixes": "true"
    }
  }],

From testing on the command line, the stanza should be

  "filters": [{
    "filter": "netfence_prefix",
    "config": {
      "remove_no_ip_prefixes": true
    }
  }]

Any thoughts on how to work around / fix this?

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.