Terraform:如果在 AZ 中找不到 EC2 实例类型产品,则处理错误

Terraform: Handle error if no EC2 Instance Type offerings found in AZ

我们正在通过 Terraform 在 AWS 中启动 G4 实例,并且经常遇到给定区域中的一个或两个 AZ 不支持 G4 实例类型的问题。

到目前为止,我已经按照下面的方式对我们的 TF 配置进行了硬编码,我在其中创建了区域和 AZ 的地图作为“azs”变量。从这张地图上,我可以在我们有 G4 实例支持的区域的目标 AZ 中启动集群。

我正在使用此 AWS article 中提到的 aws 命令行来查找给定区域中支持哪些可用区,并在我们扩展到其他区域时更新我们的“azs”变量。

variable "azs" {
  default = {
    "us-west-2"      = "us-west-2a,us-west-2b,us-west-2c"
    "us-east-1"      = "us-east-1a,us-east-1b,us-east-1e"
    "eu-west-1"      = "eu-west-1a,eu-west-1b,eu-west-1c"
    "eu-west-2"      = "eu-west-2a,eu-west-2b,eu-west-2c"
    "eu-west-3"      = "eu-west-3a,eu-west-3c"
 } 

然而,上述方法需要人工干预并经常更新(如果 AWS 稍后在给定区域添加对不支持的 AZ 的支持)

有这个 用户试图做同样的事情但是他可以使用后备实例类型让我们说如果给定实例类型不支持任何 AZ。

在我的用例中,我不能使用任何其他后备实例类型,因为我们的应用程序服务器仅在 G4 上运行。

我曾尝试使用上述堆栈溢出问题中提到的解决方法作为答案,但它失败并显示以下错误消息。

Error: no EC2 Instance Type Offerings found matching criteria; try different search

on main.tf line 8, in data "aws_ec2_instance_type_offering" "example": 8: data "aws_ec2_instance_type_offering" "example" {

我正在使用下面的 TF 配置,其中我的 preferred_instance_types 是 g4dn.xlarge。

provider "aws" {
  version = "2.70"
}
data "aws_availability_zones" "all" {
  state = "available"
}

data "aws_ec2_instance_type_offering" "example" {
  for_each = toset(data.aws_availability_zones.all.names)
  filter {
    name   = "instance-type"
    values = ["g4dn.xlarge"]
  }
  filter {
    name   = "location"
    values = [each.value]
  }
  location_type            = "availability-zone"
  preferred_instance_types = ["g4dn.xlarge"]
}

output "foo" {
  value = { for az, details in data.aws_ec2_instance_type_offering.example : az => details.instance_type }
}

我想知道如何处理此故障,因为 Terraform 无法在给定区域的一个 AZ 中找到 g4 实例类型并失败。

是否有任何 Terraform 错误处理我可以暂时通过此错误并将支持的可用区作为输出?

我已经检查了您之前提到的其他问题,但我始终无法正确获得输出。感谢@ydaetskcoR 在 post 中的回复 - 我可以学到一些东西并让我的循环工作。

这里有一种方法可以满足您的需求...让我知道它是否适合您。

而不是“aws_ec2_instance_type_offering", use "aws_ec2_instance_type_offerings”...(最后有一个's'。它们是不同的数据源...

我将只在此处粘贴代码,并假设您能够解码其中的逻辑。我正在过滤一种特定的实例类型,如果它不受支持,instance_types 将是黑色的,我列出了一个没有空值的 AZ。

variable "az" {
  default="us-east-1"
}

variable "my_inst" {
  default="g4dn.xlarge"
}

data "aws_availability_zones" "example" {
  filter {
    name   = "opt-in-status"
    values = ["opt-in-not-required"]
  }
}

data "aws_ec2_instance_type_offerings" "example" {
for_each=toset(data.aws_availability_zones.example.names)

  filter {
    name   = "instance-type"
    values = [var.my_inst]
  }


  filter {
    name   = "location"
    values = ["${each.key}"]
  }

  location_type = "availability-zone"
}


output "az_where_inst_avail" {
  value = keys({ for az, details in data.aws_ec2_instance_type_offerings.example :
  az => details.instance_types if length(details.instance_types) != 0 })
}

输出如下所示。 us-east-1e 没有实例类型,它不在输出中。测试几个案例,看看它是否每次都有效。

Outputs:

az_where_inst_avail = [
  "us-east-1a",
  "us-east-1b",
  "us-east-1c",
  "us-east-1d",
  "us-east-1f",
]

我认为有更简洁的方法。数据源已经根据给定的过滤器过滤可用区。有一个属性 -> locations 将生成所需 location_type.

的列表
provider "aws" {
  region = var.region
}

data "aws_ec2_instance_type_offerings" "available" {
  filter {
    name = "instance-type"
    values = [var.instance_type]
  }

  location_type = "availability-zone"
}

output "azs" {
  value = data.aws_ec2_instance_type_offerings.available.locations
}

其中 instance_type 是 t3.micro 并且 region 是 us-east-1,这准确地产生了:

azs = tolist([
  "us-east-1d",
  "us-east-1a",
  "us-east-1c",
  "us-east-1f",
  "us-east-1b",
])

您不需要向它提供可用区域列表,因为它已经从提供的区域中获取可用区域列表。