Dev
Github actions - AWS ECR/Lambda 자동 배포
foxlee
2022. 2. 3. 17:40
기존 방식
- 코드를 수정한다.
- [수동]도커이미지를 빌드시킨 후 태그 설정 후 AWS ECR로 푸쉬한다.
- [수동] AWS 콘솔에 가서 Lambda function 에서 새로 푸쉬한 이미지로 바꿔준다.
- aws lambda update-function-code --function-name 람다함수이름 --image-uri 이미지주소를 AWS CLI를 통해 업데이트 가능하므로 AWS 웹페이지 콘솔에서 할 필요는 없음
Github actions을 활용한 자동 배포
- 코드를 수정한 후 lambda/deploy 브랜치에 푸쉬한다.
- [자동]Github actions 을 통해 이미지를 빌드한다.
- [자동]깃 커밋 id(sha1으로 만들어진 해시값)를 태그로 설정하고 AWS ECR로 푸쉬한다.
- [자동]ECR에 푸쉬할때의 주소로 Lambda 함수의 image-uri를 업데이트한다.
디버깅
- 현재 람다함수에 firebase api 키 정보 등을 포함한 credentials.json이 있고, 현재 gitignore에 있기 때문에 이 파일이 빠진채로 도커가 빌드됨 -> 깃헙의 환경변수로 추가하던지(--build-args, ARG,ENV in Dockerfile) 아니면 깃헙 비공개 또는 기존 방법을 이용(스크립트로 만들어서 aws에 접속하지 않고 스크립트 실행만으로 배포).
- 권한
- ECR 권한은 AmazonEC2ContainerRegistryFullAccess
- Lambda 권한은 AWSLambda_FullAccess
- steps 에서 변수 선언
- run: echo "image_uri=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_ENV 이 다음 스텝부터 ${{ env.image_uri }} 로 변수 값 참조 가능
- https://docs.github.com/en/actions/learn-github-actions/environment-variables#GITHUB_ENV
- https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-environment-variable
- 테스트 당시 람다 함수를 초기 생성시 도커 이미지로 선택하지 않고 기본 값으로 설정하니 도커가 zip 파일로 설정되어서 image uri 업데이트 명령어 실행 실패(에러: UpdateFunctionCode operation: Please don't provide ImageUri when updating a function with packageType Zip.)
- 람다 함수 명령어 - aws lambda update-function-code --function-name $LAMBDA_FUNCTION --image-uri $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
- 람다 함수 업데이트 관련 문서 - https://docs.aws.amazon.com/cli/latest/reference/lambda/update-function-code.html
name: Push image to Amazon ECR and update Amazon Lambda function image url
on:
push:
branches:
- lambda/deploy
env:
AWS_REGION: ap-northeast-2
ECR_REPOSITORY: crawler
LAMBDA_FUNCTION: tistory_crawler
WORKING_DIRECTORY: ./lambda
jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
environment: production
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Set Image uri
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}
run: |
echo "image_uri=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_ENV # 이미지 uri 변수 만들기 (아래 스텝에서 같이 만들면 변수 값 없음)
- name: Build, tag, and push image to Amazon ECR
id: build-image
working-directory: ${{ env.WORKING_DIRECTORY }}
run: |
echo "build and push to ${{ env.image_uri }}"
docker build -t ${{ env.image_uri }} --build-arg LAMBDA_ENV=prod .
docker push ${{ env.image_uri }}
- name: Update image url of Lambda layer
run: |
echo "update Lambda image url to ${{ env.image_uri }}"
aws lambda update-function-code --function-name $LAMBDA_FUNCTION --image-uri ${{ env.image_uri }}
# docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG --build-arg LAMBDA_ENV=prod FIRESTORE_TYPE=${{ secrets.FIRESTORE_TYPE }} .
# Dockerfile - github actions 에서 도커 이미지 빌드시 위와 같이 --build-arg LAMBDA_ENV=prod 를 설정해주고
# 아래처럼 해당 arg 이름을 ARG, ENV 로 설정해주면
# 해당 이미지로 만든 컨테이너까지 전달됨
# 파이썬 파일에서 os.environ.get('LAMBDA_ENV') == 'prod' 는 True
FROM amazon/aws-lambda-python:3.8
ARG LAMBDA_ENV
ARG FIRESTORE_TYPE
ENV FIRESTORE_TYPE ${FIRESTORE_TYPE}
ENV LAMBDA_ENV ${LAMBDA_ENV}
RUN /var/lang/bin/python3.8 -m pip install --upgrade pip
WORKDIR /var/task/
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["lambda_function.handler"]
참조 링크
- ECR을 사용하지 않고 바로 도커 이미지를 압축하여 람다 함수에 바로 적용하기 - https://blog.jakoblind.no/aws-lambda-github-actions/
- ECR에 이미지 올리기 https://aws.plainenglish.io/build-a-docker-image-and-publish-it-to-aws-ecr-using-github-actions-f20accd774c3