是否可以通过不需要的名称来过滤aws_ami中的AMI

时间:2019-08-12 15:52:37

标签: amazon-web-services terraform terraform-provider-aws

一段时间以来,我们一直在使用Terraform来管理我们的基础架构,而我目前正在重构其中的一部分。我们希望在AWS内部使用两个Autoscaling组,其中一个组运行最新版本的AMI,而另一个组使用以前的版本。因此,我试图查找两个AMI。

首先,我们查找最新版本。这是我们当前基础架构的工作方式,很好:

data "aws_ami" "ami_latest" {
  most_recent = true

  filter {
    name   = "name"
    values = ["server-name-*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["self"]
}

我现在想去找到我们以前的版本。我以为我可以利用Terraform中的name_regex选项,对我刚在第一个块中返回的名称进行否定的前瞻,从而返回 previous 最新版本:

data "aws_ami" "ami_previous" {
  most_recent = true

  filter {
    name   = "name"
    values = ["server-name-*"]
  }

  #our AMIs have . in them, so I'm escaping for the regex:
  name_regex ="^(?!${replace(data.aws_ami.ami_latest.name, ".", "\\.")}).+"

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["self"]
}

但是,这会导致崩溃:

  

panic:regexp:Compile(`^(?! server-name-1234.1234.1234.1234)。+`):解析regexp时出错:Perl语法无效或不受支持:`(?!`

我们当前正在使用Terraform 0.11.10。尽管我们计划升级到0.12+,但脚本中仍有许多地方需要更新,以修复两者之间的各种重大更改。

是否有一种方法可以过滤掉AMI,以在0.11.10中获得所需信息?有没有办法让内置的name过滤器执行此操作?

或者,0.12.6是否更新了正则表达式支持? -我不愿意解决所有问题,以尝试使用0.12.6,只是发现它仍然存在相同的问题。


另一种方法是自己使用过滤器-似乎如果我直接在AWS控制台中过滤AMI列表,我可以使用两个过滤器分别获得名称:server-name-*和{{1} },第二个是最新版本。这给了我所需的信息。但是,我无法在Terraform的过滤器块中使用它。我已经尝试过以下几种组合方式:

!'server-name.123.123.123.123'

并尝试其他事情,例如使用两个过滤器块,将否定的过滤器放在首位等。它们全都不导致找到AMI-好像当否定的过滤器在控制台上工作时,它们无法通过控制台工作。 API,所以这也是死胡同。

2 个答案:

答案 0 :(得分:0)

我发现了一种解决方法,至少在暂时情况下,可以在我们的特定用例中使用。

我们的版本号的格式为server-name-a.b.c.d,其中c表示实际的发行版号。通过从最新版本中找到该特定编号,减去一个编号,然后进行过滤,我可以找到先前的版本:

name_regex ="^server-name-\\d+\\.\\d+\\.${element(split(".", data.aws_ami.ami_latest.name), 2) - 1}\\.\\d+$"

它并不特别健壮(例如,如果我们跳过一个版本,它将失败),因此我仍然对其他解决方案持开放态度,但这暂时阻止了我...

答案 1 :(得分:0)

我意识到这已经快一年了。

我用来解决此问题的一种模式是将标签添加到AMI,并按标签过滤。这可以避免依赖版本号,尽管可以将其用于进一步扩展此概念。

标签,例如:

  • 产品
  • 组件
  • 版本
  • 环境

位置:

产品:widget1

组件:后端

版本:1.2.3

环境:生产蓝色或生产绿色

祝你好运!