使用 terragrunt generate provider block 导致与模块中的 require providers 块发生冲突
Using terragrunt generate provider block causes conflicts with require providers block in module
我正在使用 Terrag运行t 和 Terraform 版本 0.14.8。
我的项目使用单存储库结构,因为项目要求将 Terrag运行t 文件和 Terraform 模块打包在一个包中。
文件夹结构:
project root:
├── environments
│ └── prd
│ ├── rds-cluster
│ │ └── terragrunt.hcl
│ └── terragrunt.hcl
└── modules
├── rds-cluster
│ ├── README.md
│ ├── main.tf
│ ├── output.tf
│ └── variables.tf
└── secretsmanager-secret
├── README.md
├── main.tf
├── output.tf
└── variables.tf
在 prd/terragrunt.hcl 中,我定义了远程状态块和生成提供程序块。
remote_state {
backend = "s3"
...
}
generate "provider" {
path = "provider.tf"
if_exists = "overwrite_terragrunt"
contents = <<EOF
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
provider "aws" {
region = "ca-central-1"
}
EOF
}
在environments/prd/rds-cluster/terragrunt.hcl中,我定义如下:
include {
path = find_in_parent_folders()
}
terraform {
source = "../../../modules//rds-cluster"
}
inputs = {
...
}
在modules/rds-cluster/main.tf中,我定义如下:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 3.0"
}
}
}
// RDS related resources...
我的问题是,当我尝试 运行 terrag运行t plan under environments/prd/rds-cluster
时,我收到以下错误消息:
Error: Duplicate required providers configuration
on provider.tf line 3, in terraform:
3: required_providers {
A module may have only one required providers configuration. The required
providers were previously configured at main.tf:2,3-21.
我可以通过在 provider 块中声明版本来解决这个问题,如图所示 here. However, the version attribute in provider blocks has been deprecated in Terraform 0.13; Terraform 建议改用 terraform 块下的 required_providers 子块。
有人知道我需要做什么才能为我的 aws 提供商使用新的 required_providers 块吗?
如您所见,Terraform 期望每个模块仅具有其所需提供程序的一个定义,这是为了避免当声明分布在多个文件中时 Terraform 检测特定原因的原因不明确的情况。
但是,为了支持这种零碎的代码生成用例,Terraform 有一个名为 Override Files 的高级功能,它允许您明确标记某些文件以进行不同的处理模式,它们可以选择性地覆盖来自其他文件,而不是创建全新的定义。
此机制的详细信息取决于您覆盖的块类型,但 Merging terraform
blocks` 部分讨论了与您的特定情况相关的行为:
If the required_providers
argument is set, its value is merged on an element-by-element basis, which allows an override block to adjust the constraint for a single provider without affecting the constraints for other providers.
In both the required_version
and required_providers
settings, each override constraint entirely replaces the constraints for the same component in the original block. If both the base block and the override block both set required_version then the constraints in the base block are entirely ignored.
上面的实际含义是,如果您有一个包含 AWS 提供商条目的 required_providers
块的覆盖文件,那么 Terraform 会将其视为已存在的任何类似条目的完全替换在非覆盖文件中,但它不会影响根本没有出现在覆盖文件中的其他供应商要求条目。
将所有这些放在一起,您应该能够通过要求 Terragrunt 将此生成的文件命名为 provider_override.tf
而不是仅仅 provider.tf
来获得您正在寻找的结果,这将激活覆盖文件处理行为,从而允许此生成的文件覆盖 AWS 提供商要求的任何现有定义,同时允许配置保留它们可能也在定义的任何其他提供商要求。
我正在使用 Terrag运行t 和 Terraform 版本 0.14.8。
我的项目使用单存储库结构,因为项目要求将 Terrag运行t 文件和 Terraform 模块打包在一个包中。
文件夹结构:
project root:
├── environments
│ └── prd
│ ├── rds-cluster
│ │ └── terragrunt.hcl
│ └── terragrunt.hcl
└── modules
├── rds-cluster
│ ├── README.md
│ ├── main.tf
│ ├── output.tf
│ └── variables.tf
└── secretsmanager-secret
├── README.md
├── main.tf
├── output.tf
└── variables.tf
在 prd/terragrunt.hcl 中,我定义了远程状态块和生成提供程序块。
remote_state {
backend = "s3"
...
}
generate "provider" {
path = "provider.tf"
if_exists = "overwrite_terragrunt"
contents = <<EOF
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
provider "aws" {
region = "ca-central-1"
}
EOF
}
在environments/prd/rds-cluster/terragrunt.hcl中,我定义如下:
include {
path = find_in_parent_folders()
}
terraform {
source = "../../../modules//rds-cluster"
}
inputs = {
...
}
在modules/rds-cluster/main.tf中,我定义如下:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 3.0"
}
}
}
// RDS related resources...
我的问题是,当我尝试 运行 terrag运行t plan under environments/prd/rds-cluster
时,我收到以下错误消息:
Error: Duplicate required providers configuration
on provider.tf line 3, in terraform:
3: required_providers {
A module may have only one required providers configuration. The required
providers were previously configured at main.tf:2,3-21.
我可以通过在 provider 块中声明版本来解决这个问题,如图所示 here. However, the version attribute in provider blocks has been deprecated in Terraform 0.13; Terraform 建议改用 terraform 块下的 required_providers 子块。
有人知道我需要做什么才能为我的 aws 提供商使用新的 required_providers 块吗?
如您所见,Terraform 期望每个模块仅具有其所需提供程序的一个定义,这是为了避免当声明分布在多个文件中时 Terraform 检测特定原因的原因不明确的情况。
但是,为了支持这种零碎的代码生成用例,Terraform 有一个名为 Override Files 的高级功能,它允许您明确标记某些文件以进行不同的处理模式,它们可以选择性地覆盖来自其他文件,而不是创建全新的定义。
此机制的详细信息取决于您覆盖的块类型,但 Merging terraform
blocks` 部分讨论了与您的特定情况相关的行为:
If the
required_providers
argument is set, its value is merged on an element-by-element basis, which allows an override block to adjust the constraint for a single provider without affecting the constraints for other providers.In both the
required_version
andrequired_providers
settings, each override constraint entirely replaces the constraints for the same component in the original block. If both the base block and the override block both set required_version then the constraints in the base block are entirely ignored.
上面的实际含义是,如果您有一个包含 AWS 提供商条目的 required_providers
块的覆盖文件,那么 Terraform 会将其视为已存在的任何类似条目的完全替换在非覆盖文件中,但它不会影响根本没有出现在覆盖文件中的其他供应商要求条目。
将所有这些放在一起,您应该能够通过要求 Terragrunt 将此生成的文件命名为 provider_override.tf
而不是仅仅 provider.tf
来获得您正在寻找的结果,这将激活覆盖文件处理行为,从而允许此生成的文件覆盖 AWS 提供商要求的任何现有定义,同时允许配置保留它们可能也在定义的任何其他提供商要求。