# Откуда Terraform берёт значения переменных _Переменные и outputs · TerraformLab Knowledge Base_ **TL;DR:** Источников шесть с приоритетом: -var в CLI > -var-file > *.auto.tfvars (по алфавиту) > terraform.tfvars > env TF_VAR_* > default. Если значения нет нигде. Terraform спросит интерактивно. Понимание приоритета критично для CI/CD. ## Шесть источников значений Terraform читает значения переменных из нескольких мест. От **высокого** приоритета к низкому: 1. **`-var` в CLI**, `terraform plan -var="env=prod"`. Перебивает всё. 2. **`-var-file` в CLI**, `terraform plan -var-file=prod.tfvars`. Если несколько `-var-file`, последний выигрывает. 3. **`*.auto.tfvars` и `*.auto.tfvars.json`**, все файлы с этим суффиксом в корне проекта, читаются автоматически. **В алфавитном порядке**, последний по алфавиту выигрывает при коллизии. 4. **`terraform.tfvars` и `terraform.tfvars.json`**, фиксированное имя, читается автоматически. 5. **Env-переменные `TF_VAR_*`**, `export TF_VAR_env=prod` затем `terraform plan`. 6. **`default` в блоке variable**. Это самый низкий приоритет, fallback. Если ничего из вышеперечисленного не задано и нет `default`. Terraform спросит интерактивно в терминале. ## Пример приоритета Допустим, переменная объявлена так: ```hcl variable "env" { type = string default = "dev" } ``` Что увидит Terraform в разных ситуациях: | Источники | Значение `var.env` | |---|---| | Ничего | `"dev"` (из default) | | `export TF_VAR_env=staging` | `"staging"` | | `TF_VAR_env=staging` + `terraform.tfvars` содержит `env = "prod"` | `"prod"` (.tfvars перебил env) | | Всё вышеперечисленное + `-var-file=temp.tfvars` где `env = "qa"` | `"qa"` | | Всё + `-var="env=hotfix"` | `"hotfix"` | Правило простое: **что ближе к CLI, то выиграет**. ## Когда что использовать - **`default`**, для значений, которые редко меняются и подходят 90% случаев. Регион AWS, instance type small. - **`terraform.tfvars`**, основные значения для проекта. **Часто** добавляют в `.gitignore`, потому что там бывают токены и секреты. - **`*.auto.tfvars`**, конфигурация по окружениям если без `-var-file`. Например, `dev.auto.tfvars` загрузится автоматически в dev-папке. - **`-var-file`**, для CI/CD: один HCL, разные tfvars для dev/staging/prod. Файл подбирается переменной окружения или флагом. - **`-var`**, для разовых override'ов. «Запусти plan один раз с другим значением, не меняя файлы». - **`TF_VAR_*`**, для CI: секреты, которые нельзя в git. CI-система кладёт их в env. ## TF_VAR_*, особенности Префикс `TF_VAR_` + имя переменной: ```bash export TF_VAR_env=prod export TF_VAR_db_password="$(vault read -field=password kv/prod/db)" terraform plan ``` Если переменная типа `string` или `number` или `bool`, значение env идёт как есть. Если переменная типа `list` или `map`, env-значение должно быть **JSON**: ```bash export TF_VAR_tags='{"env": "prod", "team": "platform"}' export TF_VAR_azs='["us-east-1a", "us-east-1b"]' ``` Регистр имени важен: `TF_VAR_my_var` ≠ `TF_VAR_MY_VAR`. ## auto.tfvars vs .tfvars, нюанс Файл `terraform.tfvars`. Это единственное фиксированное имя. Файлы `*.auto.tfvars`, любое имя с этим суффиксом. Зачем разделение? - `terraform.tfvars`. Это основной набор; часто в .gitignore. - `dev.auto.tfvars`, `staging.auto.tfvars`, `prod.auto.tfvars`, окружения; **обычно коммитятся**. Подгружаются все сразу, но в одной workspace должна быть только нужная. Альтернативный подход, держать файлы окружений в отдельных папках, без auto-суффикса, передавать через `-var-file=envs/prod.tfvars`. Это проще для CI. ## Подводные камни - **`*.auto.tfvars` подгружаются ВСЕ.** Если у вас в корне `dev.auto.tfvars` и `prod.auto.tfvars` одновременно, оба читаются, последний по алфавиту перебивает. Это часто не то, что хочет автор. - **terraform.tfvars в git, частая утечка секретов.** Если кладёте туда токены, обязательно `.gitignore`. Не полагайтесь на «никто не посмотрит». - **Не передавайте секреты через `-var`.** Это попадёт в shell history. Используйте `TF_VAR_*` через `read -s` или вытащите через secrets-manager. - **JSON для сложных типов в env.** Если объявили `type = list(string)` и попробовали `TF_VAR_x=us-east-1`. Terraform не парсит это как list, упадёт. Нужно `TF_VAR_x='["us-east-1"]'`. - **Интерактивный ввод, не для CI.** Если в CI забыли передать переменную, Terraform зависнет на вопросе и пайплайн встанет навсегда. Лечится `-input=false` (упадёт с понятной ошибкой вместо ожидания). ## Команды ```bash terraform plan -var='env=prod' -var='region=us-east-1' ``` Несколько -var флагов: каждый своя переменная. ```bash terraform plan -var-file=envs/prod.tfvars ``` Подгрузить файл с переменными конкретного окружения. ```bash TF_VAR_env=prod TF_VAR_region=us-east-1 terraform plan ``` Через env. Удобно в CI: секреты приходят как переменные окружения. ```bash terraform plan -input=false ``` Запретить интерактивные вопросы. В CI обязательно. ## См. также - [Блок variable: вход в конфигурацию](/terraform/kb/tf-variable.md) - [.tfvars: файлы со значениями переменных](/terraform/kb/tf-tfvars.md)