「サーバーレスでWebアプリを公開したいけど、インフラの管理は面倒…」
「関係者だけにプレビュー版を公開したいけど、認証の設定が難しそう…」

そんな悩みを持つあなたに、Google CloudのCloud Runは最適なソリューションです。
この記事では、あなたのPCに何もインストールすることなく、ブラウザ上のターミナルであるCloud Shellだけを使って、
「Hello World」を表示するWebアプリケーションをCloud Runにデプロイする方法を解説します。

さらに、ただデプロイするだけでなく、許可されたGoogleアカウントを持つユーザーだけがアクセスできるように、2つの異なる方法でセキュリティを設定します。

  1. IAP for Cloud Run: 手軽で迅速にアクセス制御を実現する方法
  2. Cloud Load Balancing: より高機能で拡張性の高いアクセス制御を実現する方法

この記事を読み終える頃には、あなたはCloud Shellを自在に操り、セキュアなサーバーレスアプリケーションをデプロイできるようになっているでしょう。

前提条件

  • Google Cloud Platform (GCP) のプロジェクトが作成済みであること。
  • プロジェクトで課金が有効になっていること。(本チュートリアルのリソースは無料枠の範囲内で収まる可能性が高いですが、念のためご確認ください)
  • プロジェクトに対するオーナー権限、または同等の権限を持っていること。
  • このチュートリアルでは以下の課金対象サービスを利用します。
    • Cloud Run
    • Cloud Build(ソースコードからコンテナイメージをビルド)
    • Artifact Registry(コンテナイメージを保存)
    • Cloud Load Balancing(パターン2で利用)

Step 0: 共通の準備 – Cloud ShellとHello Worldアプリ

まずは、すべての作業の土台となる環境とアプリケーションを準備します。

1. Cloud Shellの起動

Google Cloudコンソールを開き、画面右上の [>_] アイコンをクリックしてCloud Shellを起動します。
Cloud Shellが起動したら、以降のコマンドはすべてこのターミナルで実行します。

2. プロジェクトの設定

Cloud Shellで作業対象のプロジェクトIDを設定します。
[YOUR_PROJECT_ID] はご自身のプロジェクトIDに置き換えてください。

gcloud config set project [YOUR_PROJECT_ID]

3. APIの有効化

Cloud Runや関連サービスを利用するために、必要なAPIを有効化します。

gcloud services enable \
    run.googleapis.com \
    iam.googleapis.com \
    iap.googleapis.com \
    compute.googleapis.com \
    artifactregistry.googleapis.com \
    cloudbuild.googleapis.com

4. OAuth同意画面の設定

IAP(Identity-Aware Proxy)を利用してユーザー認証を行うには、OAuth同意画面の設定が必要です。
今回は、組織内のユーザーのみを対象とする[内部]設定で進めます。

  • Cloudコンソールのナビゲーションメニューから [APIとサービス] > [OAuth同意画面] を選択します。
  • [User Type][内部] を選択し、[作成] をクリックします。
  • 以下の必須項目を入力します。
    • アプリ名: Cloud Run IAP Tutorial など、分かりやすい名前を入力します。
    • ユーザーサポートメール: ご自身のメールアドレスを選択します。
    • デベロッパーの連絡先情報: ご自身のメールアドレスを入力します。
  • [保存して次へ] をクリックし、スコープやテストユーザーの設定は不要なので、そのまま最後まで進めて設定を完了します。

5. アプリケーションコードの作成 (Cloud Shell エディタ)

次に、Cloud Runで動かすPythonアプリケーションのコードを書いていきます。
Cloud ShellにはWebベースのエディタが内蔵されているので今回はこちらを用います。

1. Cloud Shellエディタを開く
Cloud Shellターミナルの右上にある「エディタを開く」ボタンをクリックします。

2. 作業ディレクトリの作成
エディタのターミナル(または元のCloud Shellターミナル)で、作業用のディレクトリを作成し、移動します。

mkdir cloudrun-hello-python
cd cloudrun-hello-python

3. Pythonアプリケーションの作成 (app.py)

エディタのファイルエクスプローラーで、cloudrun-hello-python フォルダを右クリックし、「New File」を選択して app.py というファイルを作成します。
以下のコードを貼り付けて保存してください。
これは、WebフレームワークのFlaskを使い、「Hello World.」という文字列を返すだけのシンプルなアプリです。

# app.py
import os
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "Hello World."

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))

4.依存関係ファイルの作成 (requirements.txt)

同様に requirements.txt ファイルを作成し、Flaskと、本番環境で推奨されるWSGIサーバーであるGunicornを記述します。

# requirements.txt
Flask==3.1.1
gunicorn==23.0.0

5. Dockerfileの作成
アプリケーションをコンテナ化するための設計図である Dockerfile を作成します。

# Dockerfile
# Pythonの公式イメージをベースにする
FROM python:3.12-slim

# pipをアップグレードする
RUN pip install --upgrade pip --root-user-action ignore

# 作業ディレクトリを設定
WORKDIR /app

# 依存関係ファイルをコピーしてインストール
COPY requirements.txt requirements.txt
RUN pip install --no-cache-dir -r requirements.txt --root-user-action ignore

# アプリケーションのコードをコピー
COPY . .

# Cloud Runがコンテナを起動する際に使用するポートを環境変数から取得
ENV PORT 8080

# アプリケーションの起動コマンド
CMD ["gunicorn", "--bind", "0.0.0.0:8080", "app:app"]

これでアプリケーションの準備は完了です。ディレクトリには app.py, requirements.txt, Dockerfile の3つのファイルがあるはずです。

6. コンテナイメージのビルドとプッシュ

再び、Cloud Shellターミナルに戻り、Cloud Buildを使ってコンテナイメージをビルドし、Artifact Registryにプッシュします。

1. Artifact Registryリポジトリの作成
コンテナイメージを保存する場所を作成します。ここでは helloworld-images という名前のリポジトリを asia-northeast1 (東京) リージョンに作成します。

gcloud artifacts repositories create helloworld-images \
    --repository-format=docker \
    --location=asia-northeast1 \
    --description="Cloud Run container images"

2. Cloud Buildでビルド&プッシュ
Cloud Buildを使うと、ソースコードからコンテナイメージのビルドとArtifact Registryへのプッシュを一つのコマンドで実行できます。

# cloudrun-hello-pythonディレクトリに移動
cd cloudrun-hello-python

# プロジェクトIDを変数に格納
export PROJECT_ID=$(gcloud config get-value project)

gcloud builds submit --tag asia-northeast1-docker.pkg.dev/${PROJECT_ID}/helloworld-images/hello-python:latest

このコマンドは、カレントディレクトリの Dockerfile を使ってイメージをビルドし、asia-northeast1-docker.pkg.dev/... という名前でArtifact Registryに保存します。

これで、デプロイの準備が整いました!

Step 1: Cloud Runサービスのデプロイ(内部アクセス限定)

まずは、外部からの直接アクセスを許可しない設定でCloud Runサービスをデプロイします。
こちらが、後述にて設定する2つの認証パターンのベースとなります。

gcloud run deploy helloworld-service \
  --image=asia-northeast1-docker.pkg.dev/${PROJECT_ID}/helloworld-images/hello-python:latest \
  --platform=managed \
  --region=asia-northeast1 \
  --no-allow-unauthenticated
  • --no-allow-unauthenticated: 未認証のアクセスをすべて拒否します。

デプロイが完了すると、Service [helloworld-service] deployed. というメッセージとURLが表示されますが、この時点ではまだブラウザからアクセスしても「Forbidden」と表示されるはずです。

パターン1: IAP for Cloud Run で手軽にアクセス制御

この方法は、ロードバランサを使わずにCloud Runの機能だけでシンプルにアクセス制御を実現します。
内部ツールや開発環境の共有に最適です。

1. IAPを有効化

以下のコマンドでIAPを有効化する。

gcloud beta run services update helloworld-service \
  --region=asia-northeast1 \
  --iap

2. IAM権限の付与

2種類のIAMロールを、アクセスを許可したいユーザーに付与します。
[YOUR_EMAIL_ADDRESS] はアクセスを許可したいGoogleアカウントのメールアドレス(例: user@example.com)に置き換えてください。

gcloud beta iap web add-iam-policy-binding \
  --resource-type=cloud-run \
  --service=helloworld-service \
  --member=user:[YOUR_EMAIL_ADDRESS] \
  --region=asia-northeast1 \
  --role="roles/iap.httpsResourceAccessor"

3. 動作確認

デプロイ時に表示されたCloud RunサービスのURLにブラウザでアクセスしてください。
1. Googleのログイン画面が表示されます。
2. 先ほど権限を付与したGoogleアカウントでログインします。
3. ブラウザに「Hello World.」と表示されれば成功です!
4. 以降の更新はCloud Shellのターミナルから以下の手順で行うことが可能です。

# 1. 先にコンテナを更新する
export PROJECT_ID=$(gcloud config get-value project)
gcloud builds submit --tag asia-northeast1-docker.pkg.dev/${PROJECT_ID}/helloworld-images/hello-python:latest

# 2. 次にコンテナをデプロイする
gcloud run deploy helloworld-service \
  --image=asia-northeast1-docker.pkg.dev/${PROJECT_ID}/helloworld-images/hello-python:latest \
  --region=asia-northeast1

パターン2: Cloud Load Balancing で高機能なアクセス制御

この方法は、グローバル外部HTTP(S)ロードバランサをCloud Runの前に配置します。
Cloud CDNやCloud Armor (WAF)との連携が可能で、より大規模で堅牢なシステムを構築する際に役立ちます。

今回はドメインがない場合を想定し、ロードバランサのIPアドレスに直接アクセスする構成を構築します。
認証にはこちらもIAPを利用します。

1. Cloud RunのIngress設定を変更

Cloud Runサービスへのアクセスを未認証の呼び出しを許可した上で、内部トラフィックとロードバランサ経由のみに制限します。
また、こちらではCloud Run側の「IAP」は無効にします。

export PROJECT_ID=$(gcloud config get-value project)
gcloud beta run deploy helloworld-service \
  --image=asia-northeast1-docker.pkg.dev/${PROJECT_ID}/helloworld-images/hello-python:latest \
  --region=asia-northeast1 \
  --ingress=internal-and-cloud-load-balancing \
  --allow-unauthenticated \
  --no-iap

2. Serverless NEGの作成

Cloud Runサービスをロードバランサのバックエンドとして接続するための「Serverless Network Endpoint Group (NEG)」を作成します。

gcloud compute network-endpoint-groups create helloworld-neg \
  --network-endpoint-type=serverless \
  --cloud-run-service=helloworld-service \
  --region=asia-northeast1

3. バックエンドサービスの作成とIAPの有効化

Serverless NEGをアタッチするバックエンドサービスを作成し、IAPを有効化します。

# バックエンドサービスの作成
gcloud compute backend-services create helloworld-backend-service \
  --global \
  --load-balancing-scheme=EXTERNAL_MANAGED

# バックエンドサービスにServerless NEGを追加
gcloud compute backend-services add-backend helloworld-backend-service \
  --global \
  --network-endpoint-group=helloworld-neg \
  --network-endpoint-group-region=asia-northeast1

# バックエンドサービスでIAPを有効化
gcloud compute backend-services update helloworld-backend-service \
  --iap=enabled \
  --global

4. 自己署名証明書の作成とアップロード

HTTPS通信のために、ドメインがない場合でも利用できる自己署名証明書を作成します。

# Cloud Shell上で証明書と秘密鍵を作成
openssl req -x509 -newkey rsa:2048 -nodes -keyout private.key -out certificate.crt -subj "/CN=example.com"

# Google CloudにSSL証明書としてアップロード
gcloud compute ssl-certificates create helloworld-ssl-cert \
  --certificate=certificate.crt \
  --private-key=private.key \
  --global

5. ロードバランサのフロントエンド設定

リクエストを受け付けるためのIPアドレス、転送ルールなどを作成します。

# URLマップを作成
gcloud compute url-maps create helloworld-lb-map \
  --default-service helloworld-backend-service

# ターゲットHTTPSプロキシを作成
gcloud compute target-https-proxies create helloworld-proxy \
  --url-map=helloworld-lb-map \
  --ssl-certificates=helloworld-ssl-cert

# グローバルIPアドレスを予約
gcloud compute addresses create helloworld-lb-ip --global

# 転送ルールを作成
gcloud compute forwarding-rules create helloworld-forwarding-rule \
  --load-balancing-scheme=EXTERNAL_MANAGED \
  --network-tier=PREMIUM \
  --address=helloworld-lb-ip \
  --target-https-proxy=helloworld-proxy \
  --global \
  --ports=443

6. IAM権限の付与

ロードバランサ経由でのアクセスに必要なIAMロールを付与します。
[YOUR_EMAIL_ADDRESS] はアクセスを許可したいGoogleアカウントのメールアドレスに置き換えてください。

gcloud iap web add-iam-policy-binding \
  --resource-type=backend-services \
  --service=helloworld-backend-service \
  --member="user:[YOUR_EMAIL_ADDRESS]" \
  --role="roles/iap.httpsResourceAccessor"

7. 予約したグローバルIPアドレスにアクセスした場合にのみユーザーのアクセスを許可する

最後にバックエンドサービスに対して予約したグローバルIPアドレスにアクセスした場合のみ、
ユーザーがアクセスできるように以下の手順で設定を追加します。

まず、予約したIPアドレスを確認します。

gcloud compute addresses describe helloworld-lb-ip --global --format="value(address)"

以降はGoogle Cloud Consoleから以下の手順で設定してください。

  • Google Cloud Consoleで [セキュリティ] > [Identity-Aware Proxy] に移動します。
  • 一覧から、helloworld-backend-service を見つけます。
  • そのサービス行の右端にある三点メニューから [設定] をクリックし、[設定パネル] を表示します。
  • [設定パネル] で、[許可されたドメインを有効にする] のチェックボックスを有効化します。
  • [許可するドメイン] に、予約したIPアドレス(例: 34.123.45.XX)を入力します。
  • [保存] をクリックします。

8. 動作確認

設定が反映されるまで数分かかることがあります。

こちらでもまず、予約したIPアドレスを確認します。

gcloud compute addresses describe helloworld-lb-ip --global --format="value(address)"

表示されたIPアドレス(例: 34.123.45.XX)をコピーし、ブラウザのアドレスバーに `https://[IPアドレス]` の形式で入力してアクセスします。

  • ブラウザに「この接続ではプライバシーが保護されません」という警告が表示されることがあります。これは自己署名証明書を使っているためです。[詳細設定] などをクリックし、[(安全でない)サイトに移動] を選択してアクセスを続行します。
  • 未ログイン時はGoogleのログイン画面が表示されます、権限を付与したアカウントでログインします。
  • 「Hello World.」と表示されれば成功です!

メリット・デメリット比較

どちらのパターンを選ぶべきか、それぞれの長所と短所をまとめました。

IAP for Cloud Run (パターン1) Cloud Load Balancing (パターン2)
メリット 設定が非常にシンプル
✅ 追加コンポーネントがなく低コスト
✅ デプロイ後すぐに使える
高機能(Cloud CDN, Cloud Armor連携)
単一のエンドポイントで複数サービスを統合
✅ パスベースルーティングなど高度なルーティングが可能。
デメリット ❌ ロードバランサの高度な機能は使えない
❌ 複数サービスを束ねるのが難しい
設定が複雑
❌ ロードバランサの追加コストが発生
❌ ドメインがないとHTTPS化が手間

こんな時はこのパターン!

  • パターン1: 社内ツール、ステージング環境、小規模なWebアプリなど、手軽さスピードを重視する場合。
  • パターン2: 外部公開する本番サービス、DDoS対策やCDNによる高速化が必要なWebサイトなど、拡張性堅牢性を重視する場合。

まとめ

今回は、Cloud Shellだけを使ってPythonアプリケーションをCloud Runにデプロイし、IAPを利用してセキュアにアクセス制御する2つの方法をご紹介しました。

  • 手軽さを重視するなら IAP for Cloud Run
  • 拡張性や高度な機能を求めるなら Cloud Load Balancing

という使い分けを基本に、あなたの要件に合った方法を選択してください。このチュートリアルが、あなたのCloud Run活用の第一歩となれば幸いです。