IT/Terraform

[Terraform] 특정 파일을 zip으로 변환하기 (Lambda함수 배포)

반응형

Intro

Terrafrom에서 특정 파일을 zip변환 할일이 있을까? 싶지만 terraform으로 Lambda함수를 배포하기 위해서는 zip파일이 있어야 합니다. Lambda의 소스코드 레벨을 IAC영역인 terraform소스코드와 같이 관리하는게 맞을까?라는 고민도 하긴 했었습니다만 DevOps엔지니어로서 인프라 자동화를 피할 수는 없기 때문에 개발자들이 직접 사용하는 Lambda영역이 아니라고 한다면 DevOps영역에서 관리하는 terraform소스 코드내에 Lambda 소스 코드가 포함되어도 된다고 생각합니다. 일반적으로 개발에서 직접 사용하는 Lambda함수 구조는 api gateway를 동반하는데, 이때 serverless platform(https://www.serverless.com/)이라는 오픈소스로 배포를 하기도 합니다.

Terraform data “archive_file” 사용해볼까?

이 방법은 앞전 포스팅에서도 언급한 적이 있는데, terraform의 버그가 있어서 이 zip으로 변경이 되지 않습니다. (해시코프 형님들 이 버그 언제 고쳐주는건가요?)

  • data.tf
 data "archive_file" "lambda_to_zip" {
   type        = "zip"
   source_file = "./lambda_function/lambda_exam.py/"
   output_path = "./lambda_function/lambda_exam.zip"
 }
  • lambda.tf
resource "aws_lambda_function" "lambda_exam" {

  filename         = "${data.archive_file.lambda_to_zip.output_path}"
    source_code_hash = "${data.archive_file.lambda_to_zip.output_base64sha256}"
  ... (생략)
}

그 대신 Terraform data “exteranl” 사용

아래와 같이 external 이라는 data 리소스를 활용하여 zip파일로 변환할 수 있습니다. 단 zip으로 변환하는 쉘 스크립트가 동반되어야 하며 해당 쉘스크립트에서는 jq명령어를 사용하게 됩니다.

  • data.tf
data "external" "lambda_to_zip" {
  program = ["sh", "./script/zip.sh"]
  query = {
    input_path = "./lambda_function/lambda_exam.py/"
    output_path = "./lambda_function/lambda_exam.zip"
  }
}
  • lambda.tf
resource "aws_lambda_function" "lambda_exam" {

  filename = "${data.external.lambda_to_zip.result.output_path}"
    source_code_hash = "${data.external.lambda_to_zip.result.output_hash}"
  ... (생략)
}
  • zip.sh

아래 스크립트를 보면 jq가 들어가있는데, 해당 쉘 스크립트를 동작하는 환경에서 jq명령어가 반드시 있어야한다는 단점도 있습니다.

#!/bin/bash

ARGS=$(cat -)
INPUT_PATH=$(echo $ARGS | jq -r ".input_path")
OUTPUT_PATH=$(echo $ARGS | jq -r ".output_path")

rm -f $OUTPUT_PATH

cd $INPUT_PATH
zip -rqX $OUTPUT_PATH ./*

OUTPUT_HASH=$(cat $OUTPUT_PATH | openssl sha -binary -sha256 | base64)

jq -ncM \
  '{ "output_path": $output_path, "output_hash": $output_hash }' \
  --arg output_path "$OUTPUT_PATH" \
  --arg output_hash "$OUTPUT_HASH"
반응형