Github Actions, Code Deploy, Nginx를 이용한 무중단 배포 및 SSL 적용 (2)

유제·2022년 7월 31일
0

저번 포스팅에서는 Github Actions Workflow 내에서 빌드 결과물을 zip 파일로 만드는 것까지 진행했습니다. 이번 포스팅에서 다룰 부분은 아래 파란 부분입니다.

3. AWS 초기 설정하기

For Github Actions

보안 상의 이유로 Workflow에서 바로 Code Deploy, S3에 접근할 수 없습니다. 그래서 Github Actions에서 AWS 서비스에 접근할 수 있는 권한을 얻기 위해 AWS IAM 사용자를 생성해주도록하겠습니다.

먼저 AWS IAM 대쉬보드에 접속 후 사용자를 선택해주세요.

사용자 추가 버튼을 누른 후 AWS 자격 증명 유형을 액세스 키로 선택한 다음, 다음: 권한을 눌러주세요.

기존 정책 직접 연결을 누르고, AmazonS3FullAccessAWSCodeDeployFullAccess를 선택해주세요. 태그 설정은 자유이므로 생략하겠습니다.

사용자를 생성하기 전에 권한 요약에 아래와 같이 되어있어야합니다.

사용자를 만든 후 액세스 ID와 액세스 키를 복사하거나, .csv를 다운받아서 저장해주세요.

For CodeDeploy

EC2에 배포를 하는 것이기 때문에 CodeDeploy는 EC2에 대한 접근 권한이 있어야합니다. 그래서 CodeDeploy를 위한 IAM 역할을 만들어주겠습니다.

AWS 서비스 > 다른 AWS 서비스의 사용 사례 - CodeDeploy를 선택해주세요.

정책은 AWSCodeDeployRole밖에 없으니 이것을 선택해주고, 역할을 생성하시면 됩니다.

For EC2

EC2에서는 S3에 올린 zip을 다운받기 위해서 S3에 대한 접근 권한이 있어야합니다. 그래서 EC2를 위한 IAM 역할을 만들어주겠습니다.

AWS 서비스 > EC2를 선택해주세요.

그 다음 AmazonS3ReadOnlyAccess 정책을 추가하고, 역할을 생성해주세요.

IAM 사용자와 IAM 역할의 차이점

  • IAM 사용자 : 말 그대로 특정 권한을 가진 사용자를 만드는 것입니다. (회원가입이라고도 할 수 있죠. 근데 이제 아이디와 비밀번호를 정해주는..) 그래서 사용자를 만들면 액세스 키 ID와 비밀 액세스 키가 발급되며 해당 정보를 가지고 로그인을 할 수 있습니다.

  • IAM 역할 : AWS 서비스가 다른 AWS 서비스에 접근할 수 있는 권한을 주는 것입니다. 그래서 IAM 사용자와 달리 액세스 키 ID와 비밀 액세스 키가 발급되지 않으며, 특정 서비스의 대시보드에서 역할을 수정합니다. 예를 들어서 EC2에게 역할을 부여하기 위해서는 EC2 대시보드에 들어가야합니다. 이 과정은 아래에서 다룹니다.

✅ IAM 역할은 AWS 서비스가 다른 AWS 서비스에 접근할 수 있는 권한을 주는 것이기 때문에 Github Actions에게는 IAM 역할이 아니라 IAM 사용자를 만들어 준 것입니다.

4. EC2 생성하기

EC2를 생성합니다. 여기서 중요한 것은 스토리지 볼륨을 넉넉하게 설정해주어야합니다. 왜냐하면 docker container를 여러 개 띄워서 블루-그린 배포를 구현하고, 배포를 할 때마다 이미지를 생성하기 때문에 스토리지를 8기가로 설정하면 EC2에서 'No space left on device' 에러가 자주 발생합니다.

이 글은 Ubuntu 20.04 환경에 맞춰서 진행됩니다.

보안그룹 생성하기

TMI이지만 저는 아래처럼 DefaultSecurityGroup을 만들어둬서 실수로 22, 80, 443 포트를 안 여는 일은 없도록 방지를 합니다.

그리고 나중을 위해서 3001, 3002번 포트를 열어둔 보안 그룹을 따로 만들어 연결해두겠습니다.

IAM 역할 연결하기

위에서 생성한 IAM 역할을 연결해주겠습니다.
인스턴스 상태 > 보안 > IAM 역할 수정 을 선택해주세요.

IAM 역할을 업데이트 해주세요.

5. S3 생성하기

S3를 생성합니다. 저는 포스팅을 위해 생성하는 것이라 모든 퍼블릭 액세스 차단만 풀어주고, 다른 세팅은 기본값으로 하였습니다. 독자분들은 상황에 맞게 설정해주시면 될 것 같습니다.

6. CodeDeploy 세팅하기

CodeDeploy 애플리케이션을 생성해줍니다. EC2에서 사용할 것이기 때문에 EC2를 선택해줍니다.

애플리케이션 생성 후 배포 그룹을 생성해줍니다. 배포 그룹은 개발 환경, 운영 환경 등 환경별로 분리해서 사용합니다. 서비스 역할은 위에서 CodeDeploy를 위해 생성한 IAM 역할을 추가해주시면 됩니다. 배포 유형은 현재 위치로 설정해줍니다. 하나의 EC2 안에서 배포를 진행하기 때문입니다.

특정 태그가 달린 EC2 인스턴스를 선택해주세요. 키가 Name인 태그는 EC2 인스턴스의 이름을 의미합니다.

배포 구성은 CodeDeployDefault.AllAtOnce로 설정해줍니다. 그 다음 로드밸런서는 사용하지 않기 때문에 체크표시를 꺼줍니다.

다른 배포 구성에 대한 설명은 CodeDeploy에서 배포 구성 작업을 참조해주세요.

7. Github Actions에 적용하기

위에서 IAM 사용자를 생성하여 얻은 액세스 키 ID와 비밀 액세스 키를 Github Actions에서 사용해보겠습니다.

⚠️ 액세스 키 ID와 비밀 액세스 키를 main.yml에 절대 하드코딩하지마세요!

레포지토리의 Settings > Secrets > Actions로 들어가서 New Repository secret을 눌러서 AWS Access ID와 AWS Access Key를 추가해주시면됩니다.

저는 혹시 몰라서 aws region까지 시크릿에 추가해주었습니다.

이제 Github Actions에서 사용하겠습니다.

먼저 Github Actions 내 환경변수를 추가해줍시다.

name: Deploy NestJS Application

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]
  
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    
# ^^^^^^^^ 1편에 있던 내용 ^^^^^^^^

# vvvvvvvvv 추가할 내용 vvvvvvvvv

env:
  S3_BUCKET_NAME: my-nest-app-deploy-bucket # S3 버킷 이름입니다.
  PROJECT_NAME: my-nest-pp # S3 버킷 내 폴더 이름입니다. 임의로 정하면 알아서 생성해줍니다.
  AWS_CODEDEPLOY_APPLICATION_NAME: my-nest-app-codedeploy # CodeDeploy 애플리케이션 이름입니다.
  AWS_CODEDEPLOY_DEPLOYMENT_GROUP_NAME: my-nest-app-dev-group # CodeDeploy 배포 그룹 이름입니다.

시크릿에 저장한 값을 Github Actions에서 사용할 때는 ${{ secrets.SECRET_NAME }} 이렇게 사용합니다. 1편에서 작성한 워크플로우 파일 (main.yml)에 아래 내용을 추가해줍니다.

- name: Make a zip file
  run: zip -r ./$GITHUB_SHA.zip . -x "node_modules/*" "coverage/*" "src/*" "test/*" "README.md" "*.git*"
  shell: bash
  
# ^^^^^^^^ 1편에 있던 내용 ^^^^^^^^

# vvvvvvvvv 추가할 내용 vvvvvvvvv

 # 위에서 생성한 IAM 사용자 정보를 넣어 자격 증명을 수행합니다.
 - 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 }}

 # 위에서 만든 zip 파일을 S3에 업로드 합니다.
 - name: Upload to S3
   run: aws s3 cp --region ${{ secrets.AWS_REGION }} ./$GITHUB_SHA.zip s3://$S3_BUCKET_NAME/$PROJECT_NAME/$GITHUB_SHA.zip

 # CodeDeploy에게 deployment를 생성하도록 요청합니다.
 - name: Request Deployment
   run: aws deploy create-deployment --application-name $AWS_CODEDEPLOY_APPLICATION_NAME --deployment-config-name CodeDeployDefault.AllAtOnce --deployment-group-name $AWS_CODEDEPLOY_DEPLOYMENT_GROUP_NAME --s3-location bucket=$S3_BUCKET_NAME,bundleType=zip,key=$PROJECT_NAME/$GITHUB_SHA.zip

중간 점검

위의 워크플로우 내용을 추가한 후, main 브랜치에 푸쉬 혹은 PR을 날리면 Github Actions가 잘 작동할 것입니다. 그리고 Workflow가 끝날 때까지 기다렸다가 S3에 들어가시면 PROJECT_NAME 값을 이름으로 가진 폴더가 하나 생성되고, 그 안에 zip 파일이 생성된 것을 확인할 수 있습니다.

0개의 댓글