Я использую TerraForm в качестве инфраструктуры в своем приложении. Ниже приведена конфигурация, которую я использую для развертывания кода Python в лямбда-выражении. Он выполняет три шага: 1. заархивирует все зависимости и исходный код в zip-файл; 2. загрузить заархивированный файл в корзину s3; 3. разверните лямбда-функцию.
Но происходит то, что команда развертывания terraform apply завершается с ошибкой ниже:
Error: Error modifying Lambda Function Code quote-crawler: InvalidParameterValueException: Error occurred while GetObject. S3 Error Code: NoSuchKey. S3 Error Message: The specified key does not exist.
status code: 400, request id: 2db6cb29-8988-474c-8166-f4332d7309de
on config.tf line 48, in resource "aws_lambda_function" "test_lambda":
48: resource "aws_lambda_function" "test_lambda" {
Error: Error modifying Lambda Function Code praw_crawler: InvalidParameterValueException: Error occurred while GetObject. S3 Error Code: NoSuchKey. S3 Error Message: The specified key does not exist.
status code: 400, request id: e01c83cf-40ee-4919-b322-fab84f87d594
on config.tf line 67, in resource "aws_lambda_function" "praw_crawler":
67: resource "aws_lambda_function" "praw_crawler" {
Это означает, что файл развертывания не существует в корзине s3. Но это успех во второй раз, когда я запускаю команду. Похоже на проблему со временем. После загрузки zip-файла в корзину s3 zip-файл не существует в корзине s3. Вот почему первое развертывание не удалось. Но через несколько секунд вторая команда завершается успешно и очень быстро. Что-то не так в моем файле конфигурации?
Полный файл конфигурации terraform можно найти: https://github.com/zhaoyi0113/quote-datalake/blob/master/config.tf





Для этого вам нужно правильно добавить зависимость, иначе произойдет сбой.
Сначала заархивируйте файлы
# Zip the Lamda function on the fly
data "archive_file" "source" {
type = "zip"
source_dir = "../lambda-functions/loadbalancer-to-es"
output_path = "../lambda-functions/loadbalancer-to-es.zip"
}
затем загрузите его s3, указав его зависимость от zip,source = "${data.archive_file.source.output_path}" это сделает его зависимым от zip
# upload zip to s3 and then update lamda function from s3
resource "aws_s3_bucket_object" "file_upload" {
bucket = "${aws_s3_bucket.bucket.id}"
key = "lambda-functions/loadbalancer-to-es.zip"
source = "${data.archive_file.source.output_path}" # its mean it depended on zip
}
Тогда вы можете приступить к развертыванию Lambda, чтобы сделать его зависимым только от этой строки, сделайте волшебство s3_key = "${aws_s3_bucket_object.file_upload.key}"
resource "aws_lambda_function" "elb_logs_to_elasticsearch" {
function_name = "alb-logs-to-elk"
description = "elb-logs-to-elasticsearch"
s3_bucket = "${var.env_prefix_name}${var.s3_suffix}"
s3_key = "${aws_s3_bucket_object.file_upload.key}" # its mean its depended on upload key
memory_size = 1024
timeout = 900
timeouts {
create = "30m"
}
runtime = "nodejs8.10"
role = "${aws_iam_role.role.arn}"
source_code_hash = "${base64sha256(data.archive_file.source.output_path)}"
handler = "index.handler"
}
согласитесь, что в таких случаях нужно много усилий, кстати, terraform упоминает только о неявной и явной зависимости, здесь вы можете найти более подробную информацию. Learn.hashicorp.com/terraform/getting-started/dependencies.html
Спасибо, ребята, я не мог найти решение где-либо еще
Вы можете обнаружить, что source_code_hash меняется, даже если код не изменился при использовании archive_file Terraform. Если это проблема для вас, я создал модуль, чтобы исправить это: лямбда-питон-архив.
Это ответ на главный ответ:
Вам нужно добавить .output_base64sha256 к source_code_hash вместо использования base64sha256, иначе план терраформирования никогда не будет согласовываться с сообщением «без изменений / актуально».
Например:
source_code_hash = "${data.archive_file.source.output_bash64sha256}"
Ваше решение работает очень хорошо. Интересно, где я могу найти документ о таком синтаксисе в TerraForm. Его официальный документ очень неясен по этому поводу.