Tailscale Terraform Provider

repository·main·Indexed 18 days ago

https://github.com/tailscale/terraform-provider-tailscale

The Tailscale Terraform provider allows developers to manage Tailscale resources and interact with the Tailscale API using Terraform configuration. It supports multiple authentication methods, including API keys, OAuth clients, and Workload Identity Federation. The provider includes data sources for retrieving information about devices, users, services, ACL policy files, and calculating 4via6 IPv6 prefixes.

Tokens
20.2K
Snippets
66
Records
88
Agent score
60%

What's inside terraform-provider-tailscale

  1. Manage Tailscale Services with tailscale_service

    main

    The tailscale_service resource allows you to publish internal resources (such as databases or web servers) as named resources within your tailnet. When you create a service, Tailscale provides a stable MagicDNS name and a Tailscale virtual IP address pair. These services can be served by multiple nodes and act as valid access control destinations in your ACLs.

    resource "tailscale_service" "example" {
      name    = "svc:my-service"
      comment = "My service"
      ports   = ["tcp:443"]
      tags    = ["tag:web"]
    }
  2. Manage complete DNS configuration with tailscale_dns_configuration

    main

    The tailscale_dns_configuration resource allows you to manage the entire DNS configuration for your Tailscale network (Tailnet) in a single resource.

    Warning: This resource manages the entirety of the DNS configuration. It is mutually exclusive with the following resources and should not be used simultaneously with them to avoid conflicts:

    • tailscale_dns_nameservers
    • tailscale_dns_preferences
    • tailscale_dns_search_paths
    • tailscale_dns_split_nameservers
    resource "tailscale_dns_configuration" "sample_configuration" {
        nameservers {
            address            = "8.8.8.8"
        }
        nameservers {
            address            = "1.1.1.1"
            use_with_exit_node = true
        }
        split_dns {
            domain             = "foo.example.com"
            nameservers {
                address            = "1.1.1.2"
                use_with_exit_node = true
            }
            nameservers {
                address            = "1.1.1.3"
            }
        }
        split_dns {
            domain             = "bar.example.com"
            nameservers {
                address            = "8.8.8.2"
                use_with_exit_node = true
            }
        }
        search_paths       = ["example.com", "anotherexample.com"]
        override_local_dns = true
        magic_dns = true
    }
  3. Update an existing installation from the legacy provider

    main

    If you are migrating a deployment that currently uses the original davidsbond/tailscale provider to the official tailscale/tailscale provider, run the following command to replace the provider in your Terraform state:

    terraform state replace-provider registry.terraform.io/davidsbond/tailscale registry.terraform.io/tailscale/tailscale
  4. Use the tailscale_device data source

    main

    The tailscale_device data source allows you to retrieve information about a specific device within a tailnet. You can look up a device using either its full name (e.g., hostname.domain.ts.net) or its short hostname.

    If the device is not immediately available, you can use the wait_for argument to instruct the provider to retry the lookup every second until the specified duration is reached.

    data "tailscale_device" "sample_device" {
      name     = "device1.example.ts.net"
      wait_for = "60s"
    }
    
    data "tailscale_device" "sample_device2" {
      hostname = "device2"
      wait_for = "60s"
    }
  5. Use the tailscale_aws_external_id resource to enable S3 log streaming

    main

    The tailscale_aws_external_id resource generates an AWS External ID and a Tailscale AWS Account ID. These values are required to configure an AWS IAM role that allows Tailscale to securely assume a role in your AWS account for the purpose of streaming logs to an S3 bucket.

    To use this resource correctly, you must:

    1. Mint the ID using tailscale_aws_external_id.
    2. Configure an aws_iam_role with a trust policy that uses tailscale_aws_account_id as the principal and external_id in a StringEquals condition for sts:ExternalId.
    3. Pass the external_id into a tailscale_logstream_configuration resource where s3_authentication_type is set to rolearn.
    resource "tailscale_aws_external_id" "prod" {}
    
    resource "tailscale_logstream_configuration" "configuration_logs" {
      log_type               = "configuration"
      destination_type       = "s3"
      s3_bucket              = aws_s3_bucket.tailscale_logs.id
      s3_region              = "us-west-2"
      s3_authentication_type = "rolearn"
      s3_role_arn            = aws_iam_role.logs_writer.arn
      s3_external_id         = tailscale_aws_external_id.prod.external_id
    }
    
    resource "aws_iam_role" "logs_writer" {
      name               = "logs-writer"
      assume_role_policy = data.aws_iam_policy_document.tailscale_assume_role.json
    }
    
    resource "aws_iam_role_policy" "logs_writer" {
      role   = aws_iam_role.logs_writer.id
      policy = data.aws_iam_policy_document.logs_writer.json
    }
    
    data "aws_iam_policy_document" "tailscale_assume_role" {
      statement {
        actions = ["sts:AssumeRole"]
        principals {
          type = "AWS"
          identifiers = [tailscale_aws_external_id.prod.tailscale_aws_account_id]
        }
        condition {
          test     = "StringEquals"
          variable = "sts:ExternalId"
          values   = [tailscale_aws_external_id.prod.external_id]
        }
      }
    }
    
    data "aws_iam_policy_document" "logs_writer" {
      statement {
        effect = "Allow"
        actions = ["s3:*"]
        resources = [
          "arn:aws:s3:::example-bucket",
          "arn:aws:s3:::example-bucket/*"
        ]
      }
    }
  6. Import tailscale_device_subnet_routes

    main

    You can import existing device subnet rules into your Terraform state. You can use either the preferred node_id or the legacy ID.

    # Device subnet rules can be imported using the node ID (preferred), e.g.,
    terraform import tailscale_device_subnet_routes.sample nodeidCNTRL
    
    # Device subnet rules can be imported using the legacy ID, e.g.,
    terraform import tailscale_device_subnet_routes.sample 123456789
  7. Import a tailscale_device_key

    main

    You can import an existing device key into your Terraform state using either the preferred node_id or the legacy ID.

    Use the following syntax:

    # Using the node ID (preferred)
    terraform import tailscale_device_key.sample <node_id>
    
    # Using the legacy ID
    terraform import tailscale_device_key.sample <legacy_id>
    # Device key can be imported using the node ID (preferred), e.g.,
    terraform import tailscale_device_key.sample nodeidCNTRL
    # Device key can be imported using the legacy ID, e.g.,
    terraform import tailscale_device_key.sample 123456789
  8. Use the tailscale_device_authorization resource

    main

    The tailscale_device_authorization resource is used to approve new devices before they can join your tailnet. This is useful for enforcing device authorization policies. You can link the authorization to a specific device using its node_id.

    data "tailscale_device" "sample_device" {
      name = "device.example.com"
    }
    
    resource "tailscale_device_authorization" "sample_authorization" {
      # Prefer the new, stable `node_id` attribute; the legacy `.id` field still works.
      device_id  = data.tailscale_device.sample_device.node_id
      authorized = true
    }
  9. Configure Tailscale network contact details with `tailscale_contacts`

    main

    The tailscale_contacts resource allows you to manage the contact email addresses used for different types of communications within your Tailscale network (tailnet).

    Important Note on Destruction: Destroying this resource via Terraform does not unset or modify the values in the Tailscale control plane; it only removes the resource from your Terraform state. To change or remove contact details in Tailscale, you must update the resource configuration or manage them via the Tailscale web console.

    For more information on these contact preferences, see Tailscale Contact Preferences.

    resource "tailscale_contacts" "sample_contacts" {
      account {
        email = "account@example.com"
      }
    
      support {
        email = "support@example.com"
      }
    
      security {
        email = "security@example.com"
      }
    }