Github Action을 이용한 CI/CD 구축
AWS에 애플리케이션을 띄워서 운용을 해야하는 과제를 하면서 Github Action을 이용한 CI/CD 과정을 간단하게 정리한 글
1.CI/CD란?
CI : Continuous Integration(지속가능한 통합) : 개발자들이 작업한 코드가 예를 들어 main 브랜치에 push, merge 됐을 때 서버에서 자동으로 빌드, 테스트를 해주는 과정.
CD : Continuous Deployment(지속가능한 배포) : CI로 빌드, 테스트가 통과됐을 때, 운영중인 서버에 새로 통합된 코드를 자동으로 배포해주는 과정
2.왜 Github Action을 사용하였는지?
1) Github에서 제공하는 서비스이기 때문에 Github Repository에서 push, merge 됐을 때 자동으로 작업을 시작하게 하기 쉽다.
2) 커뮤니티에서 제공하는 템플릿으로 더 편하게 시작할 수 있다. 예를 들어 지금 사용하고 있는 gradle같은 경우에도 이미 빌드,테스트, 종속성 그래프를 체크하는 CI 템플릿을 제공해주기 때문에 쉽게 접근할 수 있다.
3) public repository에 대해 무료이기 때문에, 학습하는 입장에서 부담없이 사용할 수 있다.
3. 어떤 과정으로 진행되는지?
나같은 경우에는 이런 방식으로 진행되게 파이프라인을 구성했다. Github Action IP를 AWS 보안규칙에 허용했다가 풀었다가 해주는 이유는 SSH 22번 포트를 아무 IP나 다 허용해주는 건 위험하다고 생각해서 찾아보다가 어떤 귀인분께서 정리해주신 글을 보고 이 방법을 선택하게 되었다.
https://makethree.tistory.com/19
AWS EC2 인스턴스 인바운드 IP 제한 상태에서 Github Action 배포
AWS EC2 인스턴스 인바운드 보안 설정 상태에서 Github Action 배포 자동화하기 일단 먼저 인스턴스를 만드는 방법이 궁금하신 분들은 AWS 프리티어 인스턴스 만들기 에 자세하고 쉽게 설명해놨으니
makethree.tistory.com
혹시나 참고가 될까 싶어서 올리는 github action yaml 설정
name: Java CI with Gradle
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
# DB 관련 환경 변수와 JWT Secret 설정
env:
DB_URL: ${{ secrets.DB_URL }}
DB_USERNAME: ${{ secrets.DB_USERNAME }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
JWT_SECRET_KEY: ${{ secrets.JWT_SECRET_KEY }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }}
steps:
- uses: actions/checkout@v4
- name: Set up JDK 22
uses: actions/setup-java@v4
with:
java-version: '22'
distribution: 'temurin'
# Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies.
# See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md
- name: Setup Gradle
uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
- name: Build with Gradle Wrapper
run: ./gradlew build
#Docker Hub 로그인
- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
# Docker 이미지 빌드
- name: Build the Docker image
run: docker build -t ${{ secrets.DOCKER_USERNAME }}/spring-plus:latest .
# Docker Hub에 이미지 푸시
- name: Push the Docker image
run: docker push ${{ secrets.DOCKER_USERNAME }}/spring-plus:latest
#깃허브 액션 IP 가져오기
- name: Get Github action IP
id: ip
uses: haythem/public-ip@v1.3
#AWS credentials
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4.0.2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_DEFAULT_REGION }}
# 깃허브 액션 IP 보안규칙에 추가
- name: Add Github Actions IP to Security group
run: |
aws ec2 authorize-security-group-ingress --group-name ${{ secrets.AWS_SG_NAME }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32
# EC2에서 이미지 Pull, 컨테이너 실행
- name: Deploy to AWS EC2
uses: appleboy/ssh-action@v1.1.0
with:
host: ${{ secrets.HOST }}
username: ubuntu
key: ${{ secrets.RSA_KEY }}
script: |
docker pull ${{ secrets.DOCKER_USERNAME }}/spring-plus:latest
docker stop spring-plus || true
docker rm spring-plus || true
docker run --env-file .env -d --name spring-plus -p 8080:8080 ${{ secrets.DOCKER_USERNAME }}/spring-plus:latest
# 깃허브 액션 IP 보안규칙에서 제거
- name: Remove Github Actions IP from security group
run: |
aws ec2 revoke-security-group-ingress --group-name ${{ secrets.AWS_SG_NAME }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32