선행 조건
CI/CD 환경을 구축하기 위해서는 몇 가지 선행 조건을 충족해야 한다.
아래는 환경 구축 전에 준비해야 할 항목들이다.
•
Google Cloud Compute Engine VM 인스턴스에 docker와 docker-compose 설치
•
Docker Hub 계정 생성
•
배포할 API 서버
CI/CD 파이프라인 구축 방법
위의 선행 조건을 모두 준비하면, Github Actions를 사용하여 Docker 이미지를 빌드하고, Docker Hub에 푸시한 후, Google Cloud에 자동으로 배포하는 CI/CD 파이프라인을 구축할 수 있다.
1. Compute engine SSH 키 쌍 생성
Google Cloud에 SSH를 사용하여 연결하기 위한 비밀 키 파일을 생성해야 한다.
ssh-keygen -t rsa -b 2048 -f ~/.ssh/gcp_compute_key
YAML
복사
2. Google Cloud Console에서 SSH 공개 키 추가
•
Google Cloud Console → Compute Engine → VM 인스턴스 → 인스턴스 선택 후 “편집” 버튼 클릭
•
“SSH 키” 항목에서 “항목 추가” 버튼 클릭
•
gcp_compute_key.pub 파일의 내용을 복사 후 붙여넣기
3. gcloud 접근 권한 설정
깃허브 액션(GitHub Actions)이 Google Cloud에 안전하게 접근하기 위해서는 워크로드 아이덴티티(Workload Identity)를 사용하여 인증을 구성해야 한다.
아래는 워크로드 아이덴티티를 설정하는 과정이다.
워크로드 아이덴티티 설정
워크로드 아이덴티티(Workload Identity)는 Google Cloud에서 GitHub Actions과 같은 외부 시스템이 Google Cloud 리소스에 안전하게 액세스할 수 있도록 하는 기능이다.
•
워크로드 아이덴티티 풀 생성
gcloud iam workload-identity-pools create "github-actions-pool" \
--project="${PROJECT_ID}" \
--location="global" \
--display-name="github-actions-pool"
Shell
복사
[트러블 슈팅] PERMISSION_DENIED: Request had insufficient authentication scopes
•
생성한 워크로드 아이덴티티 풀의 ID 조회
gcloud iam workload-identity-pools describe "github-actions-pool" \
--project="${PROJECT_ID}" \
--location="global" \
--format="value(name)"
Shell
복사
◦
조회된 ID는 추후 깃허브 액션과의 연동을 위해 메모
•
워크로드 아이덴티티 풀에 인증 공급자(Github Actions) 추가
gcloud iam workload-identity-pools providers create-oidc "github-actions-provider" \
--project="${PROJECT_ID}" \
--location="global" \
--workload-identity-pool="github-actions-pool" \
--display-name="GitHub Actions OIDC Provider" \
--attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.aud=assertion.aud,attribute.repository=assertion.repository" \
--attribute-condition="attribute.repository==assertion.repository" \
--issuer-uri="https://token.actions.githubusercontent.com"
Shell
복사
[트러블 슈팅] INVALID_ARGUMENT: The attribute condition must reference one of the provider's claims.
IAM 서비스 계정 생성
깃허브 액션에서 Google Cloud 리소스에 접근할 수 있도록 IAM 서비스 계정을 생성해준다.
서비스 계정은 Google Cloud 리소스를 인증하고 권한을 부여하는 역할을 한다.
•
IAM 서비스 계정 생성
gcloud iam service-accounts create github-actions-sa \
--project="${PROJECT_ID}" \
--display-name="GitHub Actions Service Account"
Shell
복사
•
서비스 계정에 역할 할당
◦
Github Actions에서 접근할 리소스에 접근 권한을 부여한다.
◦
GCP UI → IAM 및 관리자 → IAM → 액세스 권한 부여 → Compute 관리자 역할 부여
•
서비스 계정 권한 부여
gcloud iam service-accounts add-iam-policy-binding "github-actions-sa@${PROJECT_ID}.iam.gserviceaccount.com" \
--project="${PROJECT_ID}" \
--role="roles/iam.workloadIdentityUser" \
--member="principalSet://iam.googleapis.com/${WORKLOAD_IDENTITY_POOL_ID}/attribute.repository/${REPO_AUTHOR_NAME}/${REPO_NAME}"
Shell
복사
gcloud iam service-accounts add-iam-policy-binding \
"my-service-account@developer.gserviceaccount.com" \
--member="serviceAccount:github-actions-sa@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/iam.serviceAccountUser"
Shell
복사
•
IAM 정책에 서비스 계정 역할 추가
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:my-service-account@developer.gserviceaccount.com" \
--role="roles/iap.tunnelResourceAccessor"
Shell
복사
깃허브 Secrets 설정
•
WORKLOAD_IDENTITY_PROVIDER_ID
◦
projects/{프로젝트 번호}/locations/global/workloadIdentityPools/github-actions-pool/providers/github-actions-provider
•
SERVICE_ACCOUNT
◦
github-actions-sa@{프로젝트 번호}.iam.gserviceaccount.com
4. Github Actions CI/CD 파일 작성
name: CI/CD Pipeline
# main 브랜치에 대한 Pull request 및 Merge
on:
pull_request :
branches :
- main
push:
branches:
- main
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
permissions :
id-token : write
contents : read
pull-requests : write
steps:
# 1. 레포지토리 소스 코드 작업 환경으로 가져오기
- name: Checkout Repository
uses: actions/checkout@v3
# 2. 환경변수(.env) 파일 생성
- name: Set Environment File
run: |
echo "${{ secrets.PROD_ENV }}" > .env
chmod 644 .env
cat .env
# 3. 도커허브 로그인
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
# 4. 도커 허브에 이미지 푸시
- name: Push Docker Image
uses: docker/build-push-action@v6
with:
push: true
context: .
tags: ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_IMAGE_NAME }}:latest
# 5. GCP 인증
- name: Authenticate to GCP
id: 'auth'
uses: 'google-github-actions/auth@v2'
with:
workload_identity_provider: ${{ secrets.WORKLOAD_IDENTITY_PROVIDER }} # 생성한 워크로드 아이덴티티 풀의 ID
service_account: ${{ secrets.SERVICE_ACCOUNT_EMAIL }} # IAM 서비스 계정
# 6. GCP Compute Engine SSH로 배포
- name: Deploy to GCP Compute Engine
id: 'compute-ssh'
uses: 'google-github-actions/ssh-compute@v1'
with:
instance_name: ${{ secrets.GCP_INSTANCE_NAME }}
zone: ${{ secrets.GCP_INSTANCE_ZONE }}
ssh_private_key: ${{ secrets.GCP_SSH_PRIVATE_KEY }}
command: 'echo Hello world'
YAML
복사