简体   繁体   English

将从子 terraform 模板创建的资源 id 导入父 terraform 模板

[英]Import resource id created from child terraform template into parent terraform template

Use-case用例

  • Using Terraform I want to create different preprod env's (like: dev, qa, uat env.. so on).使用 Terraform 我想创建不同的 preprod env(例如:dev、qa、uat env .. 等等)。 Resource definition and module usage will be same, only difference will be the name prefix, so that it creates separate resources for each of the mentioned env's, but keeping the VPC common for all.资源定义和模块使用将相同,唯一的区别是名称前缀,因此它为每个提到的 env 创建单独的资源,但保持 VPC 对所有人通用。

Terraform Version: v0.13.5 Terraform 版本:v0.13.5

Directory Structure目录结构

├── 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 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

}

Output.tf Output.tf

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

dev开发者

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

prefix - is the environment name.前缀- 是环境名称。 This way it creates separate resource for each environment, as per prefix value which will be like: (dev, qa or uat..so on).这样,它会根据前缀值为每个环境创建单独的资源,例如:(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>
}

and so on.. for other environments.等等..对于其他环境。

FYI - I already ran preprod-common configuration and it has created a new AWS VPC.仅供参考 - 我已经运行了 preprod-common 配置,并且它创建了一个新的 AWS VPC。 The question is, how can I refer the vpc_id created from preprod-common into dev, qa and other lower environments?问题是,如何将 preprod-common 创建的 vpc_id 引用到 dev、qa 和其他较低环境中?

Note : - I am aware about workspaces as well but this is how I want to implement.注意: - 我也知道工作区,但这就是我想要实现的方式。

Before answering the question I just want to note some terminology: I think what you are calling a "template" here is what is actually called a Terraform module .在回答这个问题之前,我只想注意一些术语:我认为您在这里所说的“模板”实际上是所谓的Terraform模块 I'm noting that not to be pedantic but just because knowing the correct terminology will be helpful when referring to the Terraform documentation or asking other questions in the future.我注意到这不是迂腐,而是因为了解正确的术语将有助于在将来参考 Terraform 文档或询问其他问题时。

With that said, the pattern you are following here, of calling two modules and passing the output of one into another, is called Module Composition and the documentation about that pattern has a number of different examples of it.话虽如此,您在这里遵循的模式,调用两个模块并将 output 传递给另一个模块,称为模块组合,有关该模式的文档有许多不同的示例。

For your specific case, you can pass the vpc_id output from your vpc module into the security-group module like this:对于您的具体情况,您可以将vpc_id output 从您的vpc模块传递到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
}

Below is the answer to my question.以下是我的问题的答案。 Considering the same example in my question this is what you need to do.考虑到我的问题中的相同示例,这就是您需要做的。

Note: If you are saving your terraform state locally.注意:如果您在本地保存 terraform state。 That means if you are using local backend.这意味着如果您使用的是本地后端。

In your dev directory在你的开发目录中

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
}

Note: If you are saving your terraform state remotely.注意:如果您要远程保存 terraform state。 That means if you are using remote backend with Terraform Cloud.这意味着如果您将远程后端与 Terraform Cloud 一起使用。

In your dev directory在你的开发目录中

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
}

Note: If you are saving your terraform state remotely.注意:如果您要远程保存 terraform state。 That means if you are using remote backend other than terraform cloud, example S3.这意味着如果您使用 terraform 云以外的远程后端,例如 S3。 In this case as mentioned in the terraform documentation ( https://www.terraform.io/docs/backends/operations.html ), I am pasting the exact words below. In this case as mentioned in the terraform documentation ( https://www.terraform.io/docs/backends/operations.html ), I am pasting the exact words below.

Currently, the remote backend is the only backend to support remote operations, and Terraform Cloud is the only remote execution environment that supports it.目前,远程后端是唯一支持远程操作的后端,Terraform Cloud是唯一支持的远程执行环境。

In this case one solution would be to pull the terraform state of preprod-common locally, let's say in your /tmp directory and use it with the local backend.在这种情况下,一种解决方案是在本地提取preprod-common的 terraform state,假设在您的 /tmp 目录中,并将其与本地后端一起使用。

cd preprod-common

terraform state pull > /tmp/terraform.state

In your dev directory在你的开发目录中

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
}

Similarly you have to do it for other lower environments like: qa, uat, int.. so on同样,您必须为其他较低的环境执行此操作,例如:qa、uat、int.. 等等

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM