728x90
반응형
Overview
Github Action을 사용해서 Build 후 GCP Artifact Registry에 업로드 하는 방법에 대해서 알아본다.
Github Action Build and Push(with GCP Artifact Registry)
Github 에서 GCP 인증에 사용할 Service Account를 생성 후 Workload-identity-federation을 구성
Workload-identity-federation이란?
Google Cloud Platform (GCP)의 Workload Identity Federation은 external ID providers를 사용하여 Google Cloud 리소스에 접근 권한을 부여하는 기능이다. 이 기능을 사용하면 AWS, Azure, 혹은 어떤 OpenID Connect(OIDC) 호환 ID 제공자를 사용하는 조직도 GCP 서비스에 안전하게 액세스할 수 있다.
- 멀티 클라우드 보안: Workload Identity Federation을 사용하면 사용자는 Google Cloud 리소스에 접근하기 위해 다른 클라우드 플랫폼의 인증 정보를 활용할 수 있다. 이는 멀티 클라우드 환경에서의 관리와 보안을 강화한다.
- 안전한 액세스 관리: GCP의 IAM(Identity and Access Management) 정책을 사용하여 외부 시스템의 사용자에게 세밀한 액세스 제어를 제공할 수 있다. 이로 인해 보안이 강화된다.
- 토큰 교환 및 갱신 자동화: Workload Identity Federation을 통해 외부 ID 제공자에서 Google Cloud로의 토큰 교환 및 갱신이 자동화되어, 사용자가 수동으로 크리덴셜을 관리할 필요가 없어진다.
- 보다 간편한 통합: 외부 시스템과의 통합이 간소화되며, 이는 특히 다양한 클라우드 환경에서 작업하는 기업에 유용하다.
테라폼을 사용해서 구성해준다.
## Service Account ##
module "service_accounts" {
source = "../../modules/service_accounts"
project_id = var.project
names = ["github-action"]
display_name = "github-action"
description = "github-action admin"
}
## Workload Identity Federation ##
data "google_service_account" "github-action" {
account_id = "github-action"
depends_on = [module.service_accounts]
}
module "workload_identity_federation" {
source = "../../modules/workload_identity_federation"
project_id = var.project
pool_id = "pool-github-action"
provider_id = "provider-github-action"
attribute_mapping = {
"google.subject" = "assertion.sub"
"attribute.actor" = "assertion.actor"
"attribute.aud" = "assertion.aud"
"attribute.repository" = "assertion.repository"
}
issuer_uri = "<https://token.actions.githubusercontent.com>"
service_accounts = [
{
name = data.google_service_account.github-action.name
attribute = "attribute.repository/somaz94/*" # attribute.repository/github repository/*
all_identities = true
},
{
name = data.google_service_account.github-action.name
attribute = "attribute.repository/somaz94-2/*"
all_identities = true
}
]
}
Console에서 아래와 같이 확인가능하다.
아래와 같이 권한을 부여하였다.
Github Action Workflow 구성
간단하게 Build Workflow를 구성해본다.
- Configure GCP credentials 부분에서 `secrets.GCP_WORKLOAD_IDENTITY_PROVIDER` 값으로는 `projects/${project_id}/locations/global/workloadIdentityPools/pool-github-action/providers/provider-github-action 를 secret` 으로 저장해준다.
- `secrets.GCP_SERVICE_ACCOUNT` 값으로는 `github-action@${project_id}.iam.gserviceaccount.com` 를 secret으로 저장해준다.
name: 1.Build
on:
push:
branches:
# - dev
- '*'
- '!main'
- 'release/*'
paths:
- apps/game/**
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
inputs:
environment:
type: environment
description: Select the environment
required: true
service:
description: Which service to be built. game or admin or etc...
required: true
type: choice
options:
- game
workflow_call:
inputs:
branch:
description: Source branch name
required: true
type: string
environment:
description: Target environment
required: true
type: string
service:
description: Service to be built. game or admin or etc...
required: true
type: string
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
build:
name: Build Image
runs-on: ubuntu-20.04
env:
PROJECT: somaz
SERVICE: ${{ github.event.inputs.service || inputs.service }}
ENVIRONMENT: ${{ github.event.inputs.environment || inputs.environment }}
# Add "id-token" with the intended permissions.
permissions:
contents: read
id-token: write
steps:
- name: Check out branch for workflow call
id: checkout-for-workflow-call
if: ${{ inputs.branch }}
uses: actions/checkout@v4
with:
ref: ${{ inputs.branch }}
- name: Check out branch for workflow dispatch
if: ${{ steps.checkout-for-workflow-call.outcome == 'skipped' }}
uses: actions/checkout@v4
- name: Set GCP region JP for prod environment
if: ${{ env.ENVIRONMENT == 'stage' || env.ENVIRONMENT == 'prod' }}
id: set-prod-region
run: |
echo "GCP_REGION=asia-northeast1" >> $GITHUB_ENV
- name: Set GCP region KR
if: ${{ steps.set-prod-region.outcome == 'skipped' }}
run: |
echo "GCP_REGION=asia-northeast3" >> $GITHUB_ENV
- name: Extract most recent environment from the last 50 commits
if: github.event_name == 'push'
run: |
git log -50 --pretty=%B
COMMIT_MESSAGES=$(git log -50 --pretty=%B)
ENVIRONMENT=$(echo "$COMMIT_MESSAGES" | grep -oP 'server\\(\\K[^)]*' | head -1 | sed 's/gcp_//')
echo "ENVIRONMENT=$ENVIRONMENT" >> $GITHUB_ENV
- name: Use input environment if provided
if: github.event_name == 'workflow_dispatch' && inputs.environment
run: |
echo "ENVIRONMENT=${{ inputs.environment }}" >> $GITHUB_ENV
- name: Use Default Service Name if push event
if: github.event_name == 'push'
run: |
echo "SERVICE=${{ inputs.service || 'game' }}" >> $GITHUB_ENV
- name: Setup environment
id: env_output
run: |
echo "Environment set to: ${{ env.ENVIRONMENT }}"
echo "Service set to: ${{ env.SERVICE }}"
- name: Configure GCP credentials
id: auth
uses: google-github-actions/auth@v2
with:
token_format: access_token
workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }}
access_token_lifetime: 500s
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2
- name: Login to Artifact Registry
id : artifact
uses: docker/login-action@v3
with:
registry: ${{ env.GCP_REGION }}-docker.pkg.dev
username: oauth2accesstoken
password: ${{ steps.auth.outputs.access_token }}
- name: Set short sha
id: vars
run: |
echo "short_sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build, tag, and push image to GCP Artifact Registry
uses: docker/build-push-action@v5
env:
GCP_SOMAZ_MGMT_PROJECT: ${{ secrets.GCP_SOMAZ_MGMT_PROJECT }}
GAR_REGISTRY: ${{ env.GCP_REGION }}-docker.pkg.dev
# SERVICE_NAME: ${{ inputs.service }}
SERVICE_NAME: ${{ env.SERVICE }}
GAR_REPOSITORY: ${{ env.PROJECT }}
IMAGE_TAG: ${{ steps.vars.outputs.short_sha }}
with:
context: .
file: ${{ env.SERVICE_NAME }}.Dockerfile
push: true
tags: ${{ env.GAR_REGISTRY }}/${{ env.GCP_SOMAZ_MGMT_PROJECT }}/${{ env.SERVICE }}-${{ env.PROJECT }}/${{ env.SERVICE }}-${{ env.PROJECT }}:${{ steps.vars.outputs.short_sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Set branch var for workflow_dispatch
if: github.event_name == 'workflow_dispatch'
run: |
echo "IS_BUILD_TRIGGERED_BY_WORKFLOW_DISPATCH=true" >> $GITHUB_ENV
- name: Outputs build results
run: |
echo "target service: ${{ env.SERVICE }}"
echo "resource branch for workflow dispatch: ${{ github.ref_name }}"
echo "resource branch for workflow call: ${{ inputs.branch }}"
echo "deploy environment: ${{ env.ENVIRONMENT }}"
echo "gar region: ${{ env.GCP_REGION }}"
echo "image tags: ${{ steps.vars.outputs.short_sha }}"
outputs:
tag: ${{ steps.vars.outputs.short_sha }}
is_build_triggered_by_workflow_dispatch: ${{ env.IS_BUILD_TRIGGERED_BY_WORKFLOW_DISPATCH }}
service: ${{ env.SERVICE }}
environment: ${{ env.ENVIRONMENT }}
- 이렇게 쉽게 Github Action과 GCP Workload Federation을 사용해서, Image Build 후 Push 과정을 구성할 수 있다.
Reference
https://gist.github.com/palewire/12c4b2b974ef735d22da7493cf7f4d37
728x90
반응형
'IaC > CI CD Tool' 카테고리의 다른 글
7. Gitlab CI Template 활용 (0) | 2024.06.27 |
---|---|
6. Gitlab CI Build(with GCP Artifact Registry, Harbor) (0) | 2024.06.24 |
ArgoCD SSO 구성 가이드(GCP Oauth) (0) | 2024.04.14 |
6. Github Action (With Using Concurrency) (0) | 2024.03.20 |
5. Github Action (With Using jobs in a workflow & Choosing the runner for a job) (0) | 2024.03.15 |