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 에서 변수 선언
  • 테스트 당시 람다 함수를 초기 생성시 도커 이미지로 선택하지 않고 기본 값으로 설정하니 도커가 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"]

 

참조 링크