Spring/Spring ++

Github Actions + Code Deploy + Ngxin + ubuntu 20.04로 무중단 배포하기 (2)

backend dev 2022. 10. 23.

S3에 올린 jar를 가져다가 배포시키기

전 게시글은 빌드한 결과인 jar파일을 zip파일로 압축시켜 s3에 올리는 workflow를 구성했고

실제로 잘 동작한걸 확인할 수 있었다!

 

 

 

Code deploy를 이용하여 배포시키기

Code deploy란 aws에서 제공하는 어플리케이션 자동 배포 서비스이다!

EC2,AWS Lambda와 같은 서비스에 배포가 가능하고 

현재위치 배포 또는

블루/그랜 배포 (= 무중단 배포)도 지원함 ( 하지만 나는 무중단배포에 nginx를 이용할것임) 

 

 

이제 Code deploy에게 배포하라고 시켜보자  ( 그러면 Code deploy는 Code deploy agent에게 배포명령을 전달할것임)

 

 

Code deploy의 배포과정

1. 개발한 어플리케이션(프로젝트) 최상단 경로에 AppSpec.yml 이라는 파일을 추가한다.

(AppSpec.yml 파일은 배포에 필요한 모든 절차를 적어두는 명세서라고 생각하면된다 ! ,내가 원하는 대로 배포 절차를 적는곳!)

 

2. CodeDeploy에 프로젝트의 특정 버전을 배포해 달라고 요청하면, CodeDeploy는 배포를 진행할 EC2 인스턴스에 설치돼 있는 CodeDeploy Agent들과 통신하며 Agent들에게 요청받은 버전을 배포해 달라고 요청한다!

 

3. 요청 받은 Agent들은 코드 저장소(이 게시글에서는 빌드파일을 압축해서 올려놓은 s3를 의미)에서

프로젝트 전체를 서버에 내려받고, AppSpec.yml 파일을 읽어 해당 파일에 적힌 절차대로 배포를 진행한다.

 

4. Agent는 배포를 진행한 후 CodeDeploy에게 성공/실패 등의 결과를 알려준다 (aws의 code deploy를 가면 배포마다 어떻게 진행되는지 어디서 실패했는지 확인가능)

 

CodeDeploy Agent 는 EC2 인스턴스에 설치되어 CodeDeploy의 명령을 기다리고 있는 프로그램입니다.

실제로 배포를 수행하는 것은 Agent이기 때문에 반드시 EC2 인스턴스에 설치되어 있어야 합니다.

 

EC2 설치 + Ec2설정, 자바설치 등은 스킵

 

Code Deploy Agent 설치

저는 EC2를 우분투 서버로 사용합니다.

https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/codedeploy-agent-operations-install-ubuntu.html

 

Ubuntu Server용 CodeDeploy 에이전트 설치 - AWS CodeDeploy

출력을 임시 로그 파일에 쓰는 것은 Ubuntu 20.04에서 install 스크립트를 사용하여 알려진 버그를 해결하는 동안 사용해야 하는 해결 방법입니다.

docs.aws.amazon.com

여기서 우분투 버전별 code Deploy agent 설치방법을 참고하시면됩니다!

 

저는 ubuntu 20.04의 최신버전을 사용하므로 아래 방법을 이용해 받았습니다.

#!/bin/bash
# Ubuntu 22.04에서의 CodeDeploy 설치

sudo apt-get update
sudo apt-get install ruby-full ruby-webrick wget -y
cd /tmp

wget https://aws-codedeploy-ap-northeast-2.s3.amazonaws.com/releases/codedeploy-agent_1.3.2-1902_all.deb 
#가장 최신버전의 CodeDeploy를 찾아서 설치했으나, 원하는 버전이 있다면 해당 버전으로 설치해도 무방함

mkdir codedeploy-agent_1.3.2-1902_ubuntu22 #폴더명은 자율
dpkg-deb -R codedeploy-agent_1.3.2-1902_all.deb codedeploy-agent_1.3.2-1902_ubuntu22
sed 's/Depends:.*/Depends:ruby3.0/' -i ./codedeploy-agent_1.3.2-1902_ubuntu22/DEBIAN/control
dpkg-deb -b codedeploy-agent_1.3.2-1902_ubuntu22/
sudo dpkg -i codedeploy-agent_1.3.2-1902_ubuntu22.deb
systemctl list-units --type=service | grep codedeploy

sudo service codedeploy-agent status #잘 깔렸는지 확인하는 부분

마지막 status 부분으로 잘깔렸는지 확인할 수 있습니다.

 

출처,참고,더자세한정보

 

Ubuntu 22.04에 CodeDeploy Agent 설치하기

우분투 버전을 갑작스럽게 올리긴 했다,,, 뭐든 최신게 좋은게 아닌가.. 18.04에서 사용하던 명령어가 되어지지 않고,, https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/codedeploy-agent-operati..

ssue-dev.tistory.com

 

 

AWS CodeDeploy agent not installing on ubuntu 22.04

I tried installing codedeploy agent on ubuntu 22.04 but not working. I have installed ruby 2.6.0 via rbenv. ubuntu@ip-172-31-37-7:~$ sudo ./install --sanity-check deb I, [2022-08-10T06:26:28.905059 #

stackoverflow.com

 

잘 깔린거같은데 status로 확인했을대 실행되지않아있다면 다음 명령어를 입력

sudo service codedeploy-agent start

 

 

 

 

EC2에 IAM 역할 부여

전 게시글에서 IAM 사용자를 만들었습니다 ( s3,code deploy 둘의 full access 권한을 가지는!)

 

github actions가 해당  IAM 계정을 이용해서 (액세스키값과 시크릿키값을 가지고 )

 

s3와 code deploy에 관련된 액션들을 수행 할수 있도록 했는데

 

이번에는 EC2에 S3,Code Deploy 권한 정책을 부여해준다! ( 여기서는 IAM 사용자를 추가해서 하는게 아닌 IAM의 역할을 이용한다)

 

IAM 사용자와 IAM 역할을 구분하기 위해서 

IAM 사용자 부터 알아보자

 

IAM사용자 같은경우는  생성할때 두가지 방법으로 접근 유형을 선택하게 합니다.

IAM 사용자 생성 화면

 

이전 게시글에서 만든 IAM 사용자는 액세스키를 이용해서 접근하게끔 했습니다!  (workflow 환경에서 사용하려고 == 개발환경에 사용하려고)

 

밑에 암호 - aws관리 콘솔 엑세스 관련은 

 

aws 홈페이지 로그인시 나오는 루트계정말고 IAM 계정을 선택하는 그 화면에서 사용하는것같습니다.

 

모든 권한을 가진 루트계정말고 일부 권한을 부여한 IAM계정을 다른 사용자에게 줘서 접근할 수 있게하는용도 또는 다른프로그램에서 아이디/비밀번호를 이용해서 접근할 수 있게끔하는 두가지 방법이 있다!

 

---

 

그렇다면

 

IAM 역할은?

IAM 역할도 부여한 정책(권한)을 넣어주면서 만들어준다.

 

IAM 사용자는 키값이나, 아이디/비밀번호와 같은걸 이용해서 IAM 사용자에 접근하고 해당 권한을 이용하는데

 

IAM 역할은 직접 부여함으로서 , 부여받은 대상이 해당 권한을 가지게 되는것 같다.

 

IAM 역할은 다른계정의 IAM 사용자(내 aws루트계정말고) , 혹은 다른 AWS 서비스(EC2와 같은!)가 수행하는 역할 권한을 부여하는것이다!

 

---

 

 

다시 돌아가서 EC2에 부여할 IAM 역할을 생성 해보자

들어가면 몇개 만들어져있을텐데 기본적으로 존재하는거니까 

 

새로 하나 만들어주자

 

만드는 화면을 확인하면 알 수 있듯이 

IAM 역할은 AWS 서비스와 AWS 계정등에 부여가능하다!

 

Aws 서비스를 체크해주고

EC2에 쓸거니까 체크해준다! 그리고 다음누른다!

 

권한정책에서

 

저번 게시글에서 IAM 사용자만들때 선택했던거와같이

 

AmazonS3FullAccess와

AWSCodeDeployFullAccess를 선택해준다!

 

 

 

그다음 역할이름은 대략 정해주고

태그와 설명수정은 원하면 해주고 역할 생성해준다.

 

 

이렇게 역할이 생성됬으면

 

EC2 화면으로 돌아가서 IAM역할을 연결해줄것이다.

 

EC2에 IAM 역할연결

 

EC2 대시보드에서 내가 원하는 Ec2 클릭해서 체크되게끔하고

작업 -> 보안 -> IAM역할수정

 

아까 역할 만들때 이름정했던걸 찾아서 설정해주면된다!

 

 

 

Code Deploy IAM 역할 생성!

이제 Code Deploy 어플리케이션을 생성하기 전에 Code Deploy를 위한 IAM Role이 필요하다!

 

방금전에 역할을 생성해서 EC2에 적용해줬던거처럼!

 

 

다시 역할만들기로 간다! (만드는 방법이 좀다름!)

 

 

 

밑에 다른 AWS 서비스의 사용 사례를 누르고 code deploy를 검색후 체크해서 넘어가준다!

 

 

 

권한추가를 보면 자동으로 AWSCodeDeployRole이 있다!

다음 눌러준다!

 이름 원하는대로 정하고 역할을 생성해주면됨!

 

 

왜 code deploy에는 저런 정책을 사용하는것일까?

 

2단계: CodeDeploy에 대한 서비스 역할 생성 - AWS CodeDeploy

2단계: CodeDeploy에 대한 서비스 역할 생성 AWS에서 서비스 역할은 AWS 리소스에 액세스할 수 있는 권한을 AWS 서비스에 부여하는 데 사용됩니다. 서비스 역할에 연결하는 정책에 따라 서비스에 액세

docs.aws.amazon.com

EC2/온프레미스 배포의 경우 AWSCodeDeployRole 정책을 연결합니다. 

이 정책은 서비스 역할에서 다음을 수행하는 데 필요한 권한을 제공합니다.

Amazon EC2 Auto Scaling 그룹 이름으로 인스턴스의 태그를 읽거나 Amazon EC2 인스턴스를 식별합니다.

Amazon EC2 Auto Scaling 그룹, 수명 주기 후크 및 크기 조정 정책을 읽고, 생성하고, 업데이트하고, 삭제합니다.

Amazon SNS 주제로 정보를 게시합니다.

CloudWatch 경보에 관한 정보를 검색합니다.

Elastic Load Balancing을 읽고 업데이트합니다.

 

다음과 같은 이유로 AWSCodeDeployRole의 정책을 사용한다고 보면된다 ( 간단하게 code deploy가 EC2에 접근하기위해)

어디다가 배포하는지에 따라 선택하는 정책이 다르다. 위에 사이트를 참고해보면될듯!

 

다시 돌아와서 역할을 생성했으니 다음으로 넘어가보자

 

Code Deploy 어플리케이션 생성

어플리케이션이란?

애플리케이션은 CodeDeploy에서 사용하는 단순한 이름 또는 컨테이너로, 배포 중에 올바른 개정, 배포 구성 및 배포 그룹이 참조되도록 합니다. (참조 : https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/applications-create.html)

 

 

code deploy 어플리케이션 배포그룹 생성

 

 

어플리케이션 생성후 

생성된 어플리케이션을 클릭하고 

 

배포그룹 생성을 눌러준다!

이름설정해주고

 

서비스 역할은 방금만든 역할을 선택해준다!

 

배포유형은 현재위치로!

이 게시글에서는 무중단배포를 nginx로 진행할것이기 때문이다!

 

현재 위치 배포와 블루/그린 배포 모두 무중단 배포의 형태들이라고한다

다만 지금 우리는 서버를 여러 대 띄우는 방식이 아니라, 하나의 EC2 내부에서 두 개의 포트에 WAS를 띄우고 스위칭하는 방식을 쓸 것이기 때문에 CodeDeploy가 무중단 배포의 역할을 가지고 있지는 않다고한다!

 

 

 

Ec2 인스턴스 체크!

 

Ec2 만들때 태그값을 지정할 수 있는데 그때 지정했던 태그를 선택해준다 ( 안했다면 태그 추가하고오자!)

 

AWs 에이전트는 설치안함!

 

배포 설정은 

여러 대의 서버를 어떤 단계에 따라 순차적으로 배포할 것인지를 선택하는 설정인데

 

어차피 EC2가 하나기 때문에 한번에 배포를 끝내는 CodeDeployDefault.AllAtOnce 를 선택


로드밸런서는 없기 때문에 활성화를 해제하고 배포 그룹을 생성!

 

Code deploy의 설정끝!

 

 

appspec.yml 생성하기

code deploy 설정은 끝났으니

code deploy agent가 배포할때 참고할 명세서를 작성해보자

 

appspec.yml에 내가 원하는 배포 작업들을 적어주면 code deploy agent가 해당 파일을 읽어 그대로 진행해준다!

 

appspec.yml은 프로젝트의 최상단에 생성해준다!

 

appspec.yml

version: 0.0
os: linux

files:
  - source:  /
    destination: /var/www/dev_planet/cicd_template #ubuntu에서 배포될 프로젝트가 저장될 위치
    overwrite: yes

permissions:
  - object: /
    pattern: "**"
    owner: ubuntu #ec2 host이름.
    group: ubuntu

 

일단 이정도 내용만 복붙해보자

 

destination은 빌드된 jar파일을 어디다가 배포하면되는지 (=어디다가 저장할지 , s3에서 받아온 프로젝트를 어디에 저장되면되는지!)

  * 폴더가 생성되면서 저장되는게 아니라 jar파일안에 내용물이 저장되는형태 (지정한 위치에 src폴더,logs폴더등 빌드된 내용물이 저장된다고 보면된다)

 

owner, group 같은경우는 host 이름을 적어주면되는데

ec2 만들때

os를 ubuntu로 했으면 기본적으로 ubuntu로 설정되어있을것이다

linux라면 ec2-user로 되어있음

 

 

GithubActions 스크립트에 명령추가하기!

Github Actions를 쓰기위해 생성한 workflow에 대한 yml파일에다가

명령을 추가해준다!

 

deploy.yml (전체코드)

name: planet-system

on:
  workflow_dispatch:
  
env:
  S3_BUCKET_NAME: wogus-planet-bucket
  PROJECT_NAME: Planet
  

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Set up JDK 1.8
        uses: actions/setup-java@v1
        with:
          java-version: 1.8
          
      - name: Copy Secret
        env:
          PLANET_SECRET: ${{ secrets.PLANET_SECRET }}
          PLANET_SECRET_DIR: src/main/java/com/example/demo/config/secret
          PLANET_SECRET_TEST_DIR: src/test/java/com/example/demo/config/secret
          PLANET_SECRET_DIR_FILE_NAME: Secret.java
        run: echo $PLANET_SECRET | base64 --decode > $PLANET_SECRET_DIR/$PLANET_SECRET_DIR_FILE_NAME && 
                echo $PLANET_SECRET | base64 --decode > $PLANET_SECRET_TEST_DIR/$PLANET_SECRET_DIR_FILE_NAME      
      - name: Copy dev_yml
        env:
          DEV_APPLICATION_YML: ${{ secrets.DEV_APPLICATION_YML }}
          DEV_APPLICATION_YML_DIR: src/main/resources
        # PLANET_SECRET_TEST_DIR: src/test/java/com/example/demo/config/secret
          DEV_APPLICATION_YML_FILE_NAME: application.yml
        run: echo $DEV_APPLICATION_YML | base64 --decode > $DEV_APPLICATION_YML_DIR/$DEV_APPLICATION_YML_FILE_NAME #&& 
                #echo $PLANET_SECRET | base64 --decode > $PLANET_SECRET_TEST_DIR/$PLANET_SECRET_DIR_FILE_NAME    

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew
        shell: bash

      - name: Build with Gradle
        run: ./gradlew build
        shell: bash
        
      - name: Make zip file
        run: zip -r ./$GITHUB_SHA.zip .
        shell: bash

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_GITHUB_ACTION_ACCESS_KEY }}
          aws-secret-access-key: ${{ secrets.AWS_GITHUB_ACTION_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_GITHUB_ACTION_REGION }}

      - name: Upload to S3
        run: aws s3 cp --region ap-northeast-2 ./$GITHUB_SHA.zip s3://$S3_BUCKET_NAME/$PROJECT_NAME/$GITHUB_SHA.zip
        
        
        #추가 한 부분.
      - name: Code Deploy
        run: aws deploy create-deployment --application-name planet --deployment-config-name CodeDeployDefault.AllAtOnce --deployment-group-name planet_code_deploy --s3-location bucket=$S3_BUCKET_NAME,bundleType=zip,key=$PROJECT_NAME/$GITHUB_SHA.zip

이제 밑에 추가한 부분말고 더이상 github action 스크립트에 추가할 부분이없다.

밑에 추가한 부분을 보면 

배포를 하겠다는 명령부분인데

 

아까 code deploy 어플리케이션 만들때 설정한 이름,

code deploy 어플리케이션의 배포그룹 만들때 설정한 배포 방법인 CodeDeployDefault.AllAtOnce,

배포그룹이름,

환경변수로 지정한 버킷이름,

받아올 프로젝트의 파일타입 (zip파일로 저장했으니),

s3에서 프로젝트의 위치및 파일이름

 

을 전달해준다!

 

 

이렇게 스크립트에 추가내용까지 작성해주고 저장한후

 

Github Actions에서 해당 workflow(빌드/테스트 + 배포) 를 실행하면 배포가 실패할것이다.

 

Code deploy agent를 설치후 시작한 후 

Ec2에  IAM 역할을 부여했기 때문에  Code deploy agent가 IAM role을 가지고있어 배포가 실패함

 

EC2에 접속해서 다음 명령어를 입력하여 Agent를 재시작한다.

sudo service codedeploy-agent restart

 

그리고 난후 내 프로젝트 레포지토리의 Actions에 가서 Workflow를 실행해보면

 

Codle deploy의 배포가 성공한것을 확인할 수 있다.

 

 

성공하면 저런 초록체크모양이뜬다

실패시 클릭해서 어디에서 왜 실패했는지 자세히 살펴보자!

 

 

배포가 잘됬는지 아까 지정한 프로젝트 저장위치로 가보자!

src등 프로젝트의 내용물들이 잘 들어간것을 확인할 수 있다!

 

지금까지 구현한것은 workflow를 실행하면 자동으로 빌드/테스트를 해주고 그 후 ec2로 배포(저장)이 되는것이다!

 

다음에는 nginx를 이용한 무중단 배포로 가보자

 

 

출처,참고,더자세한 정보

 

Github Actions + CodeDeploy + Nginx 로 무중단 배포하기 (2)

CodeDeploy 소개 전 시간에 이어 다음으로는 Github Actions 에서 CodeDeploy 에게 S3에 있는 jar 파일을 가져가서 담당한 배포 그룹의 EC2에 배포해 줘! 라는 명령을 내릴 수 있도록 구성해 보겠습니다. 먼저

wbluke.tistory.com

 

댓글