Можно ли фильтровать AMI в aws_ami по именам, которые вам не нужны?

Некоторое время мы использовали Terraform для управления нашей инфраструктурой, и в настоящее время я занимаюсь рефакторингом ее части. Нам нужны две группы автомасштабирования внутри AWS, где одна группа запускает последнюю версию наших AMI, а другая группа использует предыдущую версию. Таким образом, я пытаюсь найти оба AMI.

Сначала ищем последний выпуск. Вот как работает наша текущая инфраструктура, и это нормально:

data "aws_ami" "ami_latest" {
  most_recent = true

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

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

  owners = ["self"]
}

Теперь я хочу найти нашу предыдущую версию. Я думал, что смогу использовать name_regex < / a> в Terraform и выполните отрицательный просмотр имени, которое я только что вернул в первом блоке, возвращая, таким образом, предыдущий последний выпуск:

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). +`): ошибка синтаксического анализа регулярного выражения: недопустимый или неподдерживаемый синтаксис Perl: `(?!`

В настоящее время мы используем Terraform 0.11.10. Хотя у нас есть планы по обновлению до 0.12+, в наших скриптах есть ряд мест, которые необходимо будет обновить, чтобы исправить различные критические изменения между ними.

Есть ли способ отфильтровать AMI, чтобы получить то, что мне нужно в 0.11.10? Есть ли способ заставить встроенный name фильтр сделать это?

В качестве альтернативы, есть ли в 0.12.6 обновленная поддержка регулярных выражений? - Я не хочу исправлять все проблемы, чтобы попробовать 0.12.6, просто чтобы обнаружить, что у него все еще есть та же проблема.


Альтернативным подходом было бы использование самих фильтров - кажется, если я отфильтрую список AMI непосредственно в консоли AWS, я смогу получить то, что мне нужно, используя два фильтра по имени: server-name-* и !'server-name.123.123.123.123', где вторая - последняя версия. Это возвращает мне нужную мне информацию. Однако я не могу заставить это работать в блоках фильтров в Terraform. Я пробовал различные комбинации по линиям:

filter {
  name   = "name"
  values = ["server-name-*", "!'${data.aws_ami.ami_latest.name}'"]
}

И попробуйте другие вещи, такие как использование двух блоков фильтров, установка первого отрицательного и т. Д. Ни один из них не приводит к обнаружению AMI - похоже, что, хотя отрицаемые фильтры работают на консоли, они не работают через API, поэтому это тоже тупик.


person James Thorpe    schedule 12.08.2019    source источник
comment
Что касается поддержки регулярных выражений, Terraform написан на go, а go не поддерживает утверждения lookahead или lookbehind во встроенной библиотеке регулярных выражений golang.org/pkg/regexp/syntax Если в 0.12 не добавлена ​​внешняя библиотека регулярных выражений, которая поддерживает утверждения с опережением, ответ будет отрицательным.   -  person Ngenator    schedule 12.08.2019
comment
@Ngenator Спасибо, это полезно знать.   -  person James Thorpe    schedule 12.08.2019
comment
Это регулярное выражение в любом случае анализируется поставщиком AWS, а не Terraform Core, поэтому вопрос, какую реализацию регулярного выражения использует этот поставщик, а не какую версию Terraform. На самом деле, реализация этого конкретного аргумента источника данных не претерпела существенных изменений с момента его добавления, и он действительно использует механизм регулярных выражений RE2. Это ошибка, заключающаяся в том, что он вылетал из-за синтаксической ошибки, а не из-за ошибки проверки, поэтому было бы здорово, если бы вы открыли проблему по этому поводу в поставщик AWS.   -  person Martin Atkins    schedule 13.08.2019
comment
@MartinAtkins Спасибо, это имеет смысл. Я думаю, что наш провайдер, вероятно, немного устарел - не обновился по тем же причинам, что и критические изменения в наших скриптах. Я попытаюсь убедиться, что неподдерживаемое регулярное выражение по-прежнему вызывает ту же ошибку в последней версии, прежде чем открывать проблему.   -  person James Thorpe    schedule 13.08.2019


Ответы (2)


Я нашел обходной путь, который может работать в нашем конкретном случае использования, по крайней мере, временно.

Наши номера версий имеют вид server-name-a.b.c.d, где c обозначает фактический номер версии. Найдя это конкретное число в последней версии, вычтя из него единицу и отфильтровав по нему, я могу найти предыдущую версию:

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

Он не кажется особенно надежным (и выйдет из строя, например, если мы пропустим версию), поэтому я все еще очень открыт для других решений, но это разблокирует меня на данный момент ...

person James Thorpe    schedule 12.08.2019

Я понимаю, что этому почти год.

Шаблон, который я использую для решения этой проблемы, заключается в добавлении тегов в AMI и фильтрации по тегам. Это позволяет не полагаться на номера версий, хотя их можно использовать для дальнейшего расширения этой концепции.

такие теги, как:

  • Продукт
  • Составная часть
  • Версия
  • Среда

Где:

Товар: widget1

Компонент: backend

Версия: 1.2.3

Окружающая среда: производственный синий или производственный зеленый

Удачи!

person todd    schedule 18.06.2020