본문 바로가기

Infra/aws

Github Action과 AWS Code Deploy를 이용한 배포 파이프라인 자동화하기 (Step 1)

회사에서 매번 앱 런칭 할 때 마다 매번 새로운 서버를 올리는데 배포 파이프라인을 자동화하지 않아서 자잘한 변경사항이 있어도 모든 과정을 수동으로 다 업데이트해야하는 귀찮음이 있어서 CD/CI를 직접 공부하고 구축해보기로 했다. 

 

일단 그 첫 스텝으로 일반 EC2 인스턴스에 Nest.js 앱을 github action과 aws code deploy로 배포해보기로 했다. (docker container로 올리는것 까지)  

 

출처 : https://github-wiki-see.page/m/prgrms-web-devcourse/Team_17TOP_Film_BE/wiki/CI-CD

 

배포 플로우 

  1. github 레포지토리의 master 브랜치에 commit이 발생
  2. github action 으로 프로젝트 빌드 후 S3에 zip 업로드 
  3. CodeDeploy는 빌드된 zip 파일을 s3로 부터 가져와서 ec2에 deploy

 

환경 

  • EC2 instance: t3a.small (회사에서 사용하는 인스턴스라 선택했는데 적당한 네트워크 성능을 가진 인스턴스면 아무거나 괜찮을듯 하다)
  • instance os : ubunut 20.04
  • application : nest.js  
  • node image : node:16-alpine

 

이제 본격적으로 배포를 해보자 

* AWS IAM 사용자 key 생성과 정책연결 방법은 여기서는 생략한다. (나는 S3 full access와 codeDeploy full access 정책을 추가했다.) 

 

Step 1 github action -> s3

1. S3 bucket, EC2 인스턴스 생성

- 빌드 결과물을 저장할 S3 bucket 과 애플리케이션을 배포할 EC2 인스턴스를 생성한다. 

 

2. EC2 IAM Role 변경 

배포할 인스턴스>작업>보안>IAM 역할 수정 에 들어가서 EC2의 IAM role을 연결해준다. 

나는 AmazonS3FullAccess, AWSCodeDeployFullAccess, AWSCodeDeployRole 권한을 가진 role을 연결해줬다.

(추후에 정확히 필요한 권한만 연결하도록 수정하는게 좋을듯하다)

 

3. CodeDeploy application 생성 

- 적당한 이름을 설정하고, EC2를 사용하므로 컴퓨팅 플랫폼은 EC2/온프레미스를 선택한다.

 

4. CodeDeploy application 배포 그룹 생성 

- 배포그룹이름 : 알아서

- 서비스 역할 : EC2 IAM 에 설정해준 권한과 같은 role를 설정했다 

- 배포 유형 : 현재 위치 

- 환경 구성 > Amazon EC2 인스턴스 : Amazon EC2 인스턴스에서 본인이 원하는 태그를 이용하여 배포하기 위해 만든 EC2 인스턴스를 연결해준다.  

- AWS Systems Manager를 사용한 에이전트 구성 > AWS CodeDeploy 에이전트 설치 : Command를 사용하여 설치하는 방식을 사용했기 때문에 '안 함' 선택

- 배포 설정 > 배포 구성 : CodeDeployDefault.AllAtOnce

- 로드 밸런서 : 로드 밸런싱 활성화 해제

 

간단한 배포를 연습하기 위해 위 설정으로 배포 그룹 설정했고, 다른 설정들은 추후에 더 공부해서 사용해보도록하자. 

 

5. github에 Secret key 등록 

배포할 repository 에서 Settings>Secrets>Actions에서 계정의 access key, secret access key, region을 적당한 key string으로 등록해준다. 

 

6. Github action workflow 설정 파일 작성

- 배포할 project repository의 Action 탭에 들어가면 workflow를 작성할 수 있는데 다른 사람이 만들어 놓은 workflow 설정파일 템플릿을 사용해도되고 직접 작성해도된다. 여기서는 set up a workflow yourself를 클릭해서 직접 생성했다. 

 

- 여기서 사용한 설정 항목에 대한 간략한 설명 

  • on : workflow가 어떤 이벤트에 대해 실행될지 지정
  • runs-on : job을 실행할 운영체제 
  • steps: job의 동작을 정의
  • uses : 각 스탭에서 사용할 액션을 지정, https://github.com/marketplace?type=actions 여기서 다른 사람들이 만들어놓은 액션을 사용할 수 있다. 
  • name : 각 스텝에서 표시되는 이름 
  • run : 시스템 shell 명령어 실행 
  • env : 환경변수 설정 

참고 : https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions

 

 

Workflow syntax for GitHub Actions - GitHub Docs

About YAML syntax for workflows Workflow files use YAML syntax, and must have either a .yml or .yaml file extension. If you're new to YAML and want to learn more, see "Learn YAML in Y minutes." You must store workflow files in the .github/workflows directo

docs.github.com

- 이 프로젝트에서 작성한 workflow 설정 파일은 아래와같다. 

# This is a basic workflow to help you get started with Actions

name: Deploy

# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the "master" branch
  push:
    branches: [ "master" ]
  pull_request:
    branches: [ "master" ]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v3

      # Runs a single command using the runners shell
      - name: Check Node
        run: node -v

      # 의존파일 설치
      - name: Install Dependencies
        run: npm ci
        
      # Build
      - name: Build
        run: npm run build
        
      # zip 파일 생성
      - name : zip create
        run : zip -qq -r "build 결과물 zip 이름(ex build.zip)" .
        shell : bash 
      
      # with에 secrets에서 설정한 key를 설정한다. 
      
      - 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: ${{ secrets.AWS_REGION }} 
      
      - name: Upload to S3
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        run: |
          aws s3 cp --region "업로드할 s3 region" "build 결과물 zip 이름(ex build.zip)" s3://"bucket_name"
      
      - name: Deploy
        run: aws deploy create-deployment
          --application-name "CodeDeploy 애플리케이션 이름"
          --deployment-config-name CodeDeployDefault.AllAtOnce
          --deployment-group-name "CodeDeploy 그룹 이름"
          --s3-location bucket="s3 버킷 이름",key="build 결과물 zip 이름",bundleType=zip

 

 

 

- yml 파일을 github에서 작성하고 커밋을 하면 자동으로 workflow 가 동작을 하고, 빌드에 성공하면 s3에 빌드 결과물 파일(여기서는 build 결과물 zip 파일)이 업로드된다. 

 

- workflow 파일을 작성 후 개발환경에서 pull을 해보면 .github/workflows 디렉토리에 작성한 yml 파일이 pull 된다.

 

- 이제부터 workflow 설정 파일의 on 에 지정한 작업(여기서는 master branch에 pull request나 push) 을 하면 자동으로 github action이 build 프로세스를 진행한다.