Terraform lambda source_code_hash 업데이트 동일한 코드로
Terraform과 함께 AWS Lambda를 성공적으로 구축했습니다:
resource "aws_lambda_function" "lambda" {
filename = "dist/subscriber-lambda.zip"
function_name = "test_get-code"
role = <my_role>
handler = "main.handler"
timeout = 14
reserved_concurrent_executions = 50
memory_size = 128
runtime = "python3.6"
tags = <my map of tags>
source_code_hash = "${base64sha256(file("../modules/lambda/lambda-code/main.py"))}"
kms_key_arn = <my_kms_arn>
vpc_config {
subnet_ids = <my_list_of_private_subnets>
security_group_ids = <my_list_of_security_groups>
}
environment {
variables = {
environment = "dev"
}
}
}
명령을 실행하면 가 변경되었기 때문에 람다 리소스를 업데이트해야 한다는 메시지가 표시되지만 람다 파이썬 코드베이스(동일한 레포의 폴더에 버전이 있음)를 업데이트하지 않았습니다:
~ module.app.module.lambda.aws_lambda_function.lambda
last_modified: "2018-10-05T07:10:35.323+0000" => <computed>
source_code_hash: "jd6U44lfe4124vR0VtyGiz45HFzDHCH7+yTBjvr400s=" => "JJIv/AQoPvpGIg01Ze/YRsteErqR0S6JsqKDNShz1w78"
매번 파이썬 소스를 압축해서 소스가 바뀌기 때문인 것 같아요. 파이썬 코드에 변화가 없다면 어떻게 피할 수 있을까요? 만약 내가 파이썬 코드베이스를 바꾸지 않았다면(내 말은, 왜 해시가 바뀌는지) 내 가설은 일관적인가?
이것은 당신이 그저 업로드만 하고 있기 때문입니다. 테라폼은 파일을 람다에 업로드할 때 해시를 계산하는 해시와 비교한다. 두 개의 다른 파일에서 해싱이 수행되므로 다른 해싱을 수행하게 됩니다. 업로드 중인 파일과 정확히 동일한 파일에서 해시를 실행해 보십시오.
저는 @ODYN-Kon이 제공한 것과 대비하여 제 답변을 추가하려고 합니다.
리소스 "aws_lambda_function"의 소스 코드 해시 필드가 업로드하는 zip의 일부 해시와 비교되지 않습니다. 대신, 해시는 마지막으로 실행된 때의 테라폼 저장 상태와 비교하여 확인될 뿐이다. 그래서 다음에 테라폼을 실행하면 실제 파이썬 파일의 해시를 계산하여 변경되었는지 확인합니다. 그런 경우 zip이 변경되어 Lambda 함수 리소스를 다시 실행해야 한다고 가정합니다. source_code_hash는 원하는 값을 갖거나 아예 생략할 수 있습니다. 임의 문자열의 상수로 설정할 수 있으며 테라폼 구성을 편집하지 않는 한 변경되지 않습니다.
문제는 테라폼이 당신이 zip 파일을 업데이트했다고 가정한다는 것입니다. zip 아카이브에 디렉토리 또는 파일이 하나만 있다고 가정하면 Terraform data source archive_file을 사용하여 zip 파일을 만들 수 있습니다. 디렉토리와 파일(JS world: source + node_modules/)이 필요해서 사용할 수 없는 경우가 있습니다. 그러나 다음과 같이 사용할 수 있습니다:
data "archive_file" "lambdaCode" {
type = "zip"
source_file = "lambda_process_firewall_updates.js"
output_path = "${var.lambda_zip}"
}
또는 "source_file" 문을 다음과 같이 바꾸면 전체 디렉토리를 보관할 수 있습니다
이렇게 하면 source_hash 필드는 zip 아카이브 파일의 해시 코드를 참조하여 블록에 삽입할 수 있습니다. 그러면 zip이 변경될 때마다 람다 함수가 업데이트됩니다. 그리고 데이터 소스 아카이브 파일은 source_file이 변경될 때마다 zip을 재생성해야 한다는 것을 알고 있습니다.
당신의 경우에 근본적인 원인을 설명하지는 못했지만, 더 나은 곳으로 갈 수 있도록 도움을 줬으면 좋겠네요. 저장된 상태의 항목을 나열한 : - 를 통해 테라폼의 저장 상태를 확인할 수 있습니다. 람다 함수 블록과 일치하는 것을 찾은 다음 실행할 수 있습니다. 예를 들어, 제가 작업하고 있는 것은 다음과 같습니다:
는 다음을 포함하여 약 30개의 출력 라인을 제공합니다:
source_code_hash = 2fKX9v/둘루QF0H6O9+iRnID2gokhfpXIXpxyeVBUM0=
명령줄 명령을 통해 해시를 비교할 수 있습니다. MacOS: 에서 sha256sum이 설치된 예입니다.
언급한 바와 같이 zip의 여러 요소가 단일 디렉터리에 분리되지 않은 경우 archive_file을 사용할 수 없습니다. 아마 그런 일이 자주 일어날 것 같아서 하시코프 사람들이 archive_file을 확장해서 여러 개를 지원했으면 좋겠어요. 바둑 코드도 봤는데 비 오는 날 프로젝트네요. 내가 사용하는 한 가지 변형은 source_code_hash를 그대로 사용하는 것이다. 하지만 그것은 여전히 내가 tf를 두 번 실행해야 한다.
다른 사람들이 말했듯이, 당신의 zip은 당신의 파일명과 해시에 사용되어야 한다.
람다 정의에 잘못된 해시 함수를 사용하는 경우에도 유사한 재생성 문제가 발생할 수 있음을 말씀드리고 싶습니다. 예를 들어 filesha256(.zip)은 매번 람다를 재생성합니다. source_code_hash에 언급된 것처럼 filebase64sha256("file.zip")(테라폼 0.11.12+) 또는 base64sha256("file.zip")을 사용해야 합니다
이것은 나에게 효과가 있고 코드가 변경되지 않았을 때 람다 함수에 대한 업데이트를 트리거하지 않습니다
data "archive_file" "lambda_zip" {
type = "zip"
source_dir = "../dist/go"
output_path = "../dist/lambda_package.zip"
}
resource "aws_lambda_function" "aggregator_func" {
description = "MyFunction"
function_name = "my-func-${local.env}"
filename = data.archive_file.lambda_zip.output_path
runtime = "go1.x"
handler = "main"
source_code_hash = data.archive_file.lambda_zip.output_base64sha256
role = aws_iam_role.function_role.arn
timeout = 120
publish = true
tags = {
environment = local.env
}
}
몇 년 늦게 와서 마이키의 원래 게시물이 나에게 답이었고 슬프게도 나는 명성이 없기 때문에 그것을 지지할 수 없다고 말했다. 그러므로 나는 다른 어떤 해결책도 나에게 통하지 않았기 때문에 여기서 그의 대답을 자세히 설명할 것이다.
내 문제는 CI/CD 프로세스가 실행될 때마다 람다 zip이 재구축되어 모든 pip 패키지를 다시 가져올 수 있고 따라서 zip 간 타임스탬프가 모두 소진되어 다른 해시가 발생한다는 것이었다. 유사한 스레드에 대한 다른 답변들이 지적했듯이, 이제 당신이 살펴볼 수 있는 결정론적 zip이라고 불리는 몇 개의 라이브러리가 떠돌고 있다.
이제 마이키의 대답을 들어보자. 이건 순전한 마법이다. 테라폼의 람다 블록에서 source_code_hash를 제거하면 파일 이름이 변경된 경우에만 테라폼이 다시 배포됩니다. 따라서 다른 변화가 없다면 테라폼은 처음 생성될 때와 다시는 생성되지 않을 것입니다. 이 파일의 장점은 파일 이름에 원하는 모든 해시를 효과적으로 넣을 수 있다는 것입니다. 따라서 간단한 예는 실제 소스 코드 파일의 md5 해시를 bash로 계산하는 것입니다:
md5sum <modules/lambda/lambda-code/main.py | sed 's/ .*$//'
파일 이름에 md5를 계산하지 않고 파일을 여는 것은 파일 이름 앞에 <파일명 앞에>가 실제로 있다는 것에 유의하십시오(변경되지 않도록). main.py 에 변경 사항이 없는 두 개의 다른 실행에서 실행을 시도하면 md5는 동일합니다. main.py 을 변경하면 md5가 변경됩니다. 이것은 우리가 이것을 완전히 통제할 수 있기 때문에 이름, 버전화 또는 해싱 뒤에 있는 핵심 아이디어는 파일 이름에서 발생할 것이다. 요구사항에 따라 해시를 계산할 수도 있습니다.txt와 파일 이름을 함께 추가합니다. 종속성이 변경될 것으로 예상되는 경우 파일 이름을 변경합니다.
마지막으로, 우리는 이것을 작동시키기 위해 테라폼에서 약간의 논리를 바꿀 필요가 있을 것이다. 이전에 말씀드린 대로 source_code_hash를 제거할 예정입니다. 새로운 변수 파일명을 가져오기 위해 해시는 런타임에 계산되므로 이름을 알 수 없으므로 여러 가지 방법을 사용할 수 있으므로 환경 변수 경로를 시연하겠습니다. 환경 변수는 TF_VAR_가 접두사로 필요합니다.
따라서 테라폼을 실행하기 전에 CI/CD 도구에서 이제 다음과 같은 해시를 계산해야 합니다:
lambda_zip=$(md5sum <modules/lambda/lambda-code/main.py | sed 's/ .*$//').zip#calculate new name the string parsing is to remove *- at end of hash
mv lambda_zip.zip ${lambda_zip}#rename the zip with the new hashed name
export TF_VAR_lambda_zip=${lambda_zip}#set TF env var
그리고 테라폼으로:
variable "lambda_zip" {
type = string
description = "..."
}
resource "aws_lambda_function" "lambda" {
filename = "${var.lambda_zip}"
function_name = "test_get-code"
role = <my_role>
handler = "main.handler"
timeout = 14
reserved_concurrent_executions = 50
memory_size = 128
runtime = "python3.6"
tags = <my map of tags>
kms_key_arn = <my_kms_arn>
vpc_config {
subnet_ids = <my_list_of_private_subnets>
security_group_ids = <my_list_of_security_groups>
}
environment {
variables = {
environment = "dev"
}
}
}
그 정도면 충분합니다. 이제 코드를 변경하지 않으면 md5 해시가 실행할 때마다 동일하게 계산되므로 테라폼이 다시 배치되지 않습니다. 그러나 코드를 수정하면 md5 해시가 변경되므로 파일 이름이 변경되고 이제 테라폼이 zip을 다시 배치합니다.
'개발하자' 카테고리의 다른 글
플러터 리버팟: 첫 번째 실행이 실패한 후 FutureProvider를 트리거하는 방법은 무엇입니까? (0) | 2023.10.08 |
---|---|
terraform plan이 Error를 반환합니다: 지원되지 않는 인수 (1) | 2023.10.07 |
플러터 파이어베이스: Stream provider를 사용하여 로그인한 사용자의 세부 정보를 앱 전체에 스트리밍하고 싶습니다 (0) | 2023.10.06 |
pip은 mac에서 "pip이 TLS/SSL이 필요한 위치로 구성되어 있지만 python의 ssl 모듈을 사용할 수 없습니다."라는 오류를 표시합니다 (0) | 2023.10.05 |
변수 내 테라폼 변수 (1) | 2023.10.05 |