Tailscale Terraform Provider for Programmatic Tailnet Management

Tailscale provides a managed mesh VPN that is typically configured through the web console or the tailscale CLI. For teams that operate dozens or hundreds of nodes, and for organizations that want immutable infrastructure definitions, the Tailscale Terraform provider offers infrastructure as code for the control plane. The provider lets operators define ACL policies, DNS preferences, device properties, and authentication keys from Terraform state, applying changes through the Tailscale API with the same drift detection and plan preview that Terraform users expect from other cloud resources.

The provider is maintained by Tailscale. It originated as a community project and was later adopted into the Tailscale organization. The source code now lives under the Tailscale organization, the provider is published under the Tailscale namespace in the Terraform registry, and new versions are signed with a Tailscale-managed key. Development continues in lockstep with Tailscale features, with reviews for new functionality and community contributions.

Provider installation and authentication

The Tailscale Terraform provider is distributed through the Terraform registry under tailscale/tailscale. Installation is declared in the required providers block and the provider is initialized with an API credential.

terraform { required_providers { tailscale = { source = "tailscale/tailscale" version = "~> 0.16" } } }

A basic provider configuration uses an API key.

provider "tailscale" { api_key = "tskey-api-..." }

The api_key can also be supplied via the TAILSCALE_API_KEY environment variable. The default API endpoint is https://api.tailscale.com.

Tailscale recommends trust credentials rather than a personal API key. A trust credential is an OAuth client or federated identity that is associated with the tailnet, not an individual user, does not expire, and supports scopes. The provider can be configured with OAuth client credentials:

provider "tailscale" { oauth_client_id = "..." oauth_client_secret = "tskey-client-..." }

OAuth clients are created in the Tailscale admin console at https://login.tailscale.com/admin/settings/oauth by clicking Generate oauth client and noting oauth_client_id and oauth_client_secret.

The provider configuration must also specify the tailnet. A dash - references the default tailnet of the trust credential or API access token used as credentials. Using the default tailnet from the credential information is the best option for most users. Alternatively the tailnet ID can be specified explicitly.

Core resources and capabilities

The provider exposes resources for policy, DNS, keys, and device management. Common use cases include defining an ACL file, setting DNS settings, generating auth keys with specific attributes, and managing device properties.

Supported resource categories include:

  • Define your policy file using the tailscale_acl resource
  • Set DNS settings, including global nameservers, restricted nameservers for split DNS, and MagicDNS enable or disable
  • Generate an auth key including setting whether it is reusable, ephemeral, pre-authorized, and tagged using the tailscale_key resource
  • Manage properties of a device

DNS resources include tailscale_dns_nameservers, tailscale_dns_search_paths, and tailscale_dns_preferences.

ACL and policy as code

The tailscale_acl resource allows the tailnet ACL JSON policy to be stored in version control. Changes to groups, tags, and access rules are applied via Terraform plan and apply, removing manual edits in the admin console.

DNS configuration

Programmatic DNS configuration covers:

  • Global nameservers via tailscale_dns_nameservers
  • Split DNS search paths via tailscale_dns_search_paths
  • MagicDNS enable or disable via tailscale_dns_preferences

These settings are critical for multi-site deployments where internal name resolution must be deterministic and reproducible.

Authentication keys and device bootstrapping

The tailscale_key resource, also referenced as tailscale_tailnet_key in examples, creates short-lived or reusable auth keys with fine grained controls.

resource "tailscale_tailnet_key" "hourlykey" { reusable = true ephemeral = true preauthorized = true expiry = 3600 description = "Hourly key Terraform managed" tags = ["tag:server"] }

With reusable = true, ephemeral = true, preauthorized = true, and expiry = 3600, Terraform will automatically create a tailnet key that is valid for one hour, automatically expires, and is sufficient to bootstrap servers and allow them to join the tailnet.

Integration with cloud-init is common. A DigitalOcean droplet example uses user_data to run tailscale up with the generated key:

```
resource "digitaloceandroplet" "server" {
user
data = <

cloud-config

runcmd:
- tailscale up --authkey ${tailscaletailnetkey.hourlykey.key} --accept-routes --accept-dns
EOF
```

Pre-baking the Tailscale client is often preferred to installing software at boot time, but the pattern demonstrates how Terraform-managed keys can be injected into instance templates for automated enrollment.

Operational patterns at scale

Managing Tailscale at large scale without manual intervention is critical for efficiency. Manually setting tags, approving devices, configuring subnets, and creating authentication keys would make scaling Tailscale in a large environment nearly impossible.

Terraform enables rapid deployment of an entire multi-VPC infrastructure in seconds. Similarly, Terraform can streamline and automate Tailscale configurations, making it both efficient and scalable.

A typical workflow starts by exploring the provider capabilities and deploying each module individually. With a fresh Tailscale account, the first goal is often to manage account settings programmatically, then expand to device lifecycle, subnet routers, and ACLs.

Tags are used to drive policy. Keys can be tagged with tag:server, tag:worker, or similar, and ACLs reference tags rather than individual node names. This allows auto-approval of devices that present the correct tags via pre-authorized keys.

Provider versioning and release history

The provider is actively maintained. The Terraform registry documentation is the source of truth for the most up-to-date information and latest release.

Release examples include:

Version Notable changes
v0.29.2 build dependency bumps, datasourcedevice typo fix, resourcetailnetkey fix for erroneous recreation
v0.29.1 maintenance release
v0.29.0 plugin framework migration for datasourceacl and resourceawsexternal_id, dependency updates

Changelog entries for v0.29.2 include:

  • 9ae1292: build(deps): bump goreleaser/goreleaser-action from 7.2.1 to 7.2.2
  • 40e5693: build(deps): bump tailscale.com from 1.98.1 to 1.98.3
  • 9c5bc60: datasourcedevice: fix typo in error message
  • fc9a21b: resourcetailnetkey: fix erroneous key recreation in not found case

Version 0.29.0 introduced migrations to the plugin framework:

  • dd6da5: datasourceacl: migrate to plugin framework
  • 23fc22c: resourceawsexternal_id: migrate to plugin

Dependency updates are common across releases, reflecting the Go ecosystem and HashiCorp Terraform Plugin SDK.

Authentication methods comparison

Method Credential type Association Expiry Scope support
Personal API key tskey-api User Can expire Limited
OAuth client oauthclientid + oauthclientsecret Tailnet Non-expiring trust credential Yes
Federated identity OAuth / OIDC Tailnet Non-expiring Yes

Trust credentials are associated with the tailnet, not an individual user, do not expire, and support scopes. For details, refer to trust credentials.

Resource support overview

Resource Purpose
tailscale_acl Define tailnet policy file
tailscalednsnameservers Set global nameservers
tailscalednssearch_paths Set restricted nameservers for split DNS
tailscalednspreferences Enable or disable MagicDNS
tailscale_key Generate auth key with reusable, ephemeral, pre-authorized, tagged attributes
tailscaletailnetkey Create short-lived bootstrap keys

Practical configuration steps

  • Generate oauth client credentials in the admin console and note oauth_client_id and oauth_client_secret.
  • Add the Tailscale provider to Terraform with source tailscale/tailscale and a pinned version.
  • Configure the provider with OAuth credentials or API key and tailnet identifier.
  • Define tailscale_acl for policy, DNS resources for name resolution, and tailscale_key for automated enrollment.
  • Use Terraform output values to inject keys into cloud-init or instance user data for bootstrapping.

The provider allows configuration of ACLs, DNS settings, auth key creation, and device management from a single Terraform workspace. This makes it possible to treat the Tailscale control plane as code, with peer review, plan previews, and automated rollbacks.

Conclusion

The Tailscale Terraform provider transforms tailnet management from console driven operations to declarative infrastructure. By moving the provider under Tailscale ownership, the project gained committed support, signed releases, and alignment with product development. The combination of trust credentials, tailnet-scoped authentication, and resources for ACLs, DNS, keys, and devices enables teams to automate enrollment, enforce policy, and maintain consistency across hundreds of nodes.

Key strengths are the ability to generate short lived, pre-authorized, tagged keys for automated bootstrapping, the ability to define ACLs as code, and the ability to manage DNS preferences without manual intervention. The provider also integrates cleanly with existing Terraform workflows for cloud providers, allowing Tailscale configuration to be co-deployed with VPCs, compute instances, and service meshes.

Operational maturity comes from using OAuth clients instead of personal API keys, pinning provider versions, and treating tailnet configuration as a first class artifact in CI/CD pipelines. Release history shows active maintenance with plugin framework migrations and regular dependency updates. For organizations scaling Tailscale, Terraform provides the control plane automation needed to keep tags, devices, subnets, and policies in sync with infrastructure changes.

Sources

  1. tailscale.com docs integrations terraform-provider
  2. tailscale.com blog terraform
  3. github.com tailscale terraform-provider-tailscale
  4. kaspergrubbe.com let your servers join your tailscale tailnet
  5. github.com tailscale terraform-provider-tailscale releases
  6. blog.mcqueenlab.net posts Tailscale Terraform

Related Posts