Входные переменные
Входные переменные позволяют настраивать аспекты модулей, не изменяя исходный код самого модуля. Эта функциональность позволяет использовать модули в разных конфигурациях OpenTofu, делая их комбинируемыми и повторно используемыми.
Когда вы объявляете переменные в корневом модуле конфигурации, их значения можно задавать с помощью параметров CLI и переменных среды. Когда вы объявляете их в дочерних модулях, вызывающий модуль должен передать значения в блоке module.
Если вы знакомы с традиционными языками программирования, полезно сравнить модули с определениями функций:
- Входные переменные подобны аргументам функции.
- Выходные значения подобны возвращаемым значениям функции.
- Локальные значения подобны временным локальным переменным функции.
Для краткости входные переменные часто называют просто «переменными» или «переменными OpenTofu», если из контекста понятно, о каком типе переменных идет речь. К другим типам переменных в OpenTofu относятся переменные среды (задаваемые оболочкой, в которой работает OpenTofu) и переменные выражений (используемые для косвенного представления значения в выражении).
Объявление входной переменной
Каждая входная переменная, принимаемая модулем, должна быть объявлена с помощью блока variable:
variable "image_id" {
type = string
}
variable "availability_zone_names" {
type = list(string)
default = ["us-west-1a"]
}
variable "docker_ports" {
type = list(object({
internal = number
external = number
protocol = string
}))
default = [
{
internal = 8300
external = 8300
protocol = "tcp"
}
]
}Метка после ключевого слова variable — это имя переменной, которое должно быть уникальным среди всех переменных в одном модуле. Это имя используется для присвоения переменной значения извне и для обращения к значению переменной внутри модуля.
Имя переменной может быть любым допустимым идентификатором, кроме следующих: source, version, providers, count, for_each, lifecycle, depends_on, locals.
Эти имена зарезервированы для метааргументов в блоках конфигурации модуля и не могут использоваться в качестве имен переменных.
Аргументы
OpenTofu CLI определяет следующие необязательные аргументы для объявлений переменных:
-
default— значение по умолчанию, которое делает переменную необязательной. -
type— этот аргумент задает типы значений, допустимые для переменной. -
description— этот аргумент задает документацию входной переменной. -
validation— блок для определения правил проверки, обычно дополняющих ограничения типа. -
sensitive— ограничивает вывод OpenTofu в интерфейсе CLI, когда переменная используется в конфигурации. -
ephemeral— ограничивает использование переменной эфемерными контекстами. -
nullable— указывает, может ли переменная иметь значениеnullв модуле. -
deprecated— помечает переменную как устаревшую, чтобы предупредить вызывающие стороны о необходимости миграции. -
const— значение должно быть константным (вычисляться без состояния).
Значения по умолчанию
Объявление переменной также может содержать аргумент default. Если он указан, переменная считается необязательной, и значение по умолчанию будет использоваться, если при вызове модуля или запуске OpenTofu не задано никакое значение. Аргумент default должен содержать литеральное значение и не может ссылаться на другие объекты конфигурации.
Ограничения типа
Аргумент type в блоке variable позволяет ограничить тип значения, принимаемого в качестве значения переменной. Если ограничение типа не задано, допускается значение любого типа.
Хотя ограничения типа необязательны, мы рекомендуем указывать их: они могут служить полезными напоминаниями для пользователей модуля и позволяют OpenTofu выдавать понятное сообщение об ошибке, если используется значение неправильного типа.
Ограничения типа составляются из сочетания ключевых слов типов и конструкторов типов. Поддерживаются следующие ключевые слова типов:
stringnumberbool
Конструкторы типов позволяют задавать сложные типы, например коллекции:
list(<TYPE>)set(<TYPE>)map(<TYPE>)object({<ATTR NAME> = <TYPE>, ... })tuple([<TYPE>, ...])
Ключевое слово any можно использовать, чтобы указать, что допустим любой тип. Подробнее о значении и поведении этих типов, а также об автоматическом преобразовании сложных типов см. в разделе Ограничения типа.
Если указаны аргументы type и default, значение по умолчанию должно быть преобразуемо в указанный тип.
Документация входных переменных
Поскольку входные переменные модуля являются частью его пользовательского интерфейса, назначение каждой переменной можно кратко описать с помощью необязательного аргумента description:
variable "image_id" {
type = string
description = "The id of the machine image (AMI) to use for the server."
}Описание должно кратко пояснять назначение переменной и указывать, какое значение ожидается. Эта строка описания может быть включена в документацию модуля, поэтому ее следует писать с точки зрения пользователя модуля, а не его сопровождающего. Для пояснений сопровождающим модуля используйте комментарии.
Пользовательские правила проверки
Для конкретной переменной можно задать пользовательские правила проверки, добавив блок validation в соответствующий блок variable. Пример ниже проверяет правильность синтаксиса идентификатора AMI.
variable "image_id" {
type = string
description = "The id of the machine image (AMI) to use for the server."
validation {
condition = length(var.image_id) > 4 && substr(var.image_id, 0, 4) == "ami-"
error_message = "The image_id value must be a valid AMI id, starting with \"ami-\"."
}
}Подробнее см. в разделе Проверки пользовательских условий.
Скрытие значений в выводе CLI
Пометка переменной как sensitive не позволяет OpenTofu показывать ее значение в выводе plan или apply, когда эта переменная используется в другом месте конфигурации.
OpenTofu по-прежнему будет сохранять конфиденциальные значения в состоянии, поэтому любой, кто имеет доступ к данным состояния, сможет увидеть конфиденциальные значения в открытом виде. Подробнее см. в разделе Конфиденциальные данные в состоянии.
Объявите переменную конфиденциальной, присвоив аргументу sensitive значение true:
variable "user_information" {
type = object({
name = string
address = string
})
sensitive = true
}
resource "some_resource" "a" {
name = var.user_information.name
address = var.user_information.address
}Любые выражения, результат которых зависит от конфиденциальной переменной, также будут считаться конфиденциальными, поэтому в приведенном выше примере два аргумента resource "some_resource" "a" также будут скрыты в выводе плана:
OpenTofu will perform the following actions:
# some_resource.a will be created
+ resource "some_resource" "a" {
+ name = (sensitive value)
+ address = (sensitive value)
}
Plan: 1 to add, 0 to change, 0 to destroy.В некоторых случаях, если конфиденциальная переменная используется во вложенном блоке, OpenTofu может скрыть весь блок. Это происходит для типов ресурсов, где все блоки определенного типа должны быть уникальными, и раскрытие содержимого одного блока может подразумевать содержимое соседнего блока.
# some_resource.a will be updated in-place
~ resource "some_resource" "a" {
~ nested_block {
# At least one attribute in this block is (or was) sensitive,
# so its contents will not be displayed.
}
}Провайдер также может объявить атрибут конфиденциальным. В этом случае OpenTofu будет скрывать его в обычном выводе независимо от того, какое значение ему присвоено. Подробнее см. в разделе Конфиденциальные атрибуты ресурсов.
Если вы используете конфиденциальное значение в составе выходного значения, OpenTofu потребует также пометить само выходное значение как конфиденциальное, чтобы подтвердить, что вы намерены его экспортировать.
Случаи, в которых OpenTofu может раскрыть конфиденциальную переменную
Переменная sensitive — это концепция, относящаяся к конфигурации, а значения передаются провайдерам без какого-либо сокрытия. Ошибка провайдера может раскрыть значение, если оно включено в сообщение об ошибке. Например, провайдер может вернуть следующую ошибку, даже если «foo» — конфиденциальное значение: "Invalid value 'foo' for field"
Если атрибут ресурса используется как идентификатор ресурса, определяемый провайдером, или является его частью, apply раскроет это значение. В примере ниже атрибут prefix задан конфиденциальной переменной, но затем это значение («jae») раскрывается как часть идентификатора ресурса:
# random_pet.animal will be created
+ resource "random_pet" "animal" {
+ id = (known after apply)
+ length = 2
+ prefix = (sensitive value)
+ separator = "-"
}
Plan: 1 to add, 0 to change, 0 to destroy.
...
random_pet.animal: Creating...
random_pet.animal: Creation complete after 0s [id=jae-known-mongoose]Эфемерность
Пометка переменной как ephemeral ограничивает ее использование следующими эфемерными контекстами:
- Эфемерные ресурсы
- Эфемерные переменные
- Эфемерные выходные значения
- Локальные значения
- Провайдеры
- Провижионеры
- Блоки
connectionресурсов - Атрибуты
write-onlyресурсов
OpenTofu вообще не будет сохранять значения эфемерных переменных в состоянии. Для дальнейшей обработки при применении в плане будут сохранены только имена переменных.
Объявите переменную эфемерной, присвоив аргументу ephemeral значение true:
variable "user_password" {
type = string
ephemeral = true
}Любые выражения, результат которых зависит от эфемерной переменной, также будут считаться эфемерными.
locals {
sanitized = trimspace(var.user_password) # `sanitized` is an ephemeral local now
}Если вы используете эфемерное значение в составе выходного значения, OpenTofu потребует также настроить блок выходного значения как эфемерный.
Эфемерные переменные корневых модулей требуют особого внимания при работе с -var/-var-file. См. документацию tofu apply
Запрет значений null для входных переменных
Аргумент nullable в блоке переменной определяет, может ли вызывающий модуль присвоить переменной значение null.
variable "example" {
type = string
nullable = false
}Значение по умолчанию для nullable — true. Если nullable имеет значение true, null является допустимым значением переменной, и конфигурация модуля всегда должна учитывать возможность того, что значение переменной равно null. Передача значения null в качестве входного аргумента модуля переопределит любое значение default.
Значение nullable, равное false, гарантирует, что значение переменной никогда не будет null внутри модуля. Если nullable имеет значение false, а у переменной есть значение default, OpenTofu использует значение по умолчанию, если входному аргументу модуля присвоено null.
Аргумент nullable регулирует только то, где прямому значению переменной может быть присвоено null. Для переменных с типами коллекций или структурными типами, например списков или объектов, вызывающая сторона по-прежнему может использовать null во вложенных элементах или атрибутах, если сама коллекция или структура не равна null.
Пометка переменной как устаревшей
Аргумент deprecated в блоке переменной указывает на то, что она устарела и в будущем может быть удалена. Этот атрибут должен содержать непустую строку с инструкциями по отказу от использования этой переменной. Пример конфигурации:
variable "examle" {
type = string
deprecated = "'examle' variable must no longer be used due to a typo, use 'example' instead"
}Вызывающая сторона модуля получит предупреждение, если в ее конфигурации используется устаревшая переменная:
│ Warning: Variable marked as deprecated by the module author │ │ on main.tf line 3, in module "mod": │ 3: examle = "a" │ │ Variable "examle" is marked as deprecated with the following message: │ 'examle' variable must no longer be used due to a typo, use 'example' instead
Предупреждения об устаревании можно фильтровать или отключать с помощью аргумента CLI -deprecation. По умолчанию предупреждения об устаревших переменных модулей объединяются по имени переменной и сообщению об устаревании. Если два разных модуля используют подмодуль с устаревшей переменной, они будут показаны вместе. Чтобы увидеть их по отдельности, можно использовать -consolidation-warnings=false. Подробнее см. описание этого параметра в списке параметров команд plan и apply.
Пометка переменной как константной
Аргумент const = true в блоке переменной указывает, что ее значение должно вычисляться без доступа к состоянию. Благодаря этому переменную можно использовать как константное значение при вычислении источников модулей и бэкендов.
Противоположный аргумент const = false запрещает использовать переменную в любом из перечисленных выше контекстов вычисления и явно объявляет ее «неконстантной» независимо от указанного значения или выражения.
Если аргумент не указан, OpenTofu анализирует конфигурацию, чтобы определить, можно ли использовать указанное для переменной выражение или значение как константу.
variable "dependency_version" {
type = string
const = true
}
module "my_mod" {
source = "my-module-source"
version = var.dependency_version
}Использование значений входных переменных
В модуле, объявившем переменную, к ее значению можно обращаться из выражений как var.<NAME>, где <NAME> соответствует метке, указанной в блоке объявления:
Входные переменные создаются блоком variable, но обращаться к ним нужно как к атрибутам объекта с именем var.
resource "aws_instance" "example" {
instance_type = "t2.micro"
ami = var.image_id
}Присвоенное переменной значение доступно только в выражениях модуля, в котором она была объявлена.
Присвоение значений переменным корневого модуля
Если переменные объявлены в корневом модуле конфигурации, задать их можно несколькими способами:
- По отдельности, с помощью параметра командной строки
-var. - В файлах определений переменных (
.tfvars), указанных в командной строке или загружаемых автоматически. - В качестве переменных среды.
В следующих разделах эти способы описаны подробнее. Этот раздел не относится к дочерним модулям: значения входных переменных для них задаются в конфигурации родительского модуля, как описано в разделе Модули.
Переменные в командной строке
Чтобы задать отдельные переменные в командной строке, используйте параметр -var при запуске команд tofu plan и tofu apply:
tofu apply -var="image_id=ami-abc123"
tofu apply -var='image_id_list=["ami-abc123","ami-def456"]' -var="instance_type=t2.micro"
tofu apply -var='image_id_map={"us-east-1":"ami-abc123","us-east-2":"ami-def456"}'В примерах выше показан подходящий синтаксис для оболочек в стиле Unix, например в Linux или macOS. Подробнее о цитировании в оболочке, включая дополнительные примеры для командной строки Windows, см. в разделе Входные переменные в командной строке.
В одной команде можно использовать параметр -var несколько раз, чтобы задать несколько переменных.
Файлы определений переменных (.tfvars)
Чтобы задать множество переменных, удобнее указать их значения в файле определений переменных (имя файла должно оканчиваться на .tfvars или .tfvars.json), а затем указать этот файл в командной строке с помощью -var-file:
tofu apply -var-file="testing.tfvars"
В файлах определений переменных используется тот же базовый синтаксис, что и в файлах языка OpenTofu, но они содержат только присваивания значений именам переменных:
image_id = "ami-abc123" availability_zone_names = [ "us-east-1a", "us-west-1c", ]
Кроме того, OpenTofu автоматически загружает ряд файлов определений переменных, если они существуют:
- Файлы с точными именами
terraform.tfvarsилиterraform.tfvars.json. - Любые файлы, имена которых оканчиваются на
.auto.tfvarsили.auto.tfvars.json.
Файлы, имена которых оканчиваются на .json, разбираются как объекты JSON, свойства корневого объекта соответствуют именам переменных:
{
"image_id": "ami-abc123",
"availability_zone_names": ["us-west-1a", "us-west-1c"]
}Переменные среды
В качестве запасного способа определения переменных OpenTofu ищет в среде собственного процесса переменные среды с именами, начинающимися с TF_VAR_, за которым следует имя объявленной переменной.
Это может быть полезно при запуске OpenTofu в автоматизированной среде или последовательности команд OpenTofu с одними и теми же переменными. Например, в приглашении bash в системе Unix:
$ export TF_VAR_image_id=ami-abc123 $ tofu plan ...
В операционных системах, где имена переменных среды чувствительны к регистру, OpenTofu сопоставляет имя переменной в точности с указанным в конфигурации. Поэтому требуемое имя переменной среды обычно содержит как прописные, так и строчные буквы, как в примере выше.
Значения сложных типов
Если значения переменных задаются в файле определений переменных, для присвоения значений сложных типов, например списков и карт, можно использовать обычный синтаксис литеральных выражений OpenTofu.
Для параметра командной строки -var и переменных среды действуют некоторые особые правила. Для удобства OpenTofu по умолчанию трактует значения -var и переменных среды как литеральные строки, для которых требуется только экранирование в оболочке и не требуется специальное экранирование для OpenTofu. Например, в оболочке в стиле Unix:
$ export TF_VAR_image_id='ami-abc123'
Однако если для переменной корневого модуля с помощью ограничения типа требуется сложное значение (список, множество, карта, объект или кортеж), OpenTofu попытается разобрать его с использованием того же синтаксиса, что и в файлах определений переменных. При этом необходимо внимательно соблюдать правила экранирования строк в оболочке:
$ export TF_VAR_availability_zone_names='["us-west-1b","us-west-1d"]'
Для удобства чтения и чтобы не беспокоиться об экранировании в оболочке, мы рекомендуем всегда задавать значения сложных переменных с помощью файлов определений переменных. Подробнее о кавычках и экранировании аргументов -var см. в разделе Входные переменные в командной строке.
Значения для необъявленных переменных
Если вы задали значение переменной, но не объявили соответствующую переменную с помощью variable {}, в зависимости от способа задания значения может появиться ошибка или предупреждение.
Если вы укажете значения для необъявленных переменных, определённых как переменные окружения, ошибка или предупреждение не появятся. Это связано с тем, что переменные окружения могут быть объявлены, но не использоваться во всех конфигурациях, которые могут быть запущены.
Если вы укажете значения для необъявленных переменных, определённых в файле, появится предупреждение. Это помогает в случаях, когда вы указали значение переменной, предназначенное для объявления переменной, но, возможно, допустили ошибку при определении значения. Например, следующая конфигурация:
variable "moose" {
type = string
}И следующий файл .tfvars:
mosse = "Moose"
Приведут к тому, что OpenTofu предупредит вас об отсутствии объявленной переменной "mosse", что поможет обнаружить эту ошибку.
Если вы используете файлы .tfvars в нескольких конфигурациях и ожидаете, что это предупреждение будет появляться и дальше, можно воспользоваться параметром -compact-warnings, чтобы сделать вывод более кратким.
Если вы укажете значения для необъявленных переменных в командной строке, OpenTofu вернёт ошибку. Чтобы избежать этой ошибки, либо объявите блок переменной для этого значения, либо удалите значение переменной из вызова OpenTofu.
Приоритет определений переменных
Все перечисленные выше способы задания переменных можно использовать вместе в любых сочетаниях. Если одной переменной присвоено несколько значений, OpenTofu использует последнее найденное значение, заменяя все предыдущие. Обратите внимание, что одной переменной нельзя присвоить несколько значений из одного источника.
OpenTofu загружает переменные в следующем порядке; более поздние источники имеют приоритет над более ранними:
- Переменные окружения
- Файл
terraform.tfvars, если он существует. - Файл
terraform.tfvars.json, если он существует. - Все файлы
*.auto.tfvarsили*.auto.tfvars.json, обработанные в лексическом порядке имён файлов. - Все параметры
-varи-var-fileкомандной строки в порядке их указания.
Переменные со значениями типа map и object работают так же, как и другие переменные: последнее найденное значение заменяет предыдущие. Это изменение по сравнению с предыдущими версиями OpenTofu, в которых значения map объединялись, а не заменялись.
Copyright (c) The OpenTofu Authors
Copyright (c) 2014 HashiCorp, Inc.
Mozilla Public License, version 2.0
https://opentofu.org/docs/v1.12/language/values/variables/