Terraform - 条件数据源

时间:2017-01-25 18:09:54

标签: amazon-web-services terraform

在terraform中,有没有办法有条件地使用数据源?例如:

 data "aws_ami" "application" {
     most_recent = true
     filter {
         name = "tag:environment"
         values = ["${var.environment}"]
     }
     owners = ["self"]
}

我希望能够通过命令行传递一个环境变量,并根据它确定天气或不尝试获取此数据源。

我知道有资源可以使用count属性,但似乎不能将其用于数据源。

我会考虑在模块中删除此代码,但模块也不能使用count参数。

最后,另一种选择是为数据源提供“默认”值,如果它返回null,但我认为这也不可行。

还有其他可能的解决方案吗?

1 个答案:

答案 0 :(得分:6)

你实际上可以使用数据源计数的条件,但是当我尝试时,我还没有设法为它设计一个好的用例。

作为一个例子,我成功地完成了这项工作:

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"
}