Как запустить команду перед zip-папкой data.archive_file в Terraform?

Я пытаюсь реализовать лямбда-функцию aws с помощью terraform.

У меня просто null_resource есть локальный провайдер и resource.archive_file, который архивирует исходный код после завершения всей подготовки.

resource "null_resource" "deps" {

  triggers = {
    package_json = "${base64sha256(file("${path.module}/src/package.json"))}"
  }

  provisioner "local-exec" {
    command = "cd ${path.module}/src && npm install"
  }
}

resource "archive_file" "function" {
    type = "zip"
    source_dir = "${path.module}/src"
    output_path = "${path.module}/function.zip"

    depends_on = [ "null_resource.deps" ]
}

Последние изменения в Terraform объявлены устаревшими resource.archive_file, поэтому следует использовать data.archive_file. К сожалению, data выполняется до ресурсов, поэтому локальный провайдер из зависимого ресурса вызывается сразу после создания zip. Таким образом, приведенный ниже код больше не выдает предупреждений, но вообще не работает.

resource "null_resource" "deps" {

  triggers = {
    package_json = "${base64sha256(file("${path.module}/src/package.json"))}"
  }

  provisioner "local-exec" {
    command = "cd ${path.module}/src && npm install"
  }
}

data "archive_file" "function" {
    type = "zip"
    source_dir = "${path.module}/src"
    output_path = "${path.module}/function.zip"

    depends_on = [ "null_resource.deps" ]
}

Я что-то упускаю? Как правильно это сделать с последними версиями.

Terraform: v0.7.11 ОС: Win10


person Mike Chaliy    schedule 22.11.2016    source источник
comment
Думаю, вы правы, и только Terraform сделать это невозможно.   -  person Anton Babenko    schedule 25.11.2016
comment
Пример в вопросе отлично подходит для меня. Вы можете использовать параметр working_dir вместо префикса cd.   -  person Yep_It's_Me    schedule 20.07.2019


Ответы (2)


Оказывается, проблема связана с тем, как ядро ​​Terraform обрабатывает depends_on ресурсы данных. Сообщается о нескольких проблемах, одна из которых связана с поставщиком архивов и еще один в ядре.

Следующий обходной путь указан в проблеме с поставщиком архива. Обратите внимание, что он использует data.null_data_source, чтобы находиться между null_resource и data.archive_file, что делает его явной зависимостью, а не неявной зависимостью с depends_on.

resource "null_resource" "lambda_exporter" {
  # (some local-exec provisioner blocks, presumably...)

  triggers = {
    index = "${base64sha256(file("${path.module}/lambda-files/index.js"))}"
  }
}

data "null_data_source" "wait_for_lambda_exporter" {
  inputs = {
    # This ensures that this data resource will not be evaluated until
    # after the null_resource has been created.
    lambda_exporter_id = "${null_resource.lambda_exporter.id}"

    # This value gives us something to implicitly depend on
    # in the archive_file below.
    source_dir = "${path.module}/lambda-files/"
  }
}

data "archive_file" "lambda_exporter" {
  output_path = "${path.module}/lambda-files.zip"
  source_dir  = "${data.null_data_source.wait_for_lambda_exporter.outputs["source_dir"]}"
  type        = "zip"
}
person Yep_It's_Me    schedule 28.10.2019
comment
Спасибо, это решение намного более изящно, чем некоторые из предыдущих идей, которые я прочитал, и решает мою проблему, когда архив был помечен как измененный при каждом запуске. - person Alex Varju; 16.11.2019
comment
Это делает написание лямбда-выражений с терраформой намного лучше. Спасибо! - person Sean; 09.10.2020

В Terraform 0.8 появился новый источник данных external, который позволяет запускать внешние команды и извлекать выходные данные. См. data.external.

Источник данных должен только использоваться для получения некоторого значения зависимости, а не для выполнения npm install, вы все равно должны делать это через null_resource. Поскольку это источник данных Terraform, он не должен иметь никаких побочных эффектов (хотя в этом случае вам могут понадобиться некоторые, не уверен).

Итак, в основном null_resource выполняет зависимости, data.external получает какое-то значение, от которого вы можете зависеть для архива (например, путь к каталогу), затем data.archive_file выполняет архивирование.

Это, вероятно, будет лучше всего работать с псевдослучайным именем каталога, потенциально, чтобы сделать грязные проверки немного чище.

person Paul Tyng    schedule 19.12.2016
comment
Я был бы очень признателен за образец этой цепочки зависимостей на основе оригинала. Я только начинаю и считаю это очень полезным. Спасибо. - person David Fernandez; 30.01.2019