docs: примеры DNS-зон и записей (карта зон + N зон в цикле)

This commit is contained in:
Repinoid
2026-10-16 15:50:50 +03:00
parent 4ebfa414bd
commit 42048d058a
14 changed files with 334 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "tf-registry.containerk8s.services.ngcloud.ru/nubes-test/nubes" {
version = "3.4.0"
constraints = "3.4.0"
hashes = [
"h1:7wpWUTAHpddZXHiecwezW5qaNq17WJLTEnE/kF8lNN4=",
]
}
+40
View File
@@ -0,0 +1,40 @@
# DNS-зоны и записи через Terraform
Пример: доменные зоны компании и записи в них — целиком через Terraform.
Зоны задаются картой `var.zones` (`for_each`), записи — вложенным циклом
(`flatten` + `for_each`).
## Ресурсы
| Ресурс | Сервис | Назначение |
|---|---|---|
| `nubes_zones_v2` | 109 | DNS-зона |
| `nubes_zones_v2_record` | подресурс зоны | Запись внутри зоны (A / CNAME / …) |
## Что в конфиге
- N зон из `var.zones` (по умолчанию 2: `tfzone-a.test`, `tfzone-b.test`);
- по 3 записи в каждой зоне (`A`, `A`, `CNAME`).
Чтобы добавить/убрать зону или запись — правьте `var.zones`, затем `apply`.
## Как запустить
```bash
cp terraform.tfvars.example terraform.tfvars # подставить api_endpoint (если нужно)
# api_token — в secrets.auto.tfvars (НЕ в terraform.tfvars!)
terraform init
terraform plan
terraform apply # запускает пользователь
```
## Проверки
- После `apply` повторный `plan` должен давать `No changes`.
- Изменение значения записи → обычный `apply` (поле `record_input` модифицируемое).
- Чтобы зона работала в интернете, домен у регистратора надо делегировать на NS
`ns3.ngcloud.ru` / `ns4.ngcloud.ru`.
## См. также
- `../dns_zones_generated/` — тот же сценарий, но N зон генерируются программно.
+45
View File
@@ -0,0 +1,45 @@
# =============================================================================
# Пример: доменные зоны компании и записи в них — через Terraform.
#
# Ресурсы провайдера Nubes:
# - nubes_zones_v2 (сервис 109) — DNS-зона;
# - nubes_zones_v2_record (подресурс зоны, record) — запись внутри зоны.
#
# ⚠️ Имя поля в HCL = `name` из схемы (snake_case); `code` (camelCase) — имя в API.
#
# Зоны задаются картой `var.zones` (ключ → zone_name + records).
# Чтобы добавить/убрать зону или запись — правьте `var.zones` и делайте `apply`.
# =============================================================================
locals {
# Плоская карта записей «зона:имя» (вложенный цикл → merge/flatten),
# чтобы `for_each` у записей давал стабильные адреса.
records = merge([
for zk, z in var.zones : {
for rk, r in z.records :
"${zk}:${rk}" => {
zone = zk
name = rk
type = r.type
values = r.values
}
}
]...)
}
# Зоны: N штук из var.zones (for_each по ключам карты — стабильные адреса).
resource "nubes_zones_v2" "zone" {
for_each = var.zones
resource_name = "dns-zone-${each.key}"
zone_name = each.value.zone_name
}
# Записи: record_input = [{record=<значение>}, ...] из списка values.
resource "nubes_zones_v2_record" "record" {
for_each = local.records
zones_v2_id = nubes_zones_v2.zone[each.value.zone].id
record_name = each.value.name
record_type = each.value.type
record_input = jsonencode([for v in each.value.values : { record = v }])
record_ttl = 3600
}
+4
View File
@@ -0,0 +1,4 @@
provider "nubes" {
api_token = var.api_token
api_endpoint = var.api_endpoint
}
+15
View File
@@ -0,0 +1,15 @@
# Копировать в terraform.tfvars и подставить значения.
# ⚠️ api_token — СЕКРЕТ: сюда НЕ класть. Держите в отдельном secrets.auto.tfvars
# (формат: api_token = "<JWT>"). Оба файла (*.tfvars) закрыты в .gitignore.
api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc"
# Зоны задаются переменной `zones` (карта: ключ → zone_name + records).
# Дефолт — в variables.tf; здесь можно переопределить, напр.:
#
# zones = {
# a = { zone_name = "tfzone-a.test", records = {
# www = { type = "A", values = ["10.0.0.1", "10.0.0.2"] }
# cdn = { type = "CNAME", values = ["www.tfzone-a.test."] }
# } }
# }
+44
View File
@@ -0,0 +1,44 @@
# Переменные примера. api_token — СЕКРЕТ, держать в secrets.auto.tfvars (не коммитить).
variable "api_token" {
description = "Nubes API token (JWT). Секрет — в secrets.auto.tfvars."
type = string
sensitive = true
}
variable "api_endpoint" {
description = "API Gateway URL стенда"
type = string
default = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc"
}
# Зоны: карта «короткое имя → { zone_name, records }».
# records — карта «имя записи → { type, values }».
variable "zones" {
description = "Зоны компании: имя + записи (type / values[])"
type = map(object({
zone_name = string
records = map(object({
type = optional(string, "A")
values = list(string)
}))
}))
default = {
a = {
zone_name = "tfzone-a.test"
records = {
www = { type = "A", values = ["10.0.0.77", "203.0.113.14"] }
api = { type = "A", values = ["192.168.3.14", "10.0.0.2"] }
cdn = { type = "CNAME", values = ["www.tfzone-a.test."] }
}
}
b = {
zone_name = "tfzone-b.test"
records = {
www = { type = "A", values = ["172.16.5.20", "10.0.0.9"] }
api = { type = "A", values = ["10.0.0.8", "198.51.100.7"] }
cdn = { type = "CNAME", values = ["www.tfzone-b.test."] }
}
}
}
}
+10
View File
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.5.0"
required_providers {
nubes = {
source = "tf-registry.containerk8s.services.ngcloud.ru/nubes-test/nubes"
version = "3.4.0"
}
}
}
+10
View File
@@ -0,0 +1,10 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "tf-registry.containerk8s.services.ngcloud.ru/nubes-test/nubes" {
version = "3.4.0"
constraints = "3.4.0"
hashes = [
"h1:7wpWUTAHpddZXHiecwezW5qaNq17WJLTEnE/kF8lNN4=",
]
}
+47
View File
@@ -0,0 +1,47 @@
# N DNS-зон, сгенерированных программно (в цикле)
Пример-близнец `../dns_zones/`, но здесь зоны **не задаются вручную**, а
генерируются из числа `var.zone_count`:
```hcl
zones = {
for i in range(1, var.zone_count + 1) :
"${var.zone_prefix}-${i}" => {
zone_name = "${var.zone_prefix}-${i}.${var.zone_domain}"
records = { www = ..., api = ... }
}
}
```
Удобно, когда зон много и они однотипны (напр. 10 зон `tfzone-1 … tfzone-10`).
## Ресурсы
| Ресурс | Сервис | Назначение |
|---|---|---|
| `nubes_zones_v2` | 109 | DNS-зона |
| `nubes_zones_v2_record` | подресурс зоны | Запись внутри зоны (A / CNAME / …) |
## Разница с `../dns_zones/`
| | `dns_zones` | `dns_zones_generated` |
|---|---|---|
| Источник зон | явная карта `var.zones` | `range(1, zone_count+1)` в `locals` |
| Когда удобно | разный набор зон/записей | много однотипных зон |
## Как запустить
```bash
cp terraform.tfvars.example terraform.tfvars # при желании: zone_count = N
# api_token — в secrets.auto.tfvars (НЕ в terraform.tfvars!)
terraform init
terraform plan
terraform apply # запускает пользователь
```
## Проверки
- После `apply` повторный `plan` должен давать `No changes`.
- Изменение `zone_count` добавляет/убирает зоны (стабильные адреса `for_each`).
- Чтобы зоны работали в интернете, домен у регистратора надо делегировать на NS
`ns3.ngcloud.ru` / `ns4.ngcloud.ru`.
+54
View File
@@ -0,0 +1,54 @@
# =============================================================================
# Пример: N DNS-зон генерируются ПРОГРАММНО (в цикле) — через Terraform.
#
# Отличие от ../dns_zones/: там зоны заданы явной картой `var.zones`,
# а здесь зоны генерируются из числа `var.zone_count` через `range(...)`.
# Удобно, когда зон много и они однотипны (tfzone-1 … tfzone-N).
#
# Ресурсы: nubes_zones_v2 (109) + подресурс nubes_zones_v2_record (записи).
# ⚠️ Имя поля в HCL = `name` из схемы (snake_case).
# =============================================================================
locals {
# N зон генерируются программно: tfzone-1 … tfzone-N.
zones = {
for i in range(1, var.zone_count + 1) :
"${var.zone_prefix}-${i}" => {
zone_name = "${var.zone_prefix}-${i}.${var.zone_domain}"
records = {
www = { type = "A", values = ["10.0.${i}.1"] }
api = { type = "A", values = ["10.0.${i}.2"] }
}
}
}
# Плоская карта записей «зона:имя» (вложенный цикл → merge/flatten).
records = merge([
for zk, z in local.zones : {
for rk, r in z.records :
"${zk}:${rk}" => {
zone = zk
name = rk
type = r.type
values = r.values
}
}
]...)
}
# Зоны: N штук, сгенерированных в locals (for_each по ключам — стабильные адреса).
resource "nubes_zones_v2" "zone" {
for_each = local.zones
resource_name = "dns-zone-${each.key}"
zone_name = each.value.zone_name
}
# Записи: record_input = [{record=<значение>}, ...] из списка values.
resource "nubes_zones_v2_record" "record" {
for_each = local.records
zones_v2_id = nubes_zones_v2.zone[each.value.zone].id
record_name = each.value.name
record_type = each.value.type
record_input = jsonencode([for v in each.value.values : { record = v }])
record_ttl = 3600
}
+4
View File
@@ -0,0 +1,4 @@
provider "nubes" {
api_token = var.api_token
api_endpoint = var.api_endpoint
}
@@ -0,0 +1,10 @@
# Копировать в terraform.tfvars и подставить значения.
# ⚠️ api_token — СЕКРЕТ: сюда НЕ класть. Держите в отдельном secrets.auto.tfvars
# (формат: api_token = "<JWT>"). Оба файла (*.tfvars) закрыты в .gitignore.
api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc"
# Сколько зон сгенерировать (tfzone-1 … tfzone-N):
zone_count = 10
zone_prefix = "tfzone"
zone_domain = "test"
+31
View File
@@ -0,0 +1,31 @@
# Переменные примера. api_token — СЕКРЕТ, держать в secrets.auto.tfvars.
variable "api_token" {
description = "Nubes API token (JWT). Секрет — в secrets.auto.tfvars."
type = string
sensitive = true
}
variable "api_endpoint" {
description = "API Gateway URL стенда"
type = string
default = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc"
}
variable "zone_count" {
description = "Сколько зон сгенерировать (tfzone-1 … tfzone-N)"
type = number
default = 10
}
variable "zone_prefix" {
description = "Префикс имени зоны"
type = string
default = "tfzone"
}
variable "zone_domain" {
description = "Домен зон (суффикс FQDN)"
type = string
default = "test"
}
+10
View File
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.5.0"
required_providers {
nubes = {
source = "tf-registry.containerk8s.services.ngcloud.ru/nubes-test/nubes"
version = "3.4.0"
}
}
}