您可以像使用资源一样对数据源使用条件,也可以在模块上使用 Terraform 0.13+:
variable "lookup_ami" {
default = true
}
data "aws_ami" "application" {
count = var.lookup_ami ? 1 : 0
most_recent = true
filter {
name = "tag:environment"
values = [var.environment]
}
owners = ["self"]
}
Terraform 0.12+ 中的一个用例是利用三元语句的惰性求值,如下所示:
variable "internal" {
default = true
}
data "aws_route53_zone" "private_zone" {
count = var.internal ? 1 : 0
name = var.domain
vpc_id = var.vpc_id
private_zone = var.internal
}
data "aws_route53_zone" "public_zone" {
count = var.internal ? 0 : 1
name = var.domain
private_zone = var.internal
}
resource "aws_route53_record" "www" {
zone_id = var.internal ? data.aws_route53_zone.private_zone.zone_id : data.aws_route53_zone.public_zone.zone_id
name = "www.${var.domain}"
type = "A"
alias {
name = aws_elb.lb.dns_name
zone_id = aws_elb.lb.zone_id
evaluate_target_health = false
}
}
这将在 var.internal 为 true 时在专用区域中创建一条记录,而在 var.internal 为 false 时在公共区域中创建一条记录。
对于这个特定的用例,您还可以使用 Terraform 0.12+ 的 null 更简单地重写它:
variable "internal" {
default = true
}
data "aws_route53_zone" "zone" {
name = var.domain
vpc_id = var.internal ? var.vpc_id : null
private_zone = var.internal
}
resource "aws_route53_record" "www" {
zone_id = data.aws_route53_zone.zone.zone_id
name = "www.${data.aws_route53_zone.zone.name}"
type = "A"
alias {
name = aws_elb.lb.dns_name
zone_id = aws_elb.lb.zone_id
evaluate_target_health = false
}
}
如果var.internal 设置为true,这只会将vpc_id 参数传递给aws_route53_zone 数据源,因为当private_zone 为false 时,您无法设置vpc_id。
旧 Terraform 0.11 和更早的答案:
实际上,您可以根据数据源的数量使用条件,但我尝试过时还没有找到一个好的用例。
作为一个例子,我成功地完成了这个工作:
data "aws_route53_zone" "private_zone" {
count = "${var.internal == "true" ? 1 : 0}"
name = "${var.domain}"
vpc_id = "${var.vpc_id}"
private_zone = "true"
}
data "aws_route53_zone" "public_zone" {
count = "${var.internal == "true" ? 0 : 1}"
name = "${var.domain}"
private_zone = "false"
}
但是在如何选择它的输出方面遇到了问题,因为 Terraform 将在决定使用三元的哪一侧之前评估三元条件中的任何变量(而不是惰性评估)。所以这样的事情是行不通的:
resource "aws_route53_record" "www" {
zone_id = "${var.internal ? data.aws_route53_zone.private_zone.zone_id : data.aws_route53_zone.public_zone.zone_id}"
name = "www.example.com"
type = "A"
alias {
name = "${aws_elb.lb.dns_name}"
zone_id = "${aws_elb.lb.zone_id }"
evaluate_target_health = "false"
}
}
因为如果internal 为真,那么您将获得private_zone 数据源但不会获得public_zone 数据源,因此三元组的后半部分无法评估,因为data.aws_route53_zone.public_zone.zone_id 未定义且与其他方式也一样。
在您的情况下,您可能只想有条件地使用数据源,以便可以执行以下操作:
variable "dynamic_ami" { default = "true" }
variable "default_ami" { default = "ami-123456" }
data "aws_ami" "application" {
most_recent = true
filter {
name = "tag:environment"
values = ["${var.environment}"]
}
owners = ["self"]
}
resource "aws_instance" "app" {
ami = "${var.dynamic_ami == "true" ? data.aws_ami.application.id : var.default_ami}"
instance_type = "t2.micro"
}