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 обсуждались такие же темы в следующих выпусках:

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.

https://github.com/hashicorp/terraform/issues/25431

Другие вопросы по тегам