「サーバーレスでWebアプリを公開したいけど、インフラの管理は面倒…」
「関係者だけにプレビュー版を公開したいけど、認証の設定が難しそう…」
そんな悩みを持つあなたに、Google CloudのCloud Runは最適なソリューションです。
この記事では、あなたのPCに何もインストールすることなく、ブラウザ上のターミナルであるCloud Shellだけを使って、
「Hello World」を表示するWebアプリケーションをCloud Runにデプロイする方法を解説します。
さらに、ただデプロイするだけでなく、許可されたGoogleアカウントを持つユーザーだけがアクセスできるように、2つの異なる方法でセキュリティを設定します。
- IAP for Cloud Run: 手軽で迅速にアクセス制御を実現する方法
- 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活用の第一歩となれば幸いです。