Terraform провайдер / разделение переменных в модулях
Есть ли способ абстрагирования поставщика для всех модулей, определенных в проекте.
например, у меня есть этот проект
├── modules
│ ├── RDS
│ └── VPC
└── stacks
├── production
│ └── main.tf
└── staging
└── main.tf
и работает нормально... проблема с определением модулей
├── RDS
│ ├── README.md
│ ├── main.tf
│ ├── providers.tf
│ └── variables.tf
└── VPC
├── README.md
├── main.tf
├── providers.tf
└── variables.tf
провайдер в обоих этих модулях точно такой же
# providers.tf
provider "aws" {
region = "${var.region}"
version = "~> 1.26"
}
и переменные в каждом модуле разные, но все они имеют region
переменная.
# variables.tf
variable "region" {
default = "eu-central-1"
description = "AWS region."
}
# other module dependent variables...
Есть ли способ определить эти биты информации на уровне модулей, так что я получаю что-то вроде этого
├── modules
│ ├── providers.tf <<< include the *shared* provider definition block
│ ├── variables.tf <<< include the *shared* region vaiable definition block
│ ├── RDS
│ │ ├── README.md
│ │ ├── main.tf
│ │ └── variables.tf
│ └── VPC
│ ├── README.md
│ ├── main.tf
│ └── variables.tf
И последнее: определения модулей в большинстве случаев имеют атрибут ресурса (извлечение модуля из реестра terraform... поэтому я не знаю, возможно ли унаследовать как источник из реестра, так и базовый модуль)
3 ответа
Сейчас это невозможно сделать. Ранее на github обсуждались такие же темы в следующих выпусках:
- https://github.com/hashicorp/terraform/issues/5480
- https://github.com/hashicorp/terraform/issues/4585
- https://github.com/hashicorp/terraform/issues/2714
- https://github.com/hashicorp/terraform/issues/1742
TL; DR
разделение переменных между модулями противоречит принципам ясности / ясности ядра terraform.
Вы можете абстрагировать параметры провайдера от модуля, передав псевдоним провайдера для использования. Это позволяет вам создать модуль без ссылки на такие вещи, как Region, а затем передать эти детали при вызове.
Для вашего случая использования вы можете определить альтернативных провайдеров в ваших папках стека (вероятно, лучше всего определить это в файле и сделать символические ссылки для каждой папки стека):
# stacks/{staging,production}/providers.tf
provider "aws" {
alias = "us-east-1"
region = "us-east-1"
}
provider "aws" {
alias = "us-east-2"
region = "us-east-2"
}
Затем, когда вы вызываете модули, передайте псевдоним провайдера, который вы хотите использовать (предполагается, что модуль использует только 1 из любого конкретного типа провайдера):
# stacks/{staging,production}/main.tf
module "VPC-us-east-1" {
source = "../../modules/VPC"
providers = {
aws = "aws.us-east-1"
}
}
module "VPC-us-east-2" {
source = "../../modules/VPC"
providers = {
aws = "aws.us-east-2"
}
}
Если вы знаете terragrunt, это не будет проблемой вообще.
Terragrunt - это тонкая оболочка для Terraform, которая предоставляет дополнительные инструменты для работы с несколькими модулями Terraform.
Он предназначен для решения проблемы, с которой вы только что столкнулись.
account
└ _global
└ region
└ _global
└ environment
└ resource
Быстрый старт
Посмотрите https://github.com/gruntwork-io/terragrunt-infrastructure-modules-example и https://github.com/gruntwork-io/terragrunt-infrastructure-live-example для полностью работающего примера кода, демонстрирующего эти функции
ты можешь использовать prod/terraform.tfvars
или же prod/account.tfvars
для глобальных переменных или поместите файл tfvars в _global
папка.
В настоящее время для языка конфигурации Hashicorp нет функции глобальных переменных.
А также variables
используются для определения интерфейсов модулей модулей или действуют как переменные ENV (inline ENV). Итак, это не лучший способ использовать переменную как глобальную. Потому что каждый раз, когда вы определяете какие-то модули, вам всегда нужно думать о том, какие переменные вы использовали в верхних модулях. И, вероятно, вы закончите так:first_module_s3_bucket_name
, second_module_s3_bucket_name
.
Но locals
имеет смысл делиться с дочерними модулями. Потому что местные жители считают, что это помогает избежать повторения одного и того же значения.
Если вам интересно, есть новое обсуждение запроса функции Hashicorp.