기본 설명
흐름
- 사용자가 Repository로 코드를 push
- 해당 code build 후 zip파일로 압축 후 S3업로드
- 업로드한 파일을 codeDeploy를 통해 EC2에 배포 후 jar 파일 실행
CodeDeploy란
Amazon EC2 인스턴스, 온프레미스 인스턴스, 서버리스 Lambda 함수, Amazon ECS 서비스로 애플리케이션 배포를 자동화하는 배포 서비스
배포 유형
- 실행 중 배포(현재 위치 배포) - 운영 중인 Instance내에 App 중지 후 최신 App 설치 후 시작
- 블루/그린 배포
주요 구성 요소
- APP
- Computing Platform(EC2, ECS, Lambda)
- 배포 구성, 그룹(개별 Instance 집합), 유형
- IAM Instance Profile: EC2 Instace에 연결하는 IAM 역할, S3, Github Repo 접근 시 권한 포함
- 개정: 소스 코드, 실행 파일, 배포 스크립트, 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
추가적으로 진행할 사항들이다
- 이제 EC2에 S3와 CodeDeploy에 접근을 할 수 있도록 IAM 정책을 할당한 역할을 EC2에 적용해준다
정책
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:*",
"codedeploy:*"
],
"Resource": "*"
}
]
}
- 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 어플리케이션을 생성하는 것
또 하나는 해당 어플리케이션 내부에 배포 그룹을 생성 하는 것이다
- CodeDeploy 어플리케이션 생성
- 배포그룹 생성 배포그룹에는 역할이 필요로 하는데 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
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 &
'공부기록' 카테고리의 다른 글
Nginx 적용기 (0) | 2023.11.05 |
---|---|
[실습] CICD-4 (0) | 2023.09.29 |
[실습] CICD - 2 (0) | 2023.08.29 |
[이론] CI/CD - 1 (0) | 2023.08.28 |
[Infra] CICD (0) | 2023.05.24 |