【问题标题】:Using terragrunt generate provider block causes conflicts with require providers block in module使用 terragrunt generate provider 块会导致与模块中的 require providers 块发生冲突
【发布时间】:2021-06-20 13:04:44
【问题描述】:

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

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

我的问题是当我尝试在environments/prd/rds-cluster 下运行 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.

我可以通过在提供程序块中声明版本来解决此问题,如 here 所示。但是,提供程序块中的版本属性一直是deprecated in Terraform 0.13; Terraform 建议使用 terraform 块下的 required_providers 子块。

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

【问题讨论】:

    标签: terraform terraform-provider-aws terraform0.12+ terragrunt


    【解决方案1】:

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

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

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

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

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

    上述的实际含义是,如果您有一个带有 required_providers 块的覆盖文件,其中包含 AWS 提供商的条目,那么 Terraform 会将其视为已存在于非覆盖文件,但不会影响覆盖文件中根本没有出现的其他提供者需求条目。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-25
      • 1970-01-01
      • 2012-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-23
      相关资源
      最近更新 更多