使用 Terragrunt 从一个 Terraform 模块创建多个对象

Create multiple objects from one Terraform module using Terragrunt

我正在通过 terragrunt 使用 terraform。 我有一个文件夹,里面只有一个 terragrunt.hcl 文件。此文件的目的是在 GCP 中创建多个子网。

要创建子网,我有一个需要多个输入的模块。

我希望能够在我的 terragrunt.hcl 文件中创建多个子网。

我认为最好的方法是创建一个包含字典(或 terraform 所称的地图)的列表,然后遍历它们。

我有一些代码不起作用

这是一些无法工作的代码。

#terragrunt.hcl

include {
  path = find_in_parent_folders()
}

  inputs = {
    # Common tags to be assigned to all resources
    subnetworks = [
      {
        "subnetName": "subnet1-euw"
        "subNetwork": "10.2.0.0/16"
        "region": "europe-west1"
      },
      {
        "subnetName": "subnet1-usc1"
        "subNetwork": "10.3.0.0/16"
        "region": "us-central1"
      }
    ]
  }

terraform {
  module "subnetworks" {
    source = "github.com/MyProject/infrastructure-modules.git//vpc/subnetwork"
    vpc_name = "MyVPC"
    vpc_subnetwork_name = [for network in subnetworks: network.subnetName]
    vpc_subnetwork_cidr = [for network in subnetworks: network.subNetwork]
    vpc_subnetwork_region = [for network in subnetworks: network.region]
  }
}

似乎我不能在 "terraform" 块中使用 "module"。希望代码至少显示了我想要实现的目标。

供参考,我调用的模块如下所示

#main.tf

terraform {
  # Intentionally empty. Will be filled by Terragrunt.
  backend "gcs" {}
}

resource "google_compute_subnetwork" "vpc_subnetwork" {
  name          = var.vpc_subnetwork_name
  ip_cidr_range = var.vpc_subnetwork_cidr
  region        = var.vpc_subnetwork_region
  network       = var.vpc_name
}
#variables.tf
variable "vpc_name" {
  description = "Name of VPC"
  type        = string
}

variable "vpc_subnetwork_name" {
  description = "Name of subnetwork"
  type        = string
}

variable "vpc_subnetwork_cidr" {
  description = "Subnetwork CIDR"
  type        = string
}

variable "vpc_subnetwork_region" {
  description = "Subnetwork region"
  type        = string
}

Terragrunt 没有循环结构。在 Terragrunt 中,您可以使用目录层次结构来执行您在这里想要执行的操作。例如,要实现上述目标,可以这样:

└── live
    ├── empty.yaml
    ├── euw
    │   ├── region.yaml
    │   └── vpc
    │       └── terragrunt.hcl
    ├── terragrunt.hcl
    └── usc1
        ├── region.yaml
        └── vpc
            └── terragrunt.hcl

live/terragrunt.hcl 中,您使其他 yaml 文件在 terragrunt 配置中可用:

# live/terragrunt.hcl
inputs = merge(
  # Configure Terragrunt to use common vars encoded as yaml to help you keep often-repeated variables (e.g., account ID)
  # DRY. We use yamldecode to merge the maps into the inputs, as opposed to using varfiles due to a restriction in
  # Terraform >=0.12 that all vars must be defined as variable blocks in modules. Terragrunt inputs are not affected by
  # this restriction.
  yamldecode(
    file("${get_terragrunt_dir()}/${find_in_parent_folders("region.yaml", "${path_relative_from_include()}/empty.yaml")}"),
  )
)

在每个地区的 region.yaml 中,您只需说明地区:

# live/euw/region.yaml
# These variables apply to this entire region. They are automatically pulled in using the extra_arguments
# setting in the root terraform.tfvars file's Terragrunt configuration.
region: "europe-west1"
# live/usc1/region.yaml
region: "us-central1"

现在您可以在每个区域 terragrunt.hcl 文件中将区域作为变量引用:

# live/euw/vpc/terragrunt.hcl
terraform {
  source = "github.com/MyProject/infrastructure-modules.git//vpc/subnetwork"
}

include {
  path = find_in_parent_folders()
}

inputs = {
  vpc_subnetwork_name = "subnet1-${region}"
  vpc_subnetwork_cidr = "10.2.0.0/16"
  vpc_subnetwork_region = region
  vpc_name = "MyVPC"
}

还有:

# live/usc1/vpc/terragrunt.hcl
terraform {
  source = "github.com/MyProject/infrastructure-modules.git//vpc/subnetwork"
}

include {
  path = find_in_parent_folders()
}

inputs = {
  vpc_subnetwork_name = "subnet1-${region}"
  vpc_subnetwork_cidr = "10.3.0.0/16"
  vpc_subnetwork_region = region
  vpc_name = "MyVPC"
}

您可能会发现来自 Gruntwork 的 example terragrunt repository 很有帮助。