Перейти к основному содержимому

Terraform-провайдер

Провайдер yuccastream/tuna описывает ресурсы tuna кодом: домены и доменные зоны, шлюзы, эндпоинты, IP-политики, TLS-сертификаты, SSH-ключи и временные токены. Работает с Terraform и OpenTofu.

Провайдер в Terraform Registry

Документация по всем ресурсам и атрибутам — на странице yuccastream/tuna в Terraform Registry.

Установка​

Нужен Terraform 1.11 или новее: в более старых версиях не работают write-only атрибуты, а через них передаётся приватный ключ TLS-сертификата.

terraform {
required_version = ">= 1.11"

required_providers {
tuna = {
source = "yuccastream/tuna"
}
}
}

provider "tuna" {}
terraform init

В OpenTofu Registry провайдера пока нет. Для OpenTofu укажите реестр явно: source = "registry.terraform.io/yuccastream/tuna".

Аутентификация​

Провайдеру нужен API-ключ. Выпустите его в личном кабинете со скоупом tunnels:write: этого достаточно для всех ресурсов провайдера, полный доступ api не нужен. Ключ со скоупом по умолчанию read_api подходит только для чтения, apply с ним завершится ошибкой.

API-ключ нельзя выпустить через API, поэтому провайдер не управляет ключами: их создают только в личном кабинете.

Ключ передаётся переменной окружения (рекомендуется) или в блоке provider:

export TUNA_API_KEY="<API-ключ>"
provider "tuna" {
api_key = var.tuna_api_key
}
ПараметрПеременная окруженияОписание
api_keyTUNA_API_KEYAPI-ключ
api_urlTUNA_API_URLАдрес API, по умолчанию https://api.tuna.am

Ресурсы​

РесурсЧто описывает
tuna_domainЗарезервированный домен: поддомен встроенной зоны, своей зоны или собственный домен
tuna_domain_zoneДоменная зона
tuna_tls_certificateTLS-сертификат для доменной зоны
tuna_gatewayШлюз на зарезервированном домене
tuna_endpointTCP-порт
tuna_ip_policyIP-политика
tuna_ip_policy_ruleПравило IP-политики
tuna_public_keyПубличный SSH-ключ
tuna_temporal_tokenВременный токен для запуска туннелей

Источник данных tuna_tunnels возвращает список туннелей аккаунта.

Параметр location у доменов, зон и эндпоинтов принимает значения ru или nl.

Полный справочник по атрибутам — в Terraform Registry.

Сценарий: временные туннели для CI​

Terraform резервирует домен и выпускает временный токен с ограничениями, а CI-задача поднимает туннель с этим токеном. Основной API-ключ в CI не попадает.

resource "tuna_domain" "preview" {
subdomain = "myapp-preview"
location = "ru"
}

resource "tuna_temporal_token" "ci" {
description = "CI preview"
duration = "24h"
allow_http = true
allow_tcp = false
limit_by_active_tunnels = 5
limit_by_created_tunnels = 100
}

output "ci_tunnel_token" {
value = tuna_temporal_token.ci.token
sensitive = true
}

Токен помечен как sensitive, поэтому забирайте его явно:

terraform apply
export TUNA_TOKEN="$(terraform output -raw ci_tunnel_token)"
tuna http 8080 --subdomain=myapp-preview

Проверить, что туннель поднялся, можно через источник данных:

data "tuna_tunnels" "all" {}

output "active_tunnels" {
value = [for t in data.tuna_tunnels.all.tunnels : t.public_url if t.active]
}

Сценарий: своя зона с сертификатом и доступом по IP​

resource "tuna_tls_certificate" "wildcard" {
description = "wildcard for tunnels.example.com"
certificate_pem = file("${path.module}/cert.pem")
private_key_pem = file("${path.module}/key.pem")
}

resource "tuna_domain_zone" "example" {
domain = "tunnels.example.com"
location = "ru"
tls_certificate_id = tuna_tls_certificate.wildcard.id
}

resource "tuna_domain" "app" {
subdomain = "app"
location = "ru"
domain_zone_id = tuna_domain_zone.example.id
}

resource "tuna_ip_policy" "office" {
name = "office-only"
active = true
}

resource "tuna_ip_policy_rule" "office_allow" {
ip_policy_id = tuna_ip_policy.office.id
name = "office"
cidr = "203.0.113.0/24"
action = "allow"
}

private_key_pem — write-only атрибут: провайдер передаёт ключ в API, но не сохраняет его в state.

Шлюз​

resource "tuna_domain" "api" {
subdomain = "myapp-api"
location = "ru"
}

resource "tuna_gateway" "api" {
domain_id = tuna_domain.api.id
policy = file("${path.module}/policy.yaml")
}

В policy.yaml лежит политика трафика. Домен со шлюзом занят шлюзом: туннель на нём не запустится, сервер ответит Domain already reserved by gateway. Для туннеля резервируйте отдельный домен.

Изменение ресурсов​

В API нет редактирования эндпоинтов, доменов, доменных зон и временных токенов, поэтому любое изменение их атрибутов (включая alias или description) пересоздаёт ресурс. У временного токена при этом меняется значение: туннели со старым токеном придётся перезапустить.

Шлюзы, IP-политики и их правила обновляются на месте. Правило пересоздаётся только при смене ip_policy_id.

Импорт​

Существующие ресурсы импортируются по числовому ID из личного кабинета или API:

terraform import tuna_domain.app 123
terraform import tuna_gateway.api 123

У правила IP-политики составной ID <ip_policy_id>/<rule_id>:

terraform import tuna_ip_policy_rule.office_allow 123/456

API не возвращает приватный ключ сертификата, поэтому после импорта tuna_tls_certificate задайте private_key_pem в конфигурации.