使用 Terraform 获取 AMI 的动态数据源

Dynamic data source for fetching AMI using Terraform

因此,以下数据源将获取带有 component:web 标记的最新 AMI。假设我有一些组件有自己的 AMI。不是创建同一个块 5 次,有没有办法让它更动态,我可以传入 component 的值?我似乎想不出可以传入的唯一值。我需要稍微重构一下我的代码吗?

data "aws_ami" "web" {
  filter {
    name   = "state"
    values = ["available"]
  }

  filter {
    name   = "tag:component"
    values = ["web"]
  }

  most_recent = true
}

我有一个 defaults 模块用作元数据查找,它在其中获取和输出 AMI ID 和 VPC ID 等基本内容。

默认模块

# defaults/main.tf

data "aws_ami" "web" {
  filter {
    name   = "state"
    values = ["available"]
  }

  filter {
    name   = "tag:component"
    values = ["web"]
  }

  most_recent = true
}

output "web_ami" {
  value = "${data.aws_ami.web.id}"
}

主要代码

# service_name/main.tf

module "defaults" {
  source      = "../defaults"
  region      = "${var.region}"
  environment = "${var.environment}"
}

module "ftpserver" {
  source .    = "../ec2_instance"
  ami_id      = "${module.defaults.web_ami}"
  ...
}

我会将 aws_ami 数据源移动到模块中,让它直接查找 AMI,而不是从外部传入。

所以我会将 ec2_instance 模块更改为:

variable "ami_component" {}

data "aws_ami" "selected" {
  filter {
    name   = "state"
    values = ["available"]
  }

  filter {
    name   = "tag:component"
    values = ["${var.ami_component"]
  }

  most_recent = true
}

resource "aws_instance" "instance" {
  ami           = "${data.aws_ami.selected.id}"
  instance_type = "t2.micro"

  tags {
    Name = "HelloWorld"
  }
}

如果您随后觉得需要能够覆盖 ec2_instance 模块中的 AMI,您可以将其更改为:

variable "ami_component" {}

variable "override_ami" {
  default = ""
}

data "aws_ami" "selected" {
  filter {
    name   = "state"
    values = ["available"]
  }

  filter {
    name   = "tag:component"
    values = ["${var.ami_component"]
  }

  most_recent = true
}

resource "aws_instance" "instance" {
  ami           = "${var.override_ami != "" ? var.override_ami : data.aws_ami.selected.id}"
  instance_type = "t2.micro"

  tags {
    Name = "HelloWorld"
  }
}

这使用条件来检查 override_ami 变量是否已设置为其他内容,在这种情况下它将使用它,否则它将使用 ami_component 变量来查找适当的 AMI并改用它。

这有利于将 AMI 选择逻辑移动到 Terraform 模块中,使该模块的接口更加简单。