Github Actions AWS EC2 Code Deploy 예제 2 (이전 완료)
github actions를 사용하여 EC2 인스턴스에 자동으로 배포 하게되는 플로우 입니다.
전체 진행은 다음과 같습니다.
- github actions는 이벤트(Pull Request, Push 등) 를 통해 workflow를 실행
- workflow는 EC2로 배포된 파일을 S3로 저장합니다.
- workflow는 CodeDeploy를 통해 2. 에서 저장한 파일을 EC2로 배포합니다.
- (선택) CodeDeploy는 배포가 완료된 이후 스크립트를 실행합니다.
이 포스팅 에서는 github actions를 위한 세팅에 대해 다룹니다.
1. workflow 파일 만들기
Github Actions workflow를 활성화 하기 위해선 적절한 yml 파일이 필요합니다.
해당 yml파일의 위치는 /.github/workflows/ 경로에 존재하여야 합니다.
1.1 yml파일
다음은 workflow를 구성하는 yml파일 예시 입니다.
name: Master Branch Build And Push DockerHub
on:
push:
branches:
- master
jobs:
aws_deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: make zip
run: |
zip -r ./test.zip .
shell: bash
- name: configure AWS
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: ap-northeast-2
- name: upload s3
run: aws s3 cp --region ap-northeast-2 ./test.zip s3://${{secrets.AWS_BUCKET_NAME}}/test1/test.zip
- name: code deploy
run: aws deploy create-deployment --application-name ${{secrets.DEPLOY_APPLICATION_NAME}} --deployment-config-name CodeDeployDefault.OneAtATime --deployment-group-name ${{secrets.DEPLOY_GROUP_NAME}} --s3-location bucket=${{secrets.AWS_BUCKET_NAME}},bundleType=zip,key=p1/test.zip
1.1.1 on
이벤트를 정의하며, 해당 예제에서는 master브랜치가 push 되었을때 해당 workflow가 실행됩니다.
1.1.2 jobs
해당 workflow에는 하나의 job (aws_deploy)가 존재합니다.
jobs.aws_deploy
aws_deploy는 하나의 job 입니다. job에서는 여러 step들이 실행됩니다.
jobs.aws_deploy.runs-on
해당 job은 ubuntu 호스트 위에서 실행됩니다.
jobs.aws_deploy.steps
진행될 작업들의 집합입니다.
- Checkout
- make zip
- configure AWS
- upload s3
- code deploy
5개의 작업으로 이루어져 있습니다.
jobs.aws_deploy.steps.Checkout
workflow가 해당 repository에 접근하기 위해 checkout을 해줍니다.
jobs.aws_deploy.steps.make zip
s3에 업로드 하기 위해 zip 형태로 만들어 줍니다.
appspec.yml파일이 압축시킨 경로의 root path에 존재해야 합니다!! (뒤에서 다룸)
jobs.aws_deploy.steps.configure AWS
AWS cli를 다루기 위해 AWS configure를 진행합니다.
이때 사용되는 access key나 secret key는 이전 포스트에서 설명한 사용자 csv파일에 나와있습니다.
region은 서울(ap-northeast-2)로 지정해 줍니다.
${{{secrets.}}에 대해선 아래에서 다룹니다
jobs.aws_deploy.steps.upload s3
이제 만들어진 zip 파일을 s3로 업로드 하는 명령입니다.
aws s3 cp --region ap-northeast-2 ./test.zip s3://${{secrets.AWS_BUCKET_NAME}}/test1/test.zip
ap-northeast-2라는 region에
./test.zip 파일을
${{secrets.AWS_BUCKET_NAME}} 버킷의 /test1 폴더에 test.zip 이라는 객체로 저장합니다.
버킷은 파일시스템으로 파일들을 관리하는것이 아닌, 객체 단위로 파일들을 관리합니다. 하지만 편의상 파일 디렉토리처럼 표현해 줍니다.
jobs.aws_deploy.steps.code deploy
s3에 있는 코드를 배포하는 단계입니다.
aws deploy create-deployment \
--application-name ${{secrets.DEPLOY_APPLICATION_NAME}} \
--deployment-config-name CodeDeployDefault.OneAtATime \
--deployment-group-name ${{secrets.DEPLOY_GROUP_NAME}} \
--s3-location bucket=${{secrets.AWS_BUCKET_NAME}},bundleType=zip,key=p1/test.zip
명령의 옵션은 다음과 같습니다.
- –application-name : codedeploy의 이름입니다.
- –deployment-config-name : deploy설정입니다.
- –deployment-group-name : 배포 그룹 이름입니다.
- –s3-location bucket : s3 버켓 이름입니다. bundleType : 압축 타입 key : 객체의 경로 입니다 (S3가 파일 시스템은 아니지만 경로를 통해 나타냅니다.)
2. secrets
github actions의 secrets는 외부로 노출되서는 안될 값들을 다룰때 사용됩니다. 예를들어 access token이나, secret key등을 다룰때는 yml파일에 그대로 노출시키지 않고, secrets를 설정하여 ${{secrets.FOO}} 형태로 사용하게 됩니다.
secrets 설정은 다음과 같이 진행합니다.
github repository settinggithub의 repository setting 페이지에 간다면, Secrets => Actions 탭이 있습니다.
new repository secret여기서 new repository secret 버튼을 눌러 새로운 secret을 만듭니다.
create secret여기서 name과 value를 설정해주면 끝납니다.
이제 저 secret은 workflow yml 파일에서 ${{secrets.FOO}}로 사용되게 되고, workflow가 진행하면서 BAR라는 값으로 치환되어 사용됩니다.
3. appspec.yml
3.1 배포파일 압축
배포를 위해선 압축시킨 파일의 루트 경로에 appspec.yml이라는 배포를 위한 파일이 존재하여야 합니다.
우리가 이 workflow에서 배포할 파일은 test.zip 이라는 파일입니다.
이 파일은 make zip 단계에서 zip -r ./test.zip . 명령을 통해 repository 전체를 test.zip이라는 파일로 압축합니다.
이때 test.zip이 압축시킬 repository의 구조는 다음과 같습니다.
zip -r ./test.zip .
이렇게 압축할 경우 압축시킨 root path에 appspec.yml이 존재하므로, 배포가 정상적으로 이루어지게 됩니다.
하지만 압축을 zip -r ./test.zip ./test_dir1 로 하여 test.zip의 root path에 appspec.yml파일이 존재하지 않는다면, 이는 deploy시 오류가 발생하게 됩니다.
하지만 아래 그림과 같이 appspec.yml 파일이 test_dir1 디렉토리 내부에 있다면, zip -r ./test.zip ./test_dir1 로 압축하여 deploy하여도 zip 디렉토리의 루트경로에 appspec.yml이 존재하게 되므로 문제가 없습니다.
zip -r ./test.zip ./test_dir1
3.2 appspec.yml 작성
appspec.yml 작성 예시입니다.
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu/run_script
permissions:
- object: /home/ubuntu/run_script
owner: ubuntu
group: ubuntu
hooks:
AfterInstall:
- location: ./init.sh
timeout: 360
runas: ubuntu
3.2.1 version
version은 0.0으로 고정값입니다.
3.2.2 os
linux 고정값입니다.
3.2.3 files
배포시킬 파일들을 지정합니다.
files.source
배포시킬 파일들을 지정합니다.
배포시킬 경로는 S3에 올라가있는 test.zip을 기준으로 경로가 계산됩니다.
만약 예시파일처럼 /로 되어있다면 test.zip의 모든 파일들을 배포하게 되므로 바로 위에서 예로든 test.zip을 기준으로 본다면
- appspec.yml
- test_dir1
- test_dir2
- init.sh
4개의 파일 및 디렉토리가 ec2에 배포되게 됩니다.
하지만 특정 파일, 디렉토리만을 배포하고 싶다면 해당 디렉토리 경로를 적어주면 됩니다.
source: /test_dir1로 지정되어 있다면 ec2에는 test_dir1 디렉토리만 배포되게 됩니다.
files.destination
배포시킬 ec2의 경로 입니다. source에서 지정한 파일들이 해당 호스트 경로에 배포됩니다.
3.2.4 permissions
배포시킨 파일에 대한 권한을 설정합니다.
permissions.object
권한을 적용할 경로입니다.
permissions.owner
해당 경로내의 파일들의 소유권을 지정합니다
permissions.group
해당 경로내의 파일들의 그룹을 지정합니다
hooks
AWS의 Code Deploy의 생명주기는 다음과 같습니다.
hooks는 위 그림중 하늘색으로 칠해진 시점에서 설정할 수 있게 됩니다.
Install 단계를 지나게 되면 파일의 배포가 완료되게 됩니다. 위 예시에서는 AfterInstall 시점에 hooks를 설정하였으므로
S3로부터 EC2로 파일의 배포가 완료된 이후 init.sh라는 스크립트를 실행하게 됩니다.
location
배포시킨 파일중 실행시킬 스크립트를 지정합니다.
timeout
timeout을 지정합니다
runsas
스크립트를 실행시킬 유저를 선택합니다.
여기까지 진행하면 github actions를 위한 세팅이 완료됩니다.