Github Actions, AWS Codedeploy 배포 자동화(2)

이전 글에서 Github Actions, Codedeploy 배포 자동화에 필요한 AWS 세팅을 모두 끝냈고 
이번 포스팅에선 .yml .sh 파일을 이용해 개체들을 연결해 보려고 한다.


1. EC2 인스턴스에 Codedeploy 설치


1) awscli 설치

EC2 인스턴스에 Codedeploy를 설치하기 전에 awscli 라는 AWS의 API 호출을 도와주는 툴을 설치해야 하는데, awscli 는 python 으로 만들어졌기 때문에 python 부터 깔아주자.
(EC2 인스턴스가 아마존 리눅스라면 awscli 가 내장되어 있다 - 여기선 ubuntu 기준으로 작성했다.)

sudo apt-get update

sudo apt-get install python3         -->    파이썬 설치

curl -O https://bootstrap.pypa.io/get-pip.py

python3 get-pip.py --user        -->    pip 설치

ModuleNotFoundError: No module named 'distutils.util' 오류가 뜬다면

sudo apt-get install python3-distutils

- pip3 PATH 설정

ls -a ~

위 명령어를 입력하고, 쉘 스크립트에 따라(아래 파일 중 하나만 있음)
.bash_profile , .bash_login , .profile , .zshrc , .tcshrc , .cshrc , .login 
파일을 열어 PATH=~/.local/bin:$PATH  의 앞에 export를 추가한다.

export PATH=~/.local/bin:$PATH

source ~/파일이름
으로 변경 사항을 저장한다.

pip3 install awscli --upgrade        -->    awscli 설치

여기까지 진행했다면 awscli 가 설치되어 aws 명령어를 사용할 수 있다.

aws configure

위 명령어로 IAM 사용자를 등록해주자.

이제부터 이전 글에서 따로 소중히 보관해뒀던 액세스 키 페어가 쓰인다!
키 페어를 입력하고 region name 은 ap-northeast-2(서울) , format은 json으로 입력해주자.


2) Codedeploy 설치


aws s3 cp s3://aws-codedeploy-ap-northeast-2/latest/install . --region ap-northeast-2
-->     Codedeploy Install 파일 다운로드

chmod +x ./install     -->    Install 파일에 실행 권한 추가

sudo ./install auto     -->    설치 시작

아마존 리눅스라면 ruby가 기본적으로 깔려 있기 때문에 바로 진행되지만, 우분투는 직접 깔아주어야 한다.

sudo apt-get install ruby-full     -->     ruby 설치

sudo service codedeploy-agent start     -->     codedeploy 실행

sudo service codedeploy-agent status 를 입력하면

Codedeploy agent가 실행중이다.
여기까지 EC2 에서의 설정이 모두 끝났다~!
이제 Github 로 ㄱㄱㅅ~~

5. Github 설정 및 appspec.yml, 쉘 스크립트 작성


1) Github Secret에 액세스 키 페어 등록


Github Actions 에서 S3 에 접근하기 위해선 사용자 인증을 해야 하는데, 그럴려면 위에서도 사용했던 액세스 키 페어가 필요하다.
하드코딩으로 프로젝트 내에 키 페어를 넣어버리면 아마존에서 친히 전화를 해준다..ㅎ
(레포지토리 날아간다..)
Github에서 제공하는 기능 중에 Secrets 라는 기능이 있는데, 해당 레포지토리 내에서 사용 가능한 변수를 만들어 준다.(환경 변수처럼 사용이 가능)
액세스 키 페어를 Secrets 에 등록해보자.

Github 레포지토리의 Settings -> Secrets 탭 -> New secret


이름(키 값)과 Value 를 정해주자.
액세스 키에 대한 변수와 액세스 시크릿 키에 대한 변수 두 개를 만들어 주면 된다.


Secrets 변수가 만들어졌다.
Secrets 변수는 한 번 만들면 Value 값을 다신 확인할 수 없다. 새로 등록하거나 삭제만 가능하다.


2) Github Workflow 작성


workflow가 작성되어 있는 Github 레포지토리에 커밋이 들어오면 workflow가 자동으로 실행되어 CI(지속적 통합)이 수행된다.
우리가 작성한 workflow 파일의 흐름대로 프로젝트를 빌드하고, 테스트하는 작업을 자동으로 해준다. (가상의 OS 가 생성되어 그 위에서 동작한다)
또, aws 와의 연동을 통해 빌드, 테스트가 완료된 프로젝트를 aws S3 로 전송할 수도 있다!

Github 레포지토리의 Actions 탭을 처음 들어가면 위와 같은 화면이 나온다.
Github 에선 여러가지 언어의 미리 구현된 workflow 환경들을 제공해준다.
우리는 딱히 많은 기능이 필요없기 때문에 직접 커스텀하도록 하자.

name: Deploy
on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

env:
  PROJECT_NAME: web-cloning
  BK_NAME: samplebk1234
  APP_NAME: sampleApp
  DEPLOY_GROUP: sampleDeployGroup   

jobs:
  build:
    name: Build, EC2
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2

    - name: Make zip file
      run: zip -qq -r ./$GITHUB_SHA.zip .
      shell: bash

    - name: Transfer to EC2
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_IAM_MANAGE_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_IAM_MANAGE_SECRET_ACCESS_KEY }}
        aws-region: ap-northeast-2

    - name: Upload to S3
      run: aws s3 cp --region ap-northeast-2 ./$GITHUB_SHA.zip s3://$BK_NAME/$PROJECT_NAME/$GITHUB_SHA.zip

    - name: Code Deploy
      run: aws deploy create-deployment --application-name $APP_NAME --deployment-config-name CodeDeployDefault.OneAtATime --deployment-group-name $DEPLOY_GROUP --s3-location bucket=$BK_NAME,bundleType=zip,key=$PROJECT_NAME/$GITHUB_SHA.zip

위 코드가 필자가 작성한 .yml 파일이다.
코드가 상당히 직관적으로 되어 있는데, 여러 개의 연속 혹은 병렬로 실행되는 하나 이상의 jobs 와 각 jobs 마다 steps 를 수행하게끔 되어있다.
하나하나 코드를 뜯어보자.

name: Deploy
on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

name : 콘솔에 표시될 이름이다. 각 수행의 이름이 표시된다.
on : 해당 파일이 실행될 조건을 정해준다. push, pull_request, schedule을 트리거로 사용할 수 있다.

env:
  PROJECT_NAME: web-cloning
  BK_NAME: samplebk1234
  APP_NAME: sampleApp
  DEPLOY_GROUP: sampleDeployGroup   

아래에서 사용될 환경 변수를 지정할 수 있다.
가독성 및 오타 방지를 위해 자주 쓰일 변수를 미리 만들어주자.

jobs:
  build:
    name: Build, EC2
    runs-on: ubuntu-latest

build 라는 job을 생성했고, ubuntu-latest 환경에서 실행된다.

steps:
    - uses: actions/checkout@v2

    - name: Make zip file
      run: zip -qq -r ./$GITHUB_SHA.zip .
      shell: bash

uses : 여러가지 미리 정의된 액션을 수행할 수 있다.
run, shell : bash 쉘에서 해당 run의 명령어를 수행한다.

$GITHUB_SHA : Github에서 기본적으로 제공되는 환경 변수다. 매 커밋마다 다른 이름의 zip 파일이 생성되도록 하기 위해 사용했다.

위 run 명령어로 전체 프로젝트가 압축된다.

- name: Transfer to EC2
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_IAM_MANAGE_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_IAM_MANAGE_SECRET_ACCESS_KEY }}
        aws-region: ap-northeast-2

AWS 에서 제공하는 액션을 사용해 AWS API 를 사용할 수 있게끔 인증하는 부분이다.
위에서 설정한 Secrets 변수를 이용해 인증해 주었다.

- name: Upload to S3
      run: aws s3 cp --region ap-northeast-2 ./$GITHUB_SHA.zip s3://$BK_NAME/$PROJECT_NAME/$GITHUB_SHA.zip

AWS API 를 이용해 S3 버킷으로 압축된 프로젝트 파일을 전송한다.


- name: Code Deploy
      run: aws deploy create-deployment --application-name $APP_NAME --deployment-config-name CodeDeployDefault.OneAtATime --deployment-group-name $DEPLOY_GROUP --s3-location bucket=$BK_NAME,bundleType=zip,key=$PROJECT_NAME/$GITHUB_SHA.zip

Codedeploy Application 의 배포 그룹으로 배포가 진행된다.

여기까지 했다면 Github 커밋 -> 빌드 -> S3 로 프로젝트 전송까지 자동화가 되었다.
위 .yml 파일을 프로젝트에 커밋하면, 자동으로 Actions 가 수행된다.


오류없이 잘 작동했다.👍
만약 오류가 났다면 오타를 잘 확인해보자.
여기까지 하고 AWS Codedeploy를 확인해보면 당연히 배포가 실패했을 거다.
파일을 받았으면 그 파일로 뭘 어떻게 배포하란 건지 Codedeploy한테 알려줘야 한다.


3) appspec.yml , deploy.sh 작성


Codedeploy agent는 프로젝트 내의 appspec.yml 이란 파일의 내용대로 배포를 수행한다.
AWS의 appspec.yml 문서에 자세한 내용이 있다.
appspec 내용은 아직 더 공부해야 될 거 같고, 배포 자동화를 성공시키는게 목표기 때문에 정말 간단하게 작성했다.

version0.0
oslinux

files:
  - source/
    destination/server
permissions:
  - object/server/
    ownerubuntu
    groupubuntu
    mode755
hooks:
  AfterInstall:
    - locationdeploy.sh
      timeout720
      runasroot

파일이 저장될 위치를 지정하고, EC2 인스턴스(우분투)의 기본 사용자인 ubuntu를 설정하고, AfterInstall 시에 프로젝트 내의 deploy.sh 쉘 스크립트를 root 사용자가 실행하게끔 했다.
720 초 동안 배포가 끝나지 않으면 실패하도록 설정했다.

이제 정말 마지막으로 deploy.sh 만 남았다.
이 파일은 배포를 할 때 필요한 명령어들이 모여 있는 파일이다.
본인의 프로젝트 환경에 따라 맞춰서 명령어들을 작성하면 된다.

#!/usr/bin/env bash

REPO=/server
cd ${REPO}

sudo npm install

npm run-script dev

package.json 의 dependecies 에 맞게 모듈을 업데이트하고, 서버를 실행시켜 주는 명령어만 작성했다.


배포 자동화가 드디어 끝났다!! 
이제 Github에 프로젝트를 커밋하기만 하면 세팅한 대로 자동으로 배포까지 완료가 된다.
3일동안 온갖 자료들을 찾아가며 꾸역꾸역 구현에 성공했는데 스무스하게 배포되는 걸 보니 
너무 편-안하다.
한 번 세팅해두면 개발에만 집중할 수 있으니 고생한 시간이 아깝진 않은 것 같다.👍

댓글

이 블로그의 인기 게시물

HTML - input file 버튼 꾸미기

HTML - 이미지 미리보기(jQuery 없이)

BOJ - DNA 유사도(2612)