목차

    과정
    1. Github main 브랜치에 Push
    2. Github Actions에서 AWS S3에 빌드 파일 및 Dockerfile, deploy.sh 등 업로드
    3. Github Actions이 AWS CodeDeploy에 배포 요청
    4. CodeDeploy가 배포 실행
    5. 도커 빌드 및 실행

     

    위와 같은 과정으로 자동 배포화가 진행됩니다.

    Github Actions -> S3 빌드 및 업로드

    - S3 버킷 생성

     

    

    IAM 사용자를 통해 S3 저장소에 접근 할 것이기 때문에 모든 퍼블릭 액세스를 차단합니다.

     

     

    아래와 같이 버킷이 생성된 것을 확인 할 수 있습니다.

    IAM 설정

    IAM > 사용자 > 사용자 추가

    - 정책 추가

    GitHub Actions 워크플로우에서 AWS 리소스를 사용하기 위해

    AmazonS3FullAccess와 AWSCodeDeployFullAccess 정책을 추가한다.

     

    - Access Key 생성

    보안 자격 증명 -> 액세스 키 만들기

    위와 같이 설정 해줍니다.

     

    생성된 액세스 키는 csv 파일로 저장해둡니다. 이후에 Github Actions에서 secreats 를 설정해줘야 합니다.

     

    - 역할생성

    IAM -> 역할 -> 역할 만들기

     

    1. EC2 역할 생성

    CodeDeploy 서비스를 사용하여 EC2 인스턴스에 애플리케이션을 배포하기 위해 AmazonEC2RoleforCodeDeploy 역할을 추가한다.

     

     

    2. CodeDeploy 역할 생성

    자동으로 권한이 추가된다.

     

    - EC2 IAM 역할 수정

    사용중인 EC2 인스턴스 접속 후에 작업 -> 보안 -> IAM 역할 수정을 해준다. 

    설정한 role-ec2-codedeploy로 역할을 수정해준다. (이후에 인스턴스 재부팅 한 번 해야한다.)

     

    CodeDeploy 설정

    CodeDeploy-> 배포 -> 애플리케이션 -> 애플리케이션 생성

     

    - 배포그룹 생성

    환경 구성의 키 값은 사용중인 인스턴스 값을 사용한다.

     

     


    Github 설정

    - Secrets

    github -> settings -> secrets and variables -> Actions

    위에 IAM 설정에서 가져온 액세스 키의 정보들을 AWS_ACCESS_KEY_ID 와 AWS_SECRET_ACCESS_KEY에 저장하고, APPLICATION에는 spring boot 프로젝트 내의 application.yml 파일 내용을 넣습니다.

     

    - Github Actions Workflow

     Actions에서 새로운 Wokrflow를 생성해준다.

    main-deploy.yml

    # 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: Deploy to Production
    
    on:
      push:
        branches:
          - main
    jobs:
      deploy:
        runs-on: ubuntu-latest
    
        steps:
          - name: Checkout source code
            uses: actions/checkout@master
    
          - name: Set up JDK 11
            uses: actions/setup-java@v3
            with:
              java-version: '11'
              distribution: 'temurin'
    
          - name: Gradle Caching
            uses: actions/cache@v3
            with:
              path: |
                ~/.gradle/caches
                ~/.gradle/wrapper
              key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
              restore-keys: |
                ${{ runner.os }}-gradle-
          - name: Make application.yml
            run: |
              cd ./src/main
              mkdir resources
              cd ./resources
              touch ./application.yml
              echo "${{ secrets.APPLICATION }}" > ./application.yml
            shell: bash
    
          - name: Grant execute permission for gradlew
            run: chmod +x gradlew
    
          - name: Build with Gradle
            run: ./gradlew build
    
          - name: Make zip file
            run: |
              mkdir deploy
              cp ./appspec.yml ./deploy/
              cp ./Dockerfile ./deploy/
              cp ./scripts/*.sh ./deploy/
              cp ./build/libs/*.jar ./deploy/
              zip -r -qq -j ./spring-build.zip ./deploy
    
          - name: Configure AWS credentials
            uses: aws-actions/configure-aws-credentials@v2
            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: Upload to S3
            run: |
              aws s3 cp \
                --region ap-northeast-2 \
                ./spring-build.zip s3://jeonsg2-bucket
    
          - name: Code Deploy
            run: aws deploy create-deployment --application-name spring-deploy
              --deployment-config-name CodeDeployDefault.OneAtATime
              --deployment-group-name spring-deploy-group
              --s3-location bucket=jeonsg2-bucket,bundleType=zip,key=spring-build.zip

     

     

    EC2 설정

    S3에 있는 파일을 담을 app 폴더를 생성한다.

    mkdir ~/app

     

    Docker 설치

    sudo apt update //우분투 패키지 인덱스 업데이트
    sudo apt install docker.io -y //도커 설치
    sudo service docker start //도커 시작
    sudo systemctl status docker.service //확인

     

    프로젝트 파일 설정

    Dockerfile (프로젝트 루트 디렉토리에 넣어주면 된다.)

    FROM openjdk:11
    
    WORKDIR /Toy-project
    
    COPY Toy_project-0.0.1-SNAPSHOT.jar app.jar
    
    ENTRYPOINT ["java","-jar","app.jar"]

     

    scripts/depoly.sh

    #!/bin/bash
    
    echo "> 현재 실행 중인 Docker 컨테이너 pid 확인" >> /home/ubuntu/deploy.log
    CURRENT_PID=$(sudo docker container ls -q)
    
    if [ -z $CURRENT_PID ]
    then
      echo "> 현재 구동중인 Docker 컨테이너가 없으므로 종료하지 않습니다." >> /home/ubuntu/deploy.log
    else
      echo "> sudo docker stop $CURRENT_PID"   # 현재 구동중인 Docker 컨테이너가 있다면 모두 중지
      sudo docker stop $CURRENT_PID
      sleep 5
    fi
    
    cd /home/ubuntu/app
    sudo docker build -t imagee:v1.0 .
    sudo docker run -d -p 8080:8080 imagee:v1.0

     

    appspec.yml

    version: 0.0
    os: linux
    files:
      - source: /
        destination: /home/ubuntu/app
        overwrite: yes
    
    permissions:
      - object: /
        pattern: "**"
        owner: ubuntu
        group: ubuntu
    
    hooks:
      ApplicationStart:
        - location: deploy.sh
          timeout: 60
          runas: ubuntu

     

     

    배포 자동화 결과

    GitHub Actions Workflows
    S3 bucket
    CodeDeploy 자동 배포 성공
    EC2 인스턴스 내에서 실행되는 docker image

     

    1. Spring boot 프로젝트에서 GitHub로 push를 하게 되면 GitHub Actions는 push event를 감지하여 자동으로 시작된다.

    2. Actions는 빌드 도구 Gradle를 사용하여 Spring boot 애플리케이션을 빌드한다.

    3. 빌드가 성공하면 빌드 된 애플리케이션 아티팩트 JAR를 생성한다.

    4. Actions는 해당 JAR파일을 S3 버킷에 업로드한다.

    5. CodeDeploy는 S3 버킷에서 애플리케이션 아티팩트를 가져와 EC2 인스턴스에 배포한다.

    6. 배포가 성공하면 최신 버전의 애플리케이션 EC2 인스턴스에서 실행된다.

     

    위의 순서와 같이 자동 배포화가 이루어집니다.