1

我将 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
}

在 environment/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...

我的问题是,当我尝试在 下运行 terragrunt plan 时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.

我可以通过在提供程序块中声明版本来解决这个问题,如下所示。但是,提供程序块中的 version 属性已在 Terraform 0.13 中被弃用;Terraform 建议使用 terraform 块下的 required_providers 子块。

有谁知道我需要做什么才能为我的 aws 提供程序使用新的 required_providers 块?

4

1 回答 1

3

正如您所看到的,Terraform 期望每个模块只有一个定义其所需提供程序,这是为了避免当声明分布在多个文件中时,Terraform 为何检测到特定的情况不清楚。

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

此机制的详细信息取决于您要覆盖的块类型,但“合并terraform”部分讨论了与您的特定情况相关的行为:

如果required_providers设置了参数,则其值将逐个元素合并,这允许覆盖块调整单个提供者的约束,而不会影响其他提供者的约束。

required_versionrequired_providers设置中,每个覆盖约束都会完全替换原始块中相同组件的约束。如果基本块和覆盖块都设置了 required_version,那么基本块中的约束将被完全忽略。

上述的实际含义是,如果您有一个required_providers包含 AWS 提供程序条目的块的覆盖文件,则 Terraform 会将其视为已存在于非覆盖文件中的任何类似条目的完全替换,但它赢了'不影响根本没有出现在覆盖文件中的其他提供者要求条目。

provider_override.tf将所有这些放在一起,您应该能够通过要求 Terragrunt 命名这个生成的文件而不是仅仅来获得您正在寻找的结果provider.tf,这将激活覆盖文件处理行为,从而允许这个生成的文件覆盖任何现有的定义AWS 提供商要求,同时允许配置保留他们可能也在定义的任何其他提供商要求。

于 2021-03-23T21:04:57.180 回答