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
참고 자료
'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 |