Terraform 使用terragrunt生成提供程序块会导致与模块中的require providers块冲突

Terraform 使用terragrunt生成提供程序块会导致与模块中的require providers块冲突,terraform,terraform-provider-aws,terraform0.12+,terragrunt,Terraform,Terraform Provider Aws,Terraform0.12+,Terragrunt,我将Terragrunt与Terraform版本0.14.8一起使用 我的项目使用mono repo结构,因为项目要求将Terragrunt文件和Terraform模块打包在一个包中 文件夹结构: project root: ├── environments │   └── prd │   ├── rds-cluster │   │   └── terragrunt.hcl │   └── terragrunt.hcl └── modules ├── rds-cl

我将Terragrunt与Terraform版本0.14.8一起使用

我的项目使用mono repo结构,因为项目要求将Terragrunt文件和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
}
在modules/rds cluster/main.tf中,我定义了以下内容:

include {
  path = find_in_parent_folders()
}

terraform {
  source = "../../../modules//rds-cluster"
}

inputs = {
 ...
}
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 3.0"
    }
  }
}

// RDS related resources...
我的问题是,当我尝试在
环境/prd/rds集群下运行terragrunt plan时,我收到以下错误消息:

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块中声明版本来解决这个问题,如图所示。但是,提供程序块中的版本属性已被删除;Terraform建议改为在Terraform block下使用所需的_providers子块


有人知道我需要做什么才能为我的aws提供商使用新的required_providers块吗?

正如您所看到的,Terraform希望每个模块只有一个所需提供商的定义,这是为了避免出现这样一种情况,即当声明散布在多个文件中时,Terraform为什么会检测到一个特定的文件

然而,为了支持这种零碎的代码生成,用例Terraform有一个名为的高级功能,它允许您显式地将某些文件标记为不同的处理模式,其中这些文件有选择地覆盖来自其他文件的特定定义,而不是创建全新的定义

此机制的详细信息取决于覆盖的块类型,但上一节将讨论与特定情况相关的行为:

如果设置了
required\u providers
参数,则其值将逐个元素合并,从而允许覆盖块调整单个提供程序的约束,而不会影响其他提供程序的约束

required_version
required_providers
设置中,每个替代约束都会完全替换原始块中相同组件的约束。如果基础块和替代块都设置了所需版本,则基础块中的约束将完全忽略

上述内容的实际含义是,如果您有一个覆盖文件,其中包含一个AWS提供商条目的
required\u providers
块,则Terraform会将其视为非覆盖文件中已存在的任何类似条目的完全替代品,但它不会影响根本不出现在覆盖文件中的其他提供程序需求条目

将所有这些放在一起,您应该能够通过要求Terragrunt将生成的文件命名为
provider\u override.tf
,而不仅仅是
provider.tf
,从而获得您想要的结果,这将激活覆盖文件处理行为,从而允许生成的文件覆盖AWS提供程序需求的任何现有定义,同时允许配置保留它们可能定义的任何其他提供程序需求