# 시스템의 패키지 목록을 업데이트하고 설치된 패키지를 최신 버전으로 업그레이드.
$ sudo apt update && sudo apt upgrade
# Ruby 언어의 전체 설치 버전을 시스템에 설치.
$ sudo apt install ruby-full
# 네트워크를 통해 파일을 다운로드하는 명령어인 wget을 설치.
$ sudo apt install wget
$ cd /home/ubuntu
# AWS CodeDeploy 에이전트 설치 스크립트 다운로드.
$ wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install
# 다운로드한 설치 스크립트에 실행 권한 부여.
$ chmod +x ./install
# AWS CodeDeploy 에이전트를 자동으로 설치하고 출력을 로그 파일로 저장.
$ sudo ./install auto > /tmp/logfile
# AWS CodeDeploy 에이전트의 서비스 상태 확인.
$ sudo service codedeploy-agent status
- Node.js 설치
# NVM 설치
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
# NVM 환경 변수 설정
$ export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
$ nvm install 20.5.0
$ nvm use 20.5.0
$ node -v
- Nest CLI 설치
$ npm install -g @nestjs/cli
$ nest -v
-
S3 Bucket 생성
-
S3용 IAM 사용자 생성
-
사용자 → 보안자격 증명 → 액세스 키 → 액세스 키 만들기
-
액세스 키와 비밀 액세스 키 저장
-
CodeDeploy IAM 역할 생성
-
CodeDeploy 애플리케이션 생성
-
CodeDeploy 배포 그룹 생성 - 생성한 CodeDeploy IAM 역할 설정 및 환경 구성 EC2 인스턴스 태그 추가
-
Github Repository 생성
-
배포할 프로젝트 root 경로에 appspec.yml 파일 생성
version: 0.0 os: linux files: - source: / destination: /home/ubuntu/github_action overwrite: yes permissions: - object: / pattern: '**' owner: ubuntu group: ubuntu hooks: ApplicationStart: - location: /src/scripts/deploy.sh timeout: 60 runas: ubuntu
- version : appspec.yml 파일의 버전을 의미합니다.
- os : 배포 대상 운영 체제를 지정합니다.
- files : 배포할 파일과 위치를 지정합니다.
- source : 배포할 파일이 위치한 소스 디렉토리 경로입니다.
- destination : 파일을 배포할 대상 경로입니다.
- overwrite : 대상 위치에 이미 파일이 있을 경우 덮어쓸지 여부를 결정합니다.
- permissions : 배포된 파일의 권한을 설정합니다.
- object : 권한을 설정할 대상을 지정합니다.
- pattern : 권한을 적용할 파일 패턴을 지정합니다. ‘**’는 모든 파일과 디렉토리에 권한을 적용합니다.
- owner 및 group : 파일의 소유자와 그룹을 지정합니다.
- hooks : 배포 생명 주기 동안 실행할 스크립트를 정의합니다.
- ApplicationStart : 애플리케이션 시작 시 실행할 스크립트입니다.
- location : 스크립트 파일의 위치를 지정합니다.
/src/scripts/deploy.sh
는 EC2 인스턴스 내 스크립트 파일 경로입니다. - timeout : 스크립트 실행이 완료되기를 기다리는 최대 시간(초)입니다.
- runas : 스크립트를 실행할 사용자를 지정합니다.
-
deploy.sh 파일 생성
#!/bin/bash PROJECT_NAME="github_action" DEPLOY_PATH="/home/ubuntu/$PROJECT_NAME/" DEPLOY_LOG_PATH="/home/ubuntu/$PROJECT_NAME/deploy.log" DEPLOY_ERR_LOG_PATH="/home/ubuntu/$PROJECT_NAME/deploy_err.log" APPLICATION_LOG_PATH="/home/ubuntu/$PROJECT_NAME/application.log" echo "===== 배포 시작 : $(date +%c) =====" >> $DEPLOY_LOG_PATH echo "> 현재 동작중인 어플리케이션 pid 체크" >> $DEPLOY_LOG_PATH CURRENT_PID=$(pgrep -fl "node.*$PROJECT_NAME" | awk '{print $1}') if [ -z $CURRENT_PID ] then echo "> 현재 동작중인 어플리케이션 존재 X" >> $DEPLOY_LOG_PATH else echo "> 현재 동작중인 어플리케이션 존재 O" >> $DEPLOY_LOG_PATH echo "> 현재 동작중인 어플리케이션 강제 종료 진행" >> $DEPLOY_LOG_PATH echo "> kill -9 $CURRENT_PID" >> $DEPLOY_LOG_PATH kill -9 $CURRENT_PID fi echo "> 애플리케이션 배포" >> $DEPLOY_LOG_PATH cd $DEPLOY_PATH nohup node dist/main.js >> $APPLICATION_LOG_PATH 2> $DEPLOY_ERR_LOG_PATH & sleep 3 echo "> 배포 종료 : $(date +%c)" >> $DEPLOY_LOG_PATH
-
Github Actions Secrets 설정 / 빌드시 동적으로 변수값을 주입하기 위해 OVERRIDE_VALUE 설정
-
Github Repository -> Actions → set up a workflow yourself
-
deploy.yml 파일 작성 → commit
name: CI-CD on: push: branches: - main workflow_dispatch: env: S3_BUCKET_NAME: asher-devops-test-bucket RESOURCE_PATH: src/config/env/.env CODE_DEPLOY_APPLICATION_NAME: devops-test-code-deploy CODE_DEPLOY_DEPLOYMENT_GROUP_NAME: devops-test jobs: build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 - name: Set up Node.js uses: actions/setup-node@v2 with: node-version: 20.5.0 - name: Create .env file run: | DIRECTORY_PATH=$(dirname $RESOURCE_PATH) mkdir -p $DIRECTORY_PATH echo "OVERRIDE_VALUE=${{ secrets.OVERRIDE_VALUE }}" >> $RESOURCE_PATH - name: Install Dependencies run: npm install - name: Build run: npm run build - name: Make zip file run: zip -r ./$GITHUB_SHA.zip dist node_modules package.json src/scripts/deploy.sh appspec.yml shell: bash - 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 run: aws s3 cp --region ${{ secrets.AWS_REGION }} ./$GITHUB_SHA.zip s3://$S3_BUCKET_NAME/$GITHUB_SHA.zip - name: Code Deploy run: | aws deploy create-deployment \ --deployment-config-name CodeDeployDefault.AllAtOnce \ --application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \ --deployment-group-name ${{ env.CODE_DEPLOY_DEPLOYMENT_GROUP_NAME }} \ --s3-location bucket=$S3_BUCKET_NAME,bundleType=zip,key=$GITHUB_SHA.zip
-
Checkout : GitHub 저장소의 코드를 체크아웃합니다. 워크플로우가 실행되는 러너에 저장소의 코드를 복제합니다.
-
Set up Node.js : 20.5.0 버전의 Node.js를 설정합니다.
-
Create .env file : 지정된 경로에 .env 파일을 생성하고, GitHub Secrets에서 ‘OVERRIDE_VALUE’ 값을 이 파일에 추가합니다.
-
Install Dependencies : ‘npm install’ 명령어를 사용하여 프로젝트의 종속성을 설치합니다.
-
Build : ‘npm run build’ 명령어를 사용하여 애플리케이션을 빌드합니다.
-
Make zip file : 빌드된 ‘dist/’ 디렉토리, ‘node_modules’, ‘package.json’, ‘deploy.sh’, ‘appspec.yml’ 파일을 포함하는 ZIP 파일을 생성합니다.
-
Configure AWS credentials : AWS 자격증명을 설정하여 AWS 서비스에 액세스할 수 있도록 합니다.
-
Upload to S3 : 생성된 ZIP 파일을 AWS S3 버킷으로 업로드합니다.
-
Code Deploy : AWS CodeDeploy를 사용하여 S3에 업로드된 ZIP 파일을 EC2 인스턴스에 배포합니다.
로컬

메인 서버

메시지 - ERROR [codedeploy-agent(15693)]: InstanceAgent::Plugins::CodeDeployPlugin::CommandPoller: Missing credentials - please check if this instance was started with an IAM instance profile
문제 확인 경로 - /var/log/aws/codedeploy-agent/codedeploy-agent.log
원인 : EC2에 CodeDeploy 관련 IAM Role이 부여되기 전에 CodeDeploy Agent가 실행되면서 IAM Role을 못 가져간 것
조치 : sudo service codedeploy-agent restart