DevOps/AWS

AWS CodeDeploy를 Node.js환경에서 Github Actions에서 사용하기!

JangKroed 2023. 3. 18. 20:32
728x90
반응형

사용한 버전

이름 버전
ubuntu 20.04.6
node 18.15.0
npm 9.5.0

 

AWS S3 버킷 생성

Github Actions에서 빌드한 프로젝트를 압축파일로 만든뒤 업로드 해둘 곳이 필요한데, S3를 만들어 이용한다.

AWS - S3 - 버킷 - 버킷 만들기를 눌러준다.

이름만 지정한 뒤 다른설정은 그대로 두고 버킷을 생성해준다.

 

EC2 IAM 역할 설정

EC2에서 S3와 CodeDeploy를 이용할 수 있게 권한을 주어야 한다.

AWS - IAM - 액세스 관리 - 역할 - 역할 만들기로 들어가준다.

다음을 눌러준다.

 

AWSCodeDeployFullAccess
AmazonS3FullAccess

두 가지 권한을 선택해주고 다음을 눌러준다.

 

역할 이름을 입력하여 역할을 생성해주고 EC2에 연결해준다.

 

AWS - EC2 - 인스턴스로 이동한 후 생성된 EC2인스턴스에 마우스를 대고 우클릭을하고 보안 - IAM 역할 수정을 선택한다.

 

 

CodeDeploy IAM 설정

EC2 IAM  설정 후 CodeDeploy도 IAM설정이 필요하다.

AWS - IAM - 액세스 관리 - 역할 - 역할만들기 선택

AWS서비스 및 CodeDeploy 선택 후 다음 선택

 

다음 선택

역할 이름을 입력하고 역할을 생성해준다.

 

CodeDeploy 애플리케이션 생성

AWS - CodeDeploy -  애플리케이션 - 애플리케이션 생성을 선택해준다.

애플리케이션 이름 입력 후 컴퓨팅 플랫폼을 EC2/온프레미스로 선택 후 애플리케이션 생성을 해준다.

정상적으로 생성이 되었다면 배포그룹을 생성해준다.

\

.배포 그룹 이름을 입력하고 서비스 역할에는 미리 생성해두었던 CodeDeploy IAM을 선택한다.

 

배포 유형은 건드리지 않고 환경 구성만 Amazon EC2 인스턴스를 선택하고 연결할 EC2 인스턴스의 태그 이름을 입력한다.

 

로드 밸런싱 활성화 체크가 되어있다면 해체한 뒤 배포 그룹 생성을 선택한다.

 

AWS IAM 사용자 추가

Github Actions에서 S3에 접근하여 파일을 업로드할 수 있게 IAM사용자를 추가한다.

AWS - IAM - 액세스 관리 - 사용자 - 사용자 추가를 선택한다.

 

사용자 이름 입력 후 AWS Management Console에 대한 사용자 액세스 권한 제공 체크 - IAM  사용자를 생성하고 싶음 선택한 후 다음으로 넘어간다.

 

직접 정책 연결에서 AWSCodeDeployFullAccess, AmazonS3FullAccess 를 체크 한 뒤 다음으로 넘어간다.

 

확인 후 사용자 생성 선택

 

사용자 목록으로 돌아가기 선택 후 보안 자격 증명 - 액세스 키 - 액세스 키 만들기 선택

 

액세스 키 만들기 선택

액세스 키와 비밀 액세스 키를 따로 메모하거나 .csv 파일을 다운로드 하고 완료를 눌러준다.

 

Github 환경변수 등록

env파일과 AWS access key, access secret  key를 깃허브에 업로드 하지 않으므로 깃허브에 등록해주어야 한다.

Settings - Security - Secrets - Actions로 이동하여 New repository secret을 눌러준다.

 

 

Github Actions workflow 생성

프로젝트 루트 폴더에서 .github/workflows/deploy.yml 파일을 생성하여 아래 코드를 입력해 준다.

name: project-cicd

on:
  push:
    branches: ['dev']
  pull_request:
    branches: ['dev']

jobs:
  buildAndTest:
    name: CI Pipeline
    runs-on: ubuntu-20.04
    strategy:
      matrix:
        node-version: [18.15.0]

    steps:
      - uses: actions/checkout@v3

      - name: Install Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'

      - name: Install dependencies
        run: npm install
      - name: Run build
        run: npm run build

  deploy:
    name: CD Pipeline
    runs-on: ubuntu-20.04

    strategy:
      matrix:
        node-version: [18.15.0]
    needs: buildAndTest
    steps:
      - uses: actions/checkout@v3
      - name: Create env file
        run: |
          touch .env
          cat << EOF >> .env
          ${{ secrets.ENV }}
      - name: Install Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'

      - name: Install dependencies
        run: npm install
      - name: Run build
        run: npm run build

      - name: zip file
        run: zip -r cicdtest.zip ./build/src ./build/server.js ./scripts ./appspec.yml ./.env ./package.json

      - name: AWS connect
        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 to S3
        run: aws s3 cp --region ap-northeast-2 ./cicdtest.zip s3://build-S3/build/

      - name: deploy with AWS codeDeploy
        run: aws deploy create-deployment
          --application-name codedeploy-app
          --deployment-config-name CodeDeployDefault.OneAtATime
          --deployment-group-name codedeploy-group
          --s3-location bucket=build-S3,bundleType=zip,key=build/cicdtest.zip

 

deploy.yml 구성

on: // github actions가 실행될 trigger
  push: 
    branches: ['dev'] // dev 브랜치에 push 할때 실행
  pull_request:
    branches: ['dev'] // dev 브랜치에 pull_request 할때 실행
jobs: // 사용할 가상환경을 설정
  buildAndTest:
    name: CI Pipeline
    runs-on: ubuntu-20.04 // 인스턴스의 버전
    strategy:
      matrix:
        node-version: [18.15.0] // node의 버전
    steps:
      - uses: actions/checkout@v3 // Github repository에 올려둔 코드를 CI서버로 받고 특정 브랜치로 전환하는 과정
      - name: Create env file // Github에 등록한 환경변수들로 .env 파일을 생성
        run: |
          touch .env
          cat << EOF >> .env
          ${{ secrets.ENV }}
      - name: Install Node.js ${{ matrix.node-version }} // 명시한 Node버전에 맞게 설치
        uses: actions/setup-node@v3 
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'

      - name: Install dependencies // 패키지 설치
        run: npm install
      - name: Run build // 빌드
        run: npm run build

      - name: zip file // 명시한 파일 및 폴더를 cicdtest.zip파일로 압축
        run: zip -r cicdtest.zip ./build/src ./build/server.js ./scripts ./appspec.yml ./.env ./package.json

      - name: AWS connect // S3에 접근하기 위한 IAM 사용자 키 값 등록
        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 to S3 // S3 cicdtest.zip파일 업로드
        run: aws s3 cp --region ap-northeast-2 ./cicdtest.zip s3://build-S3/build/

      - name: deploy with AWS codeDeploy // CodeDeploy 실행 및 마지막줄 경로에 압축을 풀어 EC2에 배포
        run: aws deploy create-deployment
          --application-name codedeploy-app
          --deployment-config-name CodeDeployDefault.OneAtATime
          --deployment-group-name codedeploy-group
          --s3-location bucket=build-S3,bundleType=zip,key=build/cicdtest.zip

 

appspec.yml 파일 작성

appspec.yml 파일은 CodeDeploy가 배포를 관리하는 애플리케이션 사양 파일이다.

CodeDeploy가 EC2에 프로젝트를 설치하고나면 EC2에서 이루어질 작업을 해당 파일에 작성할 수 있다.

 

프로젝트 루트 폴더에 appspec.yml 파일을 추가한다.

version: 0.0
os: linux
files:
  - source: /
    destination: /home/ubuntu/projects
    overwrite: yes

permissions:
  - object: /home/ubuntu
    pattern: "**"
    owner: ubuntu
    group: ubuntu

hooks:
  AfterInstall:
    - location: scripts/after-deploy.sh
      timeout: 300
      runas: ubuntu

destination - CodeDeploy가 EC2에 배포할 위치

location - 프로젝트가 옮겨지고 난 후 이루어질 작업을 작성한 파일경로

 

after-deploy.sh 파일 작성

프로젝트 루트 경로에 scripts 폴더를 생성 후 그 안에 after-deploy.sh 파일을 추가한다.

 

#!/bin/bash
REPOSITORY=/home/ubuntu/projects


cd $REPOSITORY

npm install

sudo su

pm2 kill

export NODE_ENV=production && pm2 start build/server.js

패키지 설치 후 관리자 권한으로 전환하고 이전에 실행중이던 프로젝트를 모두 종료하고 프로젝트를 실행한다.

 

EC2 CodeDeploy Agent 설치

node / npm / pm2 설치

curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
sudo apt-get install -y npm
sudo npm install -g pm2

awscli 설치

sudo apt update
sudo apt install awscli

AWS Access Key, Access Secret Key 입력

 sudo aws configure
AWS Access Key ID : 다운 받은 csv 파일 내에 Access Key ID
AWS Secret Access KEy : 다운 받은 csv 파일 내에 Secret Access Key
Default region name : ap-northeast-2
Default output format : json

CodeDeploy Agent 설치 파일 다운로드 후 install 파일에 권한 추가

wget https://aws-codedeploy-ap-northeast-2.s3.amazonaws.com/latest/install
chmod +x ./install

rudy 설치 후 CodeDeploy Agent 설치

sudo apt-get install ruby
sudo ./install auto
sudo service codedeploy-agent status # 설치 확인

위와같이 active 상태라면 정상이다.

 

인스턴스 부팅 시 codedeploy-agent가 자동으로 재시작되도록 shell script를 작성해준다.

sudo vi /etc/init.d/codedeploy-startup.sh

i로 편집모드 진입 

#!/bin
sudo service codedeploy-agent restart

esc -> :wq 저장 후 나가기

작성한 스크립트 파일에 실행 권한을 추가한다.

sudo chmod +x /etc/init.d/codedeploy-startup.sh

 

deploy.yml 파일에 작성한 브랜치로 Github Actions 실행

deploy.yml 파일에 작성한 브랜치로 Github Actions를 실행하여 배포가 되는지 확인한다.

728x90
반응형