Terraform提供程序/模块中的变量共享

a14*_*14m 12 terraform terragrunt terraform-provider-aws

有没有一种方法可以为项目中定义的所有模块抽象提供程序。

例如,我有这个项目

??? modules
?   ??? RDS
?   ??? VPC
??? stacks
    ??? production
    ?   ??? main.tf
    ??? staging
        ??? main.tf
Run Code Online (Sandbox Code Playgroud)

而且工作正常...问题在于模块的定义

??? RDS
?   ??? README.md
?   ??? main.tf
?   ??? providers.tf
?   ??? variables.tf
??? VPC
    ??? README.md
    ??? main.tf
    ??? providers.tf
    ??? variables.tf
Run Code Online (Sandbox Code Playgroud)

这两个模块中的提供者完全相同

# providers.tf
provider "aws" {
  region = "${var.region}"
  version = "~> 1.26"
}
Run Code Online (Sandbox Code Playgroud)

并且每个模块中的变量都不同,但是它们都有region变量。

# variables.tf
variable "region" {
  default     = "eu-central-1"
  description = "AWS region."
}
# other module dependent variables...
Run Code Online (Sandbox Code Playgroud)

有没有一种方法可以在模块级别上定义那些信息位,以便最终得到大致类似的内容

??? 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
Run Code Online (Sandbox Code Playgroud)

最后一件事,模块定义大多数时候都具有资源属性(从terraform注册表中拉出一个模块...因此,我不知道从注册表和基本模块继承源是否可行)

a14*_*14m 13

现在不可能实现这一目标。之前在 github 上有关于以下问题的相同主题的讨论:

TL;DR
模块之间的变量共享违反了 terraform 核心清晰度/明确性原则。

变通方法
变通方法是将*shared*文件放在父目录中并使用符号链接将它们添加到模块中。

  • 因此,Terraform 开发人员错过了软件开发的一个核心概念:DRY。瘸。 (3认同)

BMW*_*BMW 6

如果您了解terragrunt,这将完全没有问题。

Terragrunt 是 Terraform 的一个瘦包装器,它提供了额外的工具来处理多个 Terraform 模块。

它专为您刚刚遇到的问题而设计。

account
 ? _global
 ? region
    ? _global
    ? environment
       ? resource
Run Code Online (Sandbox Code Playgroud)

快速开始

查看terragrunt-infrastructure-modules-exampleterragrunt-infrastructure-live-example 存储库以获取演示这些功能的完整示例代码

您可以使用prod/terraform.tfvarsprod/account.tfvars全局变量或将 tfvars 文件放在_global文件夹下。


Eri*_*son 5

您可以通过传入要使用的提供程序别名来从模块中抽象出提供程序参数。这允许您在不参考 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"
}
Run Code Online (Sandbox Code Playgroud)

然后,当您调用模块时,传入您要使用的提供程序别名(假设一个模块仅使用任何特定提供程序类型中的 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"
  }
}
Run Code Online (Sandbox Code Playgroud)