### Install Tailscale Terraform Provider
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/README.md
Add this to your Terraform configuration to install the Tailscale provider. Run `terraform init` afterwards.
```terraform
terraform {
required_providers {
tailscale = {
source = "tailscale/tailscale"
version = "~> 0.16" // Latest 0.16.x
}
}
}
provider "tailscale" {
api_key = "tskey-api-..."
}
```
--------------------------------
### Example Usage of tailscale_device_key
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/device_key.md
This example demonstrates how to use the tailscale_device_key resource to disable key expiry for a device. It first fetches device information using a data source and then applies the key expiry setting.
```terraform
data "tailscale_device" "example_device" {
name = "device.example.com"
}
resource "tailscale_device_key" "example_key" {
# Prefer the new, stable `node_id` attribute; the legacy `.id` field still works.
device_id = data.tailscale_device.example_device.node_id
key_expiry_disabled = true
}
```
--------------------------------
### Run Acceptance Tests Locally
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/README.md
Starts a local control server and runs acceptance tests. Ensure necessary Tailscale environment variables are set.
```shell
./tool/go run -tags tailscale_saas ./cmd/devcontrol --generate-test-devices=terraform-acceptance-testing &
make testacc_local
```
--------------------------------
### Create a Tailscale Service
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/service.md
Use this resource to create a Tailscale Service. Ensure the name starts with 'svc:' and specify the ports to be exposed.
```terraform
resource "tailscale_service" "example" {
name = "svc:my-service"
comment = "My service"
ports = ["tcp:443"]
tags = ["tag:web"]
}
```
--------------------------------
### Example Usage of tailscale_devices Data Source
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/data-sources/devices.md
Use this data source to fetch a list of devices. You can filter by a name prefix and by specific device attributes like 'isEphemeral' or 'tags'.
```terraform
data "tailscale_devices" "sample_devices" {
name_prefix = "example-"
filter {
name = "isEphemeral"
values = ["true"]
}
filter {
name = "tags"
values = ["tag:server", "tag:test"]
}
}
```
--------------------------------
### tailscale_devices
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/data-sources/devices.md
Example usage of the tailscale_devices data source to fetch devices, filtering by name prefix and specific device properties like 'isEphemeral' and 'tags'.
```APIDOC
## tailscale_devices
### Description
The devices data source describes a list of devices in a tailnet.
### Usage
```terraform
data "tailscale_devices" "sample_devices" {
name_prefix = "example-"
filter {
name = "isEphemeral"
values = ["true"]
}
filter {
name = "tags"
values = ["tag:server", "tag:test"]
}
}
```
### Schema
#### Optional
- `filter` (Block Set) Filters the device list to elements devices whose fields match the provided values. (see [below for nested schema](#nestedblock--filter))
- `name_prefix` (String) Filters the device list to elements whose name has the provided prefix
#### Read-Only
- `devices` (Block List) The list of devices in the tailnet (see [below for nested schema](#nestedblock--devices))
- `id` (String) The ID of this resource.
### Nested Schema for `filter`
Required:
- `name` (String) The name must be a top-level device property, e.g. isEphemeral, tags, hostname, etc.
- `values` (Set of String) The list of values to filter for. Values are matched as exact matches.
### Nested Schema for `devices`
Read-Only:
- `addresses` (List of String) The list of device's IPs
- `authorized` (Boolean) Whether the device is authorized to access the tailnet
- `blocks_incoming_connections` (Boolean) Whether the device blocks incoming connections
- `client_version` (String) The Tailscale client version running on the device
- `created` (String) The creation time of the device
- `expires` (String) The expiry time of the device's key
- `hostname` (String) The short hostname of the device
- `id` (String) The ID of this resource.
- `is_external` (Boolean) Whether the device is marked as external
- `key_expiry_disabled` (Boolean) Whether the device's key expiry is disabled
- `last_seen` (String) The last seen time of the device
- `machine_key` (String) The machine key of the device
- `name` (String) The full name of the device (e.g. `hostname.domain.ts.net`)
- `node_id` (String) The preferred indentifier for a device.
- `node_key` (String) The node key of the device
- `os` (String) The operating system of the device
- `tags` (Set of String) The tags applied to the device
- `tailnet_lock_error` (String) The tailnet lock error for the device, if any
- `tailnet_lock_key` (String) The tailnet lock key for the device, if any
- `update_available` (Boolean) Whether an update is available for the device
- `user` (String) The user associated with the device
```
--------------------------------
### Importing tailscale_device_key Resource
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/device_key.md
These examples show how to import an existing tailscale_device_key resource into your Terraform state. You can use either the preferred node ID or the legacy ID for the import.
```shell
# Device key can be imported using the node ID (preferred), e.g.,
terraform import tailscale_device_key.sample nodeidCNTRL
```
```shell
# Device key can be imported using the legacy ID, e.g.,
terraform import tailscale_device_key.sample 123456789
```
--------------------------------
### Run Specific Acceptance Test
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/README.md
Runs a specific acceptance test by passing arguments to the 'go test' command using the TESTARGS variable. This example targets 'TestAccTailscaleACL'.
```shell
TESTARGS='-run TestAccTailscaleACL' make testacc_local
```
--------------------------------
### tailscale_service Data Source
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/data-sources/service.md
Example usage of the tailscale_service data source to fetch details about a service.
```APIDOC
## tailscale_service Data Source
### Description
The Service data source describes a single Service in a tailnet.
### Schema
#### Required
- `name` (String) The name of the Service (e.g. `svc:my-service`).
#### Read-Only
- `addrs` (List of String) The IP addresses assigned to the Service.
- `comment` (String) A comment describing the Service.
- `id` (String) The Service name, e.g. 'svc:my-service'.
- `ports` (List of String) The ports that the Service listens on.
- `tags` (Set of String) The ACL tags applied to the Service.
### Example Usage
```terraform
data "tailscale_service" "example" {
name = "svc:my-service"
}
```
```
--------------------------------
### Example Usage of tailscale_aws_external_id
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/aws_external_id.md
This example demonstrates how to use the `tailscale_aws_external_id` resource in conjunction with `tailscale_logstream_configuration` and AWS IAM resources to enable Tailscale to stream logs to an S3 bucket. It shows how to reference the generated `external_id` and `tailscale_aws_account_id` in the IAM role's trust policy.
```terraform
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/*"
]
}
}
```
--------------------------------
### Manage Tailscale DNS Configuration
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/dns_configuration.md
Use this resource to define the entire DNS setup for your Tailnet. Ensure no other DNS management resources are used concurrently. Configure nameservers, split DNS rules, search paths, and enable MagicDNS.
```terraform
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
}
```
--------------------------------
### Example Usage of tailscale_acl Data Source
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/data-sources/acl.md
This data source can be used to fetch the entire Tailscale policy file for a tailnet. No specific configuration is required beyond referencing the data source.
```terraform
data "tailscale_acl" "example" {}
```
--------------------------------
### Get all users
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/data-sources/users.md
Use the `tailscale_users` data source to fetch all users in your Tailscale network. No additional configuration is required.
```terraform
data "tailscale_users" "all-users" {}
```
--------------------------------
### Get device by name
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/data-sources/device.md
Use the `name` argument to specify the full DNS name of the device. The `wait_for` argument can be used to poll for the device information for a specified duration.
```terraform
data "tailscale_device" "sample_device" {
name = "device1.example.ts.net"
wait_for = "60s"
}
```
--------------------------------
### Get device by hostname
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/data-sources/device.md
Use the `hostname` argument to specify the short hostname of the device. The `wait_for` argument can be used to poll for the device information for a specified duration.
```terraform
data "tailscale_device" "sample_device2" {
hostname = "device2"
wait_for = "60s"
}
```
--------------------------------
### Import a Posture Integration
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/posture_integration.md
Import an existing posture integration into your Terraform state. Use the posture integration ID provided by Tailscale.
```shell
# Posture integration can be imported using the posture integration id, e.g.,
terraform import tailscale_posture_integration.sample_posture_integration 123456789
```
--------------------------------
### Create a Posture Integration
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/posture_integration.md
Use this resource to create a new posture integration. Ensure you provide the correct posture provider and authentication details.
```terraform
resource "tailscale_posture_integration" "sample_posture_integration" {
posture_provider = "falcon"
cloud_id = "us-1"
client_id = "clientid1"
client_secret = "test-secret1"
}
```
--------------------------------
### Configure DNS Preferences
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/dns_preferences.md
Use this resource to enable MagicDNS for your Tailscale network. Ensure the `magic_dns` argument is set to `true`.
```terraform
resource "tailscale_dns_preferences" "sample_preferences" {
magic_dns = true
}
```
--------------------------------
### Configure Tailscale Provider
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/index.md
Configure the Tailscale provider with your OAuth client ID, secret, and tailnet. This is a common setup for interacting with the Tailscale API.
```terraform
terraform {
required_providers {
tailscale = {
source = "tailscale/tailscale"
version = ""
}
}
}
provider "tailscale" {
oauth_client_id = "my_client_id"
oauth_client_secret = "my_client_secret"
tailnet = "example.com"
}
```
--------------------------------
### tailscale_posture_integration Resource
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/posture_integration.md
The posture_integration resource allows you to manage integrations with device posture data providers. See https://tailscale.com/kb/1288/device-posture for more information.
```APIDOC
## Schema
### Required
- `client_secret` (String, Sensitive) The secret (auth key, token, etc.) used to authenticate with the provider.
- `posture_provider` (String) The third-party provider for posture data. Valid values are `falcon`, `fleet`, `huntress`, `intune`, `jamfpro`, `kandji`, `kolide`, and `sentinelone`.
### Optional
- `client_id` (String) Unique identifier for your client.
- `cloud_id` (String) Identifies which of the provider's clouds to integrate with.
- `tenant_id` (String) The Microsoft Intune directory (tenant) ID. For other providers, this is left blank.
### Read-Only
- `id` (String) The ID of this resource.
```
--------------------------------
### Import tailscale_dns_split_nameservers Resource
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/dns_split_nameservers.md
Import split DNS nameservers configuration using the domain name. This allows you to manage existing configurations within Terraform.
```bash
# Split DNS nameservers can be imported using the domain name, e.g.
terraform import tailscale_dns_split_nameservers.sample_split_nameservers example.com
```
--------------------------------
### Get Tailscale Service Information
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/data-sources/service.md
Use this data source to fetch details about a Tailscale Service by its name. This is useful for referencing service attributes in your Terraform configuration.
```terraform
data "tailscale_service" "example" {
name = "svc:my-service"
}
```
--------------------------------
### Get a user by ID
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/data-sources/user.md
Use the `tailscale_user` data source to fetch details about a user by their unique ID. This is useful for referencing user information in your Terraform configurations.
```terraform
data "tailscale_user" "32571345" {
id = 32571345
}
```
--------------------------------
### Create an OAuth Client
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/oauth_client.md
Use this resource to create a new OAuth client. Specify the desired scopes and optionally provide a description and tags. The 'scopes' argument is required, and 'tags' are mandatory if scopes include 'devices:core' or 'auth_keys'.
```terraform
resource "tailscale_oauth_client" "sample_client" {
description = "sample client"
scopes = ["all:read"]
tags = ["tag:test"]
}
```
--------------------------------
### Import Tailnet Settings
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/tailnet_settings.md
Import an existing tailnet settings configuration into Terraform management. The ID for import is typically a fixed string.
```bash
# ID doesn't matter.
terraform import tailscale_tailnet_settings.sample_preferences tailnet_settings
```
--------------------------------
### Import DNS Preferences
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/dns_preferences.md
Import an existing DNS preferences configuration into Terraform state. The ID `dns_preferences` is a placeholder and does not need to match any specific value.
```bash
# ID doesn't matter.
terraform import tailscale_dns_preferences.sample_preferences dns_preferences
```
--------------------------------
### Generate Provider Documentation
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/README.md
Generates provider documentation using terraform-plugin-docs. After running, review and commit the generated files.
```shell
go generate ./...
```
--------------------------------
### Configure a Device as an Exit Node
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/device_subnet_routes.md
Enable `0.0.0.0/0` and `::/0` routes for a device to configure it as a potential exit node. This resource ensures these routes are enabled for the specified device.
```terraform
data "tailscale_device" "sample_device" {
name = "device.example.com"
}
resource "tailscale_device_subnet_routes" "sample_exit_node" {
# Prefer the new, stable `node_id` attribute; the legacy `.id` field still works.
device_id = data.tailscale_device.sample_device.node_id
routes = [
# Configure as an exit node
"0.0.0.0/0",
"::/0"
]
}
```
--------------------------------
### Import a Tailscale Tailnet Key
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/tailnet_key.md
Import an existing Tailscale tailnet key using its ID. Note that the `key` attribute will not be populated upon import, as it is only available during resource creation.
```shell
# Tailnet key can be imported using the key id, e.g.,
terraform import tailscale_tailnet_key.sample_key 123456789
```
--------------------------------
### Create a DNS Search Paths resource
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/dns_search_paths.md
Use this resource to define the domain suffixes that devices on your network will use to resolve DNS names. Ensure the 'search_paths' argument is provided with a list of strings.
```terraform
resource "tailscale_dns_search_paths" "sample_search_paths" {
search_paths = [
"example.com"
]
}
```
--------------------------------
### tailscale_oauth_client
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/oauth_client.md
The `tailscale_oauth_client` resource allows you to create OAuth clients to programmatically interact with the Tailscale API. It requires specifying scopes and optionally allows for a description and tags.
```APIDOC
## tailscale_oauth_client Resource
### Description
The `tailscale_oauth_client` resource allows you to create OAuth clients to programmatically interact with the Tailscale API.
### Usage
```terraform
resource "tailscale_oauth_client" "sample_client" {
description = "sample client"
scopes = ["all:read"]
tags = ["tag:test"]
}
```
### Schema
#### Required
- `scopes` (Set of String) Scopes to grant to the client. See https://tailscale.com/kb/1623/ for a list of available scopes.
#### Optional
- `description` (String) A description of the OAuth client consisting of alphanumeric characters. Defaults to `""`.
- `tags` (Set of String) A list of tags that access tokens generated for the OAuth client will be able to assign to devices. Mandatory if the scopes include "devices:core" or "auth_keys".
#### Read-Only
- `created_at` (String) The creation timestamp of the key in RFC3339 format
- `id` (String) The client ID, also known as the key id. Used with the client secret to generate access tokens.
- `key` (String, Sensitive) The client secret, also known as the key. Used with the client ID to generate access tokens.
- `updated_at` (String) The updated timestamp of the key in RFC3339 format
- `user_id` (String) ID of the user who created this key, empty for OAuth clients created by other trust credentials.
### Import
Import is supported using the following syntax:
The [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import) can be used, for example:
```shell
# Note: Sensitive fields such as the secret key are not returned by the API and will be unset in the Terraform state after import.
terraform import tailscale_oauth_client.example k1234511CNTRL
```
```
--------------------------------
### Import DNS Nameservers Configuration
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/dns_nameservers.md
Import an existing DNS nameserver configuration into your Terraform state. The ID does not matter for this resource.
```bash
# ID doesn't matter.
terraform import tailscale_dns_nameservers.sample dns_nameservers
```
--------------------------------
### Import DNS Configuration
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/dns_configuration.md
Import an existing DNS configuration into Terraform management. The ID for import is fixed as 'dns_configuration'.
```shell
# ID doesn't matter.
terraform import tailscale_dns_configuration.sample_configuration dns_configuration
```
--------------------------------
### Create a Tailscale Webhook
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/webhook.md
Configure a webhook to send notifications to a Slack endpoint when nodes are created or users are deleted. Ensure the endpoint URL and desired subscriptions are specified.
```terraform
resource "tailscale_webhook" "sample_webhook" {
endpoint_url = "https://example.com/webhook/endpoint"
provider_type = "slack"
subscriptions = ["nodeCreated", "userDeleted"]
}
```
--------------------------------
### tailscale_device_subnet_routes
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/device_subnet_routes.md
The device_subnet_routes resource allows you to configure enabled subnet routes for your Tailscale devices. Routes must be both advertised and enabled for a device to act as a subnet router or exit node. Routes must be advertised directly from the device: advertised routes cannot be managed through Terraform. If a device is advertising routes, they are not exposed to traffic until they are enabled. Conversely, if routes are enabled before they are advertised, they are not available for routing until the device in question is advertising them. Note: all routes enabled for the device through the admin console or autoApprovers in the ACL must be explicitly added to the routes attribute of this resource to avoid configuration drift.
```APIDOC
## tailscale_device_subnet_routes (Resource)
### Description
The device_subnet_routes resource allows you to configure enabled subnet routes for your Tailscale devices. See https://tailscale.com/kb/1019/subnets for more information.
Routes must be both advertised and enabled for a device to act as a subnet router or exit node. Routes must be advertised directly from the device: advertised routes cannot be managed through Terraform. If a device is advertising routes, they are not exposed to traffic until they are enabled. Conversely, if routes are enabled before they are advertised, they are not available for routing until the device in question is advertising them.
Note: all routes enabled for the device through the admin console or autoApprovers in the ACL must be explicitly added to the routes attribute of this resource to avoid configuration drift.
### Schema
#### Required
- `device_id` (String) The device to set subnet routes for
- `routes` (Set of String) The subnet routes that are enabled to be routed by a device
#### Read-Only
- `id` (String) The ID of this resource.
### Import
Import is supported using the following syntax:
The [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import) can be used, for example:
```shell
# 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
```
```
--------------------------------
### Configure Enabled Subnet Routes for a Device
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/device_subnet_routes.md
Use this resource to enable specific subnet routes for a Tailscale device. Ensure the device is also advertising these routes. The `device_id` should reference the target device.
```terraform
data "tailscale_device" "sample_device" {
name = "device.example.com"
}
resource "tailscale_device_subnet_routes" "sample_routes" {
# Prefer the new, stable `node_id` attribute; the legacy `.id` field still works.
device_id = data.tailscale_device.sample_device.node_id
routes = [
"10.0.1.0/24",
"1.2.0.0/16",
"2.0.0.0/24"
]
}
```
--------------------------------
### Import existing Tailscale ACLs
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/acl.md
Use this command to import an existing Tailscale ACL configuration into Terraform management. The ID 'acl' is a placeholder and doesn't affect the import process.
```shell
# ID doesn't matter.
terraform import tailscale_acl.sample_acl acl
```
--------------------------------
### tailscale_dns_split_nameservers Resource
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/dns_split_nameservers.md
Configure split DNS nameservers for a specific domain. Requests for this domain will be resolved using the provided nameservers. Changing the domain will force resource recreation.
```terraform
resource "tailscale_dns_split_nameservers" "sample_split_nameservers" {
domain = "foo.example.com"
nameservers = ["1.1.1.1"]
}
```
--------------------------------
### Import Tailscale Device Tags
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/device_tags.md
Import existing device tags into Terraform state. You can use either the node ID (preferred) or the legacy ID for the import.
```shell
# Device tags can be imported using the node ID (preferred), e.g.,
terraform import tailscale_device_tags.sample nodeidCNTRL
```
```shell
# Device tags can be imported using the legacy ID, e.g.,
terraform import tailscale_device_tags.sample 123456789
```
--------------------------------
### Importing a tailscale_device_key Resource
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/device_key.md
You can import an existing device key into your Terraform state using its node ID or legacy ID.
```APIDOC
## Import
Import is supported using the following syntax:
The [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import) can be used, for example:
```shell
# 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
```
```
--------------------------------
### Import a DNS Search Paths resource
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/dns_search_paths.md
Import an existing DNS search paths configuration into your Terraform state. The ID for import is typically 'dns_search_paths'.
```bash
# ID doesn't matter.
terraform import tailscale_dns_search_paths.sample dns_search_paths
```
--------------------------------
### Configure Tailscale Provider with OAuth Client
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/README.md
Configure the provider using an OAuth client ID and secret instead of a personal API key.
```terraform
provider "tailscale" {
oauth_client_id = "..."
oauth_client_secret = "tskey-client-..."
}
```
--------------------------------
### Create a Tailscale Tailnet Key
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/tailnet_key.md
Use this resource to create a reusable, non-ephemeral, preauthorized key with a specified expiry and description. This key can be used to register new nodes automatically.
```terraform
resource "tailscale_tailnet_key" "sample_key" {
reusable = true
ephemeral = false
preauthorized = true
expiry = 3600
description = "Sample key"
}
```
--------------------------------
### Approve a new device
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/device_authorization.md
Use this resource to approve a new device by setting `authorized` to `true`. It's recommended to use the `node_id` attribute for the `device_id`.
```terraform
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
}
```
--------------------------------
### Configure DNS Nameservers
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/dns_nameservers.md
Use this resource to set the DNS nameservers that devices on your network will use for resolution. IPv4 or IPv6 addresses are accepted.
```terraform
resource "tailscale_dns_nameservers" "sample_nameservers" {
nameservers = [
"8.8.8.8",
"8.8.4.4"
]
}
```
--------------------------------
### tailscale_device
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/data-sources/device.md
The device data source describes a single device in a tailnet. You can use either the `name` or `hostname` argument to identify the device. The `wait_for` argument can be used to specify a duration for retrying data source retrieval.
```APIDOC
## tailscale_device (Data Source)
### Description
The device data source describes a single device in a tailnet.
### Arguments
* `name` - (Optional) The full name of the device (e.g. `hostname.domain.ts.net`).
* `hostname` - (Optional) The short hostname of the device.
* `wait_for` - (Optional) If specified, the provider will make multiple attempts to obtain the data source until the wait_for duration is reached. Retries are made every second so this value should be greater than 1s.
### Attributes
* `addresses` - (List of String) The list of device's IPs.
* `authorized` - (Boolean) Whether the device is authorized to access the tailnet.
* `blocks_incoming_connections` - (Boolean) Whether the device blocks incoming connections.
* `client_version` - (String) The Tailscale client version running on the device.
* `created` - (String) The creation time of the device.
* `expires` - (String) The expiry time of the device's key.
* `id` - (String) The ID of this resource.
* `is_external` - (Boolean) Whether the device is marked as external.
* `key_expiry_disabled` - (Boolean) Whether the device's key expiry is disabled.
* `last_seen` - (String) The last seen time of the device.
* `machine_key` - (String) The machine key of the device.
* `node_id` - (String) The preferred indentifier for a device.
* `node_key` - (String) The node key of the device.
* `os` - (String) The operating system of the device.
* `tags` - (Set of String) The tags applied to the device.
* `tailnet_lock_error` - (String) The tailnet lock error for the device, if any.
* `tailnet_lock_key` - (String) The tailnet lock key for the device, if any.
* `update_available` - (Boolean) Whether an update is available for the device.
* `user` - (String) The user associated with the device.
### Example Usage
```terraform
data "tailscale_device" "sample_device" {
name = "device1.example.ts.net"
wait_for = "60s"
}
data "tailscale_device" "sample_device2" {
hostname = "device2"
wait_for = "60s"
}
```
```
--------------------------------
### tailscale_dns_preferences
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/dns_preferences.md
The dns_preferences resource allows you to configure DNS preferences for your Tailscale network.
```APIDOC
## tailscale_dns_preferences (Resource)
### Description
The dns_preferences resource allows you to configure DNS preferences for your Tailscale network. See https://tailscale.com/kb/1054/dns for more information.
### Schema
#### Required
- `magic_dns` (Boolean) - Whether or not to enable magic DNS
#### Read-Only
- `id` (String) - The ID of this resource.
### Import
Import is supported using the following syntax:
The [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import) can be used, for example:
```shell
# ID doesn't matter.
terraform import tailscale_dns_preferences.sample_preferences dns_preferences
```
```
--------------------------------
### tailscale_webhook Resource
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/webhook.md
The `tailscale_webhook` resource allows you to configure webhook endpoints for your Tailscale network. You can specify the endpoint URL, the provider type (e.g., slack, mattermost), and the events to subscribe to.
```APIDOC
## tailscale_webhook Resource
### Description
The webhook resource allows you to configure webhook endpoints for your Tailscale network. See https://tailscale.com/kb/1213/webhooks for more information.
### Resource Definition
```terraform
resource "tailscale_webhook" "sample_webhook" {
endpoint_url = "https://example.com/webhook/endpoint"
provider_type = "slack"
subscriptions = ["nodeCreated", "userDeleted"]
}
```
### Schema
#### Required
- `endpoint_url` (String) The endpoint to send webhook events to.
- `subscriptions` (Set of String) The set of events that trigger this webhook. For a full list of event types, see the [webhooks documentation](https://tailscale.com/kb/1213/webhooks#events).
#### Optional
- `provider_type` (String) The provider type of the endpoint URL. This determines the payload format sent to the destination. Valid values are `slack`, `mattermost`, `googlechat`, and `discord`.
#### Read-Only
- `id` (String) The ID of this resource.
- `secret` (String, Sensitive) The secret used for signing webhook payloads. Only set on resource creation. See https://tailscale.com/kb/1213/webhooks#webhook-secret for more information.
### Import
Import is supported using the following syntax:
The [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import) can be used, for example:
```shell
# Webhooks can be imported using the endpoint id, e.g.,
terraform import tailscale_webhook.sample_webhook 123456789
```
```
--------------------------------
### tailscale_device_tags Resource
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/device_tags.md
The `tailscale_device_tags` resource is used to apply tags to Tailscale devices. It requires a `device_id` and a set of `tags` to be applied.
```APIDOC
## tailscale_device_tags (Resource)
### Description
The device_tags resource is used to apply tags to Tailscale devices. See https://tailscale.com/kb/1068/acl-tags/ for more details.
### Schema
#### Required
- `device_id` (String) The device to set tags for
- `tags` (Set of String) The tags to apply to the device
#### Read-Only
- `id` (String) The ID of this resource.
### Import
Import is supported using the following syntax:
The [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import) can be used, for example:
```shell
# Device tags can be imported using the node ID (preferred), e.g.,
terraform import tailscale_device_tags.sample nodeidCNTRL
# Device tags can be imported using the legacy ID, e.g.,
terraform import tailscale_device_tags.sample 123456789
```
```
--------------------------------
### Import Device Subnet Routes
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/device_subnet_routes.md
Import existing device subnet route configurations into Terraform management. Use the node ID for preferred imports, or the legacy ID if necessary.
```shell
# 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
```
--------------------------------
### tailscale_tailnet_key Resource
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/tailnet_key.md
The tailnet_key resource allows you to create pre-authentication keys that can register new nodes without needing to sign in via a web browser.
```APIDOC
## tailscale_tailnet_key (Resource)
### Description
The tailnet_key resource allows you to create pre-authentication keys that can register new nodes without needing to sign in via a web browser. See https://tailscale.com/kb/1085/auth-keys for more information
### Schema
#### Optional
- `description` (String) A description of the key consisting of alphanumeric characters. Defaults to `""`.
- `ephemeral` (Boolean) Indicates if the key is ephemeral. Defaults to `false`.
- `expiry` (Number) The expiry of the key in seconds. Defaults to `7776000` (90 days).
- `preauthorized` (Boolean) Determines whether or not the machines authenticated by the key will be authorized for the tailnet by default. Defaults to `false`.
- `recreate_if_invalid` (String) Determines whether the key should be created again if it becomes invalid. By default, reusable keys will be recreated, but single-use keys will not. Possible values: 'always', 'never'.
- `reusable` (Boolean) Indicates if the key is reusable or single-use. Defaults to `false`.
- `tags` (Set of String) List of tags to apply to the machines authenticated by the key.
- `user_id` (String) ID of the user who created this key, empty for keys created by OAuth clients.
#### Read-Only
- `created_at` (String) The creation timestamp of the key in RFC3339 format
- `expires_at` (String) The expiry timestamp of the key in RFC3339 format
- `id` (String) The ID of this resource.
- `invalid` (Boolean) Indicates whether the key is invalid (e.g. expired, revoked or has been deleted).
- `key` (String, Sensitive) The authentication key
### Import
Import is supported using the following syntax:
```shell
# Tailnet key can be imported using the key id, e.g.,
terraform import tailscale_tailnet_key.sample_key 123456789
```
-> ** Note ** the `key` attribute will not be populated on import as this attribute is only populated
on resource creation.
```
--------------------------------
### tailscale_tailnet_settings
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/tailnet_settings.md
Manages tailnet-wide settings for your Tailscale network.
```APIDOC
## tailscale_tailnet_settings (Resource)
### Description
The tailnet_settings resource allows you to configure settings for your tailnet.
### Schema
#### Optional
- `acls_external_link` (String) Link to your external ACL definition or management system. Must be a valid URL.
- `acls_externally_managed_on` (Boolean) Prevent users from editing policies in the admin console to avoid conflicts with external management workflows like GitOps or Terraform.
- `devices_approval_on` (Boolean) Whether device approval is enabled for the tailnet
- `devices_auto_updates_on` (Boolean) Whether auto updates are enabled for devices that belong to this tailnet
- `devices_key_duration_days` (Number) The key expiry duration for devices on this tailnet
- `https_enabled` (Boolean) Whether provisioning of HTTPS certificates is enabled for the tailnet
- `network_flow_logging_on` (Boolean) Whether network flow logs are enabled for the tailnet
- `posture_identity_collection_on` (Boolean) Whether identity collection is enabled for device posture integrations for the tailnet
- `regional_routing_on` (Boolean) Whether regional routing is enabled for the tailnet
- `users_approval_on` (Boolean) Whether user approval is enabled for this tailnet
- `users_role_allowed_to_join_external_tailnet` (String) Which user roles are allowed to join external tailnets
#### Read-Only
- `id` (String) The ID of this resource.
### Import
Import is supported using the following syntax:
The [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import) can be used, for example:
```shell
# ID doesn't matter.
terraform import tailscale_tailnet_settings.sample_preferences tailnet_settings
```
```
--------------------------------
### tailscale_device_authorization Resource
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/device_authorization.md
The device_authorization resource is used to approve new devices before they can join the tailnet.
```APIDOC
## Schema
### Required
- `authorized` (Boolean) Whether or not the device is authorized
- `device_id` (String) The device to set as authorized
### Read-Only
- `id` (String) The ID of this resource.
## Import
Import is supported using the following syntax:
The [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import) can be used, for example:
```shell
# Device authorization can be imported using the node ID (preferred), e.g.,
terraform import tailscale_device_authorization.sample_authorization nodeidCNTRL
# Device authorization can be imported using the legacy ID, e.g.,
terraform import tailscale_device_authorization.sample_authorization 123456789
```
```
--------------------------------
### Configure Tailnet Settings
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/tailnet_settings.md
Use this resource to manage your tailnet's global settings. It allows for external ACL management, device and user approval workflows, and key expiry durations.
```terraform
resource "tailscale_tailnet_settings" "sample_tailnet_settings" {
acls_externally_managed_on = true
acls_external_link = "https://github.com/octocat/Hello-World"
devices_approval_on = true
devices_auto_updates_on = true
devices_key_duration_days = 5
users_approval_on = true
users_role_allowed_to_join_external_tailnet = "member"
posture_identity_collection_on = true
https_enabled = true
}
```
--------------------------------
### tailscale_dns_configuration Resource
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/dns_configuration.md
Manages the complete DNS configuration for your Tailscale network, including nameservers, split DNS, search paths, and MagicDNS settings.
```APIDOC
## tailscale_dns_configuration (Resource)
### Description
The `dns_configuration` resource allows you to manage the complete DNS configuration for your Tailscale network. This resource is meant to manage the entirety of a Tailnet's DNS configuration and conflicts with other DNS management resources like `tailscale_dns_nameservers`, `tailscale_dns_preferences`, `tailscale_dns_search_paths`, and `tailscale_dns_split_nameservers`. This resource and previously mentioned resources should not be used simultaneously.
### Schema
#### Optional
- `magic_dns` (Boolean) - Whether or not to enable MagicDNS. Defaults to true.
- `nameservers` (Block List) - Set the nameservers used by devices on your network to resolve DNS queries. `override_local_dns` must also be true to prefer these nameservers over local DNS configuration. (see [below for nested schema](#nestedblock--nameservers))
- `override_local_dns` (Boolean) - When enabled, use the configured DNS servers in `nameservers` to resolve names outside the tailnet. When disabled, devices will prefer their local DNS configuration. Defaults to false.
- `search_paths` (List of String) - Additional search domains. When MagicDNS is on, the tailnet domain is automatically included as the first search domain.
- `split_dns` (Block List) - Set the nameservers used by devices on your network to resolve DNS queries on specific domains (requires Tailscale v1.8 or later). Configuration does not depend on `override_local_dns`. (see [below for nested schema](#nestedblock--split_dns))
#### Read-Only
- `id` (String) - The ID of this resource.
### Nested Schema for `nameservers`
#### Required
- `address` (String) - The nameserver's IPv4 or IPv6 address
#### Optional
- `use_with_exit_node` (Boolean) - This nameserver will continue to be used when an exit node is selected (requires Tailscale v1.88.1 or later). Defaults to false.
### Nested Schema for `split_dns`
#### Required
- `domain` (String) - The nameservers will be used only for this domain.
#### Optional
- `nameservers` (Block List) - Set the nameservers used by devices on your network to resolve DNS queries. (see [below for nested schema](#nestedblock--split_dns--nameservers))
### Nested Schema for `split_dns.nameservers`
#### Required
- `address` (String) - The nameserver's IPv4 or IPv6 address.
#### Optional
- `use_with_exit_node` (Boolean) - This nameserver will continue to be used when an exit node is selected (requires Tailscale v1.88.1 or later). Defaults to false.
### Import
Import is supported using the following syntax:
```shell
# ID doesn't matter.
terraform import tailscale_dns_configuration.sample_configuration dns_configuration
```
```
--------------------------------
### tailscale_service
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/service.md
The Service resource allows you to manage Tailscale Services in your Tailnet. Services let you publish internal resources (like databases or web servers) as named resources in your Tailnet. Services provide a stable MagicDNS name, a Tailscale virtual IP address pair, can be served by multiple nodes, and are valid access control destinations.
```APIDOC
## tailscale_service (Resource)
### Description
The Service resource allows you to manage Tailscale Services in your Tailnet. Services let you publish internal resources (like databases or web servers) as named resources in your Tailnet. Services provide a stable MagicDNS name, a Tailscale virtual IP address pair, can be served by multiple nodes, and are valid access control destinations.
### Schema
#### Required
- `name` (String) - The name of the Service. Must begin with `svc:`.
- `ports` (Set of String) - A list of protocol:port pairs to be exposed by the Service. The only supported protocol is "tcp" at this time. "do-not-validate" can be used to skip validation.
#### Optional
- `comment` (String) - An optional comment describing the Service.
- `tags` (Set of String) - The ACL tags applied to the Service.
#### Read-Only
- `addrs` (List of String) - The IP addresses assigned to the Service.
- `id` (String) - The Service name, e.g. 'svc:my-service'.
```
--------------------------------
### Apply Tags to a Tailscale Device
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/device_tags.md
Use this resource to assign tags to a specific Tailscale device. It's recommended to use the `node_id` attribute for the device, though the legacy `.id` field is also supported.
```terraform
data "tailscale_device" "sample_device" {
name = "device.example.com"
}
resource "tailscale_device_tags" "sample_tags" {
# Prefer the new, stable `node_id` attribute; the legacy `.id` field still works.
device_id = data.tailscale_device.sample_device.node_id
tags = ["room:bedroom"]
}
```
--------------------------------
### Authenticate Tailscale Provider with API Keys
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/index.md
Authenticate the Tailscale provider using an API key. Set the `api_key` argument in the provider configuration.
```terraform
provider "tailscale" {
api_key = "my_api_key"
tailnet = "example.com"
}
```
--------------------------------
### Configure Tailscale Contacts
Source: https://github.com/tailscale/terraform-provider-tailscale/blob/main/docs/resources/contacts.md
Use the `tailscale_contacts` resource to set up email addresses for account, support, and security notifications within your Tailscale network. Ensure you have the necessary permissions to manage contact preferences.
```terraform
resource "tailscale_contacts" "sample_contacts" {
account {
email = "account@example.com"
}
support {
email = "support@example.com"
}
security {
email = "security@example.com"
}
}
```