CI/CD 자동화 배포 파이프라인을 구축하여 EC2에 웹애플리케이션을 배포하는 방법에 대해 알아보자.
웹애플리케이션 코드는 최근에 진행했던 AWS_FinalProject의 코드를 그대로 사용하고자 한다.
코드 샘플은 아래의 링크에서 확인하자.
https://github.com/ojs201/AWS_FinalProject
빌드 도구에는 Github Actions말고도 Jenkins라는 유용한 오픈소스 툴이 있지만, Jenkins는 아무래도 따로 서버를 구축해야 하기도 하고 플러그인 설치와 구성 등 다양한 설정이 필요하기 때문에 초기 설정이 복잡하다.
반면, 비교적 가까운 애플리케이션을 EC2로 배포하는 경우는 GitHub 생태계에 최적화 되어 있는 Github Actions를 사용하는 것이 좀 더 간편하게 CI/CD 파이프라인을 설정할 수 있다.
따라서, 이번 토이프로젝트에서는 Github Actions을 활용하여 파이프라인을 구축하고자 한다.
파이프라인을 구축하는 과정은 다음과 같다.
- GitHub 저장소에 '.github/workflows' 디렉토리를 생성하고, 이 안에 워크플로우 정의 파일을 작성
- 이 파일은 YAML 형식으로 작성되며, 워크플로우의 트리거 조건, 실행할 작업, 사용할 환경 등을 정의
우선, 코드가 올라가 있는 깃허브 레파지토리로 가자.
그리고 Settings 탭을 눌러보자.
Settings - Secrets and variables - Actions로 들어가자.
여기서 'New repository secret' 버튼을 눌러 변수를 생성하자.
변수명과 내용을 적어주자. 필자의 경우 EC2에 AWS에서 발급받은 pem키값으로 SSH접속을 할 것이기 때문에 Pem 키값을 넣어줬다.
이 방법 외에도, EC2 접근권한이 부여된 IAM계정을 생성 후, 액세스키와 시크릿키를 발급하여 AWS 리소스에 접근하는 방법도 있다. 하지만, 키값이 있다면 굳이 이 방법을 쓸 이유가 없다.
성공적으로 변수를 생성했다. 이제 workflow를 작성하러 가자.
프로젝트의 루트디렉토리에 .github/workflows/deploy.yml 파일을 생성하여 workflow를 다음과 같이 작성하자.
name: CI/CD Pipeline for Frontend Deployment
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Set up PEM file
run: |
echo "${{ secrets.EC2_PEM_KEY }}" > mandi.pem
chmod 600 mandi.pem
- name: Transfer files to EC2
run: |
rsync -avz -e "ssh -i mandi.pem -o StrictHostKeyChecking=no" --delete-after ./ ubuntu@43.201.250.130:/var/www/html/AWS_FinalProject
- name: Restart Nginx
run: |
ssh -i mandi.pem -o StrictHostKeyChecking=no ubuntu@43.201.250.130 "sudo systemctl restart nginx"
name: CI/CD Pipeline for Frontend Deployment
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
on: 이 워크플로우가 실행될 조건을 설정합니다. 여기서는 main 브랜치에 푸시(pushing) 이벤트가 발생할 때마다 이 워크플로우가 실행되도록 설정되어 있습니다.
jobs: 하나 이상의 작업(jobs)을 정의하는 섹션입니다. 여기서는 deploy라는 이름의 작업을 정의했습니다.
runs-on: 이 작업이 실행될 환경을 설정합니다. 여기서는 ubuntu-latest 환경에서 실행됩니다.
uses: GitHub의 체크아웃 액션을 사용하여 레포지토리의 코드를 가져옵니다. @v3는 버전을 나타냅니다.
- name: Set up PEM file
run: |
echo "${{ secrets.EC2_PEM_KEY }}" > mandi.pem
chmod 600 mandi.pem
run: 이 단계에서 실행할 커맨드를 정의합니다.
- echo "${{ secrets.EC2_PEM_KEY }}" > mandi.pem: GitHub Secrets에서 EC2의 PEM 키를 가져와 mandi.pem 파일로 저장합니다. 이 키는 EC2 인스턴스에 SSH로 접속하는 데 필요합니다.
- chmod 600 mandi.pem: PEM 파일의 권한을 설정하여 소유자만 읽고 쓸 수 있도록 합니다.
- name: Transfer files to EC2
run: |
rsync -avz -e "ssh -i mandi.pem -o StrictHostKeyChecking=no" --delete-after ./ ubuntu@43.201.250.130:/var/www/html/AWS_FinalProject
run: 이 단계에서 실행할 커맨드를 정의합니다.
- rsync -avz -e "ssh -i mandi.pem -o StrictHostKeyChecking=no": rsync를 사용하여 로컬 파일을 EC2로 전송합니다.
- -a: 아카이브 모드로 파일과 디렉토리를 복사합니다.
- -v: 자세한 출력을 보여줍니다.
- -z: 전송 중 파일을 압축합니다.
- -e "ssh -i mandi.pem -o StrictHostKeyChecking=no": SSH를 사용하여 PEM 키를 통해 연결합니다. StrictHostKeyChecking=no는 SSH가 호스트 키를 검증하지 않도록 합니다.
- --delete-after: 대상에서 소스에 존재하지 않는 파일을 삭제합니다.
- ./: 현재 디렉토리의 모든 파일을 소스로 사용합니다.
- ubuntu@43.201.250.130:/var/www/html/AWS_FinalProject: EC2 인스턴스의 목적지 경로입니다.
코드 작성이 완료되었으면, 이제부터는 main레포에 push를 할 때마다, 변경된 코드가 반영되어 EC2에 배포가 될 것이다.