{"slug":"manage-tailscale-resources-using-terraform","title":"Manage Tailscale resources using Terraform","tags":["tailscale"],"agent_summary":"Last validated: Jan 30, 2026","trigger_phrases":[],"runnable":false,"markdown":"\r\n# Manage Tailscale resources using Terraform\r\n\r\nLast validated: Jan 30, 2026\r\n\r\n[Terraform](https://www.terraform.io/) is an infrastructure as code (IaC) tool that lets you deploy infrastructure programmatically. Tailscale maintains the [Tailscale Terraform provider](https://registry.terraform.io/providers/tailscale/tailscale/latest) in the Terraform registry by Tailscale. We recommend using the latest version of the provider.\r\n\r\nYou can use the Tailscale Terraform provider to:\r\n\r\n- Define your [policy file](https://tailscale.com/docs/features/tailnet-policy-file) using the [`tailscale_acl` resource](https://registry.terraform.io/providers/tailscale/tailscale/latest/docs/resources/acl).\r\n- Set [DNS settings](https://tailscale.com/docs/reference/dns-in-tailscale), including:\r\n  - Global nameservers using the [`tailscale_dns_nameservers` resource](https://registry.terraform.io/providers/tailscale/tailscale/latest/docs/resources/dns_nameservers).\r\n  - Restricted nameservers for split DNS, using the [`tailscale_dns_search_paths` resource](https://registry.terraform.io/providers/tailscale/tailscale/latest/docs/resources/dns_search_paths).\r\n  - [MagicDNS](https://tailscale.com/docs/features/magicdns) using the [`tailscale_dns_preferences` resource](https://registry.terraform.io/providers/tailscale/tailscale/latest/docs/resources/dns_preferences).\r\n- Generate an [auth key](https://tailscale.com/docs/features/access-control/auth-keys) (including setting whether it's reusable, ephemeral, pre-authorized, and tagged)\r\nusing the [`tailscale_key` resource](https://registry.terraform.io/providers/tailscale/tailscale/latest/docs/resources/tailnet_key).\r\n- Manage properties of a device, including:\r\n  - [Device approval](https://tailscale.com/docs/features/access-control/device-management/device-approval) using the [`tailscale_device_authorization` resource](https://registry.terraform.io/providers/tailscale/tailscale/latest/docs/resources/device_authorization).\r\n  - [Key expiry](https://tailscale.com/docs/features/access-control/key-expiry) using the [`tailscale_device_key` resource](https://registry.terraform.io/providers/tailscale/tailscale/latest/docs/resources/device_key).\r\n  - [Tags](https://tailscale.com/docs/features/tags) using the [`tailscale_device_tags` resource](https://registry.terraform.io/providers/tailscale/tailscale/latest/docs/resources/device_tags).\r\n  - [Subnet routes](https://tailscale.com/docs/features/subnet-routers) using the [`tailscale_device_subnet_routes` resource](https://registry.terraform.io/providers/tailscale/tailscale/latest/docs/resources/device_subnet_routes).\r\n\r\nRefer to the [Terraform Provider documentation](https://registry.terraform.io/providers/tailscale/tailscale/latest/docs) for the full list of supported resources.\r\n\r\n## [Credentials and tailnet configuration](https://tailscale.com/docs/integrations/terraform-provider\\#credentials-and-tailnet-configuration)\r\n\r\nTo use Terraform with Tailscale, configure the [Tailscale Terraform provider](https://registry.terraform.io/providers/tailscale/tailscale/latest) with your\r\nTailscale credentials, which can be a [trust credential](https://login.tailscale.com/admin/settings/trust-credentials) or an [API access token](https://login.tailscale.com/admin/settings/keys).\r\n\r\nTailscale recommend that you use a trust credential (an OAuth client or federated identity) because trust credentials are associated with the tailnet, not an individual user, do not expire, and support [scopes](https://tailscale.com/docs/reference/trust-credentials#scopes). For details, refer to [trust credentials](https://tailscale.com/docs/reference/trust-credentials).\r\n\r\nYou must also specify your tailnet in the Tailscale Terraform provider configuration. You can provide a dash (`-`) to reference the default tailnet of the [trust credential](https://tailscale.com/docs/reference/trust-credentials) (or API access token) used as credentials. Using the default tailnet from the credential information is the best option for most users. Alternatively, you can specify your [tailnet ID](https://tailscale.com/docs/concepts/tailnet-name#tailnet-id). You can find your tailnet ID in the [General](https://login.tailscale.com/admin/settings/general) page of the admin console.\r\n\r\nIt is not recommended to store sensitive information, such as an OAuth client or API access token, in source control. Instead, use an environment variable or a secrets manager.\r\n\r\nUse the default variables `TAILSCALE_OAUTH_CLIENT_ID`, `TAILSCALE_OAUTH_CLIENT_SECRET`, and `TAILSCALE_TAILNET` to provide your credentials and tailnet organization name to the Tailscale Terraform provider. Alternatively, refer to the Terraform documentation for [setting values with variables](https://developer.hashicorp.com/terraform/tutorials/configuration-language/sensitive-variables#set-values-with-variables).\r\n\r\nIf you are using a federated identity instead of an OAuth client, use the default `TAILSCALE_IDENTITY_TOKEN` variable instead of `TAILSCALE_OAUTH_CLIENT_SECRET`.\r\n\r\nIf you are using an API access token instead of an OAuth client, use the default `TAILSCALE_API_KEY` variable instead of `TAILSCALE_OAUTH_CLIENT_ID` and `TAILSCALE_OAUTH_CLIENT_SECRET`.\r\n\r\n### [Environment variables](https://tailscale.com/docs/integrations/terraform-provider\\#environment-variables)\r\n\r\nYou can store most information as environment variables in Terraform. Tailscale uses environment variables for the following configuration settings:\r\n\r\n| **Setting** | **Description** | **Environment variable** |\r\n| --- | --- | --- |\r\n| `api_key`<br> (String, Sensitive) | The API key to use for authenticating requests to the API. <br>Conflicts with '`TAILSCALE_OAUTH_CLIENT_ID`' and '`TAILSCALE_OAUTH_CLIENT_SECRET`'. | `TAILSCALE_API_KEY` |\r\n| `base_url`<br> (String) | The base URL of the Tailscale API. <br>Defaults to `https://api.tailscale.com`. | `TAILSCALE_BASE_URL` |\r\n| `TAILSCALE_OAUTH_CLIENT_ID`<br> (String) | The OAuth application or federated identity's ID when using OAuth client credentials or workload identity federation. If set, then either '`TAILSCALE_OAUTH_CLIENT_SECRET`' or '`TAILSCALE_IDENTITY_TOKEN`' must also be set, but not both. <br>Conflicts with '`api_key`'. | `TAILSCALE_OAUTH_CLIENT_ID` |\r\n| `TAILSCALE_OAUTH_CLIENT_SECRET`<br> (String, Sensitive) | The OAuth application's secret when using OAuth client credentials. If set, '`TAILSCALE_OAUTH_CLIENT_ID`' must also be set. <br>Conflicts with '`api_key`' and '`identity_token`'. | `TAILSCALE_OAUTH_CLIENT_SECRET` |\r\n| `TAILSCALE_IDENTITY_TOKEN`<br> (String, Sensitive) | The JWT identity token to exchange for a Tailscale API token when using a federated identity. <br>Conflicts with '`api_key`' and '`client_secret`'. | `TAILSCALE_OAUTH_CLIENT_SECRET` |\r\n| `tailnet`<br> (String) | The [tailnet ID](https://tailscale.com/docs/concepts/tailnet-name#tailnet-id) to perform actions in. | `TAILSCALE_TAILNET` |\r\n\r\n### [Migrate from the community-contributed Terraform provider](https://tailscale.com/docs/integrations/terraform-provider\\#migrate-from-the-community-contributed-terraform-provider)\r\n\r\nIf you previously used the community-contributed Terraform provider, and now want to use the provider managed and published by Tailscale, update the `source` argument in your Terraform configuration. That is, update `source = \"davidsbond/tailscale\"` to `source = \"tailscale/tailscale\"`.\r\n\r\n## [Special thanks](https://tailscale.com/docs/integrations/terraform-provider\\#special-thanks)\r\n\r\nSpecial thanks to [David Bond](https://github.com/davidsbond), who contributed and maintained the original community-contributed Tailscale Terraform provider. Tailscale now maintains and publishes this provider.\r\n\r\n## [Support](https://tailscale.com/docs/integrations/terraform-provider\\#support)\r\n\r\nThe Tailscale Terraform provider is maintained and published in the Terraform registry by Tailscale. If you have an issue or feature request, [contact support](https://tailscale.com/contact/support) or [file a GitHub issue](https://github.com/tailscale/terraform-provider-tailscale/issues).\r\n\r\n![Project Logo](https://cdn.brandfetch.io/tailscale.com/fallback/lettermark/theme/dark/h/256/w/256/icon?c=1bfwsmEH20zzEfSNTed)\r\n\r\nAsk AI\r\n\r\nreCAPTCHA\r\n\r\nRecaptcha requires verification.\r\n\r\nprotected by **reCAPTCHA**\r\n","html":"<h1>Manage Tailscale resources using Terraform</h1>\n<p>Last validated: Jan 30, 2026</p>\n<p><a href=\"https://www.terraform.io/\">Terraform</a> is an infrastructure as code (IaC) tool that lets you deploy infrastructure programmatically. Tailscale maintains the <a href=\"https://registry.terraform.io/providers/tailscale/tailscale/latest\">Tailscale Terraform provider</a> in the Terraform registry by Tailscale. We recommend using the latest version of the provider.</p>\n<p>You can use the Tailscale Terraform provider to:</p>\n<ul>\n<li>Define your <a href=\"https://tailscale.com/docs/features/tailnet-policy-file\">policy file</a> using the <a href=\"https://registry.terraform.io/providers/tailscale/tailscale/latest/docs/resources/acl\"><code>tailscale_acl</code> resource</a>.</li>\n<li>Set <a href=\"https://tailscale.com/docs/reference/dns-in-tailscale\">DNS settings</a>, including:\n<ul>\n<li>Global nameservers using the <a href=\"https://registry.terraform.io/providers/tailscale/tailscale/latest/docs/resources/dns_nameservers\"><code>tailscale_dns_nameservers</code> resource</a>.</li>\n<li>Restricted nameservers for split DNS, using the <a href=\"https://registry.terraform.io/providers/tailscale/tailscale/latest/docs/resources/dns_search_paths\"><code>tailscale_dns_search_paths</code> resource</a>.</li>\n<li><a href=\"https://tailscale.com/docs/features/magicdns\">MagicDNS</a> using the <a href=\"https://registry.terraform.io/providers/tailscale/tailscale/latest/docs/resources/dns_preferences\"><code>tailscale_dns_preferences</code> resource</a>.</li>\n</ul>\n</li>\n<li>Generate an <a href=\"https://tailscale.com/docs/features/access-control/auth-keys\">auth key</a> (including setting whether it's reusable, ephemeral, pre-authorized, and tagged)\r\nusing the <a href=\"https://registry.terraform.io/providers/tailscale/tailscale/latest/docs/resources/tailnet_key\"><code>tailscale_key</code> resource</a>.</li>\n<li>Manage properties of a device, including:\n<ul>\n<li><a href=\"https://tailscale.com/docs/features/access-control/device-management/device-approval\">Device approval</a> using the <a href=\"https://registry.terraform.io/providers/tailscale/tailscale/latest/docs/resources/device_authorization\"><code>tailscale_device_authorization</code> resource</a>.</li>\n<li><a href=\"https://tailscale.com/docs/features/access-control/key-expiry\">Key expiry</a> using the <a href=\"https://registry.terraform.io/providers/tailscale/tailscale/latest/docs/resources/device_key\"><code>tailscale_device_key</code> resource</a>.</li>\n<li><a href=\"https://tailscale.com/docs/features/tags\">Tags</a> using the <a href=\"https://registry.terraform.io/providers/tailscale/tailscale/latest/docs/resources/device_tags\"><code>tailscale_device_tags</code> resource</a>.</li>\n<li><a href=\"https://tailscale.com/docs/features/subnet-routers\">Subnet routes</a> using the <a href=\"https://registry.terraform.io/providers/tailscale/tailscale/latest/docs/resources/device_subnet_routes\"><code>tailscale_device_subnet_routes</code> resource</a>.</li>\n</ul>\n</li>\n</ul>\n<p>Refer to the <a href=\"https://registry.terraform.io/providers/tailscale/tailscale/latest/docs\">Terraform Provider documentation</a> for the full list of supported resources.</p>\n<h2><a href=\"https://tailscale.com/docs/integrations/terraform-provider#credentials-and-tailnet-configuration\">Credentials and tailnet configuration</a></h2>\n<p>To use Terraform with Tailscale, configure the <a href=\"https://registry.terraform.io/providers/tailscale/tailscale/latest\">Tailscale Terraform provider</a> with your\r\nTailscale credentials, which can be a <a href=\"https://login.tailscale.com/admin/settings/trust-credentials\">trust credential</a> or an <a href=\"https://login.tailscale.com/admin/settings/keys\">API access token</a>.</p>\n<p>Tailscale recommend that you use a trust credential (an OAuth client or federated identity) because trust credentials are associated with the tailnet, not an individual user, do not expire, and support <a href=\"https://tailscale.com/docs/reference/trust-credentials#scopes\">scopes</a>. For details, refer to <a href=\"https://tailscale.com/docs/reference/trust-credentials\">trust credentials</a>.</p>\n<p>You must also specify your tailnet in the Tailscale Terraform provider configuration. You can provide a dash (<code>-</code>) to reference the default tailnet of the <a href=\"https://tailscale.com/docs/reference/trust-credentials\">trust credential</a> (or API access token) used as credentials. Using the default tailnet from the credential information is the best option for most users. Alternatively, you can specify your <a href=\"https://tailscale.com/docs/concepts/tailnet-name#tailnet-id\">tailnet ID</a>. You can find your tailnet ID in the <a href=\"https://login.tailscale.com/admin/settings/general\">General</a> page of the admin console.</p>\n<p>It is not recommended to store sensitive information, such as an OAuth client or API access token, in source control. Instead, use an environment variable or a secrets manager.</p>\n<p>Use the default variables <code>TAILSCALE_OAUTH_CLIENT_ID</code>, <code>TAILSCALE_OAUTH_CLIENT_SECRET</code>, and <code>TAILSCALE_TAILNET</code> to provide your credentials and tailnet organization name to the Tailscale Terraform provider. Alternatively, refer to the Terraform documentation for <a href=\"https://developer.hashicorp.com/terraform/tutorials/configuration-language/sensitive-variables#set-values-with-variables\">setting values with variables</a>.</p>\n<p>If you are using a federated identity instead of an OAuth client, use the default <code>TAILSCALE_IDENTITY_TOKEN</code> variable instead of <code>TAILSCALE_OAUTH_CLIENT_SECRET</code>.</p>\n<p>If you are using an API access token instead of an OAuth client, use the default <code>TAILSCALE_API_KEY</code> variable instead of <code>TAILSCALE_OAUTH_CLIENT_ID</code> and <code>TAILSCALE_OAUTH_CLIENT_SECRET</code>.</p>\n<h3><a href=\"https://tailscale.com/docs/integrations/terraform-provider#environment-variables\">Environment variables</a></h3>\n<p>You can store most information as environment variables in Terraform. Tailscale uses environment variables for the following configuration settings:</p>\n<p>| <strong>Setting</strong> | <strong>Description</strong> | <strong>Environment variable</strong> |\r\n| --- | --- | --- |\r\n| <code>api_key</code><br> (String, Sensitive) | The API key to use for authenticating requests to the API. <br>Conflicts with '<code>TAILSCALE_OAUTH_CLIENT_ID</code>' and '<code>TAILSCALE_OAUTH_CLIENT_SECRET</code>'. | <code>TAILSCALE_API_KEY</code> |\r\n| <code>base_url</code><br> (String) | The base URL of the Tailscale API. <br>Defaults to <code>https://api.tailscale.com</code>. | <code>TAILSCALE_BASE_URL</code> |\r\n| <code>TAILSCALE_OAUTH_CLIENT_ID</code><br> (String) | The OAuth application or federated identity's ID when using OAuth client credentials or workload identity federation. If set, then either '<code>TAILSCALE_OAUTH_CLIENT_SECRET</code>' or '<code>TAILSCALE_IDENTITY_TOKEN</code>' must also be set, but not both. <br>Conflicts with '<code>api_key</code>'. | <code>TAILSCALE_OAUTH_CLIENT_ID</code> |\r\n| <code>TAILSCALE_OAUTH_CLIENT_SECRET</code><br> (String, Sensitive) | The OAuth application's secret when using OAuth client credentials. If set, '<code>TAILSCALE_OAUTH_CLIENT_ID</code>' must also be set. <br>Conflicts with '<code>api_key</code>' and '<code>identity_token</code>'. | <code>TAILSCALE_OAUTH_CLIENT_SECRET</code> |\r\n| <code>TAILSCALE_IDENTITY_TOKEN</code><br> (String, Sensitive) | The JWT identity token to exchange for a Tailscale API token when using a federated identity. <br>Conflicts with '<code>api_key</code>' and '<code>client_secret</code>'. | <code>TAILSCALE_OAUTH_CLIENT_SECRET</code> |\r\n| <code>tailnet</code><br> (String) | The <a href=\"https://tailscale.com/docs/concepts/tailnet-name#tailnet-id\">tailnet ID</a> to perform actions in. | <code>TAILSCALE_TAILNET</code> |</p>\n<h3><a href=\"https://tailscale.com/docs/integrations/terraform-provider#migrate-from-the-community-contributed-terraform-provider\">Migrate from the community-contributed Terraform provider</a></h3>\n<p>If you previously used the community-contributed Terraform provider, and now want to use the provider managed and published by Tailscale, update the <code>source</code> argument in your Terraform configuration. That is, update <code>source = \"davidsbond/tailscale\"</code> to <code>source = \"tailscale/tailscale\"</code>.</p>\n<h2><a href=\"https://tailscale.com/docs/integrations/terraform-provider#special-thanks\">Special thanks</a></h2>\n<p>Special thanks to <a href=\"https://github.com/davidsbond\">David Bond</a>, who contributed and maintained the original community-contributed Tailscale Terraform provider. Tailscale now maintains and publishes this provider.</p>\n<h2><a href=\"https://tailscale.com/docs/integrations/terraform-provider#support\">Support</a></h2>\n<p>The Tailscale Terraform provider is maintained and published in the Terraform registry by Tailscale. If you have an issue or feature request, <a href=\"https://tailscale.com/contact/support\">contact support</a> or <a href=\"https://github.com/tailscale/terraform-provider-tailscale/issues\">file a GitHub issue</a>.</p>\n<p><img src=\"https://cdn.brandfetch.io/tailscale.com/fallback/lettermark/theme/dark/h/256/w/256/icon?c=1bfwsmEH20zzEfSNTed\" alt=\"Project Logo\"></p>\n<p>Ask AI</p>\n<p>reCAPTCHA</p>\n<p>Recaptcha requires verification.</p>\n<p>protected by <strong>reCAPTCHA</strong></p>\n"}