본문 바로가기
TIL

[240219] CI/CD 공부 (2) CD

by 진진리 2024. 2. 19.
728x90
  • CI/CD 공부 (1) CI

https://jinjinjincode.tistory.com/256

 

[240110] CI/CD 공부

CI/CD란? Continuous Integration/Continuous Deployment(Delivery)의 약자로, 지속적인 통합과 지속적인 제공을 의미 기본 개념 지속적인 통합(Continuous Integration): 자동화된 빌드와 자동화된 테스트를 제공 지속적

jinjinjincode.tistory.com

  • 수동 배포

https://jinjinjincode.tistory.com/259

 

[240114] AWS, docker로 수동 배포하기

CD를 구축하기 전에 먼저 배포 과정을 익히기 위해서 수동 배포를 해보려고 한다. 지난번에 AWS RDB와 EC2를 만들었고 그 이후 과정부터 진행하고자 한다. gradle 빌드하여 jar 파일 생성 인텔리제이에

jinjinjincode.tistory.com

  • 무중단 배포

https://jinjinjincode.tistory.com/262

 

[240128] docker + nginx 무중단배포 구축하기

기존에는 코드가 수정되면 CI/CD를 통해 도커 이미지가 올라가게 되고, EC2 서버에서 해당 이미지를 컨테이너로 실행하여 배포를 진행해야 했다. 이 과정에서는 코드가 수정될 때마다 수정 내용을

jinjinjincode.tistory.com

'CI/CD 공부 (1) CI'에서 check.yml을 통해 깃허브 액션을 통한 빌드 자동화를 구축하였다.
이후에 수동 배포를 진행해보았고 해당 내용을 토대로 cd.yml을 통해 배포 자동화를 구축하였다.
사용자 테스트를 진행하면서 무중단배포의 필요성을 느껴 적용해본 후에 cd.yml에 추가하였다.
따라서 배포 자동화 과정에 대해 한 번 정리해보고자 한다.

 

 

CD를 위한 cd.yml 작성

name: CI/CD using github actions & docker

on:
  push:
    branches:
      - develop

permissions:
  contents: read

jobs:
  push_to_registry:
    name: Push to aws container registry
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

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

      - name: make application-prod.yml
        if: contains(github.ref, 'develop') || contains(github.ref, 'main')
        run: |
          cd ./src/main/resources
          touch ./application-prod.yml
          echo "${{ secrets.YML_PROD }}" > ./application-prod.yml
        shell: bash

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

      - name: Build with Gradle
        env:
          SPRING_PROFILES_ACTIVE: prod
        run: ./gradlew clean build --stacktrace
        shell: bash

      - name: Docker build & push to prod
        if: contains(github.ref, 'develop') || contains(github.ref, 'main')
        run: |
          docker login -u ${{ secrets.DOCKER_USER }} -p ${{ secrets.DOCKER_PASSWORD }}
          docker build -t sappun -f ./Dockerfile .
          docker tag sappun:latest ${{ secrets.DOCKER_USER }}/sappun:latest
          docker push ${{ secrets.DOCKER_USER }}/sappun:latest
          
          
  pull_from_registry:
    name: Connect server ssh and pull from container registry
    needs: push_to_registry
    runs-on: ubuntu-latest
    steps:
      - name: Get Github action IP
        id: ip
        uses: haythem/public-ip@v1.2

      - name: Setting environment variables
        run: |
          echo "AWS_DEFAULT_REGION=ap-northeast-2" >> $GITHUB_ENV
          echo "AWS_SG_NAME=launch-wizard-3" >> $GITHUB_ENV

      - 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: ap-northeast-2

      - name: Add Github Actions IP to Security group
        run: |
          aws ec2 authorize-security-group-ingress --group-name ${{ env.AWS_SG_NAME }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_DEFAULT_REGION: ap-northeast-2

      - name: Deploy to prod
        if: contains(github.ref, 'develop') || contains(github.ref, 'main')
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST_NAME }}
          username: ${{ secrets.USER_NAME }}
          key: ${{ secrets.AWS_PRIVATE_KEY }}
          port: ${{ secrets.AWS_PORT }}
          script: |
            docker pull ${{ secrets.DOCKER_USER }}/sappun:latest
            chmod 777 ./deploy.sh
            ./deploy.sh
            docker image prune -f

      - name: Remove Github Actions IP from security group
        run: |
          aws ec2 revoke-security-group-ingress --group-name ${{ env.AWS_SG_NAME }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_DEFAULT_REGION: ap-northeast-2

 

jobs 및 steps 설명

1. push_to_registry 작업: 빌드 및 도커 이미지 생성 후 push

  • Checkout: 현재 레포지토리를 가져옴
  • Set up JDK 17: JDK 17 환경 구성
  • make application-prod.yml: 깃허브 secret에 저장한 내용을 가져와 application-prod.yml 파일 생성
  • Grant execute  permisssion for gradlew: Greadle 빌드 도구를 실행하기 위한 권한 부여
  • Build with Gradle: 스프링 부트 어플리케이션을 Gradle을 사용해 prod 환경에서 빌드
  • Docker build & push to prod: Docker 이미지를 빌드하고 도커허브에 push

2. aws ec2 연결 및 deploy.sh 실행

  • Get Github action IP: 깃허브 액션 실행 환경의 IP 주소를 가져옴
  • Setting environment variables: AWS 지역 및 보안 그룹 이름을 환경 변수로 설정
  • Configure AWS credentials: AWS 자격 증명 구성
  • Add Github Actions IP to Security group: 보안 그룹에 깃허브 액션 IP 주소를 추가
  • Deploy to prod: AWS EC2 인스턴스로 SSH 연결하고 최신 Docker 이미지를 가져와 배포 스크립트 실행
    • 이때 배포 스크립트를 통해 블루-그린 배포를 구현함
  • Remove Github Actions IP from security group: 보안 그룹에서 깃허브 액션 IP 주소 제거

 

'TIL' 카테고리의 다른 글

알람 기능 구현 방법  (0) 2024.05.05
[240128] docker + nginx 무중단배포 구축하기  (0) 2024.01.28
[240118] userDetails null 오류  (0) 2024.01.18
[240117] ec2 서버 실행  (0) 2024.01.17
[240114] AWS, docker로 수동 배포하기  (0) 2024.01.15