我有以下tf文件:
provider "aws" {
region = "us-east-1"
}
module "ec2"{
source = “../service1”
app = "${var.app}"
env = "${var.env}"
}
module "workspaces"{
source = “../service2”
app = "${var.app}"
env = "${var.env}"
}
即使service1和service2是不同的模块,它们的基础变量。tf文件也完全相同。有没有一种方法可以为两个模块使用common variables.tf文件?
答案 0 :(得分:0)
是的。
文件夹结构为:
/service1
--main.tf
--var.tf
/service2
--main.tf
--var.tf
main.tf
var.tf
./ service1 / var.tf和./service2/var.tf 的内容:
variable "app" {}
variable "env" {}
./ var.tf
的内容variable "app" {
default = "YOUR-APP-NAME"
}
variable "env" {
default = "dev"
}
或者您可以保持所有var.tf的内容相同,并从CLI传递-var标志。
答案 1 :(得分:0)
每个模块的变量声明是完全独立的,因此Terraform中没有内置功能可以共享它们。
如果您使用的文件系统支持符号链接,则可以将相同的.tf
文件符号链接到多个目录中,以获得相似的效果。但是,除非变量声明的集合特别大或太复杂,否则我建议只复制它们:从长远来看,保持每个配置的独立性通常比避免少量复制简单的样板代码更有用。
如果您使用的是Terraform v0.12,则可能希望将所有这些通用设置组合为一个对象值,以减少样板:
locals {
context = {
app = "example"
env = var.environment
}
}
module "ec2" {
source = "../service1"
context = local.context
}
module "workspaces" {
source = "../service2"
context = local.context
}
如下所示的变量声明(在每个子模块中)将使该context
对象的形状更加明确,因此,如果传递了不适当的值,Terraform可以检测并报告有关该错误的错误:< / p>
variable "context" {
type = object({
app = string
env = string
})
}
当分解为多个模块时,通常需要经过上述类似的标准上下文设置,但是如果您的系统特别复杂(模块代表的许多不同子系统),从长远来看可能会有所帮助确切地讲每个模块都需要什么并显式地传递那些单独的东西,而不是仅仅在各处传递相同的对象。
例如,如果您想从其调用者那里decouple ec2
模块中进行设计,也许您会对其进行设计,以使其不包含“应用”或“环境”的概念-这些概念属于调用者模块,但不是EC2概念-而是以更以EC2为中心的方式表示同一件事,例如通过标签:
locals {
# Common tags for all AWS objects
aws_tags = {
Name = "example ${var.environment}"
Environment = var.environment
}
}
module "ec2" {
source = "../service1"
# (other EC2-oriented settings)
tags = local.aws_tags
}
使用这种方法,EC2模块仅关心EC2概念,而根模块将其自身的“应用”和“环境”概念转换为EC2标签概念。例如,这可以允许稍后在不同的上下文中使用相同的EC2模块,其中使用不同的标记方案。
Module Composition的Terraform文档部分中有关于此方法的更多信息。