数据源允许查询或计算一些数据以供其他地方使用。
使用数据源可以使得Terraform代码使用在Terraform管理范围之外的一些信息,或者是读取其他Terraform代码保存的状态。
每一种Provider都可以在定义一些资源类型的同时定义一些数据源。
通常来讲,在同一个云服务产品下有不同的资源和对应的数据源,资源(resource
)用于对远程基础设施进行增删改,数据源(data
)用于对远程基础设施进行查询。
如下图所示为AWS中EBS产品下对应的资源和数据源:
声明数据源
数据源通过data块声明:
data "aws_ami" "example" {most_recent = trueowners = ["self"]tags = {Name = "app-server"Tested = "true"}
}
一个data块请求Terraform从一个指定类型的数据源aws_ami
读取指定数据并且把结果输出到Local Name为example
的实例中。
可以在同一模块内的代码中通过数据源名称来引用数据源,但无法从模块外部直接访问数据源。
同资源类似,一个数据源类型以及它的名称一同构成了该数据源的标识符,所以数据源类型加名称的组合在同一模块内必须是唯一的。
在data块体中是传给数据源的查询条件,查询条件参数的种类取决于数据源的类型,在上述例子中,most_recent
、owners
和tags
都是定义查询aws_ami数据源时使用的查询条件,详见ami#argument-reference
数据源参数
每一种数据源资源都关联到一种外部数据源,数据源类型决定了它接收的查询参数以及输出的数据,每一种数据源类型都属于一个Provider。
大部分data
块内的数据源参数都是由对应的数据源类型定义的,这些参数的赋值可以使用完整的Terraform表达式能力或其他Terraform语言的功能。
与资源(resource
)类似,Terraform也为所有类型的数据源定义了一些元参数。
数据源行为
如果数据源的查询参数涉及到的表达式只引用了字面量或是在执行terraform plan
时就已知的数据(比如输入变量),那么数据源会在执行Terraform的”refresh”阶段时被读取,然后Terraform会构建变更计划,这保证了在制定变更计划时Terraform可以使用这些数据源的返回数据。
如果查询参数的表达式引用了那些只有执行部分执行变更计划以后才能知晓的数据,比如另一个还未被创建的托管资源的输出,那么数据源的读取操作会被推迟到”apply”阶段,任何引用该数据源输出的表达式的值在执行到数据源被读取完之前都是未知的。
本地数据源
虽然绝大多数数据源都对应了一个通过远程基础设施API访问的外部数据源,但是也有一些特殊的数据源仅存在于Terraform进程内部,计算并对外输出一些数据。
比如说,本地数据源有template_file
、local_file
、aws_iam_policy_document
等。
本地数据源的行为与其他数据源完全一致,但他们输出的结果数据只是临时存在于Terraform运行时,每次计算一个新的变更计划时这些值都会被重新计算。
数据源的依赖关系
数据源有着与资源(resource
)一样的依赖机制,也可以在data
块内设置depends_on
元参数来显式声明依赖关系。
多数据源实例
与资源(resource
)一样,数据源也可以通过设置count
、for_each
元参数来创建一组多个数据源实例,并且Terraform也会把每个数据源实例单独创建并读取相应的外部数据,对count.index
与each
的使用也是一样的,在count
与for_each
之间选择的原则也是一样的。
指定Provider实例
同资源(resource
)一样,数据源也可以通过provider
元参数指定使用特定Provider实例。
数据源的生命周期
同资源不一样,数据源目前不可以通过设置lifecycle
块来定制化生命周期,但数据源内部lifecycle被设置为保留关键字以备将来可以支持该功能。
引用数据源
引用数据源数据的语法是data.<TYPE>.<NAME>.<ATTRIBUTE>
:
# 定义aws_ami数据源
data "aws_ami" "web" {filter {name = "state"values = ["available"]}filter {name = "tag:Component"values = ["web"]}most_recent = true
}# 引用数据源
resource "aws_instance" "web" {ami = data.aws_ami.web.idinstance_type = "t1.micro"
}