공부기록

실습CICD-3

jhs0129 2023. 9. 29. 19:01
320x100
반응형
320x100

기본 설명

흐름

  1. 사용자가 Repository로 코드를 push
  2. 해당 code build 후 zip파일로 압축 후 S3업로드
  3. 업로드한 파일을 codeDeploy를 통해 EC2에 배포 후 jar 파일 실행

CodeDeploy란

Amazon EC2 인스턴스, 온프레미스 인스턴스, 서버리스 Lambda 함수, Amazon ECS 서비스로 애플리케이션 배포를 자동화하는 배포 서비스

배포 유형

  • 실행 중 배포(현재 위치 배포) - 운영 중인 Instance내에 App 중지 후 최신 App 설치 후 시작
  • 블루/그린 배포

주요 구성 요소

  1. APP
  2. Computing Platform(EC2, ECS, Lambda)
  3. 배포 구성, 그룹(개별 Instance 집합), 유형
  4. IAM Instance Profile: EC2 Instace에 연결하는 IAM 역할, S3, Github Repo 접근 시 권한 포함
  5. 개정: 소스 코드, 실행 파일, 배포 스크립트, AppSpec 를 포함하는 archive file

EC2 기반 배포

App + AppSpec(yml 형식) 파일로 구성해서 배포

AppSpec: 배포 그룹의 Instance에 App 배포 방식 지정, 항상 프로젝트 루트 디렉토리에 위치해야 함

Instance에 파일을 복사할 위치 및 배포 스크립트를 실행할 시점 등과 같은 배포 명세가 포함
AppSpec 양식

배포하는 동안 CodeDeploy Agent는 AppSpec 파일의 hooks section에서 현재 이벤트의 이름을 조회, 이벤트가 발견되면 실행할 스크립트 목록을 검색(나타나는 순서대로 순차 실행)
각 스크립트 상태는 CodeDeploy Agent의 log file에 기록

Amazon Linux, Ubuntu Server Instance : /var/log/aws/codedeploy-agent 폴더에 codedeploy-agent.YYYYMMDD.log로 로그 파일 교체
/opt/codedeploy-agent/deployment-root/

다음으로 설정을 진행할 것이고 크게 AWS, Github 두가지 설정으로 나뉜다

반응형

AWS 설정

기본 VPC subnet등을 구성하는 것은 Infra 구축을 참고하면 된다

EC2 생성

EC2를 생성하는 것 자체는 간단하니 넘어가도록 하겠다

간단한 스펙정도만 작성을하면

  • Amazon Linux
  • t2.micro
  • storage 20gb
  • public subnet에 위치
  • java version 17

추가적으로 진행할 사항들이다

  1. 이제 EC2에 S3와 CodeDeploy에 접근을 할 수 있도록 IAM 정책을 할당한 역할을 EC2에 적용해준다

정책

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:*",
                "codedeploy:*"
            ],
            "Resource": "*"
        }
    ]
}
  1. CodeDeploy에서 EC2 Instance를 배포에서 사용할 수 있게 해주는 소프트웨어 패키지인 CodeDeploy Agent를 설치해주면 된다
sudo yum update
sudo yum install ruby
sudo yum install wget
cd /home/ec2-user
wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto

CodeDeploy Agent가 실행 중인지 확인
sudo service codedeploy-agent status

만약 실행중이 아니라면

sudo service codedeploy-agent start
sudo service codedeploy-agent status

이걸로 EC2 설정은 끝이다

S3 생성

S3는 추가적인 작업 없고 하나 참고할 점은 모든 퍼블릭 액세스를 차단하고 오직 AWS 내부에서 내가 접근 정책을 부여한 EC2랑 CodeDeploy에서만 접근이 가능하도록 하면 된다

필요하다면 버킷에 추가적인 디렉토리를 생성해도 된다

CodeDeploy 생성

CodeDeploy는 두가지 과정이 있는데

하나는 CodeDeploy 어플리케이션을 생성하는 것

또 하나는 해당 어플리케이션 내부에 배포 그룹을 생성 하는 것이다

  1. CodeDeploy 어플리케이션 생성
  2. 배포그룹 생성 배포그룹에는 역할이 필요로 하는데 IAM으로 돌아가 아래 사진과 같이 설정만 해주면 된다

 

S3와 CodeDeploy에서 생성한 버킷/어플리케이션, 디렉토리/배포그룹들의 이름은 Github에서 설정 시 사용할 것이기 때문에 따로 작성해두면 추후 편하다

Github 설정

앞서 CI에서 한 것과 마찬가지로 Github Action Workflow를 사용할 것인데 배포시 AWS Cli를 사용하여 배포를 진행 할 것이기 때문에 Cli에서 S3와 CodeDeploy에 접근 가능한 IAM User를 만들어 Key를 받아오자

Github용 IAM User 생성

AWS Console에 접근을 할 것은 아니기 때문에 아래 체크박스는 해제하면 된다

사용자 생성 시에 연결할 정책은 위 EC2에서 생성한 것과(CodeDeployDemo-EC2-Permission) 동일한 권한을 가진 정책을 생성한다
이름은 CodeDeployUserPermissionSet 다음과 같이 설정했다

사용자를 만들었으면 다음 아래 사진에서 보안 자격증명을 들어가 액세스키를 할당 받는다

완료를 누르기 전에 액세스키 두가지 모두 다른곳에 적어두거나 csv파일을 다운로드한 후 Github Repository로 가자

Github Repo의 Settings로 와서 Secrets and Variables 하위에 Actions 탭으로 들어와 Repository secrets에 두개의 키 모두 저장을 해두자

이곳에 저장한 값들은 Github Action Workflow 작성 시 ${{ secrets.ACCESS_KEY }} 식을 통해서 가져올 수 있다

CD Workflow 작성

name: Execute CD

on:
  push:
    branches: [ "main" ]

permissions:
  contents: read

env: 
  BUCKET_NAME: 본인 S3 버킷
  DIRECTORY_NAME: 본인 S3 버킷 내부 디렉토리
  CODE_DEPLOY_APP_NAME: 본인 CodeDeploy 어플리케이션
  DEPLOYMENT_GROUP_NAME: 본인 CodeDeploy 배포그룹

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - name: Check Repo code
      uses: actions/checkout@v3

    - name: Set up JDK 17
      uses: actions/setup-java@v3
      with:
        java-version: '17'
        distribution: 'temurin'

    - name: Permission for gradlew
      run: chmod +x ./gradlew
      shell: bash

    - name: Build with Gradle
      uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25
      with:
        arguments: build

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

    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v3
      with:
        -- 이부분에서 AWS 액세스 키를 사용한다
        aws-access-key-id: ${{ secrets.ACCESS_KEY }}
        aws-secret-access-key: ${{ secrets.PRIVATE_KEY }}
        aws-region: ap-northeast-2

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

    - name: Deploy to EC2 Instance
      run: aws deploy create-deployment --application-name $CODE_DEPLOY_APP_NAME --deployment-group-name $DEPLOYMENT_GROUP_NAME --deployment-config-name CodeDeployDefault.OneAtATime --s3-location bucket=$BUCKET_NAME,bundleType=zip,key=$DIRECTORY_NAME/$GITHUB_SHA.zip

AppSpec.yml, Deploy.sh 작성

AppSpec.yml
CodeDeploy 배포 시 Event에는 총 7개가 있는데 이중 우리는 AfterInstall 즉 코드가 전부 다운이 된 후 deploy.sh를 실행할 예정이기 때문에 아래 hook에 다음과 같이 설정해준다

  • ApplicationStop
  • DownloadBundle
  • BeforeInstall
  • Install
  • AfterInstall
  • ApplicationStart
  • ValidateService
version: 0.0
os: linux

files:
  - source: /
    destination: /home/ec2-user/code

permissions:
  - object: /

hooks:
  AfterInstall:
    - location: scripts/deploy.sh
      timeout: 60

AppSpec설명

 

CodeDeploy에 대한 개정에 애플리케이션 사양 파일 추가 - AWS CodeDeploy

Windows Server 인스턴스에 배포하는 기능은 runas 요소를 지원하지 않습니다. Windows Server 인스턴스를 배포하고 있다면 이 요소를 AppSpec 파일에 포함하지 마세요.

docs.aws.amazon.com

deploy.sh

```
#!/usr/bin/env bash

PROJECT_NAME=본인 프로젝트 이름
REPOSITORY=/home/ec2-user/code
PACKAGE=$REPOSITORY/build/libs/
JAR_NAME=$(ls -tr $PACKAGE | grep 'SNAPSHOT.jar' | tail -n 1)
JAR_PATH=$PACKAGE$JAR_NAME

echo $JAR_NAME
echo $JAR_PATH

cd $REPOSITORY

CURRENT_PID=$(pgrep -f $PROJECT_NAME)

if [ -z $CURRENT_PID ]
then
  echo "> 종료할 애플리케이션이 없습니다"
else
  echo "> 실행 중인 애플리케이션 종료 $CURRENT_PID"
  kill -15 $CURRENT_PID
  sleep 5
fi

echo "> 배포 - $JAR_PATH"
chmod +x $JAR_PATH

sudo nohup java -jar $JAR_PATH --spring.profiles.active=prod > /home/ec2-user/log/nohup_log.out 2>&1 &
320x100
반응형