在其他地形文件中使用输出地形文件
Using outputs terraform files in other terraform files
我是 Terraform 的新手,有几个问题。在 terraform 中,有没有办法在另一个 tf 文件中使用模块的输出,WITHOUT 有一个“主”terraform 文件,或者在同一个文件中定义两个模块?
例如,这是一个项目结构:
project/
├── networking
│ ├── init.tf
│ ├── terraform.tfvars
│ ├── variables.tf
│ └── vpc.tf
├── prd-project-1
│ ├── init.tf
│ ├── instances.tf
│ ├── terraform.tfvars
│ └── variables.tf
├── prd-project-2
│ ├── init.tf
│ ├── instances.tf
│ ├── terraform.tfvars
│ └── variables.tf
├── prd-project-3
│ ├── init.tf
│ ├── instances.tf
│ ├── terraform.tfvars
│ └── variables.tf
├── test
│ ├── init.tf
│ ├── instances.tf
│ ├── terraform.tfvars
│ └── variables.tf
vpc.tf
将创建 VPC 和子网。
instances.tf
将根据之前在 vpc.tf
中创建的 vpc-id 和子网创建 EC2 实例。我想 treat/manage 这些作为两个单独的操作。 IE。首先,我会 运行 terraform 来创建 vpc 和子网,然后我可能会 运行 terraform 在 prod/test 中为各种项目创建实例。在此示例中,我将只有 1 个 VPC 用于测试,1 个 VPC 用于生产。我不希望每个项目都有一个 VPC(我再次假设如果在其中一个子项目中引用了 vpc.tf
模块,TF 可能会创建)。
以这种方式管理 Terraform 代码是最佳实践吗?我担心的是,如果最终有很多项目需要 EC2 实例,我不希望所有这些都在一个巨大的 main.tf
中。我认为 safer/cleaner 将这些都单独维护,只要可以引用 vpc 输出即可。如果我正在建立一个新项目,我也不希望我的 terraform plan/applies 变慢并检查每个项目的每一个资源。
我的问题的第二部分是 - 考虑以下代码片段:
module "main-vpc" {
source = "../modules/vpc"
ENV = "prod"
AWS_REGION = var.AWS_REGION
}
module "instances" {
source = "../modules/instances"
ENV = "prod"
VPC_ID = module.main-vpc.vpc_id
PUBLIC_SUBNETS = module.main-vpc.public_subnets
}
terraform 是否足够聪明,可以确定已经使用 ENV = prod 创建了一个 VPC,并且如果我在另一个 tf file/project 中调用相同的“main-vpc”模块,它不会尝试重新创建它?
我在 Whosebug 上阅读了其他几篇文章,但它们都暗示模块的输出只能在同一 tf 文件中的另一个模块中引用。
我评论过的其他一些帖子:
- Pass terraform output from one file to another
- Terraform module - output variable as input for another module
- Terraform structure for two aws accounts
如果您想保留当前的文件夹结构,最好在每个项目中添加main.tf
:
project/
├── networking
│ ├── init.tf
│ ├── terraform.tfvars
│ ├── variables.tf
│ └── vpc.tf
├── prd-project-1
│ ├── main.tf
│ ├── init.tf
│ ├── instances.tf
│ ├── terraform.tfvars
│ └── variables.tf
├── prd-project-2
│ ├── main.tf
│ ├── init.tf
│ ├── instances.tf
│ ├── terraform.tfvars
│ └── variables.tf
├── prd-project-3
│ ├── main.tf
│ ├── init.tf
│ ├── instances.tf
│ ├── terraform.tfvars
│ └── variables.tf
├── test
│ ├── init.tf
│ ├── instances.tf
│ ├── terraform.tfvars
│ └── variables.tf
然后每个 main.tf
将是如下内容:
module "main-vpc" {
source = "../networking"
ENV = "prod"
AWS_REGION = var.AWS_REGION
}
module "instances" {
source = "../instances"
ENV = "prod"
VPC_ID = module.main-vpc.vpc_id
PUBLIC_SUBNETS = module.main-vpc.public_subnets
}
这样您就可以将项目分开,每个项目都有自己的 TF 状态文件。
Is terraform smart enough to determine that a VPC was already created with an ENV
不,不是。您必须为此编写自己的逻辑。一种常见的方法是通过变量
variable "vpc_id" {
default = ""
}
那么如果您没有为给定的项目明确指定 vpc_id
,它将创建新的 VPC。否则,它将使用您提供的 var.vpc_id
作为输入参数。使用 data sources 然后您将获得该 VPC 的其他信息,例如它的子网。
有了这个设置,你会先cd
到每个项目文件夹,然后再部署它,例如
cd ./prd-project-1
terraform apply
如果我理解你的问题,你希望拥有仍然可以相互访问输出的独立项目。因此,例如,启动 EC2 实例的项目可以引用在创建 VPC 的项目中定义的子网。
有两种方法可以做到这一点。首先,您可以使用数据源来查询当前的部署环境。例如,下面将查找带有值为“prod”的 ENV
标签的 VPC(假设我没有打错任何字):
data "aws_vpc" "prod" {
tags = { "ENV": "prod" }
}
其次,您可以使用远程状态(为了安全起见,无论如何这是个好主意)。每个项目都会将其输出写入数据存储(S3 很常见,但 Terraform 提供自己的存储),其他项目将引用它们。
虽然 SO 不喜欢链接,但我无法比 Terraform 文档更好地解释它:https://www.terraform.io/docs/language/state/backends.html
我是 Terraform 的新手,有几个问题。在 terraform 中,有没有办法在另一个 tf 文件中使用模块的输出,WITHOUT 有一个“主”terraform 文件,或者在同一个文件中定义两个模块?
例如,这是一个项目结构:
project/
├── networking
│ ├── init.tf
│ ├── terraform.tfvars
│ ├── variables.tf
│ └── vpc.tf
├── prd-project-1
│ ├── init.tf
│ ├── instances.tf
│ ├── terraform.tfvars
│ └── variables.tf
├── prd-project-2
│ ├── init.tf
│ ├── instances.tf
│ ├── terraform.tfvars
│ └── variables.tf
├── prd-project-3
│ ├── init.tf
│ ├── instances.tf
│ ├── terraform.tfvars
│ └── variables.tf
├── test
│ ├── init.tf
│ ├── instances.tf
│ ├── terraform.tfvars
│ └── variables.tf
vpc.tf
将创建 VPC 和子网。
instances.tf
将根据之前在 vpc.tf
中创建的 vpc-id 和子网创建 EC2 实例。我想 treat/manage 这些作为两个单独的操作。 IE。首先,我会 运行 terraform 来创建 vpc 和子网,然后我可能会 运行 terraform 在 prod/test 中为各种项目创建实例。在此示例中,我将只有 1 个 VPC 用于测试,1 个 VPC 用于生产。我不希望每个项目都有一个 VPC(我再次假设如果在其中一个子项目中引用了 vpc.tf
模块,TF 可能会创建)。
以这种方式管理 Terraform 代码是最佳实践吗?我担心的是,如果最终有很多项目需要 EC2 实例,我不希望所有这些都在一个巨大的 main.tf
中。我认为 safer/cleaner 将这些都单独维护,只要可以引用 vpc 输出即可。如果我正在建立一个新项目,我也不希望我的 terraform plan/applies 变慢并检查每个项目的每一个资源。
我的问题的第二部分是 - 考虑以下代码片段:
module "main-vpc" {
source = "../modules/vpc"
ENV = "prod"
AWS_REGION = var.AWS_REGION
}
module "instances" {
source = "../modules/instances"
ENV = "prod"
VPC_ID = module.main-vpc.vpc_id
PUBLIC_SUBNETS = module.main-vpc.public_subnets
}
terraform 是否足够聪明,可以确定已经使用 ENV = prod 创建了一个 VPC,并且如果我在另一个 tf file/project 中调用相同的“main-vpc”模块,它不会尝试重新创建它?
我在 Whosebug 上阅读了其他几篇文章,但它们都暗示模块的输出只能在同一 tf 文件中的另一个模块中引用。
我评论过的其他一些帖子:
- Pass terraform output from one file to another
- Terraform module - output variable as input for another module
- Terraform structure for two aws accounts
如果您想保留当前的文件夹结构,最好在每个项目中添加main.tf
:
project/
├── networking
│ ├── init.tf
│ ├── terraform.tfvars
│ ├── variables.tf
│ └── vpc.tf
├── prd-project-1
│ ├── main.tf
│ ├── init.tf
│ ├── instances.tf
│ ├── terraform.tfvars
│ └── variables.tf
├── prd-project-2
│ ├── main.tf
│ ├── init.tf
│ ├── instances.tf
│ ├── terraform.tfvars
│ └── variables.tf
├── prd-project-3
│ ├── main.tf
│ ├── init.tf
│ ├── instances.tf
│ ├── terraform.tfvars
│ └── variables.tf
├── test
│ ├── init.tf
│ ├── instances.tf
│ ├── terraform.tfvars
│ └── variables.tf
然后每个 main.tf
将是如下内容:
module "main-vpc" {
source = "../networking"
ENV = "prod"
AWS_REGION = var.AWS_REGION
}
module "instances" {
source = "../instances"
ENV = "prod"
VPC_ID = module.main-vpc.vpc_id
PUBLIC_SUBNETS = module.main-vpc.public_subnets
}
这样您就可以将项目分开,每个项目都有自己的 TF 状态文件。
Is terraform smart enough to determine that a VPC was already created with an ENV
不,不是。您必须为此编写自己的逻辑。一种常见的方法是通过变量
variable "vpc_id" {
default = ""
}
那么如果您没有为给定的项目明确指定 vpc_id
,它将创建新的 VPC。否则,它将使用您提供的 var.vpc_id
作为输入参数。使用 data sources 然后您将获得该 VPC 的其他信息,例如它的子网。
有了这个设置,你会先cd
到每个项目文件夹,然后再部署它,例如
cd ./prd-project-1
terraform apply
如果我理解你的问题,你希望拥有仍然可以相互访问输出的独立项目。因此,例如,启动 EC2 实例的项目可以引用在创建 VPC 的项目中定义的子网。
有两种方法可以做到这一点。首先,您可以使用数据源来查询当前的部署环境。例如,下面将查找带有值为“prod”的 ENV
标签的 VPC(假设我没有打错任何字):
data "aws_vpc" "prod" {
tags = { "ENV": "prod" }
}
其次,您可以使用远程状态(为了安全起见,无论如何这是个好主意)。每个项目都会将其输出写入数据存储(S3 很常见,但 Terraform 提供自己的存储),其他项目将引用它们。
虽然 SO 不喜欢链接,但我无法比 Terraform 文档更好地解释它:https://www.terraform.io/docs/language/state/backends.html