AWS CLI가 포함된 Lambda layer 만들기

Python으로 작성된 Lambda function이 AWS CLI를 실행할 수 있도록 AWS CLI가 포함된 Lambda layer를 만드는 방법을 공유한다. AWS CLI는 다소 특이한 Python 모듈일 뿐이기 때문에 일반적인 Python 모듈의 경우에도 활용할 수 있다.

Lambda layer

Lambda layer는 AWS Lambda 서비스에서 Lambda function이 필요로 하는 라이브러리 코드를 재활용하기 위한 도구이다. 자세한 내용은 https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html 에서 찾을 수 있다.

Python 모듈을 Lambda function의 deployment package 안에 직접 넣는 것보다 Lambda layer를 만드는 것이 편리하다. 해당 모듈을 사용하는 여러 Lambda function에서 layer를 가져다 쓰면서 재활용할 수 있기 때문이다.

Lambda function에서 AWS CLI를 써야 하는 경우

Python runtime을 사용하는 Lambda function에서 AWS API 호출을 하려면 AWS CLI를 실행하는 것보다 AWS의 Python SDK인 boto3 mo을 사용하는 것이 더 좋은 방법이다. 코딩하기도 편하고 boto3는 Python runtime에 포함되어 있기 때문에 바로 사용할 수 있다.

AWS CLI는 아래처럼 boto3에서 해당 기능을 지원하지 않는 명령에만 사용하는 것이 좋다.

  • aws eks update-kubeconfig
  • aws s3 sync

aws eks update-kubeconfig 명령은 Lambda function에서 EKS 클러스터에 접속할 때 kubeconfig 설정을 위해 필요하다.

Lambda layer 용 zip 파일 생성 방법

우선 pyenvvirutalenv를 설치해야 한다.

pyenv로 Lambda runtime에 맞는 Python 버전을 설치한다. 예를 들어 python3.8 용 layer를 생성하기 위해 3.8.11 을 설치할 수 있다.

1pyenv install 3.8.11 

zip-lambda-layer-awscli.sh 스크립트를 다운로드한 후 아래처럼 layer를 구성하는 zip 파일을 만든다.

1$ sh zip-lambda-layer-awscli.sh 3.8.11 
2
3# 생성되는 파일은 아래와 같다.
4$ ls *.zip
5lambda-layer-awscli-python38.zip

Terraform으로 아래처럼 Lambda layer와 function을 만들 수 있다.

 1
 2# 실제로는 아래처럼 aws_lambda_layer_version을 직접 만들지 말고, 이것을 생성하는 테라폼 모듈을 만들어서 재사용해야 한다.
 3resource "aws_lambda_layer_version" "awscli_python38" {
 4  filename   = "./lambda-layer-awscli-python38.zip"
 5  compatible_runtimes = ["python3.8"]
 6  ...
 7  }
 8
 9resource "aws_lambda_function" "main" {
10
11  runtime          = "python3.8"
12  layers           = [aws_lambda_layer_version.awscli_python38.arn]
13  ...
14}

Lambda function을 구성하는 Python 스크립트에서 아래처럼 사용하면 된다.

1# PATH 환경 변수에 포함된 /opt/bin/ 아래에 aws가 있어서 경로 지정을 하지 않아도 된다.
2subprocess.run('aws --version',shell=True,check=True)

zip-lambda-layer-awscli.sh 스크립트

zip-lambda-layer-awscli.sh의 내용은 아래와 같다.

[참고] zip 파일 구성

bin/ 아래에 aws 명령과 그것이 의존하는 Python 모듈을 설치한다.

zip 파일 내의 bin/ 디렉토리는 Lambda 실행 환경에선 /opt/bin/ 디렉토리가 된다. /opt/bin/ 디렉토리는 Lambda function의 PATH 환경 변수에 포함되어 있기 때문에 Lambda function은 aws 명령을 경로 지정 없이 실행할 수 있다.

Python은 sys.path 변수에 포함된 디렉토리에서 import하는 module들을 찾는다. Lambda function의 sys.path 변수는 /opt/ 아래 다양한 디렉토리를 포함한다. 하지만 이 layer에 포함된 모듈들은 lambda function이 아니라 /opt/bin/aws 스크립트에서 import 하기 위한 것이다. 그런데 aws 명령의 sys.path 변수에는 /opt/ 아래 디렉토리들이 포함되지 않는다. aws 명령이 awscli 모듈을 찾을 수 있게 하려면 명령과 동일한 디렉토리인 /opt/bin/ 아래에 모듈을 넣어야 한다.

Lambda는 layer를 포함한 deployment package의 크기를 제한한다. 따라서 zip 파일과 deployment package의 크기를 줄이기 위해 Python 버전별로 layer를 따로 만든다.

참고한 문서

comments powered by Disqus