GitHub Actions と Cloud Run で実現する CI/CD ハンズオン

0.はじめに

最近仕事でもコードを書く機会が多くなりました。そのきっかけで、これまで話だけで知っていた GitHub Actions を実際に手を動かして自身の環境に導入してみました。

本ブログでは、シンプルな「コードをプッシュするだけで自動でCloud Runにデプロイされる」仕組みの構築手順について紹介します。

クラウドサービスの活用を始めたい方や、デプロイ作業の自動化に興味がある方にとって参考になれば幸いです。

1.基本的な用語

1.1.GitHub Actionsとは?

GitHub Actionsは、GitHubが提供しているビルトイン機能で、リポジトリでコードを自動的にビルド・テスト・デプロイできるツールです。

設定によってはコードをプッシュするだけで勝手にデプロイまでを実施することなどが可能で、GitHub内でCI/CD(継続的インテグレーション/継続的デリバリー)のワークフローの設定が可能となります。

1.2.CI/CD(継続的インテグレーション/継続的デリバリー)の嬉しいこと

項目 ざっくりとした内容
開発効率の向上 コードの変更を自動的に検証・デプロイするため、手動作業が減少し開発サイクルが高速化
品質の安定化 自動テストによりバグの早期発見が可能になり、リリース品質が向上
デプロイリスクの低減 小さな変更を頻繁にデプロイすることで、大きな変更リリースのリスクを避けられる
コラボレーションの強化 全員が同じパイプラインを使うため、環境の一貫性が保たれる
フィードバックの迅速化 変更がすぐに反映されるため、ユーザーや関係者からのフィードバックをすぐに得られる

2. ハンズオン

2.0.前提条件

2.0.1.留意事項

  • Google Cloud プロジェクトが作成済みで、課金が有効になっていること
  • GitHubにアカウントが作成済みであること
  • GitHub CLI がインストール済みであること
  • 本手順は GoogleCloud の CloudShell環境から実施します

2.0.2.変数一覧

  • 本ハンズオンで利用する変数の一覧
項番 変数名 利用環境 変数内容
1 REPO GitHub リポジトリ名
2 YOUR_ACCOUNT GitHub アカウントID
3 SERVICE_NAME GoogleCloud Cloud Run名
4 REGION GoogleCloud 利用リージョン名
5 PROJECT_ID GoogleCloud プロジェクトID
6 SA_NAME GoogleCloud サービスアカウント名
7 SA_DISPLAY_NAME GoogleCloud サービスアカウントの説明

2.1.事前準備

# 新しいプロジェクトフォルダを作成
mkdir my-cloudrun-app && cd my-cloudrun-app

# Cloud Run APIの有効化
gcloud services enable run.googleapis.com
# Cloud Build APIの有効化
gcloud services enable cloudbuild.googleapis.com
# Container Registryを有効化
gcloud services enable artifactregistry.googleapis.com

2.2.Cloud Runを作成

2.2.1.アプリケーションの準備

  • GitHubを経由してデプロイする先となる Cloud Runを作成
# Pythonアプリのファイルを作成
# main.py
cat > main.py << EOF
import functions_framework

@functions_framework.http
def hello_http(request):
    return "Hello World"
EOF

# requirementsファイルを作成
cat > requirements.txt << EOF
functions-framework==3.*
EOF

# Dockerfileを作成
cat > Dockerfile << 'EOF'
FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

ENV PORT 8080
ENV FUNCTION_TARGET hello_http

CMD functions-framework --target=${FUNCTION_TARGET} --port=${PORT}
EOF

# .gitignoreファイルを作成
cat > .gitignore << 'EOF'
*.pyc
__pycache__/
.pytest_cache/
venv/
.env
*.json
EOF

2.2.2.GitHubへ push

# Gitの初期化
git init
git add .
git commit -m "new commit"

# リポジトリ環境変数
REPO="リポジトリ名"(例:my-cloudrun-app)
YOUR_ACCOUNT="アカウント名"(例:tetutetu214)

# リポジトリ作成
gh repo create ${REPO} --public

# ローカルリポジトリからプッシュ先の設定を行う
git remote add origin git@github.com:${YOUR_ACCOUNT}/${REPO}.git

# 変更をGitHubに更新(デフォルトブランチ名(通常は main または master)を確認して指定してください)
# git branch --show-current コマンドで現在のブランチ名を確認できます

git push -u origin master

2.2.3.Cloud Runの手動デプロイ

# Cloud Run 変数
SERVICE_NAME="サービス名"(例:test-service)
REGION="リージョン名"(例:asia-northeast1)

# デプロイコマンド
gcloud run deploy ${SERVICE_NAME} --source . --region ${REGION}
2.2.3.1.手動デプロイ時の画面
  • Cloud Runの「URL」からWEB画面を確認
    file

2.3.GitHub Actionsの準備

  • 本コマンドでは、プロジェクトディレクトリ外に作成及び、「.json」は「.gitignore」で push 出来ないようにしていますが、JSONキーについては各自で厳重に取扱いください。

2.3.1.デプロイ(GitHub Actions)用 サービスアカウント(SA)作成

  • 以下のコマンドで、GitHub Actions が Cloud Build を利用して デプロイするために必要となる権限をまとめたSAを作成する。
# 変数を設定
PROJECT_ID="あなたのGCPプロジェクトID"
SA_NAME="サービスアカウント名"(例:github-actions-deploy)
SA_DISPLAY_NAME="表示名"(例:GitHub Actions Deployment SA)

# サービスアカウントを作成
gcloud iam service-accounts create $SA_NAME \
  --project=$PROJECT_ID \
  --display-name="$SA_DISPLAY_NAME" \
  --description="Service account for GitHub Actions to deploy to Cloud Run"

# Cloud Runに対する権限
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:$SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/run.admin"

# GCSに対する権限
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:$SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/storage.admin"

# Artifactregistryに対する権限
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:github-actions-deploy@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/artifactregistry.admin"

# CloudBuildに対する権限
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:github-actions-deploy@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/cloudbuild.builds.builder"

# Service アカウントユーザ 権限を追加
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:github-actions-deploy@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/iam.serviceAccountUser"

# JSONキーを作成して保存
gcloud iam service-accounts keys create ~/github-actions-key.json \
  --iam-account="$SA_NAME@$PROJECT_ID.iam.gserviceaccount.com"

2.3.2.GitHubにて環境変数の保存

ここはGitHubでの操作

  • GitHubのリポジトリに「Settings」→「Secrets and variables」→「Actions」を選択
    file

  • 次に、Repository secrets の「New repository secret」を選択
    file

  • シークレットを登録
    2つのシークレットを作成
    GCP_PROJECT_ID:本プロジェクトのIDを貼り付け
    GCP_SA_KEY:先ほど取得した ファイルの内容をそのままコピー&ペーストしてください
    ■以下は、GCP_SA_KEYの画面抜粋
    file

  • 登録完了後の画面
    file

2.3.3.GitHub Actionsの設定ファイル作成

ここから GoogleCloud Shellでの操作に戻る

  • 今回はハンズオンのため--allow-unauthenticatedオプションで、「認証なしで誰でもアクセスできるサービスを作成」での構築をしています。
# GitHub Actions用のディレクトリ作成
mkdir -p .github/workflows

#  GitHub Actionsワークフローファイルを作成
cat > .github/workflows/cloudrun-deploy.yml << 'EOF'
name: Build and Deploy to Cloud Run
 # masterブランチにプッシュされたタイミング
on:
  push:
    branches: [ master ]
# 環境変数
env:
  SERVICE_NAME: test-service
  REGION: asia-northeast1
# 実行する作業の定義
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
    # コードを取得するステップ
    - name: Checkout code
      uses: actions/checkout@v4

    # Google 認証のステップ
    - name: Authenticate to Google Cloud
      uses: google-github-actions/auth@v2
      with:
        credentials_json: ${{ secrets.GCP_SA_KEY }}
        project_id: ${{ secrets.GCP_PROJECT_ID }}

     # SDKによるコマンドを利用できるようにするステップ
    - name: Set up Cloud SDK
      uses: google-github-actions/setup-gcloud@v2
      with:
        project_id: ${{ secrets.GCP_PROJECT_ID }}

    # デバッグ認証ステップ
    - name: Debug Authentication
      run: |
        echo "Current project: $(gcloud config get-value project)"
        echo "Current account: $(gcloud auth list --filter=status:ACTIVE --format='value(account)')"

    #  Cloud Runにデプロイ
    - name: Deploy to Cloud Run
      run: |
        gcloud config set project ${{ secrets.GCP_PROJECT_ID }}
        gcloud run deploy ${{ env.SERVICE_NAME }} \
          --source . \
          --project ${{ secrets.GCP_PROJECT_ID }} \
          --platform managed \
          --region ${{ env.REGION }} \
          --allow-unauthenticated
EOF

2.3.4.ファイルをコミットしてプッシュ

  • main.pyの内容を修正して、GitHubにpush
# main.py
cat > main.py << EOF
import functions_framework

@functions_framework.http
def hello_http(request):
    return "Hello World!!!"
EOF

# ファイルをコミットしてプッシュ
git add .
git commit -m "Update main.py"
git push

2.4.push後の確認

2.4.1.GitHubでの画面

  • GitHub画面で「Update」の文字が表示される、押下することで「Details」が表示される。
    file

  • 「Details」を押下して以下、ビルド・デプロイまでのフローが表示される。
    file

2.4.2.GoogleCloudでの画面

  • タブ「リビジョン」で新しくデプロイされたことを確認。
    file

  • Cloud Runの「URL」からWEB画面を確認。
    file

2.5.キーファイルの削除

  • こちらまで確認できた場合、2.3.1.デプロイ(GitHub Actions)用 サービスアカウント(SA)作成で作成した キーファイル (~/github-actions-key.json) は削除して問題ございません。
    セキュリティリスクを軽減させるためにも、削除することを推奨します
rm ~/github-actions-key.json

3.おわりに

3.1.得られた知見

  • GitHub Actionsの一連の設定フローを実装することができた

3.2.今後の課題

  • テストコードを追加してCI/CDパイプラインを完成させる
  • クラウドサービスのマネージドサービスとの連携強化

3.3.構築中のトラブルシューティング

  • サービスアカウント(roles/iam.serviceAccountUser)の権限不足によるデプロイ失敗
Last modified: 2025-04-27

Author