결론부터 말하자면 본인은 만족하는 유익한 업무이자 학습 시간이 되었다.
코드는 아래와 같다.
name: Deploy lambda function
on:
push:
branches:
- main
- dev
- 'feature/test'
- 'feature/test2'
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: ${{ secrets.AWS_REGION }}
PROD_FUNC_NM: ${{ secrets.PROD_FUNC_NM }}
DEV_FUNC_NM: ${{ secrets.DEV_FUNC_NM }}
DEV_ALIAS_NM: ${{ secrets.DEV_ALIAS_NM }}
jobs:
deploy_source:
name: Deploy lambda by github push
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install Node Module
if: github.ref != 'refs/heads/feature/test2'
run: npm install
- name: Compress Code to Zip File
run: zip -r9 code.zip *
- name: Upload code to prod
if: github.ref == 'refs/heads/main'
run: aws lambda update-function-code --function-name $PROD_FUNC_NM --zip-file fileb://code.zip
- name: Upload code to test
if: contains(fromJSON('["refs/heads/feature/test", "refs/heads/feature/test2"]'), github.ref)
run: aws lambda update-function-code --function-name $DEV_FUNC_NM --zip-file fileb://code.zip
publish_version:
needs: deploy_source
name: Publish version old lambda function
runs-on: ubuntu-latest
outputs:
nv: ${{ steps.nv.outputs.NEW_VERSION }}
steps:
- name: Publish test
id: nv
if: github.ref == 'refs/heads/feature/test'
run: |
NEW_VERSION=$(aws lambda publish-version --function-name $DEV_FUNC_NM --description test2 --query Version --output text)
echo "NEW_VERSION=$NEW_VERSION" >> "$GITHUB_OUTPUT"
- name: Publish test2
if: github.ref == 'refs/heads/feature/test2'
run: aws lambda publish-version --function-name $DEV_FUNC_NM --description test2
inquire_alias:
needs: publish_version
name: Inquire Alias Information
runs-on: ubuntu-latest
outputs:
ov: ${{ steps.ov.outputs.OLD_VERSION }}
nv: ${{ needs.publish_version.outputs.nv }}
steps:
- name: Inquire dev lambda alias information
id: ov
if: github.ref == 'refs/heads/feature/test'
run: |
OLD_VERSION=$(aws lambda get-alias --function-name $DEV_FUNC_NM --name dev --query FunctionVersion --output text)
echo "OLD_VERSION=$OLD_VERSION" >> "$GITHUB_OUTPUT"
update_alias:
needs: inquire_alias
name: Update Alias Information
runs-on: ubuntu-latest
steps:
- name: Update dev lambda alias information
if: github.ref == 'refs/heads/feature/test'
run: aws lambda update-alias --function-name $DEV_FUNC_NM --function-version ${{ needs.inquire_alias.outputs.ov }} --routing-config AdditionalVersionWeights={"${{ needs.inquire_alias.outputs.nv }}"=0.1} --name $DEV_ALIAS_NM
이전에 비해서 상당히 길어지도 뭔가 추가되고 눈에 보기에 복잡해졌다.
많은 시행착오를 거치고 이건 필요한데 어떻게 안될까? 라는 고민으로 탄생한 초보자의 결과물 이지만 후일 더 나은 발전을 위해 기록하고자 한다.
진행 단계는 다음과 같다.
1. 타게팅
- name : 깃허브 액션 탭에서 좌측에 표시될 해당 작업의 이름
- on : "push"를 하는데 "branches"아래 정의된 브랜치에 푸시될때 동작
name: Deploy lambda function
on:
push:
branches:
- main
- dev
- 'feature/test'
- 'feature/test2'
2. 노드의 .env, java의 yml 파일과 같은 환경변수 정의
- Github secrets에 정의하여 사용
- 정의할 레포지토리 > Settings > Secrets and variables > Actions > New repository secret
- Github Action에 env 로 등록
AWS를 사용하므로 키값과 리전 정의
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: ${{ secrets.AWS_REGION }}
PROD_FUNC_NM: ${{ secrets.PROD_FUNC_NM }}
DEV_FUNC_NM: ${{ secrets.DEV_FUNC_NM }}
DEV_ALIAS_NM: ${{ secrets.DEV_ALIAS_NM }}
3. TODO의 느낌
- jobs에 해야할 일을 정의 및 정리
- 첫번째 할일의 제목 정하기
- 일의 제목을 정했으니 세부로 들어가기 위한 부재로 name 정하기
- 부재가 정해졌으니 해당 액션을 돌릴 기반 runs-on 정하기 -> [runs-on]
- 어렸을 때 작성한 생화계획표마냥 단계 만들기
jobs:
deploy_source:
name: Deploy lambda by github push
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install Node Module
if: github.ref != 'refs/heads/feature/test2'
run: npm install
- name: Compress Code to Zip File
run: zip -r9 code.zip *
- name: Upload code to prod
if: github.ref == 'refs/heads/main'
run: aws lambda update-function-code --function-name $PROD_FUNC_NM --zip-file fileb://code.zip
- name: Upload code to test
if: contains(fromJSON('["refs/heads/feature/test", "refs/heads/feature/test2"]'), github.ref)
run: aws lambda update-function-code --function-name $DEV_FUNC_NM --zip-file fileb://code.zip
name: Checkout > git에서 특정 브랜치로 checkout하는거랑 같습니다.
name: Install Node Module > 노드모듈들을 설치 하는데!
if: github.ref != 'refs/heads/feature/test2' > feature/test2 브랜치 일때는 패스
run: npm install > 설치
name: Compress Code to Zip File > 현재 브랜치에 올라온 파일들 압축하는데
zip -r9 code.zip * > 이 명령어로 압축
name: Upload code to ~~~ > 업로드 할껀데 어디에?
if: ~~~ > 특정 브랜치면 특정 Lambda 함수에 그리고 어떻게?
run: aws lambda update-function-code --function-name ~~~ --zip-file fileb://code.zip > aws lambda update-function-code 라는 함수를 이용하여 코드 업로드(업데이트)
위처럼 if문에 or 형태로 분기쳐야할때는?
contains(fromJSON('["refs/heads/feature/test", "refs/heads/feature/test2"]'), github.ref)
이런식으로 가능합니다.
주의 : runs-on에 따라 aws 명령어가 사용되지 않을 수 있습니다.
여기서부터는 불필요의 영역일 수 있습니다.
4. 버전관리, 이력관리, 히스트관리
- 만약 핫픽스로 급하게 새로이 올린 코드에 문제가 발생하거나 의도치 않은 동작으로 이전 코드로 되돌려야할 경우를 대비하여 현재 코드의 버전을 부여하여 git처럼 버전을 관리해야 할 경우
publish_version:
needs: deploy_source
name: Publish version old lambda function
runs-on: ubuntu-latest
outputs:
nv: ${{ steps.nv.outputs.NEW_VERSION }}
steps:
- name: Publish test
id: nv
if: github.ref == 'refs/heads/feature/test'
run: |
NEW_VERSION=$(aws lambda publish-version --function-name $DEV_FUNC_NM --description test2 --query Version --output text)
echo "NEW_VERSION=$NEW_VERSION" >> "$GITHUB_OUTPUT"
- name: Publish test2
if: github.ref == 'refs/heads/feature/test2'
run: aws lambda publish-version --function-name $DEV_FUNC_NM --description test2
outputs: > 추후 Lambda의 Alias 기능을 사용하면서 최신 버전을 자동으로 사용할 목적이라면 기입 :: run으로 동작한 코드의 결과값을 지역변수로 선언한다고 생각하시면 됩니다.
또한 여러개의 변수가 다른 작업에서 선언되어야 한다면 id: ~ 옵션을 이용하시면 됩니다.
needs: ~~~ > 선행되어야 하는 작업이 존재하며 해당 작업이 완료된 후에 실행이 되어야하는 작업이라면 위 정의된 name 부분을 기입해야합니다.
run: | > "|" 를 사용하여 여러행의 명령어를 실행. 터미널에서 "&&"과 비슷
+ 변수명=$(~~~) "$"와 "()"로 감싼부분은 --query 옵션에 선언된 변수를 찾아 --output옵션에 정의된 형태로 "변수명"에 저장됩니다.
5. Lambda의 Alias기능 사용을 위해 기존 Alias 정보 조회
inquire_alias:
needs: publish_version
name: Inquire Alias Information
runs-on: ubuntu-latest
outputs:
ov: ${{ steps.ov.outputs.OLD_VERSION }}
nv: ${{ needs.publish_version.outputs.nv }}
steps:
- name: Inquire dev lambda alias information
id: ov
if: github.ref == 'refs/heads/feature/test'
run: |
OLD_VERSION=$(aws lambda get-alias --function-name $DEV_FUNC_NM --name dev --query FunctionVersion --output text)
echo "OLD_VERSION=$OLD_VERSION" >> "$GITHUB_OUTPUT"
4번과 대부분이 비슷하며 outputs 부분에 위 선행된 작업의 변수를 참조하여 가져오기 위해
${{ needs.job_name.outputs.output_name }} 의 형태로 선언합니다.
6. Lambda Alias 추가 혹은 수정
update_alias:
needs: inquire_alias
name: Update Alias Information
runs-on: ubuntu-latest
steps:
- name: Update dev lambda alias information
if: github.ref == 'refs/heads/feature/test'
run: aws lambda update-alias --function-name $DEV_FUNC_NM --function-version ${{ needs.inquire_alias.outputs.ov }} --routing-config AdditionalVersionWeights={"${{ needs.inquire_alias.outputs.nv }}"=0.1} --name $DEV_ALIAS_NM
run: 부분을 보시게 되면 아래와 같은 옵션이 존재합니다.
--routing-config AdditionalVersionWeights={"${{ needs.inquire_alias.outputs.nv }}"=0.1}
위 코드는 0.1은 Alias 선언시 가중치를 선언하는 부분으로 해당 버전이 10%의 가중치를 갖도록 합니다.
안타깝게도 2개만 되고 3개 이상은 안되서 매우 아쉬워했습니다.....
'GitHub' 카테고리의 다른 글
Github Action 으로 AWS Lambda 자동 배포하기(3) (0) | 2024.05.07 |
---|---|
Github Action 으로 AWS Lambda 자동 배포하기 (0) | 2022.12.25 |