【问题标题】:Import resource id created from child terraform template into parent terraform template将从子 terraform 模板创建的资源 id 导入父 terraform 模板
【发布时间】:2021-03-13 02:25:19
【问题描述】:

用例

  • 使用 Terraform 我想创建不同的 preprod env(例如:dev、qa、uat env.. 等等)。资源定义和模块使用相同,唯一的区别是名称前缀,因此它为每个提到的 env 创建单独的资源,但保持 VPC 对所有人通用。

Terraform 版本:v0.13.5

目录结构

├── dev
│   ├── dev.tfvars
│   ├── main.tf
│   ├── outputs.tf
│   ├── provider.tf
│   └── variables.tf
├── qa
│   ├── qa.tfvars
│   ├── main.tf
│   ├── outputs.tf
│   ├── provider.tf
│   └── variables.tf
└── preprod-common
    ├── main.tf
    ├── outputs.tf
    ├── provider.tf
    └── variables.tf

preprod-common

main.tf

  module "vpc" {
  source = "terraform-aws-modules/vpc/aws"

  name = var.vpc_name
  cidr = var.vpc_cidr

  azs             = var.vpc_azs
  private_subnets = var.vpc_private_subnets
  public_subnets  = var.vpc_public_subnets

}

输出.tf

output "vpc_id" {
  description = "The ID of the VPC"
  value       = module.vpc.vpc_id
}

开发

main.tf

module "security-group" {
  source  = "terraform-aws-modules/security-group/aws"
  
  name        = ${var.prefix}-${var.sg-name}
  vpc_id      = <vpc_id created from preprod-common>
}

前缀 - 是环境名称。这样,它会根据前缀值为每个环境创建单独的资源,例如:(dev、qa 或 uat..so on)。

qa

main.tf

module "security-group" {
  source  = "terraform-aws-modules/security-group/aws"
  
  name        = ${var.prefix}-${var.sg-name}
  vpc_id      = <vpc_id created from preprod-common>
}

等等..对于其他环境。

仅供参考 - 我已经运行了 preprod-common 配置,并且它创建了一个新的 AWS VPC。问题是,如何将 preprod-common 创建的 vpc_id 引用到 dev、qa 和其他低级环境中?

注意:- 我也知道工作空间,但这就是我想要实现的方式。

【问题讨论】:

  • 您在父模板中的何处以及如何使用 child?
  • @Marcin,这是我的问题的一部分,我该如何使用它或者使用它的最佳方式是什么?抱歉,如果我之前没说清楚的话。
  • 你使用它类似于使用vpc模块:module "child-module"它的源路径。
  • 是的,我做到了。那么当我导入本地子模块时,我需要再次定义 vpc_id 吗?导入模块中 vpc_id 的 value 参数是什么?
  • @Marcin,请再看一遍,我已经更新了我的问题以便更好地理解。

标签: amazon-web-services terraform terraform-provider-aws terraform0.12+ terraform-template-file


【解决方案1】:

在回答问题之前,我只想注意一些术语:我认为您在这里所说的“模板”实际上是所谓的Terraform module。我注意到这不是迂腐,而是因为了解正确的术语会在将来参考 Terraform 文档或提出其他问题时有所帮助。

话虽如此,您在此处遵循的模式(调用两个模块并将一个模块的输出传递给另一个模块)称为Module Composition,有关该模式的文档中有许多不同的示例。

对于您的具体情况,您可以将vpc 模块中的vpc_id 输出传递给security-group 模块,如下所示:

module "vpc" {
  source = "terraform-aws-modules/vpc/aws"

  name = var.vpc_name
  cidr = var.vpc_cidr

  azs             = var.vpc_azs
  private_subnets = var.vpc_private_subnets
  public_subnets  = var.vpc_public_subnets

}

module "security_group" {
  source = "terraform-aws-modules/security-group/aws"
  
  name   = var.sg_name
  vpc_id = module.vpc.vpc_id
}

【讨论】:

  • 感谢您输入 Martin,我一定会在将来参考时注意术语。现在回到您的答案,我知道模块组合以及它如何在单个 terraform 文件中工作,但这不是我想要的。如果您仔细查看我的问题中的目录结构,我想使用从一个 terraform 配置文件(使用 vpc 模块)创建的资源 ID 到另一个 terraform 配置文件(使用安全组模块)。我已经更新了我的问题以更清楚,请看一下。谢谢!
【解决方案2】:

以下是我的问题的答案。考虑到我的问题中的相同示例,这就是您需要做的。

注意:如果您在本地保存 terraform 状态。这意味着如果您使用的是本地后端。

在您的 dev 目录中

main.tf

data "terraform_remote_state" "vpc" {
  backend = "local"

  config = {
    path = "../preprod-common/terraform.tfstate"
  }
}

module "security-group" {
  source  = "terraform-aws-modules/security-group/aws"
  
  name        = ${var.prefix}-${var.sg-name}
  vpc_id      = data.terraform_remote_state.vpc.outputs.vpc_id
}

注意:如果您要远程保存 terraform 状态。这意味着如果您将远程后端与 Terraform Cloud 一起使用。

在您的 dev 目录中

main.tf

data "terraform_remote_state" "vpc" {
  backend = "remote"

  config = {
    organization = "hashicorp"
    workspaces = {
      name = "vpc-preprod"
    }
  }
}

module "security-group" {
  source  = "terraform-aws-modules/security-group/aws"
  
  name        = ${var.prefix}-${var.sg-name}
  vpc_id      = data.terraform_remote_state.vpc.outputs.vpc_id
}

注意:如果您要远程保存 terraform 状态。这意味着如果您使用的是 terraform 云以外的远程后端,例如 S3。在这种情况下,如 terraform 文档 (https://www.terraform.io/docs/backends/operations.html) 中所述,我将在下面粘贴确切的文字。

目前,远程后端是唯一支持远程操作的后端,Terraform Cloud是唯一支持的远程执行环境。

在这种情况下,一种解决方案是在本地提取 preprod-common 的 terraform 状态,例如在 /tmp 目录中并将其与本地后端一起使用。

cd preprod-common

terraform state pull > /tmp/terraform.state

在您的 dev 目录中

main.tf

data "terraform_remote_state" "common" {
  backend = "local"

  config = {
    path = "/tmp/terraform.tfstate"
  }
}

module "security-group" {
  source  = "terraform-aws-modules/security-group/aws"
  
  name        = ${var.prefix}-${var.sg-name}
  vpc_id      = data.terraform_remote_state.vpc.outputs.vpc_id
}

类似地,您必须为其他较低的环境执行此操作,例如:qa、uat、int.. 等等

【讨论】:

    猜你喜欢
    • 2021-05-15
    • 2018-08-01
    • 1970-01-01
    • 2021-04-17
    • 2019-06-16
    • 2021-02-15
    • 2022-09-22
    • 1970-01-01
    • 2018-04-14
    相关资源
    最近更新 更多