Могу ли я сделать так, чтобы в terraform сохранялись старые версии объектов?

Новое в терраформе, так что, возможно, он не должен работать таким образом. Я хочу использовать aws_s3_bucket_object для загрузки пакета в корзину - это часть развертывания приложения. Я собираюсь менять пакет для каждого развертывания, и я хочу сохранить старые версии.

resource "aws_s3_bucket_object" "object" {
    bucket = "mybucket-app-versions"
    key    = "version01.zip"
    source = "version01.zip"
}

Но после запуска этого для будущего развертывания я захочу загрузить версию 02, а затем версию 03 и т. Д. Terraform заменяет старый zip-архив новым ожидаемым поведением.

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

Я мог бы, конечно, просто вызвать S3 api через скрипт, но было бы здорово, если бы это было определено с остальной частью определения terraform для этого приложения.


person red888    schedule 16.11.2017    source источник


Ответы (2)


При использовании Terraform для развертывания приложений рекомендуется отделить этап сборки от этапа развертывания и использовать Terraform только для последнего.

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

Такое разделение между сборкой и развертыванием допускает более сложные ситуации, такие как откат к более старому артефакту (без его перестройки), если в новой версии есть проблемы.

В простых сценариях можно передать местоположение артефакта в Terraform с помощью Входных переменных . Например, в вашей ситуации, когда процесс сборки будет записывать zip-файл в S3, вы можете определить такую ​​переменную:

variable "archive_name" {
}

Затем это можно передать любому ресурсу, который в нем нуждается, используя синтаксис интерполяции ${var.archive_name}. Чтобы развернуть определенный артефакт, передайте его имя в командной строке с помощью -var:

$ terraform apply -var="archive_name=version01.zip"

Некоторые организации предпочитают вести учет «текущей» версии каждого приложения в каком-либо хранилище данных, например HashiCorp Consul и прочтите его с помощью источника данных. Этот подход может быть проще организовать в автоматизированном конвейере сборки, поскольку он позволяет использовать это отдельное хранилище данных для косвенной передачи имени архива между этапами сборки и развертывания без необходимости передавать какие-либо необычные аргументы самому Terraform.

person Martin Atkins    schedule 17.11.2017

В настоящее время вы указываете terraform управлять одним aws_s3_bucket_object, а terraform заботится обо всем его жизненном цикле, то есть terraform также заменит файл, если увидит в нем какие-либо изменения.

Возможно, вы ищете null_resource. Вы можете использовать его для запуска инициатора local-exec для загрузки файл со скриптом. Таким образом, старый файл не будет удален, так как terraform не управляет им напрямую. Тогда вы все равно будете вызывать API через скрипт, но весь процесс загрузки в s3 все равно будет включен в ваш terraform apply шаг.

Вот схема null_resource:

resource "null_resource" "upload_to_s3" {
  depends_on = ["<any resource that should already be created before upload>"]
  ...

  triggers = ["<A resource change that must have happened so terraform starts the upload>"]

  provisioner "local-exec" {
    command = "<command to upload local package to s3>"
  }
}
person fishi0x01    schedule 16.11.2017