Входные переменные
Входные переменные позволяют настраивать отдельные аспекты модулей, не изменяя исходный код самого модуля. Благодаря этой возможности модули можно использовать в разных конфигурациях 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 в интерфейсе командной строки, когда переменная используется в конфигурации. -
nullable— задаёт, может ли переменная иметь значениеnullв модуле.
Значения по умолчанию
Объявление переменной также может содержать аргумент 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]Запрет нулевых входных значений
Аргумент 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.
Использование значений входных переменных
Внутри модуля, в котором объявлена переменная, к её значению можно обращаться в выражениях как к 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.9/language/values/variables/