Github Action을 통하여 main브랜치에 PR이 merge 되면 자동으로 빌드 후 배포를 진행하도록 구축하였습니다.
main 브랜치에 merge가 되면 매번 ec2 instance에 들어가서 git pull -> npm run -> build pm2 start까지 하는 작업을 줄여보고자 했습니다.
Github Action에서 제공하는 탬플릿을 사용하여 간편하게 CD를 구축할 수도 있지만, 이번에는 .yml 파일을 사용하여 스크립트 형식으로 CD를 구축해 보았습니다.
EC2 인스턴스에 인바운드 규칙으로 ip를 제한해 놓았기 때문에 github action이 실행될 ip를 추가하고 제거하는 작업이 포함되어 있습니다.
구축 방법
간단합니다. 프로젝트 root에 .github/workflows 폴더 내부에 .yml 파일을 작성하면 됩니다.
(물론 .yml 파일 작성이 간단하지는 않습니다.)
.yml 파일 작성
on
on 키는 해당 workflow가 언제 실행될지를 설정합니다.
on:
push:
branches:
- main
저는 main 브랜치에 push 될 때 (PR포함) action을 실행하도록 지정하였습니다.
jobs
jobs에서 실행할 작업들을 설정합니다. 먼저 실행환경을 지정합니다. 저는 ubuntu를 지정해 주었습니다.
deploy-production-web: # 작업의 이름
runs-on: ubuntu-latest
steps에서 실제 작업들을 설정합니다.
그냥 배포작업 설정만 해도 되지만, EC2 인스턴스에 보안그룹의 인바운드 규칙이 github action의 접근을 허용하지 않기 때문에 작업과정에서 입시로 github action의 접근을 허용하는 작업이 추가되어야 합니다.
1. 먼저 github action의 ip를 받아옵니다. haythem이라는 라이브러리를 사용합니다.
- name: Get Github action IP
id: ip
uses: haythem/public-ip@v1.2
2. github env의 환경변수를 설정합니다. 저는 region과 보안그룹이름을 설정하였습니다.
- name: Setting environment variables
run: |
echo "AWS_DEFAULT_REGION=ap-northeast-2" >> $GITHUB_ENV
echo "AWS_SG_NAME=[보안그룹 이름]" >> $GITHUB_ENV
3. AWS 자격을 증명합니다. 프로젝트의 secret에서 지정한 여러 key들을 불러옵니다.
- 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
4. 1번에서 받은 ip가 보안그룹에 지정되어있는지 확인하고, 지정되어 있지 않다면 지정합니다. 해당 작업에 aws credential이 필요하므로 env로 지정해줍니다.
- name: Add Github Actions IP to Security group
run: |
CURRENT_RULE=$(aws ec2 describe-security-groups --group-name ${{ env.AWS_SG_NAME }} --query "SecurityGroups[0].IpPermissions[?FromPort==\`22\`].IpRanges[?CidrIp==\`{{ steps.ip.outputs.ipv4 }}/32\`]" --output text)
if [ -z "$CURRENT_RULE" ]; then
echo "IP not found, adding IP to security group."
aws ec2 authorize-security-group-ingress --group-name ${{ env.AWS_SG_NAME }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32
else
echo "IP is already in the security group."
fi
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
5. repository의 코드를 불러옵니다. 기본적으로 이 액션은 main branch의 최신 commit의 코드를 가져옵니다.
- name: Checkout code
uses: actions/checkout@v2
6. SCP(Secure Copy Protocol)를 사용하여 EC2 인스턴스에 파일을 복사합니다. appleboy/scp-action 라이브러리를 사용합니다.
- name: Copy files via SSH
uses: appleboy/scp-action@v0.1.3
with:
host: ${{ secrets.EC2_HOST_PRODUCTION }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_KEY }}
source: "./"
target: "~/[프로젝트 이름]/"
** appleboy/scp-action
https://github.com/appleboy/scp-action
7. 배포에 필요한 스크립트를 실행합니다. 의존성 설치, 빌드, node 환경설정, pm2 start와 같은 작업들입니다.
- name: Deploy to EC2 via SSH and run PM2 start script
uses: appleboy/ssh-action@v0.1.3
with:
host: ${{ secrets.EC2_HOST_PRODUCTION }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_KEY }}
script: |
cd ~/[프로젝트 이름]/
git pull origin main
pm2 stop [지정한 프로젝트 이름]
export PATH=$PATH:/home/ubuntu/.nvm/versions/node/v22.11.0/bin
npm install
npm run build
pm2 start [지정한 프로젝트 이름]
8. 마무리로 임시로 보안그룹에 추가했던 github action의 ip를 지우는 작업을 합니다.
- 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
전체 yml 파일
name: Deploy main Branch to AWS EC2 Instance
on:
push:
branches:
- main
env:
GITHUB_REPOSITORY: ${{ github.server_url }}/${{ github.repository }}
ACTION_URI: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
jobs:
deploy-production-web:
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=[보안그룹 이름]" >> $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: |
CURRENT_RULE=$(aws ec2 describe-security-groups --group-name ${{ env.AWS_SG_NAME }} --query "SecurityGroups[0].IpPermissions[?FromPort==\`22\`].IpRanges[?CidrIp==\`{{ steps.ip.outputs.ipv4 }}/32\`]" --output text)
if [ -z "$CURRENT_RULE" ]; then
echo "IP not found, adding IP to security group."
aws ec2 authorize-security-group-ingress --group-name ${{ env.AWS_SG_NAME }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32
else
echo "IP is already in the security group."
fi
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: Checkout code
uses: actions/checkout@v2
- name: Copy files via SSH
uses: appleboy/scp-action@v0.1.3
with:
host: ${{ secrets.EC2_HOST_PRODUCTION }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_KEY }}
source: "./"
target: "~/[프로젝트 이름]/"
- name: Deploy to EC2 via SSH and run PM2 start script
uses: appleboy/ssh-action@v0.1.3
with:
host: ${{ secrets.EC2_HOST_PRODUCTION }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_KEY }}
script: |
cd ~/[프로젝트 이름]/
git pull origin main
pm2 stop [지정한 프로젝트 이름]
export PATH=$PATH:/home/ubuntu/.nvm/versions/node/v22.11.0/bin
npm install
npm run build
pm2 start [지정한 프로젝트 이름]
- 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
'개발 프로세스 기록' 카테고리의 다른 글
Next.js App 배포하기 - 2. Https 세팅 (0) | 2025.01.19 |
---|---|
Next.js App 배포 - 1. EC2에 배포하기 (0) | 2025.01.19 |
AWS S3 정적 웹사이트 배포하기 (0) | 2023.06.30 |
댓글