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