一段时间以来,我们一直在使用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,所以这也是死胡同。
答案 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
环境:生产蓝色或生产绿色
祝你好运!