ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring boot CI/CD git action으로 aws ec2에 올리기.
    Computer Science/Spring boot 2022. 7. 9. 00:27

    우선 바로 배포를 진행할 것이기 때문에 의존성을 모두 포함한 BootJar로만 Build를 진행합니다.

    따라서 의존성을 제거하여 build하는 Jar는 skip해줍니다.(snapshot-plain.jar)

    jar{
       enabled = false
    }

    build.gradle에 추가하여 진행합니다.


    s3에 대한 접근 권한을 받아오기 위해 AWS IAM을 생성해줍니다.

    사용자를 생성해주고, 액서스 키 -> 기존 정책 직접 연결 ->

    AmazonEC2FullAccess, AmazonS3FullAccess, AWSCodeDeployFullAccess ->

    키 생성 -> 액세스 키 ID, 비밀 액세스 키 secrets-actions에 등록

    (EC2와 CodeDeploy는 S3에 파일을 저장하고 이 파일을 EC2에서 가져와 실행할 때 사용할 권한들)

     

    github action을 통해 내 spring boot를 build후 s3에 zip으로 옮깁니다.

    aws deploy는 tar, zip, tgz만 지원한다. 해당 압축 파일을 ec2로 전송하여 압축을 알아서 푼다.

    name: aws CI/CD

    on:
     
      push:
        branches: [ "master" ]
      pull_request:
        branches: [ "master" ]



    env:
      S3_BUCKET_NAME: lof-deploy
      
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v3

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

          - name: Grant execute permission for gradlew
            run: chmod +x gradlew
          - name: Build with Gradlew
            run: ./gradlew clean build
            
          - name: Make Directory
            run: mkdir deploy
            
          - name: Copy Jar
            run: cp ./build/libs/*.jar ./deploy

          - name: Make zip file
            run: zip -r ./lof.zip ./deploy
            shell: bash
            
          - 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: upload to s3
            run: aws s3 cp —region ap-northeast-2 ./lof.zip s3://$S3_BUCKET_NAME/

     

     

    https://github.com/marketplace/actions/s3-cp

    참고하기 


    ec2가 s3에 대해 접근 권한 및 deploycode권한을 가지기 위해 역할을 부여해줍니다.

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

    ->aws 서비스 -> ec2 -> AmazonS3FullAccess, AWSCodeDeployFullAccess

    -> 인스턴스 -> 보안 - IAM 역할 수정


    ec2에서 CodeDeploy 설치.

    sudo yum install ruby

    wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install

    chmod +x ./install

    sudo ./install auto

     

    확인하기

    sudo service codedeploy-agent status


    외부에서 작동시킬 CodeDeploy 생성

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

    -> aws 서비스 -> 다른 aws 서비스 -> CodeDeploy -> 생성

    CodeDeploy -> 애플리케이션 -> 애플리케이션 생성 -> EC2/온프레미스

    ->배포 그룹 -> 배포 그룹 생성 -> 서비스 역할 ( 위에 생성한 역할 ) -> Amazon EC2 인스턴스 -> 배포할 EC2 인스턴스 선택


    CodeDeploy가 자동으로 실행할 파일 생성

    codedeploy는 appspec.yml 을 읽고 실행한다.

    https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/reference-appspec-file-structure.html

    참고하기

     

    version: 0.0
    os: linux
    files:
      - source: /
        destination: /home/app
    permissions:
      - object: /home/app
        pattern: "**"
        owner: root
        mode: 777
    hooks:
      ApplicationStart:
        - location: deploy.sh
          timeout: 300
          runas: root


    appspec 으로 실행할 sh 파일 생성.

    #!/bin/bash

    REPOSITORY=/home/app
    echo "> 현재 구동 중인 애플리케이션 pid 확인"
    CURRENT_PID=$(pgrep -fla java | awk '{print $1}')
    echo "현재 구동 중인 애플리케이션 pid: $CURRENT_PID"
    if [ -z "$CURRENT_PID" ]; then
      echo "현재 구동 중인 애플리케이션이 없으므로 종료하지 않습니다."
    else
      echo "> kill -9 $CURRENT_PID"
      kill -9 $CURRENT_PID
      sleep 5
    fi
    echo "> 새 애플리케이션 배포"
    JAR_NAME=$(ls -tr $REPOSITORY/*.jar | tail -n 1)
    echo "> JAR NAME: $JAR_NAME"
    echo "> $JAR_NAME 에 실행권한 추가"
    chmod +x $JAR_NAME
    echo "> $JAR_NAME 실행"
    nohup /opt/jdk-17/bin/java -jar $JAR_NAME > $REPOSITORY/nohup.out &


    마지막으로 해당 appspec 과 sh 파일을 묶어서 zip으로 보내준다.

    name: aws CI/CD

    on:
     
      push:
        branches: [ "master" ]
      pull_request:
        branches: [ "master" ]

    env:
      S3_BUCKET_NAME: lof-deploy
      
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v3

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

          - name: Grant execute permission for gradlew
            run: chmod +x gradlew
          - name: Build with Gradlew
            run: ./gradlew clean build
            
          - name: Make Directory
            run: mkdir deploy
            
          - name: Copy Jar
            run: cp ./build/libs/*.jar ./deploy
            
          - name: Copy appspec.yml
            run: cp appspec.yml ./deploy

          - name: Copy script
            run: cp ./scripts/*.sh ./deploy

          - name: Make zip file
            run: zip -r ./lof.zip ./deploy
            shell: bash
            
          - 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: upload to s3
            run: aws s3 cp --region ap-northeast-2 ./lof.zip s3://$S3_BUCKET_NAME/
             
          - name: Deploy
            env:
              AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
              AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
            run: |
              aws deploy create-deployment --application-name lof-application --deployment-group-name lof-group --file-exists-behavior OVERWRITE --s3-location bucket=lof-deploy,bundleType=zip,key=lof.zip --region ap-northeast-2

Designed by Tistory.