Terraform - 如何创建可选数据块

muh*_*mad 1 terraform terraform-provider-aws

我创建了一些数据块来查找合适的 AMI。我有 4 个数据块来查找基于 4 个操作系统的 4 个 AMI。例子,

data "aws_ami" "centos" {
    owners = ["123456789"]
    most_recent = true
    filter {
        name = "name"
        values = ["CentOS*${var.os-version}*x86_64"]
    }
}
data "aws_ami" "suse" {
    owners = ["amazon"]
    most_recent = true
    filter {
        name = "name"
        values = ["suse-sles-${var.os-version}-sp*-v????????-hvm-ssd-x86_64"]
    }
}
Run Code Online (Sandbox Code Playgroud)

我像下面这样称呼他们ami_id=data.${os_name}.image-id

所以我想要的是只运行已经被调用的数据块。如果用户选择“suse”,则仅运行 suse 数据块。不是所有的人。现在这是一个问题,因为用户根据操作系统选择版本。例如,16.04 仅适用于 ubuntu,不适用于其他任何版本,因此其他数据块会抛出如下异常,

Error: Your query returned no results. Please change your search criteria and try again.

  on main.tf line 79, in data "aws_ami" "suse":
  79: data "aws_ami" "suse" {

Run Code Online (Sandbox Code Playgroud)

那么我怎样才能实现它呢?

Tyl*_*ler 5

一种方法可以是 Terraform 模块和count. 例如,您可以这样构建您的项目:

data对 AMI 的查找可以是子文件夹中的模块。该模块的输入将是您的os-version.

在此模块内,您可以进行变量验证来验证输入操作系统是否有效。然后,您可以构建每个data块。每个data块都有一个count值,其中查找将发生(值为1)或不发生(值为0),具体取决于os-version传入的值。

我构建了以下作为一个简单的示例。

# Main Terraform project
module "ami" {
    source = "./ami"

    arch = "arm64"
}

output "ami_arn" { value = module.ami.arn }
Run Code Online (Sandbox Code Playgroud)
# AMI module
variable "arch" {
  type = string

  validation {
    condition = (
      var.arch == "x86" || var.arch == "arm64"
    )
    error_message = "Valid architectures are 'x86' or 'arm64'."
  }
}

data "aws_ami" "aws_linux_2_x86" {
  count = var.arch == "x86" ? 1 : 0

  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "image-id"
    values = ["ami-0742b4e673072066f"]
  }
}

data "aws_ami" "aws_linux_2_arm64" {
  count = var.arch == "arm64" ? 1 : 0

  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "image-id"
    values = ["ami-015f1226b535bd02d"]
  }
}

output "arn" { value = var.arch == "x86" ? data.aws_ami.aws_linux_2_x86[0].arn : data.aws_ami.aws_linux_2_arm64[0].arn }
Run Code Online (Sandbox Code Playgroud)

这个示例不会被过滤,os-version因为我无法轻松模拟您的环境。但是,实现是相同的。

AMI 模块的输出是 ARN,或者您选择的任何其他有效输出,然后您可以将其传递到构建 EC2 实例。

在这种情况下,您不一定必须使用模块,并且可以count在主代码中进行相同级别的验证和操作。我选择这种方法是假设您有一个正在为其编码的 EC2 模块。