Terraform provider implementation for interacting with the Tailscale API.

Overview

Terraform Provider Tailscale

This repository contains a Terraform provider implementation for interacting with the Tailscale API.

Build provider

Run the following command to build the provider

$ go build -o terraform-provider-tailscale

Test sample configuration

First, build and install the provider.

$ make install

Then, navigate to the examples directory.

$ cd examples

Run the following command to initialize the workspace and apply the sample configuration.

$ terraform init && terraform apply
Issues
  • Unable to add tests to ACL

    Unable to add tests to ACL

    I have been having issues implementing ACL tests with the Terraform provider. Once I add the tests section and try to terraform apply I receive the following error.

    │ Error: Failed to set ACL
    │
    │   with tailscale_acl.cio_acl,
    │   on main.tf line 1, in resource "tailscale_acl" "cio_acl":
    │    1: resource "tailscale_acl" "cio_acl" {
    │
    │ test(s) failed (400)
    

    I am able to apply the same JSON file through the Tailscale API, so this issue only occurs with the Terraform provider.

    bug 
    opened by mikevischer 16
  • Permanent diff in ACL resources

    Permanent diff in ACL resources

    Describe the bug I get a permadiff when running terraform plan/apply.

    Since I'm fairly certain WHY I get a permadiff, I will just link to the issue I posted in the tailscale github org. (i.e I don't believe it's the terraform provider's fault but it's clearly a problem that is very visible here):

    https://github.com/tailscale/tailscale/issues/3723

    bug upstream 
    opened by johnae 12
  • switch resource type for DeviceSubnetRoutes.routes to Set

    switch resource type for DeviceSubnetRoutes.routes to Set

    What this PR does / why we need it: This PR changes DeviceSubnetRoutes to have TypeSet instead of TypeList.

    TypeList requires the items to be in a specific order; TypeSet does not. Using TypeList can result in unnecessary change detection if output returned by TS API (which does not appear to return in a fully deterministic or sorted order) is in a different order than input. It also makes diffs more difficult to read if e.g. you add a route mid-list and it detects all routes after that as changed.

    In my testing, at least, this change appears to migrate cleanly from the previous version with TypeList.

    Which issue this PR fixes (use fixes #<issue number>(, fixes #<issue_number>, ...) format, will close that issue when PR gets merged):

    Fixes #57

    Special notes for your reviewer:

    opened by victorluft 7
  • Add 'user' field to device and devices data sources

    Add 'user' field to device and devices data sources

    What this PR does / why we need it: Adds a user attribute to the tailscale_device and tailscale_devices data sources, so we can access the user associated with a device.

    Which issue this PR fixes: Fixes #48

    Special notes for your reviewer: I haven't run the acceptance tests as I don't have a test tailscale account to test against.

    opened by michael-careplanner 7
  • Allow declaration of tailscale api endpoint

    Allow declaration of tailscale api endpoint

    What this PR does / why we need it: Allow users to declare the baseurl in the provider block. Add a new baseurl variable.

    Which issue this PR fixes (use fixes #<issue number>(, fixes #<issue_number>, ...) format, will close that issue when PR gets merged): fixes https://github.com/davidsbond/terraform-provider-tailscale/issues/97

    Special notes for your reviewer:

    opened by kelcya 6
  • FR: add retry and timeout options to the tailscale_device data source

    FR: add retry and timeout options to the tailscale_device data source

    Is your feature request related to a problem? Please describe.

    My end goal is to be able to define EC2 instances in Terraform and setup DNS entries for the tailscale IP address. The current problem I have is that, unlike an AWS public or private IP, the tailscale IP address is unknown to AWS and not returned by their APIs. Furthermore, there is a delay between the time the instance is created and it's user_data script can run tailscale up .... So, using the tailscale_device data source in the same script usually results in that API call failing.

    Describe the solution you'd like I'd like to be able to do something like:

    resource "aws_instance" "enterprise" {
        # ...snip...
        user_data = templatefile("tailscale-init.sh", {
            hostname = "enterprise"
            tailscale_auth_key = '...snip...'
        })
    }
    
    
    resource "aws_route53_record" "enterprise_pub" {
        zone_id = var.some_zone_id
        name = "enterprise"
        type = "A"
        ttl = "300"
        records = [
            aws_instance.enterprise.public_ip
        ]
    }
    
    
    data "tailscale_device" "enterprise" {
      name = "enterprise.${var.some_zone_domain}"
      # Retry API call 10 times waiting 10 seconds in-between each try
      retry_count = 10
      retry_interval = "10s"
    }
    
    
    resource "aws_route53_record" "enterprise_ts" {
        zone_id = var.some_zone_id
        name = "enterprise.ts"
        type = "A"
        ttl = "300"
        records = [
            # Another FR: should have .addresses_ipv4?
            tailscale_device.enterprise.addresses[0]
        ]
    }
    

    Additional context

    If the above doesn't seem like the right approach, I'd be open to other ideas about how to provision an EC2 instance and get DNS setup for the Tailscale IP.

    enhancement 
    opened by rsyring 6
  • The `tailscale_tailnet_key` resource for non-reusable keys doesn't work

    The `tailscale_tailnet_key` resource for non-reusable keys doesn't work

    Describe the bug After applying a plan involving a non-reusable key, any further operations are impossible because of an unexpected 404 error when trying to query the API for the key.

    To Reproduce Apply a plan with a "tailscale_tailnet_key" resource with reusable = false via terraform apply and try to delete the resources using terraform destroy and get something like the following error, preventing any further action.

    │ Error: Failed to fetch key
    │
    │   with tailscale_tailnet_key.gcp,
    │   on main.tf line 16, in resource "tailscale_tailnet_key" "gcp":
    │   16: resource "tailscale_tailnet_key" "gcp" {
    │
    │ 404 page not found (404)
    

    Expected behaviour No errors. I don't think it should be necessary to query the tailscale API if the key is present in the state file.

    bug 
    opened by michaelbeaumont 6
  • Deleting tailnet key: unexpected EOF

    Deleting tailnet key: unexpected EOF

    I just tried to recreate a tailnet key using terraform. My config is something like:

    resource "time_rotating" "tskey" {
      rotation_minutes = 5
    }
    
    resource "tailscale_tailnet_key" "tskey" {
      reusable      = true
      preauthorized = true
    
      lifecycle {
        replace_triggered_by = [time_rotating.tskey]
      }
    }
    

    (Just testing rotation, natch.)

    The rotation successfully triggered a replace, but that showed an error:

    tailscale_tailnet_key.tskey: Destroying... [id=k.....CNTRL]
    ╷
    │ Error: Failed to delete key
    │
    │ hujson: line 1, column 1: parsing value: unexpected EOF
    

    Now plan is showing a 404 for that resource - so I guess the delete succeeded, but it isn't updating the state correctly?

    tailscale_tailnet_key.tskey: Refreshing state... [id=k......CNTRL]
    ╷
    │ Error: Failed to fetch key
    │
    │   with tailscale_tailnet_key.tskey,
    │   on main.tf line 35, in resource "tailscale_tailnet_key" "tskey":
    │   35: resource "tailscale_tailnet_key" "tskey" {
    │
    │ 404 page not found (404)
    

    state rm tailscale_tailnet_key.tskey fixed it, and I was able to create the new key.

    bug 
    opened by lincolnmantracer 5
  • Creating an ACL with `ssh` fails silently and disables ssh

    Creating an ACL with `ssh` fails silently and disables ssh

    I am using tailscale_acl to update the ACL:

    resource "tailscale_acl" "default" {
      acl = jsonencode({
        groups = {
          "group:dev" = [
            "[email protected]",
          ],
        },
       ...
        ssh = [
          {
            action = "accept",
            src    = ["group:dev"],
            dst    = ["tag:foo"],
            users  = ["autogroup:nonroot"]
          }
        ]
      })
    }
    

    When I apply, the ssh config is missing from the ACL at https://login.tailscale.com/admin/acls and the enable ssh button reappears. If I click enable ssh and try to re-apply, it doesn't even notice that the config has changed and needs to be updated (even though tailscale added the default ssh config).

    Pretty sure this must be an upstream bug, but wanted to raise it here first.

    bug 
    opened by lincolnmantracer 4
  • Avoid using deprecated hujson API

    Avoid using deprecated hujson API

    The hujson.Unmarshal function is deprecated. Use hujson.Standardize instead.

    The hujson package is evolving to be just a syntactic parser for HuJSON and is moving away from semantically understanding HuJSON as Go data.

    opened by dsnet 4
  • [resource] tailnet_key: remove the duplicate

    [resource] tailnet_key: remove the duplicate "id" field

    The Terraform Plugin SDK already has this functionality when you call d.SetID

    // SetId sets the ID of the resource. If the value is blank, then the
    // resource is destroyed.
    func (d *ResourceData) SetId(v string) {
    	d.once.Do(d.init)
    	d.newState.ID = v
    
    	// once we transition away from the legacy state types, "id" will no longer
    	// be a special field, and will become a normal attribute.
    	// set the attribute normally
    	d.setWriter.unsafeWriteField("id", v)
    
    	// Make sure the newState is also set, otherwise the old value
    	// may get precedence.
    	if d.newState.Attributes == nil {
    		d.newState.Attributes = map[string]string{}
    	}
    	d.newState.Attributes["id"] = v
    }
    

    What this PR does / why we need it:

    Which issue this PR fixes (use fixes #<issue number>(, fixes #<issue_number>, ...) format, will close that issue when PR gets merged):

    Fixes #

    Special notes for your reviewer:

    opened by stack72 4
  • Add support for terraform import

    Add support for terraform import

    This commit is an initial attempt to set up support for the terraform import command. It includes the default fallthrough importer for global resources such as the ACL, DNS preferences etc.

    For device-specific resources, the name of the device can be provided which will be resolved to a device identifier. The device identifier is then added to the resource so that a refresh will include it.

    Signed-off-by: David Bond [email protected]

    opened by davidsbond 0
  • Discussion: non-deterministic device name?

    Discussion: non-deterministic device name?

    I'm not exactly sure where this belongs or what I'm asking for, but figured I should note it somewhere. I've noticed in my efforts to get Tailscale installed automatically on a host and then use that device for further work in Terraform, that the device name used by Tailscale is not guaranteed.

    In Terraform, I might want to create a server "enterprise" in AWS, set it's hostname as "enterprise", install & authorize Tailscale as part of the instance's first-boot configuration, and then wait_for (#72) the device so I can use it's IP to setup a DNS record for that host.

    But, if there is already a device in Tailscale named "enterprise" then it looks like Tailscale will create the device as "enterprise1" and happily move on. That obviously breaks things if then use tailscale_device with name as enterprise.example.com.

    I've not yet tried to see Tailscale's behavior is any different using tailscale up --hostname. Also, at least in my case, the impact of this is lessened if deletions (#68) become supported.

    question upstream 
    opened by rsyring 6
  • FR: add ability to delete devices

    FR: add ability to delete devices

    Is your feature request related to a problem? Please describe.

    When destroying resources with terraform, I'd like the ability to remove the device from Tailscale. For example, when an AWS instance will be deleted, I want it's associated tailscale device to also be deleted.

    Describe the solution you'd like Keep track of devices in Terraform state and, when the device is removed, use the DELETE device API to remove the device from the tailnet.

    enhancement 
    opened by rsyring 4
Releases(v0.12.0)
Owner
David Bond
Software Engineer based in Gloucester, United Kingdom.
David Bond
Terraform Provider for Satori

Terraform Provider for Satori First time setup: make init Run the following command to build the provider make build Generate/update documentation Do

Satori Cyber 12 Apr 29, 2022
Terraform CDK aws Provider

Terraform CDK aws Provider

Hortau 1 Dec 17, 2021
An experimental OpenAPI -> Terraform Provider generator that does not yet function

tfpgen An experimental OpenAPI -> Terraform Provider generator that does not yet function. The goal is to allow developers to incrementally generate a

Brandon Croft 0 Feb 19, 2022
Go client library for interacting with Coinpaprika's API

Coinpaprika API Go Client Usage This library provides convenient way to use coinpaprika.com API in Go. Coinpaprika delivers full market data to the wo

Coinpaprika 16 Jun 12, 2022
A Go library for interacting with Cloudflare's API v4.

Go library for the Cloudflare v4 API

Cloudflare 841 Jun 30, 2022
Go library for interacting with the Discord API (work-in-progress)

zombiezen Go Client for Discord zombiezen.com/go/discord is a WIP Go library for interacting with the Discord API. It differs from DiscordGo by provid

Ross Light 2 Feb 19, 2022
Go library for interacting with CircleCI

go-circleci Go library for interacting with CircleCI's API. Supports all current API endpoints allowing you do do things like: Query for recent builds

Jesse Szwedko 63 Jul 2, 2022
Arweave-api - Arweave API implementation in golang

Arweave API Go implementation of the Arweave API Todo A list of endpoints that a

Joshua Lawson 1 Jan 16, 2022
Self Hosted Terraform Registry backed by S3

tf-registry Self Hosted Terraform Registry backed by S3 Usage tf-registry Provides a simple http server that implements the Terraform Module Registry

Nick Albury 18 Jun 22, 2022
Helps me find good enough stocks that pay enough dividends using IEX Cloud data provider.

divyield Helps me find good enough stocks that pay enough dividends using IEX Cloud data provider. Create database using the postgres/scripts/createdb

Péter Szakszon 0 Feb 4, 2022
The Bhojpur PEE is a software-as-a-service product used as a Provider's Edge Equipment based on Bhojpur.NET Platform for application delivery.

Bhojpur PEE - Provider's Edge Equipment The Bhojpur PEE is a software-as-a-service product used as a Provider's Edge Equipment based on Bhojpur.NET Pl

Bhojpur Consulting 0 Dec 31, 2021
Simple-Weather-API - Simple weather api app created using golang and Open Weather API key

Simple Weather API Simple weather api app created using golang and Open Weather

Siva Prakash 3 Feb 6, 2022
School POC of an AES implementation in an API/Client system

poc_aes_implement School POC of an AES implementation in an API/Client system How to use : Start the api with : poc-aes -api start Client commands : p

Thryn 0 Nov 29, 2021
An implementation of a simple RESTful API in Golang on AWS infrastructure.

go-api An implementation of a simple RESTful API in Golang on AWS infrastructure. Tech Stack Serverless framework Go language AWS API Gateway AWS Lamb

Amirmohsen 0 Dec 25, 2021
Unofficial golang implementation for the Preev API

go-preev The unofficial golang implementation for the Preev.pro API Table of Contents Installation Documentation Examples & Tests Benchmarks Code Stan

Mr. Z 6 Jun 2, 2022
Unofficial golang implementation for the pipl.com search API

go-pipl The unofficial golang wrapper for the pipl.com API. Table of Contents Installation Documentation Examples & Tests Benchmarks Code Standards Us

Mr. Z 5 Dec 27, 2021
Implementation of Technical Test - Article API

Technical Test on Article API Abstract For the technical test on an set of article API, this document outlines its requirements, and the design, devel

Spenser Kao 0 Feb 8, 2022
🔗 Unofficial golang implementation for the NOWNodes API

go-nownodes The unofficial golang implementation for the NOWNodes.io API Table of Contents Installation Documentation Examples & Tests Benchmarks Code

Mr. Z 2 Jan 30, 2022
Go library for accessing the MyAnimeList API: http://myanimelist.net/modules.php?go=api

go-myanimelist go-myanimelist is a Go client library for accessing the MyAnimeList API. Project Status The MyAnimeList API has been stable for years a

Stratos Neiros 31 May 10, 2022