CI/CD란?
빠르게 변화하는 기술 환경 속에서 시장과 고객의 요구에 신속하게 대응하는 것은 기업의 중요한 과제입니다. 이를 해결하기 위한 방법 중 하나가 바로 CI/CD(Continuous Integration/Continuous Delivery)입니다. CI/CD는 애플리케이션 개발과 배포의 모든 단계를 자동화하여 효율적이고 빈번한 배포를 가능하게 합니다. 간단히 말해, CI/CD는 개발 프로세스를 자동화하여 제품을 빠르게 시장에 출시하고, 업데이트할 수 있도록 하는 프로세스라 볼 수 있습니다.
Github Actions 소개
Github Actions는 특정 이벤트가 발생했을 때 자동으로 원하는 작업을 실행할 수 있도록 도와주는 툴입니다. 이 도구를 사용하면 다양한 트리거 이벤트에 대해 설정된 작업을 자동으로 수행할 수 있습니다.
Github Actiosn 주요 구성 요소
- Event: Github에서 발생할 수 있는 이벤트, 예를 들어 main 브랜치로의 Merge, Commit의 Push, Issue 생성 등이 있습니다.
- Workflows: Event가 트리거되었을 때 수행하고 싶은 작업을 정의하는 곳입니다.
- Jobs: Workflows 내에서 작업의 순서를 정의합니다. Jobs는 일반적으로 비동기적으로 수행되며, 필요한 경우 동기적으로 설정할 수 있습니다.
- Actions: Jobs 내에서 사용할 수 있는 다양한 작업을 정의한 것입니다. Github에서 제공하는 여러 Actions을 활용할 수 있습니다.
- Runners: Jobs를 실행하는 서버입니다. 각 Job은 개별 Runner에서 실행됩니다.
Github Actions Workflow 기본 YAML 파일 구조
name: "Github Actions Workflow name"
on: [push] # Github 내 commit이 push될 경우 트리거
jobs:
<job name>: # Jobs의 이름 설정
runs-on: ubuntu-latest # 실행 환경 명시
steps:
- uses: actions/checkout@v3 # checkout Actions 사용
- uses: actions/setup-node@v3 # setup-node Actions 사용
with:
node-versions: '14'
- run: npm install -g bats # Shell Script 실행
- run: bats -v
Snyk Application CI/CD Pipeline 통합
Snyk는 보안 취약점을 검사하는 도구입니다. CI/CD 파이프라인에 Snyk를 통합하면 코드의 보안성을 자동으로 검토하고 문제를 발견할 수 있습니다. 아래는 Github Actions를 사용하여 Snyk를 통합하는 방법입니다.
Backend yaml 코드
name: Snyk Security
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
permissions:
contents: read
jobs:
snyk:
permissions:
contents: read
security-events: write
actions: read
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.12
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Set up Snyk CLI
uses: snyk/actions/setup@806182742461562b67788a64410098c9d9b96adb
with:
version: 'latest'
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
- name: Authenticate Snyk CLI
run: snyk auth ${{ secrets.SNYK_TOKEN }}
- name: Debug Snyk Code test
run: |
set -x
echo "Starting Snyk Code test"
snyk code test --sarif > snyk-code.sarif || true
echo "Snyk Code test completed with exit code $?"
cat snyk-code.sarif
set +x
- name: Snyk Open Source monitor
run: snyk monitor --all-projects
- name: Upload result to GitHub Code Scanning
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: snyk-code.sarif
Frontend yaml 코드
name: Snyk Security
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
permissions:
contents: read
jobs:
snyk:
permissions:
contents: read
security-events: write
actions: read
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Snyk CLI
uses: snyk/actions/setup@806182742461562b67788a64410098c9d9b96adb
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: npm install
- name: Authenticate Snyk CLI
run: snyk auth ${{ secrets.SNYK_TOKEN }}
- name: Snyk Code test
run: snyk code test --sarif > snyk-code.sarif || true
- name: Snyk Open Source monitor
run: snyk monitor --all-projects
- name: Upload result to GitHub Code Scanning
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: snyk-code.sarif
트러블 슈팅 내역
1. Github Repository 내 환경 변수를 지정하지 않아 에러 발생 확인 ( 코드 내 "SNYK_TOKEN" 이라는 환경 변수를 지정하여 사용하나 값을 정의하지 않아 에러 발생 확인)
- Github Repository Settings → Secrets and variables → Repository secrets 메뉴로 이동하여 API Key 환경 변수 생성
2. Github Actions 실행 과정에서 하기 사진과 같이 snyk 인증 관련 에러가 발생하는 것을 확인
- yaml 코드 내 "snyk auth <SNYK_TOKEN>" 명령을 추가하여 에러 해결
3. Github Actions 실행 과정에서 하기 사진과 같이 IaC(Infrastructure as Code) 및 Docker 관련 에러 출력 확인
- 기본적으로 Github Actions 에서 제공해주는 Snyk Security 관련 코드의 경우 IaC 및 Docker file 의 경우도 취약점 검사를 진행하나, 현재 프로젝트의 경우 IaC(Infrastructure as Code), Docker 를 사용하지 않기 때문에 아래와 같이 Error 가 발생하는 것으로 확인되어 아래 사진에 표시된 코드 삭제 진행
EC2 내 코드 배포 자동화 (CD)
Github Actions를 사용하여 EC2에 github에 push된 코드를 자동으로 배포할 수 있도록 하는 코드 구현
실행 순서
- Github Action Runners 가 실행되는 서버의 IP 추출
- AWS Credential File Setting (EC2 보안 그룹 수정을 위함)
- 보안 그룹 설정 (Github Actions IP 를 Inbound 22번 포트 규칙 추가)
- SSH 를 통해 EC2에 접근하여 git pull 후 Chatbot.py 파일 재실행
- 보안 그룹 설정 (Github Action IP 를 Inbound 22번 포트 규칙 제거)
name: EC2 Deploy
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Get Github Action Runner IP
id: ip
uses: haythem/public-ip@v1.3
- name: Setting env variables
run: |
echo "AWS_DEFAULT_REGION=ap-northeast-2" >> $GITHUB_ENV
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ap-northeast-2
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: Add Github Actions IP to Security Group
run: |
aws ec2 authorize-security-group-ingress --group-id ${{ secrets.AWS_SG_ID }} --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
- name: executing remote ssh commands using key
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_KEY }}
script: |
cd /home/ubuntu/Flask-Chatbot-API
sudo git pull
sudo shutdown -r now
- name: Remove Github Actions IP from Security Group
run: |
aws ec2 revoke-security-group-ingress --group-id ${{ secrets.AWS_SG_ID }} --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
트러블 슈팅 내역
1. SG(Security Group) 설정 과정에서 아래 사진과 같이 InvalidGroup.NotFound 에러가 발생하는 것을 확인
- 해당 에러의 경우 SG를 찾을 수 없다는 에러 였는데 정상적으로 group-name 은 설정된 것으로 확인되나, 해당 에러가 지속적으로 발생되는 것으로 확인
- 문제의 원인은 일반적으로 CLI를 이용해 SG 설정 시 Default VPC를 대상으로 SG를 조회하는 것으로 확인 ⇒ 기존에 Default VPC를 삭제하고 Custom VPC를 설정하여 해당 에러가 발생하는 것으로 확인
- 해결 방안 : Default VPC 가 아닌 Custom VPC 내에서 SG를 검색하기 위해선 group-name 옵션을 사용하지 않고 group-id 옵션을 사용해 SG ID를 기반으로 Command 를 작성하여 사용하여야 하는 것을 확인해 명령을 아래와 같이 수정
aws ec2 authorize-security-group-ingress --group-id ${{ secrets.AWS_SG_ID }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32
2. SSH 접근 과정에서 "ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain" 와 같이 에러가 발생하는 것으로 확인
- secrets 값이 문제가 있어 발생하는 것 같아 계속 변경해보았으나, 지속적으로 발생하는 것으로 확인
- pem 파일을 생성하는 명령을 작성하여 해당 파일을 키 파일로 사용하여 접근하여도 같은 에러 발생하는 것으로 확인
※ 위와 같은 방법을 사용해도 문제가 없는 것을 보아 workflow 자체에는 문제가 없는 것처럼 보였음
- 해결 방안 : 구글링 시 비슷한 상황이 있는 것을 확인 ⇒ ec2 에 접근해 /etc/ssh/sshd_config 파일 내 아래와 같은 코드 추가 후 재시작
PubkeyAuthentication yes
PubkeyAcceptedKeyTypes=+ssh-rsa
참고 자료
AWS EC2 인스턴스 인바운드 IP 제한 상태에서 Github Action 배포
AWS EC2 인스턴스 인바운드 보안 설정 상태에서 Github Action 배포 자동화하기 일단 먼저 인스턴스를 만드는 방법이 궁금하신 분들은 AWS 프리티어 인스턴스 만들기 에 자세하고 쉽게 설명해놨으니
makethree.tistory.com
'Project > resume' 카테고리의 다른 글
MongoDB, Flask, Next.js 를 활용한 동적 블로그 컴포넌트 구현 (0) | 2024.08.17 |
---|---|
AI Chatbot 추천 질문 시스템 구현 / OpenAI Assistant Intruction 을 활용한 AI 응답 지정 (0) | 2024.08.17 |
MongoDB를 이용하여 Python에서 IP기반 요청 제한 구현 (0) | 2024.08.12 |
OpenAI API를 이용한 이력서 기반 AI ChatBot 백엔드 코드 구현 (0) | 2024.07.19 |
이력서 홈페이지 제작 프로젝트 (feat. 이력서 기반 AI챗봇) (0) | 2024.07.09 |