잘못된 정보가 있다면, 꼭 댓글로 알려주세요(비로그인 익명도 가능).
여러분의 피드백이 저와 방문자 모두를 올바른 정보로 인도할 수 있습니다.
감사합니다. -현록
현록의 기록저장소
AWS CodeDeploy와 Github Action으로 자동 배포 설정 본문
[Workflow]
[준비사항]
[설정]
[확인]
[Workflow]
Workflow는 다음과 같다.
Github의 특정 branch에 코드 push
↓
gradle이나 maven 등으로 build(test를 포함하고 있다면 수행)
↓
빌드 결과물(jar, war, ...)과 배포 설정(appspec.yml) 등을 압축하여 AWS S3 버킷에 업로드
↓
AWS CodeDeploy 서비스에 설정한 대로 배포 요청(배포 생성)
↓
AWS EC2에서는 설치했던 AWS CodeDeploy Agent가
AWS S3 버킷에서 배포본을 받고 압축을 푼 후, 압축 파일 내부의 appspec.yml에 정의된대로 스크립트를 실행
(실행 중이던 기존 애플리케이션/서비스를 중지하고, 새 애플리케이션으로 교체 후 재실행)
[준비사항]
AWS IAM Role에서 AWS EC2가 AWS CodeDeployAgent를 사용하기 위한 역할(Role)을 생성한다.
AWS IAM Role에서 AWS CodeDeploy 서비스를 위한 역할(Role)을 생성한다.
AWS IAM User에서 Github Action이
S3에 압축파일을 업로드하고, AWS CodeDeploy 서비스에 배포 요청을 할 수 있는
권한을 부여한 사용자를 생성하고, 액세스 키(ID, SECRET)를 발급한다.
참고로 예시에서 사용하는 최소 정책은 다음과 같다.
(작성하려면 S3 버킷과 CodeDeploy 애플리케이션 및 배포 그룹 생성을 먼저 하고 리소스를 지정할 수 있다)
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "s3:PutObject", "codedeploy:CreateDeployment", "codedeploy:GetApplicationRevision", "codedeploy:RegisterApplicationRevision", "codedeploy:GetDeploymentConfig" ], "Resource": [ "arn:aws:codedeploy:ap-northeast-2:1290????7149:deploymentconfig:CodeDeployDefault.OneAtATime", "arn:aws:codedeploy:ap-northeast-2:1290????7149:application:CODEDEPLOY애플리케이션이름", "arn:aws:codedeploy:ap-northeast-2:1290????7149:deploymentgroup:CODEDEPLOY애플리케이션이름/배포그룹이름", "arn:aws:s3:::S3버킷이름/디렉터리명.../파일명" ] } ] } |
IAM User가 생성된 것을 확인할 수 있다.
생성한 사용자를 선택하고, '보안 자격 증명' 탭으로 가서 '액세스 키 만들기'로 진입한다.
액세스 키보다 보안성이 높은 대체 권장 서비스를 권유하는 부분이다.
우리는 액세스 키를 사용해야하니 '기타'를 선택한다.
설명 태그는 선택 사항이다. 필요하면 사용한다.
위의 알림대로 이 페이지를 벗어나면 다시는 비밀 액세스 키는 볼 수 없으니,
'.csv 파일 다운로드'를 통해 안전한 곳에 저장해둔다.
위의 액세스 키를 Github의 자동 배포를 수행하려는 Repository의 설정에서 Secrets에 저장해둔다.
Github에서 배포하려는 Repository의 설정 탭으로 가서,
Security > Secrets and variables > Actions 항목에서 secret 생성으로 진입한다.
발급받았던 액세스 키와 비밀 액세스 키 쌍을 각각 따로 저장한다.
AWS S3 서비스에서 S3 버킷을 생성한다.
버킷의 root(/) 디렉터리에 업로드할 것이 아니라면, '폴더 만들기'를 통해 원하는 위치 구조를 만들어둔다.
AWS EC2 서비스에서 EC2 인스턴스를 생성한다.
ㆍ위에서 생성했던 Role 중 AmazonEC2RoleForAWSCodeDeploy 정책이 연결된 Role을 선택해준다.
ㆍEC2가 생성되면 접속해서 AWS CodeDeploy agent를 설치해야하는데,
사용자 데이터에 명령어들을 입력해두면 인스턴스 생성시 해당 명령어들을 수행해준다.
#!/bin/bash
sudo yum update -y sudo yum install -y ruby sudo yum install -y wget
/opt/codedeploy-agent/bin/codedeploy-agent stop yum erase codedeploy-agent -y
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 rm ./install |
만약 기존 사용 중인 EC2 인스턴스라면, 우클릭 메뉴에서 IAM Role을 수정할 수 있다.
기존에 아무 Role도 없었다면 생성했던 Role을 선택하면 되지만,
기존에 Role이 존재한다면 기존 Role에 AmazonEC2RoleForAWSCodeDeploy 정책을 추가하거나 합친 형태의 Role을 추가로 생성해야할 수 있다.
IAM Role을 수정했다면, 재부팅을 해야 올바르게 적용된다.
[ec2-user@ip-***-**-**-** ~]$ sudo service codedeploy-agent status The AWS CodeDeploy agent is running as PID 3468 |
EC2 인스턴스로 접속하여 AWS CodeDeploy agent가 설치되어 실행 중인지 확인한다.
설치가 안됐다면 위의 사용자 데이터에 열거했던 명령어들을 입력해보고, 서비스 start로 실행하고 status로 확인한다.
AWS CodeDeploy 서비스에서 CodeDeploy 애플리케이션을 생성하고, 배포 그룹을 생성한다.
배포 그룹을 생성해야한다.
애플리케이션의 배포 그룹을 확인해보면 생성한 배포 그룹을 볼 수 있다.
참고로 배포 그룹을 선택해서 '배포 생성'을 하면 배포 이벤트를 생성할 수 있다.
자동 배포와는 관련 없이,
이미 S3 버킷에 업로드한 압축파일이나 Github의 Commit ID를 바탕으로 프로젝트를 내려받아 수행할 수 있는데,
이는 자동 배포 부분이 아니므로 여기서는 다루지 않겠다.
(직접 배포를 생성하더라도 EC2 대상들에 대해서는 일괄적으로 배포 스크립트를 수행하니,
CI/CD pipeline과는 관련 없지만 배포부터는 자동화라 각각 인스턴스에 수동으로 접속하여 수행할 때의 실수는 줄일 수 있다.)
[설정]
appspec.yml 파일을 git 프로젝트의 root(/) 디렉터리에 생성한다.
version: 0.0
os: linux
files: # - source: / # destination: /home/ec2-user/spring-simple-http-rest - source: /build/libs destination: /home/ec2-user/spring-simple-http-rest/build/libs - source: /.aws/aws-codedeploy-scripts destination: /home/ec2-user/spring-simple-http-rest/.aws/aws-codedeploy-scripts
file_exists_behavior: OVERWRITE
permissions: - object: / pattern: "**" owner: ec2-user group: ec2-user
hooks: AfterInstall: - location: ./.aws/aws-codedeploy-scripts/stop.sh timeout: 30 runas: ec2-user ApplicationStart: - location: ./.aws/aws-codedeploy-scripts/start.sh timeout: 60 runas: ec2-user |
※ https://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file.html
ㆁ files 섹션
ㆍsource: 압축파일 기준으로 압축을 풀 디렉터리/파일
ㆍdestination: EC2 인스턴스 기준으로 설치가 될 디렉터리/파일
※ https://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file-structure-files.html
ㆁhooks 섹션
ㆍ배포 lifecycle의 각 event에 실행할 스크립트 파일을 설정할 수 있다.
ㆍ이 스크립트 파일은 기존에 존재하든, 이번 배포 압축 파일에 포함되든 둘 다 가능하지만,
기존에 존재하는 스크립트 파일이 아니라면 AfterInstall 이벤트부터 사용 가능하다.
BeforeInstall에서는 압축을 풀기 전이라 해당 스크립트 파일을 찾지 못하고 이후 과정은 캔슬되어 전체 배포 과정을 실패로 마감한다.
※ https://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file-structure-hooks.html
※ 이 appspec.yml은 압축 파일의 root(/)에 포함되어야 AWS CodeDeploy agent가 이를 토대로 작업들을 수행하지만,
OS에 설치될 필요는 없는 파일이니, files 섹션에서 appspec.yml 자신은 빠져도 상관없다.
배포가 수행될 때 실행될 스크립트파일(*.sh)들을 git 프로젝트의 원하는 디렉터리에 작성한다.
예시에서 사용한 두 개의 스크립트 파일이다.
stop.sh
#sudo systemctl stop springserver PID=$(ps -ef | grep -v grep | grep 'java -jar /home/ec2-user/spring-simple-http-rest/build/libs/simple-http-rest-1.0.0.war' | awk '{print $2}') if [ -n "$PID" ] then kill -9 $PID sleep 10 fi |
start.sh
#sudo systemctl start springserver nohup java -jar /home/ec2-user/spring-simple-http-rest/build/libs/simple-http-rest-1.0.0.war 1>/dev/null 2>&1 & |
appspec.yml과 스크립트들을 작성한 커밋들을 master branch에 push하고,
Github에서 repository로 들어가서 Github Action을 생성한다.
템플릿을 검색해서 수정해서 사용해도 되지만, 처음부터 기본판으로도 작성할 수 있다.
어차피 예시를 보여줄 것이니 이것으로 선택.
# This workflow uses actions that are not certified by GitHub. # They are provided by a third-party and are governed by # separate terms of service, privacy policy, and support # documentation. # This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
name: Java CI with Gradle and CD by AWS CodeDeploy
on: push: branches: [ "main" ] pull_request: branches: [ "main" ]
permissions: contents: read
jobs: ci-and-cd:
runs-on: ubuntu-latest
steps: - uses: actions/checkout@v3
- name: Set up JDK 17 uses: actions/setup-java@v3 with: java-version: '17' distribution: 'corretto'
- name: Run chmod to make gradlew executable run: chmod +x ./gradlew
- name: Build with Gradle uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1 with: arguments: build
- name: Make zip File run: zip -r ./build.zip ./build/libs/simple-http-rest-1.0.0.war ./appspec.yml ./.aws/aws-codedeploy-scripts # run: zip -r ./build.zip ./build/libs/*.war ./appspec.yml ./.aws/aws-codedeploy-scripts
- name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ secrets.AWS_CD_ID }} aws-secret-access-key: ${{ secrets.AWS_CD_SECRET }} aws-region: ap-northeast-2
- name: Upload to S3 run: aws s3 cp --region ap-northeast-2 ./build.zip s3://s3-cd-blackdeer/spring-simple-http-rest/build.zip
- name: AWS CodeDeploy run: > aws deploy create-deployment --application-name test-spring-simple-rest --deployment-group-name cd-deploy-group-spring-simple-http-rest --deployment-config-name CodeDeployDefault.OneAtATime --s3-location bucket=s3-cd-blackdeer,bundleType=zip,key=spring-simple-http-rest/build.zip |
'main' branch에 push나 pr이 완료되면,
gradle로 빌드 후,
빌드 파일(*.war)과 appspec.yml, 스크립트 파일들(*.sh)을 압축하고,
이 압축 파일을 AWS S3 버킷에 업로드 한 후,
AWS CodeDeploy 서비스에 배포를 요청한다.
※ https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
※ https://docs.aws.amazon.com/cli/latest/reference/s3/cp.html
※ https://docs.aws.amazon.com/cli/latest/reference/deploy/create-deployment.html
AWS S3 버킷에 압축 파일 업로드와 AWS CodeDeploy 요청에
AWS Credential이 필요하며, 그래서 IAM User와 액세스 키를 발급했던 것이다.
Repository의 Secrets에 저장했던 ID와 SECRET을 여기에서 사용한다.
[확인]
Github Action을 작성한 커밋 이후로,
main branch에 push될 때마다 해당 작업이 수행될 것이다.
Repository의 Actions 탭에서
진행 상태와 결과 및 로그 등을 확인할 수 있다.
re-run도 가능하다.
S3 버킷의 지정한 경로에 압축 파일이 업로드된 것도 확인할 수 있다.
CodeDeploy의 애플리케이션이나 배포 그룹에서는 요청된 배포 내역을 확인할 수 있다.
각 배포 ID를 누르면 인스턴스별 진행 정도나 가장 최근 이벤트 등을 알 수 있다.
아래의 'View events'를 누르면 더 상세한 lifecycle 위치를 알 수 있다.
EC2 인스턴스에서는 해당 머신에 대해 더 자세한 로그를 뒤져볼 수 있다.
/var/log/aws/codedeploy-agent/codedeploy-agent.log
'Study > AWS' 카테고리의 다른 글
AWS CodeDeploy에서 대상을 AutoScaling으로 했을 때 발생할 수 있는 문제들 (0) | 2023.02.08 |
---|---|
AWS EC2 Auto Scaling (0) | 2023.02.08 |
AWS ALB(Application Load Balancer) 기초 (0) | 2023.02.03 |
잘못된 정보가 있다면, 꼭 댓글로 알려주세요(비로그인 익명도 가능).
여러분의 피드백이 저와 방문자 모두를 올바른 정보로 인도할 수 있습니다.
감사합니다. -현록