Метааргумент providers модуля
В блоке вызова модуля необязательный метааргумент providers задаёт, какие конфигурации провайдеров из родительского модуля будут доступны внутри дочернего модуля.
# The default "aws" configuration is used for AWS resources in the root
# module where no explicit provider instance is selected.
provider "aws" {
region = "us-west-1"
}
# An alternate configuration is also defined for a different
# region, using the alias "usw2".
provider "aws" {
alias = "usw2"
region = "us-west-2"
}
# An example child module is instantiated with the alternate configuration,
# so any AWS resources it defines will use the us-west-2 region.
module "example" {
source = "./example"
providers = {
aws = aws.usw2
}
}Каждый модуль в конфигурации OpenTofu имеет собственное отдельное пространство имён конфигураций провайдеров, но пространство имён дочернего модуля заполняется конфигурациями из корневого модуля: они либо автоматически наследуют конфигурации провайдеров по умолчанию, либо явно передаются из родительского модуля с помощью аргумента providers.
Поведение по умолчанию: наследование провайдеров по умолчанию
Если дочерний модуль не объявляет никаких псевдонимов конфигурации, аргумент providers является необязательным. Если его не указать, дочерний модуль наследует все конфигурации провайдеров по умолчанию родительского модуля. (К конфигурациям провайдеров по умолчанию относятся конфигурации, в которых не используется аргумент alias.)
Если указать аргумент providers, это отменит поведение по умолчанию, и дочерний модуль получит доступ только к указанным вами конфигурациям провайдеров.
Использование и поведение
В аргументе providers используется синтаксис, похожий на синтаксис карты, с фигурными скобками в качестве разделителей ({, }). В указанном сопоставлении:
- Ключи — это адреса конфигураций провайдеров, которые будут использоваться в дочернем модуле.
- Значения — это адреса экземпляров провайдеров из родительского модуля.
В обеих частях используется синтаксис ссылок на экземпляры провайдеров, который для альтернативных конфигураций провайдеров имеет вид <PROVIDER NAME>.<ALIAS>.
В дочернем модуле ресурсы назначаются конфигурациям провайдеров обычным образом: OpenTofu либо выбирает конфигурацию по умолчанию на основе имени типа ресурса, либо ресурс указывает альтернативную конфигурацию с помощью аргумента provider. Если при вызове модуля ему передаётся карта providers, имена конфигураций провайдеров, используемые внутри модуля, фактически переназначаются на указанные конфигурации из родительского модуля.
Когда указывать провайдеры
Есть две основные причины использовать аргумент providers:
- Использование дочерним модулем других конфигураций провайдеров по умолчанию.
- Настройка модуля, которому требуются несколько конфигураций одного и того же провайдера.
Изменение конфигураций провайдеров по умолчанию
Большинство повторно используемых модулей используют только конфигурации провайдеров по умолчанию, которые автоматически наследуются от вызывающего модуля, если аргумент providers не указан.
Однако в конфигурациях OpenTofu, использующих несколько конфигураций одного и того же провайдера, может потребоваться, чтобы одни дочерние модули использовали конфигурацию провайдера по умолчанию, а другие — альтернативную. (Обычно это происходит, когда одна конфигурация используется для управления ресурсами в нескольких регионах одного облачного провайдера.)
Аргумент providers (как в приведённом выше примере кода) позволяет добиться этого, не изменяя дочерний модуль. Хотя код внутри дочернего модуля всегда ссылается на конфигурацию провайдера по умолчанию, фактическая конфигурация по умолчанию может различаться для каждого экземпляра.
Модули с альтернативными конфигурациями провайдеров
В редких случаях одному повторно используемому модулю может потребоваться несколько конфигураций одного и того же провайдера. Например, модулю, настраивающему подключение между сетями в двух регионах AWS, скорее всего, понадобятся исходный и целевой регионы. В таком случае корневой модуль может выглядеть примерно так:
provider "aws" {
alias = "usw1"
region = "us-west-1"
}
provider "aws" {
alias = "usw2"
region = "us-west-2"
}
module "tunnel" {
source = "./tunnel"
providers = {
aws.src = aws.usw1
aws.dst = aws.usw2
}
}Конфигурации провайдеров, отличные от конфигураций по умолчанию, никогда не наследуются автоматически, поэтому для любого модуля, работающего таким образом, всегда потребуется аргумент providers. В документации к модулю должны быть указаны все имена конфигураций провайдеров, которые ему требуются.
Экземпляры модуля с разными экземплярами провайдера
Если вы напишете блок provider с использованием метааргумента for_each, конфигурация провайдера динамически объявит ноль или более экземпляров провайдера.
Если вы также напишете блок module с использованием for_each, вы сможете задать адреса конфигураций провайдеров, ссылающиеся на динамически выбранные экземпляры конфигурации провайдера с несколькими экземплярами. Это позволит создать по одному экземпляру модуля для каждого экземпляра провайдера.
Например, можно создать экземпляр модуля для каждого из нескольких регионов AWS, объявив базовую инфраструктуру во всех используемых регионах. При этом сам модуль будет использовать только одну конфигурацию провайдера по умолчанию, которая будет различаться для каждого экземпляра модуля:
variable "aws_regions" {
type = map(object({
vpc_cidr_block = string
}))
}
provider "aws" {
alias = "by_region"
for_each = var.aws_regions
region = each.key
}
module "per_region" {
source = "./per-region"
# This expression filters var.aws_regions to include only
# the elements whose value is not null. Refer to the
# warning in the text below for more information.
for_each = {
for region, config in var.aws_regions : region => config
if config != null
}
providers = {
aws = aws.by_region[each.key]
}
region_name = each.key
vpc_cidr_block = each.value.vpc_cidr_block
}Модуль в ./per-region следует написать так, чтобы все ресурсы AWS в нём были связаны с конфигурацией провайдера AWS по умолчанию этого модуля. Аргумент providers в блоке module гарантирует, что конфигурация провайдера AWS по умолчанию для каждого экземпляра модуля будет связана с отдельным экземпляром aws.by_region.
Все экземпляры модуля должны ссылаться на экземпляры одной и той же конфигурации провайдера: между экземплярами модуля может меняться только выражение в квадратных скобках (each.key в примере выше).
Выражение for_each для ресурса не должно в точности совпадать с выражением for_each для связанной с ним конфигурации провайдера.
OpenTofu использует экземпляр провайдера для планирования и выполнения всех действий, связанных с экземпляром ресурса, включая удаление экземпляра ресурса, исключённого из конфигурации.
Поэтому экземпляр провайдера, переданный дочернему модулю, который объявит связанные с ним ресурсы, должен оставаться в конфигурации как минимум ещё один цикл планирования и применения после удаления экземпляра модуля. В противном случае OpenTofu не сможет спланировать удаление экземпляров ресурсов, объявленных в модуле.
Подробнее об этом ограничении см. в разделе Ссылки на экземпляры провайдеров.
Дополнительная информация для разработчиков модулей
Подробные сведения и рекомендации по работе с провайдерами внутри повторно используемого дочернего модуля см. в разделе Разработка модулей: провайдеры внутри модулей.
Copyright (c) The OpenTofu Authors
Copyright (c) 2014 HashiCorp, Inc.
Mozilla Public License, version 2.0
https://opentofu.org/docs/v1.9/language/meta-arguments/module-providers/