Как обновить ресурс aws_lambda_function Terraform при изменении почтового пакета на S3?

#amazon-s3 #aws-lambda #terraform

Вопрос:

Zip-пакет загружается в S3 не с помощью Terraform.
Lambda предоставляется ресурсом функции Terraform aws_lambda_function. Когда я меняю почтовый пакет на S3 и запускаю terraform apply команду, Terraform говорит, что ничего не изменилось.
В ресурсе aws_lambda_function есть source_code_hash поле, которое можно задать как хэш содержимого пакета. Но какое бы значение для этого хэша я ни предоставлял, оно не обновляется в состоянии Терраформирования.

Как сообщить Terraform об обновлении Лямбды в случае обновления почтового пакета в S3?

Ответ №1:

После многочисленных экспериментов по проверке того, как Terraform обрабатывает хэш, я обнаружил следующее:

  1. source_code_hash ресурс aws_lambda_функции хранится в состоянии Terraform в момент подготовки Лямбды.
  2. source_code_hash обновляется только в том случае, если вы укажете для него новое значение в ресурсе aws_lambda_function, и это новое значение соответствует хэшу фактического почтового пакета в S3.
    Поэтому Terraform проверяет фактический хэш-код пакета на S3 только в данный момент, он не проверяет его при запуске terraform apply .

Поэтому, чтобы это сработало, у нас есть следующие варианты:

  1. Загрузите Zip-пакет из S3, вычислите его хэш и передайте его в source_code_hash поле ресурса aws_lambda_function ИЛИ
  2. Загрузите почтовый пакет в S3 с помощью Terraform, используя ресурс aws_s3_bucket_object. Установите source_hash поле в этом ресурсе, чтобы сохранить его в состоянии терраформирования. Это значение может использоваться ресурсом aws_lambda_function для обновлений.

К сожалению, это поведение не задокументировано, и я потратил много времени на его обнаружение. Более того, он может быть изменен в любой момент, так как он не задокументирован, и никто не знает, что 🙁

Итак, как я решил эту проблему?
Я генерирую хэш SHA256 в кодировке base64 Zip-файла Lambda и сохраняю его в качестве метаданных для фактического Zip-файла. Затем я читаю эти метаданные в Terraform и передаю их source_code_hash .

Подробные сведения:

  1. Сгенерируйте хэш с помощью openssl dgst -binary -sha256 lambda_package.zip | openssl base64 команды.
  2. Сохраняйте хэш в качестве метаданных во время загрузки пакета с помощью aws s3 cp lambda_package.zip s3://my-best-bucket/lambda_package.zip --metadata hash=[HASH_VALUE] команды.
  3. Передать хэш source_code_hash в Терраформу
 data "aws_s3_bucket_object" "package" {
  bucket = "my-best-bucket"
  key    = "lambda_package.zip"
}

resource "aws_lambda_function" "main" {
  ...
  source_code_hash = data.aws_s3_bucket_object.package.metadata.Hash
  ...
}