TECH PLAY

株式会社G-gen

株式会社G-gen の技術ブログ

744

G-gen の三浦です。当記事では、Google Workspace の Data Loss Prevention(以下、DLP)を使用して、Gmail の機密情報が外部に漏洩するのを防ぐ方法を紹介します。 概要 Data Loss Prevention(DLP)とは 前提条件 制約 検証内容 動作確認 DLP のルール設定(警告) 動作確認(警告) DLP のルール設定(検疫) 動作確認(検疫) 動作確認(OCR) 概要 Data Loss Prevention(DLP)とは Data Loss Prevention (DLP、データ損失防止)とは、組織内の重要情報を保護し、情報流出を防ぐための技術です。クレジットカード番号やマイナンバーなどの個人情報を自動的に検出し、保護します。 Google Workspace(以下、GWS)の DLP は、Gmail に加え、Google Chat や Google ドライブにも対応しています。 社外秘の情報や顧客データなどの機密情報が、意図せず共有されたり、流出するのを防ぐルールを設定できます。 参考 : DLP で機密情報を保護する Google ドライブでの検証結果は、以下の記事で解説しています。 blog.g-gen.co.jp 前提条件 Gmail の DLP は、以下の特定の Google Workspace エディションでのみ利用可能です。 Frontline Standard Enterprise Standard / Plus Education Fundamentals / Standard / Plus Teaching and Learning Upgrade 詳細は以下の公式ドキュメントをご参照ください。 参考 : メールと添付ファイルのデータ漏洩を防止する 制約 当機能には以下のような制限があります。 Gmail はスキャンの対象ですが、Google グループは対象外です(グループの代理としてメールを送信した場合、ルールは適用されません)。 1 MB までの添付ファイルがスキャン対象で、1 MB を超える場合、先頭の 1MB のみスキャンされます。10 MB を超える場合はスキャンされません。 添付ファイルが Google ドライブにある場合、Google ドライブ側の DLP ルールが適用されます。 詳細は以下の公式ドキュメントを確認してください。 参考 : 既知の制限事項 参考 : Gmail コンテンツの DLP に関する制限 検証内容 検証手順は次のとおりです。最初に「警告」設定で動作を確認し、次に「管理者による検疫」に変更して、より強力な制御を確認します。 項番 作業 詳細 1 DLP のルール設定(警告) 「関係者外秘」または「confidential」という文字を含むメールの送信時に警告を表示する DLP ルールを設定します。 2 動作確認(警告) 条件を満たすメールを送信し、警告が表示されることを確認します。 3 DLP のルール設定(検疫) ルールを「メールを検疫する」に変更します。 4 動作確認(検疫) 対象のメールが検疫対象であることを確認し、管理者側で拒否します。 5 動作確認(OCR) OCR(光学式文字認識)スキャンを有効にし、条件を満たす画像ファイルを添付し、検疫されることを確認します。 参考 : メール検疫を設定する 動作確認 DLP のルール設定(警告) GWS の管理コンソール(URL : https://admin.google.com )にログインします。 参考 : 管理コンソールにログインする [セキュリティ] > [アクセスとデータ管理] > [データの保護] に移動し、[ルールを管理] を選択します。 ルールを管理を選択 [ルールを追加] > [新しいルール] を選択します。 新しいルールを選択 以下を設定し、[続行] を選択します。 名前:任意の DLP ルール名 範囲:DLP ルールの適用範囲を選択( 組織全体 か 特定の組織部門 、 Google グループ から選択) DLPルール作成1 以下を設定し、[続行] を選択します。 Gmail : メッセージを送信しました DLPルール作成2 [条件を追加] から以下のとおりに設定し、[続行] を選択します。 スキャンするコンテンツの種類: すべてのコンテンツ スキャン対象: 関係社外秘 か confidential という テキスト文字列を含む 場合 DLPルール作成3 以下のとおりに設定し、[続行] を選択します。 操作 操作: ユーザーへの警告 適用対象: 外部(組織外) と 内部(組織内) 宛ての全送信メール アラート 重大度: 高 アラートセンターに送信する: 有効化 し、管理者のメールアドレスを指定 DLPルール作成4 DLPルール作成5 設定内容を確認し、[作成] を選択します。 DLPルール作成6 動作確認(警告) 以下のメールを作成し、[送信する] を選択します。 テストメールの送信 警告が表示されることを確認し、[このまま送信] を選択します。送信者側で、メールが受信できていることを確認します。 警告の表示とメール送信 管理者宛てに、DLP ルールに該当する操作の通知メールが届くことを確認します。 アラート通知の確認 [セキュリティ] > [アラートセンター] へ移動し、アラートが通知されていることを確認します。 アラートセンターの確認 アラートを選択すると、詳細情報が確認できます。 アラートの詳細確認 参考 : ドライブの DLP ダッシュボードでインシデント、アラート、監査イベントを表示する 参考 : アラートの詳細を表示する DLP のルール設定(検疫) [アプリ] > [Google Workspace] > [Gmail の設定] > [検疫の管理] へ移動し、[検疫を追加] を選択します。 検疫の追加 以下を設定し、[保存] を選択します。 名前:任意の検疫設定名 送信拒否の結果: デフォルトの拒否メッセージを送信する メールが検疫されたときに定期的に通知する: 有効化 検疫の設定 [セキュリティ] > [アクセスとデータ管理] > [データの保護] > [ルールを管理] > 作成したルールを選択し、[ルールを編集] を選択します。 ルールを編集を選択 操作 まで移動し、以下のとおりに設定し、ルールを保存します。 操作: メールを検疫する 検疫の条件: 前手順で作成した検疫設定 を選択 アクションの変更(検疫) 動作確認(検疫) 先ほどと同じメールを作成して送信し、[このまま送信] を選択します。送信者側のメール受信トレイを確認し、メールが受信されてないことを確認します。 警告の表示とメール送信 管理者宛てに、メールが検疫されたことを通知するメールが届くことを確認します。 メール検疫のアラート通知確認 [アプリ] > [Google Workspace] > [Gmail の設定] > [検疫の管理] > [管理者検疫に移動] を選択し、送信したメールが存在することを確認します。 検疫されたメールの確認 メールを選択し、 許可(送信) または 拒否(送信不可) を選択します。今回は 拒否 を選択します。 拒否を選択 送信者側にメール送信が失敗したことを示すメールが届くことを確認します。 メール送信失敗通知確認 動作確認(OCR) [セキュリティ] > [アクセスとデータ管理] > [データの保護] へ移動し、[光学式文字認識(OCR)] の Gmail 設定を有効化して [保存] します。 GmailのOCRスキャンの有効化 ※ OCR スキャンを有効にした場合、スキャンの処理により画像や PDF が添付されたメールの処理に遅延が発生する可能性があります。 以下の画像ファイルを添付してメールを送信します。 添付ファイル テストメール [アプリ] > [Google Workspace] > [Gmail の設定] > [検疫の管理] > [管理者検疫に移動] を選択し、送信したメールが存在することを確認します。 検疫されたメールの確認 今回は [許可] を選択します。 許可を選択 送信者側で対象のメールを受信していることを確認します。 メールの受信確認 三浦 健斗 (記事一覧) クラウドソリューション部 2023年10月よりG-genにジョイン。元オンプレ中心のネットワークエンジニア。ネットワーク・セキュリティ・唐揚げ・辛いものが好き。
アバター
G-gen の杉村です。VPC Service Controls の 違反ダッシュボード (violation dashboard)機能を解説します。当機能は、VPC Service Controls の境界のアクセス制御に対する違反を一覧表示したり、傾向を把握するためのダッシュボード機能です。 概要 違反ダッシュボードとは ユースケース ダッシュボードの閲覧方法 ダッシュボードの内容 スクリーンショット 表示内容 ダッシュボードのフィルタ ダッシュボードの有効化 有効化画面 作成されるリソース ログルーター ログバケット 閲覧権限 概要 違反ダッシュボードとは VPC Service Controls の 違反ダッシュボード (violation dashboard)とは、VPC Service Controls の境界のアクセス制御に対する違反を一覧表示したり、傾向を把握するためのダッシュボードです。 なお、当記事で紹介する機能やスクリーンショット等は、いずれも2025年2月当時の Preview 段階中のものです。当機能は、2025年7月に一般公開(GA)されました。 参考 : Set up and view the violation dashboard VPC Service Controls とは、接続元 IP アドレスやアカウント情報に基づいて、境界(Perimeter)と呼ばれる論理的境界によって Google Cloud のデータを保護するための機能です。 VPC Service Controls の詳細は以下の記事を参照してください。 blog.g-gen.co.jp ユースケース VPC Service Controls の違反の傾向を掴むことで、プロジェクトへの不正アクセスの試みの増減を把握したり、本来は正しいとみなされるべきアクセスがどのくらい拒否されているかなど、傾向を掴むことができます。 また、本来は許可されるべきアクセスが拒否されてしまっているとき、該当の違反をダッシュボードで確認し、 トラブルシューティングトークン を取得することもできます。トラブルシューティングトークンは、境界への違反に対して発行される一意の ID です。トラブルシューティングトークンがわかれば、VPC Service Controls の 違反アナライザー (violation analyzer)により、そのアクセスが拒否された理由を詳細に確認することができます。 ダッシュボード上ではトラブルシューティングトークンが違反アナライザー画面へのリンクとなっており、すぐに違反の原因を確認することができます。 参考 : Diagnose an access denial event using the VPC Service Controls violation analyzer ダッシュボードの閲覧方法 Google Cloud コンソールのセキュリティ > VPC Service Controls 画面の左上部分に表示される「違反ダッシュボード」のリンクから、ダッシュボード画面に遷移できます。 違反ダッシュボードへの遷移(スクリーンショットはプレビュー中のもの) ダッシュボードの内容 スクリーンショット ダッシュボードは以下のように表示されます。 違反ダッシュボード(スクリーンショットはプレビュー中のもの) 表示内容 閲覧可能な情報は、以下のとおりです。 違反 指定期間内で発生した、境界に対する違反が表示されます。表示される内容は以下のとおりです。 トラブルシューティングトークン(違反の ID) プリンシパル(Google アカウント等) 接続元 IP アドレス アクセスポリシー 境界 ID リソース(境界が保護するプロジェクトまたは VPC ネットワーク) 接続先 API 名 メソッド名 モード(適用済みまたはドライラン) 前述のとおり、トラブルシューティングトークンをクリックすることで、違反アナライザー画面へ遷移し、違反とみなされた原因を確認することができます。 プリンシパル別の上位の違反 指定期間内の違反数が上位のプリンシパルやその回数が表示されます。 プリンシパル IP 別の上位の違反 指定期間内の違反数が上位の接続元 IP アドレスが表示されます。 サービス別の上位の違反 指定期間内の違反数が上位の接続先 Google Cloud API 名が表示されます。 メソッド別の上位の違反 指定期間内の違反数が上位の API メソッドが表示されます。 リソース別の上位の違反 指定期間内の違反数が上位の接続先リソース(境界が保護するプロジェクトまたは VPC ネットワーク)が表示されます。 サービス境界別の上位の違反 指定期間内の違反数が上位の境界 ID が表示されます。 ダッシュボードのフィルタ ダッシュボードの表示期間を、1時間、6時間、12時間、1日、2日、4日、7日、14日、30日、カスタムから選択できます。 ダッシュボードで表示する違反は、期間以外にも、以下の項目でフィルタできます。 アクセスポリシー リソース(境界が保護するプロジェクトまたは VPC ネットワーク) トラブルシューティングトークン(違反の ID) プリンシパル モード(適用済みまたはドライラン) トラフィックの方向(内向きまたは外向き) 接続先 API 名 メソッド ダッシュボードの有効化 有効化画面 違反ダッシュボードを閲覧する前に、ダッシュボードを有効化する必要があります。ダッシュボードでは 有効化した後の違反情報が閲覧可能 であり、 有効化する以前の情報は閲覧できません 。 初めてダッシュボード画面に遷移しようとすると、有効化の設定画面が表示されます。 ダッシュボードの有効化(スクリーンショットはプレビュー中のもの) 作成されるリソース 違反ダッシュボードは、Cloud Logging に記録される Cloud Audit Logs の ポリシー拒否監査ログ をもとに情報を表示しています。 Cloud Audit Logs のポリシー拒否監査ログについては、以下の記事をご参照ください。 参考 : Cloud Audit Logsを解説。Google Cloudの証跡管理 - 4 つの監査ログ ダッシュボードを有効化すると、 組織のルート に ログルーター (シンク)が作成されます。また有効化時に、ログルーターがポリシー拒否監査ログをルーティングする先の プロジェクトとログバケット を指定します。ログバケットは、この画面から新規作成することもできます。 なおログルーターとは、Cloud Logging がログを任意の保存先にルーティングするための設定です。 Cloud Logging のログルーターの詳細は以下の記事をご参照ください。 参考 : Cloud Loggingの概念と仕組みをしっかり解説 - ログルーティングとログの保存 ログルーター ダッシュボードを有効化すると、組織のルート(最上位階層)に reserved_vpc_sc_dashboard_log_router という名称のログルーターが作成されます。 このログルーターは、以下のようなフィルタによってポリシー拒否監査ログを抽出し、ログバケットにルーティングします。 resource . type = " audited_resource " protoPayload.metadata.@ type = " type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata " ログバケット 有効化時に指定したプロジェクトの、既存のログバケットまたは新規作成したログバケットに、ログがルーティングされます。 違反ダッシュボードはこのログバケットに保存されたログに基づいて情報を表示するため、 このログバケットに設定された保持期間が、ダッシュボードの情報の情報保持期間 となります。 閲覧権限 ダッシュボードを閲覧するには、閲覧者の Google アカウントが、ログバケットの存在するプロジェクトに対して以下のロールを持っている必要があります。 ログ表示アクセス者( roles/logging.viewAccessor ) VPC Service Controls Troubleshooter Viewer( roles/accesscontextmanager.vpcScTroubleshooterViewer ) 詳細は、以下の公式ドキュメントに記載されています。 参考 : Required roles 杉村 勇馬 (記事一覧) 執行役員 CTO 元警察官という経歴を持つ IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 認定資格および Google Cloud 認定資格はすべて取得。X(旧 Twitter)では Google Cloud や Google Workspace のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-gen の佐々木です。当記事では、Cloud Run の手動スケーリング機能について解説します。 Cloud Run とは 手動スケーリングの仕様 手動スケーリングとは サービスとリビジョンの設定 トラフィック分割への影響 サービスの無効化 手動スケーリングの使用 手動スケーリング設定時の料金 リクエストベースの課金の場合 インスタンスベースの課金の場合 スケジュールベースの自動スケーリング Cloud Scheduler の利用 自動スケーリングにおけるスケールのスケジューリング Cloud Run とは Cloud Run は Google Cloud のマネージドなコンテナ実行環境でアプリケーションを実行することができる、サーバレス コンテナコンピューティング サービスです。 Cloud Run には Cloud Run services と Cloud Run jobs、そして Cloud Functions から統合された Cloud Run functions の3種類がありますが、当記事における Cloud Run は Cloud Run services を指すものとします。 blog.g-gen.co.jp 手動スケーリングの仕様 手動スケーリングとは Cloud Run の 手動スケーリング 機能は、Cloud Run services のコンテナインスタンス数を手動で指定できる機能です。 デフォルトでは、Cloud Run services のコンテナインスタンスは自動でスケーリングを行います。受信トラフィック数と CPU 使用率に基づき、事前に指定された最小(最大)インスタンス数をスケーリングの下限(上限)として、自動的にスケーリングが行われます。一方、手動スケーリング設定を行うと、コンテナインスタンス数を任意の値に設定できます。 手動スケーリングでは新たなリビジョンをデプロイすることなく、起動するインスタンスを任意の数に固定することができます。この設定操作を Cloud Scheduler などで自動化することで、「特定の時間帯のみインスタンス数を10に固定し、それ以外の時間は3に固定する」といった自動化を実現できます。 参考: Manual scaling サービスとリビジョンの設定 手動スケーリングはサービスの設定であり、手動スケーリングを設定する場合はリビジョンのインスタンス数の設定は無視されます。リビジョンレベルとサービスレベルのインスタンス数の設定については以下の記事も参照してください。 参考: Cloud Runの最小インスタンス数をスケジュールベースで自動スケーリングする - サービスレベルの最小インスタンス数の設定 トラフィック分割への影響 手動スケーリングを使用している Cloud Run サービスでリビジョン間のトラフィック分割を設定している場合、以下のルールが適用されます。 各リビジョンに対してトラフィック分割の割合に比例したインスタンス数が割り当てられる。 トラフィック分割対象のリビジョンの数 > インスタンス数 の場合、インスタンスが存在しないリビジョンができる。そのリビジョンにトラフィックが送信された場合はエラーが返る。 リビジョンレベルの最小(最大)インスタンス数の設定は無視される。 サービスの無効化 手動スケーリングでインスタンス数を 0 に設定することで、サービスを無効にすることができます。 無効化したサービスに送信されたリクエストは、 Service unavailable または Service disabled エラーで失敗します。 手動スケーリングの使用 手動スケーリングは、サービスの作成時や更新時に設定することができます。 サービス作成時に手動スケーリングを設定する(コンソール) 既存のサービスで手動スケーリングを設定する(コンソール) gcloud コマンドの場合、 gcloud run service deploy コマンドや gcloud run service update コマンドで --scaling フラグを利用することで設定できます。以下はサービス更新時に手動スケーリングを設定するコマンドです。 # 手動スケーリングへの切り替え gcloud run services update < サービス名 > \ --scaling =< インスタンス数 > 手動スケーリングを設定すると、自動スケーリングにおけるリビジョンレベル/サービスレベルのインスタンス数の設定は無効になります。 手動スケーリング設定時の料金 リクエストベースの課金の場合 通常、リクエストベースの課金(旧称:「リクエスト処理中にのみ CPU を割り当てる」設定)では、リクエスト数に応じた料金と、リクエストの処理時間に応じた CPU、メモリの利用料金が発生します。 それに加えて、手動スケーリング設定時は、最小インスタンス数を1以上にしている場合と同様に インスタンスのアイドル時間 に対してもCPU、メモリの利用料金が発生します。 リクエストベースの課金で手動スケーリングを使用する場合 インスタンスベースの課金の場合 インスタンスベースの課金(旧称:「CPU を常に割り当てる」設定)の場合、Cloud Run の料金はリクエスト数に関係なく、インスタンスが起動している時間(アクティブ、アイドル状態問わず)に応じて CPU とメモリの料金が発生します。 したがって、手動スケーリングでインスタンスベースの課金を適用する場合は、インスタンスの起動数だけ CPU とメモリの料金が常に発生することになります。 参考 : Cloud Run pricing スケジュールベースの自動スケーリング Cloud Scheduler の利用 手動スケーリングと Cloud Scheduler を併用することで、任意の時刻にインスタンス数をスケーリングすることが可能です。 Cloud Scheduler で HTTP エンドポイントをターゲットとしたジョブを作成し、Cloud Run API へリクエストすることで、ノーコードでサービスをスケーリングすることができます。 gcloud scheduler jobs create http hello-start-instances \ --location = REGION \ --schedule =" 0 9 * * MON-FRI " \ --time-zone = America/Los_Angeles \ --uri = https://run.googleapis.com/v2/projects/PROJECT_ID/ locations/REGION/services/hello? update_mask =launchStage,scaling.manualInstanceCount \ --headers = Content-Type = application/json,X-HTTP-Method-Override = PATCH \ --http-method = PUT \ --message-body =' {"launchStage":"BETA","scaling":{"manualInstanceCount":10}} ' \ --oauth-service-account-email = PROJECT_NUMBER-compute@developer.gserviceaccount.com 参考 : Schedule-based scaling example 自動スケーリングにおけるスケールのスケジューリング なお前述の方法で、手動スケーリング設定でスケジュールに基づいてスケーリングした場合は、インスタンス数を特定の数に固定することしかできないため、設定した以上のインスタンス数が予期せず必要になったときなどに柔軟なスケールアウトを行うことができません。 以下の記事では、サービスレベルの最小インスタンス数をスケジュールベースで変更することで、最大インスタンス数の設定が有効な状態(自動スケーリングの設定)で、任意の数以上のインスタンスを維持する方法を解説しています。 blog.g-gen.co.jp 佐々木 駿太 (記事一覧) G-gen最北端、北海道在住のクラウドソリューション部エンジニア 2022年6月にG-genにジョイン。Google Cloud Partner Top Engineer 2025 Fellowに選出。好きなGoogle CloudプロダクトはCloud Run。 趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。 Follow @sasashun0805
アバター
G-genの杉村です。Vertex API 経由での Gemini API を定額で利用できる Provisioned Throughput を解説します。 概要 Provisioned Throughput とは サポートされるモデル 購入すべきユースケース 購入方法と料金 GSU(Generative AI Scale Unit) 購入期間 購入方法と料金 使用方法 自動適用 超過したスループットの扱い 明示的に従量課金を指定 スループットのモニタリング 考慮事項 ファインチューンされたモデル その他の考慮事項 概要 Provisioned Throughput とは Provisioned Throughput (プロビジョニングされたスループット)とは、Vertex AI 経由の Gemini や Claude などの生成 AI モデルの API 利用について、固定金額で利用できる月額サブスクリプションサービスです。 これらの生成 AI モデルは本来、インプットとアウトプットのボリュームに応じた従量課金(オンデマンド)です。事前にモデルとロケーション(リージョン)を指定して Provisioned Throughput を購入すると、月額利用料金で API を利用できるほか、優先的にリソースが割り当てられるため、多くのユーザーが API を利用しているときでもリソース枯渇による RESOURCE_EXHAUSTED (ステータスコード 429)エラーを回避することができます。 参考 : Provisioned Throughput overview サポートされるモデル Provisioned Throughput が利用できるモデルには、以下のようなものがあります(一部抜粋)。 Gemini 3 Pro、Gemini 3 Flash Gemini 3 Pro Image(Nano Banana Pro) Gemini 2.5 Pro、Gemini 2.5 Flash Veo 3.1、Veo 3 Imagen 4 Anthropic Claude Opus 4.5、Sonnet 4.5 最新の対象モデルの一覧は、以下の公式ドキュメントを参照してください。 参考 : Supported models 購入すべきユースケース Provisioned Throughput を購入すべきユースケースは、以下のとおりです。 重要なワークロードであり、高いスループットが継続的に求められる 生成 AI 本番環境アプリケーションのため一貫性のあるパフォーマンスが必要 スループットが 20,000 文字/秒を超えることがある 月額固定料金で API 利用料金を支払いたい 従量課金モードで Gemini API 等を利用していると、しばしば エラーコード429 Resource exhausted, please try again later. (status : RESOURCE_EXHAUSTED )が返却され、リクエストが失敗することがあります。これは Google 側でリソースが枯渇かけており、利用制限がかけられたことを意味しています。 参考 : エラーコード 429 エラーコード429 ( RESOURCE_EXHAUSTED )についての詳細は、以下の記事も参照してください。 blog.g-gen.co.jp エクスポネンシャルバックオフ(指数バックオフ)を実装してリクエストをリトライする方法もありますが、Provisioned Throughput を購入することによって優先的にリソースが割り当てられ、このようなエラーを回避することができます。 購入方法と料金 GSU(Generative AI Scale Unit) Provisioned Throughput は、 GSU (Generative AI Scale Unit)という単位で購入します。1 GSU は、例えば Gemini 1.5 Pro の場合、800文字/秒です。 GSU が持つ秒あたりの文字数について、1文字のインプットは1文字としてカウントされますが、例えば Gemini 1.5 Pro の場合、1文字のアウトプットは3文字としてカウントされます。また1枚の画像は1,052文字としてカウントされます。この消費文字数を バーンダウン率 といいます。 1 GSU あたりのスループット(文字/秒)やバーンダウン率はモデルによって異なるので、以下のドキュメントを参照してください。 参考 : Measure Provisioned Throughput また、必要なスループットの計算例が以下のドキュメントに示されています。 参考 : Example of estimating your Provisioned Throughput needs 購入期間 Provisioned Throughput は1ヶ月、3ヶ月、1年の期間で購入できます。自動更新を有効にすることで、更新作業を省略することができます。一度購入すると、コミットした期間は注文をキャンセルすることはできません。 購入時にはモデルを指定する必要があり、生成 AI では頻繁に新しいモデルが登場することを考慮すると、1年単位の購入には慎重になるべきと考えられます。ただし公式ドキュメントでは、同じリージョン内でかつ同じ事業者から提供されているモデルであれば、バージョンの切り替えができることも示されています。 なお、2025年1月現在は Preview 中ですが、1週間の単位での購入も可能です。Provisioned Throughput の Preview 機能を利用するには、応募フォームから応募し、Google から承認される必要があります。 参考 : Preview features 購入方法と料金 購入は Google Cloud コンソールの「プロビジョニングされたスループット」画面( https://console.cloud.google.com/vertex-ai/provisioned-throughput )から購入することができます。 同画面でモデル、リージョン、GSU 数、期間を入力すると、料金見積もりが表示されます。 購入に必要な権限などの詳細は、公式ドキュメントをご参照ください。 参考 : Purchase Provisioned Throughput 使用方法 自動適用 Provisioned Throughput を購入すると、自動的に利用が開始されます。プログラムのソースコードを変更する必要はありません。 参考 : Use Provisioned Throughput 超過したスループットの扱い Provisioned Throughput で購入したスループットを超過して API を利用すると、デフォルトでは従量課金が適用されます。 しかし、超過した場合に従量課金を利用せずエラーコード429を返却するようにすることもできます。REST API へのリクエスト時に、HTTP ヘッダーに X-Vertex-AI-LLM-Request-Type: dedicated を付与します。 この場合、購入した Provisioned Throughput を超過した場合に、エラーコード429レスポンスが返ります。メッセージは Too many requests. Exceeded the Provisioned Throughput. になります。 参考 : Use only Provisioned Throughput 明示的に従量課金を指定 上記とは逆に、開発環境アプリケーションからの利用であることなどを理由に、Provisioned Throughput をバイパスして従量課金モードでのみを使用するように明示的にリクエストすることもできます。REST API へのリクエスト時に、HTTP ヘッダーに X-Vertex-AI-LLM-Request-Type: shared を付与します。 参考 : Use only pay-as-you-go スループットのモニタリング Provisioned Throughput の使用状況をモニタリングするには、Cloud Monitoring が利用できます。 aiplatform.googleapis.com/PublisherModel というリソースタイプで、指標が記録されます。 インプット、アウトプットの文字数や消費されたスループット量などが記録されるため、Provisioned Throughput が過不足なく利用されているかが確認できます、。 参考 : Metrics 考慮事項 ファインチューンされたモデル ファインチューニングされたモデルにも、Provisioned Throughput が適用されます。ただし2025年1月現在は Preview 中であり、利用するには応募フォームから応募して、Google から承認される必要があります。 参考 : Preview features その他の考慮事項 その他の考慮事項としては、以下が挙げられます。 未使用のスループットは翌月に繰り越せない Provisioned Throughput を使用しても通常のクォータ(割り当て)は適用される その他の考慮事項については以下の公式ドキュメントを注意深くご参照ください。 参考 : What to consider before subscribing 杉村 勇馬 (記事一覧) 執行役員 CTO 元警察官という経歴を持つ IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 認定資格および Google Cloud 認定資格はすべて取得。X(旧 Twitter)では Google Cloud や Google Workspace のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-gen の佐々木です。当記事では Spanner の組み込みのオートスケーリング機能である Managed autoscaler を紹介します。 前提知識 Spanner とは インスタンス、ノード、処理ユニット オープンソースのオートスケーリングツール Managed autoscaler とは スケーリングのトリガー リードレプリカのオートスケーリング 費用 制限事項 オートスケーリングの設定方法 検証 サンプルコード(Go) 環境変数の設定 Spanner インスタンスの作成 データの準備 データベースとテーブルの作成 データの挿入 挿入したデータの確認 Managed autoscaler の設定 オートスケーリングの動作確認 後処理 前提知識 Spanner とは Spanner は、強整合性を保証する RDB(リレーショナルデータベース)の特徴と、グローバルに水平スケーリングできる NoSQL データベースの特徴を併せ持つ、フルマネージドな RDB サービスです。 参考 : Spanner Spanner の詳細については、以下の記事も参照してください。 blog.g-gen.co.jp インスタンス、ノード、処理ユニット Spanner は インスタンス という単位で管理され、インスタンスに割り当てられたコンピューティングリソースがインスタンス内のデータベースに割り当てられます。インスタンスには ノード 、もしくは 処理ユニット (processing units)という単位でコンピューティングリソースを割り当て、1,000処理ユニットが1ノードに相当します。このリソースの量によってストレージの上限も決められており、コンピューティングリソースもしくはストレージのどちらかに合わせてインスタンスのスケーリングを行う必要があります。 Spanner におけるノードと処理ユニットの追加・削除(スケールアウト・スケールイン)は 無停止 で行われるのが特徴であり、データベース接続を切断することなく、需要に応じた柔軟な水平スケーリングを実現できます。 オープンソースのオートスケーリングツール 当記事で紹介する Managed autoscaler が一般提供(GA)になる以前は、オープンソースのオートスケーラーを使用して Spanner にオートスケーリングを設定することができました。 オートスケーラーツールは Cloud Scheduler、Pub/Sub、Cloud Run functions、Firestore といった Google Cloud のサービスによって構成されており、Cloud Monitoring API でインスタンスの負荷状況を確認し、Spanner インスタンスのスケーリングをトリガーします。 当記事ではオープンソースのオートスケーラーツールに関する解説は行いません。組み込み機能である Managed autoscaler が一般提供になったことから、基本的にはそちらを使用してスケーリングを設定することになるでしょう。 参考: Autoscaler tool overview 参考: cloudspannerecosystem/autoscaler(GitHub) Managed autoscaler とは Managed autoscaler は Spanner に組み込みのオートスケーリング機能です。負荷に応じてインスタンスのサイズ(ノード数または処理ユニット数)が自動的に調整されます。 参考: Autoscaling overview 参考: Managed autoscaler Spanner には3種類の エディション が存在し、エディションによって提供される機能と料金が異なります。Managed autoscaler は Enterprise と Enterprise Plus エディションで利用できる機能です。Standard エディションでは利用できません。 参考 : Spanner editions overview スケーリングのトリガー Managed autoscaler は、以下の要素に基づいてインスタンスのスケーリングを行います。 スケーリング基準 説明 高優先度 CPU 使用率ターゲット (High priority CPU utilization target) スケーリングをトリガーする CPU 使用率(10%~90% で設定)。 インスタンスの CPU 使用率がターゲット値を超えるとスケールアウトがトリガーされる。 CPU 使用率がターゲット値より大幅に低い場合にスケールインがトリガーされる。 ストレージ使用率ターゲット (Storage utilization target) スケーリングをトリガーするストレージ使用率(10~99% で設定)。 下限(Minimum limit) スケールインの下限(最小1ノードまたは1,000処理ユニット)。 Managed Autoscaler を設定すると、インスタンスのデフォルトのサイズがこの値になる。 上限(Maximum limit) スケールアウトの上限。 下限の10倍を超える値に設定することはできない(下限が3ノードであれば30ノードまで設定可能) Spanner は高優先度 CPU 使用率ターゲットとストレージ使用率ターゲットの値に基づき、それぞれで推奨容量を算出します。算出された推奨容量のうち、高いほうが自動で選択されてスケーリングが行われます。 たとえば、ストレージ使用率ターゲットにより10ノード、高優先度 CPU 使用率ターゲットにより12ノード必要であると算出された場合、Managed autoscaler はインスタンスを12ノードにスケーリングします。 スケーリングが起こると、ノード間でストレージの最適化が行われ、単一のノードが過負荷にならないようにトラフィックが均等に分散されます。 参考 : How managed autoscaler works リードレプリカのオートスケーリング Managed autoscaler では、 非対称読み取り専用オートスケーリング (Asymmetric read-only autoscaling)と呼ばれる、リードレプリカのみのスケーリングもサポートされています。 参考 : Asymmetric read-only autoscaling Spanner では3種類のレプリカ(読み取り・書き込み、読み取り専用、ウィットネス)を使用することができますが、この中で 読み取り専用レプリカ のみ独立したオートスケーリングを使用することができます。 参考 : Read-only replicas リードレプリカのオートスケーリングは、リージョンごとに以下のパラメータを設定することができます。 スケーリング基準 説明 高優先度CPU使用率ターゲット (High priority CPU utilization target) スケーリングをトリガーする CPU 使用率(10%~90% で設定)。 最小コンピューティング容量制限 (Minimum compute capacity limit) スケールインの下限(ノード数または処理ユニット数)。 最大コンピューティング容量制限 (Maximum compute capacity limit) スケールアウトの上限(ノード数または処理ユニット数)。 費用 Managed autoscaler によるオートスケーリングが行われると、確保されたリソースの分、追加で料金が発生します。 Managed autoscaler を設定すると、スケールインの下限として設定されたコンピューティング容量が常時確保されるため、これが利用料のベースラインとなります。したがって、必要以上に下限を大きくしないように調整する必要があります。 既存のインスタンスにオートスケーリングを設定する場合は、過去の CPU 使用率、ストレージ使用率など各種モニタリング指標を確認し、適切なスケールイン下限、スケールアウト上限を設定します。 制限事項 Managed autoscaler を有効化したインスタンスは、以下の制限があります。 Spanner エディションの Standard を利用できない Managed autoscaler を設定しているインスタンスは 移動 することができない スケールインの下限は最低 1ノード以上、または1,000 処理ユニット以上に設定する必要がある 既存のインスタンスでオートスケーリングを有効にしたとき、既存のインスタンスのコンピューティング容量がスケールインの下限よりも一時的に低くなる可能性がある( 既存のコンピューティング容量 < スケールインの下限 のとき) オートスケーリングの設定方法 Spanner インスタンス作成時または更新時に、Managed autoscaler を有効化することができます。 たとえば gcloud CLI を使用して、既存のインスタンスに対してオートスケーリングを設定する場合、以下のようにコマンドを実行します。CPU 使用率ターゲット値とストレージ使用率ターゲット値は、どちらも必須フラグとなっています。 # インスタンスを更新して Managed autoscaler を有効化する([]内はリードレプリカの設定) # ノード数を指定する場合 $ gcloud spanner instances update < SpannerインスタンスのID > \ --autoscaling-min-nodes =< 最小ノード数 > \ --autoscaling-max-nodes =< 最大ノード数 > \ --autoscaling-high-priority-cpu-target =< CPU使用率ターゲット値 > \ --autoscaling-storage-target =< ストレージ使用率ターゲット値 > \ [ --asymmetric-autoscaling-option \ location =< リードレプリカのロケーション > ,\ min_nodes =< 最小ノード数 > ,\ max_nodes =< 最大ノード数 > ,\ high_priority_cpu_target =< CPU使用率ターゲット値 >] # インスタンスを更新して Managed autoscaler を有効化する([]内はリードレプリカの設定) # 処理ユニット数を指定する場合 $ gcloud spanner instances update < SpannerインスタンスのID > \ --autoscaling-min-processing-units =< 最小処理ユニット数 > \ --autoscaling-max-processing-units =< 最大処理ユニット数 > \ --autoscaling-high-priority-cpu-target =< CPU使用率ターゲット値 > \ --autoscaling-storage-target =< ストレージ使用率ターゲット値 > \ [ --asymmetric-autoscaling-option \ location =< リードレプリカのロケーション > ,\ min_nodes =< 最小処理ユニット数 > ,\ min_processing_units =< 最大処理ユニット数 > ,\ high_priority_cpu_target =< CPU使用率ターゲット値 >] オートスケーリングはコンソールから設定することもできます。 コンソールからオートスケーリングを設定する 参考: Enable or modify managed autoscaler on an instance 検証 サンプルコード(Go) 当記事では Go のコードを使用して Spanner インスタンス内のデータベースに対する操作を行い、Managed autoscaler の挙動を確認します。 以下のコード(main.go)では、実行時の引数に応じてデータベースとテーブルの作成、データの挿入、データの取得などの操作を行います。 // main.go package main import ( "context" "flag" "fmt" "io" "os" "strconv" "sync" "cloud.google.com/go/spanner" "google.golang.org/api/iterator" database "cloud.google.com/go/spanner/admin/database/apiv1" adminpb "cloud.google.com/go/spanner/admin/database/apiv1/databasepb" ) type Database struct { projectId string instanceId string name string } // データベースとテーブルを作成する func createDB(ctx context.Context, w io.Writer , adminClient *database.DatabaseAdminClient, db Database) error { // データベースを作成し、Singners テーブルと Albumsテーブルを作成する op, err := adminClient.CreateDatabase(ctx, &adminpb.CreateDatabaseRequest{ Parent: "projects/" + db.projectId + "/instances/" + db.instanceId, CreateStatement: "CREATE DATABASE `" + db.name + "`" , ExtraStatements: [] string { `CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX) ) PRIMARY KEY (SingerId)` , `CREATE TABLE Albums ( SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, AlbumTitle STRING(MAX) ) PRIMARY KEY (SingerId, AlbumId), INTERLEAVE IN PARENT Singers ON DELETE CASCADE` , }, }) if err != nil { return err } // データベース作成完了を待つ if _, err := op.Wait(ctx); err != nil { return err } fmt.Fprintf(w, "Created database [%s] \n " , db) return nil } // データを挿入する func insertData(ctx context.Context, w io.Writer , client *spanner.Client) error { _, err := client.ReadWriteTransaction(ctx, func (ctx context.Context, txn *spanner.ReadWriteTransaction) error { // Singers テーブルにデータを挿入する _, err := txn.Update(ctx, spanner.Statement{ SQL: `INSERT INTO Singers (SingerId, FirstName, LastName) VALUES (1, 'Marc', 'Richards'), (2, 'Catalina', 'Smith'), (3, 'Alice', 'Trentor'), (4, 'Lea', 'Martin'), (5, 'David', 'Lomond')` , }) if err != nil { return err } // Albums テーブルにデータを挿入する _, err = txn.Update(ctx, spanner.Statement{ SQL: `INSERT INTO Albums (SingerId, AlbumId, AlbumTitle) VALUES (1, 1, 'Total Junk'), (1, 2, 'Go, Go, Go'), (2, 1, 'Green'), (2, 2, 'Forever Hold Your Peace'), (2, 3, 'Terrified')` , }) if err != nil { return err } return nil }) if err != nil { return err } fmt.Fprintf(w, "data inserted \n " ) return nil } // Singers テーブルと Albums テーブルを結合してデータを取得する func joinData(ctx context.Context, w io.Writer , client *spanner.Client) error { iter := client.Single().Query(ctx, spanner.Statement{ SQL: `SELECT Singers.FirstName, Singers.LastName, Albums.AlbumTitle FROM Singers JOIN Albums ON Singers.SingerId = Albums.SingerId` , }) defer iter.Stop() fmt.Fprintln(w, "SingerId, AlbumId, AlbumTitle" ) for { row, err := iter.Next() if err == iterator.Done { break } if err != nil { return err } var ( firstName, lastName, albumTitle string ) if err := row.Columns(&firstName, &lastName, &albumTitle); err != nil { return err } fmt.Fprintf(w, "%s %s %s \n " , firstName, lastName, albumTitle) } return nil } // Spanner に負荷をかけるため joinData を並行処理で実行する func concJoinData(ctx context.Context, w io.Writer , client *spanner.Client, n int ) error { c := make ( chan bool , 1000 ) // 並行処理数の上限を設定 var wg sync.WaitGroup for i := 0 ; i < n; i++ { c <- true wg.Add( 1 ) go func () { defer wg.Done() if err := joinData(ctx, io.Discard, client); err != nil { fmt.Fprintln(w, err) } <-c }() } wg.Wait() fmt.Fprintln(w, "Concurrent join completed" ) return nil } func run(ctx context.Context, w io.Writer , cmd string , db Database) error { dbStr := fmt.Sprintf( "projects/%s/instances/%s/databases/%s" , db.projectId, db.instanceId, db.name) // コマンドに応じて処理を実行 switch cmd { case "createdb" : ctx := context.Background() adminClient, err := database.NewDatabaseAdminClient(ctx) if err != nil { return err } defer adminClient.Close() if err := createDB(ctx, w, adminClient, db); err != nil { return err } case "insertdata" : ctx := context.Background() dataClient, err := spanner.NewClient(ctx, dbStr) if err != nil { return err } defer dataClient.Close() if err := insertData(ctx, w, dataClient); err != nil { return err } case "joindata" : ctx := context.Background() dataClient, err := spanner.NewClient(ctx, dbStr) if err != nil { return err } defer dataClient.Close() if err := joinData(ctx, w, dataClient); err != nil { return err } case "concjoin" : ctx := context.Background() dataClient, err := spanner.NewClient(ctx, dbStr) if err != nil { return err } defer dataClient.Close() // 環境変数から並行処理数を取得 n, err := strconv.Atoi(os.Getenv( "CONC_NUM" )) if err != nil { return err } if err := concJoinData(ctx, w, dataClient, n); err != nil { return err } default : fmt.Println( "Usage: main.go [createdb|insertdata|joindata|concjoin]" ) return nil } return nil } func main() { // 環境変数からプロジェクトID、インスタンスID、データベース名を取得 projectId := os.Getenv( "PROJECT_ID" ) instanceId := os.Getenv( "INSTANCE_ID" ) dbname := os.Getenv( "DB_NAME" ) db := Database{ projectId: projectId, instanceId: instanceId, name: dbname, } flag.Parse() if len (flag.Args()) == 0 || len (flag.Args()) > 1 { fmt.Println( "Usage: main.go [createdb|insertdata|joindata|concjoin]" ) os.Exit( 1 ) } cmd := flag.Arg( 0 ) ctx := context.Background() if err := run(ctx, os.Stdout, cmd, db); err != nil { fmt.Println(err) os.Exit( 1 ) } } コード実行時の引数と実行される関数、処理内容の対応は以下のようになっています。 引数 実行される関数 処理内容 createdb createDB Spanner インスタンスにデータベースを作成し、その中に Singers テーブルと Albums テーブルを作成する。 insertdata insertData Singers テーブルと Albums テーブルにデータを挿入する。 joindata joinData Singers テーブルと Albums テーブルを結合する SELECT クエリを実行する。 concjoin concJoinData joinData 関数を並行して実行する。Spanner インスタンスに負荷をかけるために使用する。 参考: Go で Spanner を使ってみる 環境変数の設定 実行するコマンドやコード内から参照する環境変数を、ローカルの Linux 実行環境に設定します。 当記事では Spanner インスタンスの名前を test-instance 、データベースの名前を example-db とします。 export PROJECT_ID = < プロジェクトID > export INSTANCE_ID =test-instance export DB_NAME =example-db Spanner インスタンスの作成 Spanner インスタンスを作成します。まずは Standard エディションのインスタンスを最小サイズで作成します。 オートスケーリングの設定はインスタンス作成時でも可能ですが、当記事では後から設定を行います。 # Spanner インスタンスを作成する $ gcloud spanner instances create ${INSTANCE_ID} \ --config = regional-asia-northeast1 \ --description =" Test Instance " \ --processing-units = 100 参考: gcloud spanner instances create データの準備 データベースとテーブルの作成 Spanner インスタンスにデータベースを作成し、2つのテーブルを作成します。 # データベースとテーブルを作成する $ go run main.go createdb このコマンドを実行すると、データベースが作成されたあと、コード内に直書きされた以下のクエリによってテーブルが2つ作成されます。 CREATE TABLE Singers ( SingerId INT64 NOT NULL , FirstName STRING( 1024 ), LastName STRING( 1024 ), SingerInfo BYTES( MAX ) ) PRIMARY KEY (SingerId); CREATE TABLE Albums ( SingerId INT64 NOT NULL , AlbumId INT64 NOT NULL , AlbumTitle STRING( MAX ) ) PRIMARY KEY (SingerId, AlbumId), INTERLEAVE IN PARENT Singers ON DELETE CASCADE; データの挿入 2つのテーブルに、コード内に直書きされたデータを挿入します。 # 2つのテーブルにデータを挿入する $ go run main.go insertdata 挿入したデータの確認 挿入したデータを確認するため、以下のコマンドでクエリを実行します。 # 2つのテーブルを結合する SELECT クエリを実行する $ go run main.go joindata 以下のようにクエリの結果が返ってきます。 # 出力例 $ go run main.go joindata SingerId, AlbumId, AlbumTitle Marc Richards Total Junk Marc Richards Go, Go, Go Catalina Smith Green Catalina Smith Forever Hold Your Peace Catalina Smith Terrified Managed autoscaler の設定 Spanner インスタンスの設定を変更し、Managed autoscaler を有効化します。 Managed autoscaler はエディションが Enterprise 以上のインスタンスで使用できるため、エディションも変更する必要があります。また、オートスケーリングの下限は 1ノード(1,000処理ユニット)以上にする必要があるため、ここでは1ノードに設定します。 # Spanner インスタンスに Managed autoscaler の設定をする $ gcloud spanner instances update ${INSTANCE_ID} \ --edition = ENTERPRISE \ --autoscaling-max-nodes = 3 \ --autoscaling-min-nodes = 1 \ --autoscaling-high-priority-cpu-target = 10 \ --autoscaling-storage-target = 80 当記事では以下のようにインスタンスを更新します。動作確認のため、オートスケーリングをトリガーする CPU 使用率は低めに設定しておきます。 フラグ 設定値 説明 --edition ENTERPRISE Spanner インスタンスのエディションを設定する。 ENTERPRISE_PLUS でも可。 --autoscaling-max-nodes 3 スケーリングの最大値をノード数で設定する。 処理ユニットで設定する場合は --autoscaling-max-processing-units を使用する。 --autoscaling-min-nodes 1 スケーリングの最小値をノード数で設定する(最小1)。 処理ユニットで設定する場合は --autoscaling-min-processing-units を使用する(最小1,000)。 --autoscaling-high-priority-cpu-target 10 オートスケーリングをトリガーする CPU 使用率の値を設定する。(%) --autoscaling-storage-target 80 オートスケーリングをトリガーするストレージ使用率の値を設定する。(%) 以下のコマンドでオートスケーリング有効化後の設定を確認します。 # Spanner インスタンスの詳細を確認する(出力抜粋) $ gcloud spanner instances describe ${INSTANCE_ID} autoscalingConfig: autoscalingLimits: maxNodes: 3 minNodes: 1 autoscalingTargets: highPriorityCpuUtilizationPercent: 10 storageUtilizationPercent: 80 参考: gcloud spanner instances update オートスケーリングの動作確認 オートスケーリングを設定した Spanner インスタンスに負荷をかけ、スケーリング動作を確認します。 まず、環境変数にクエリの実行数を設定します。 # クエリ実行数を設定する $ export CONC_NUM = 1000000 以下のコマンドを実行し、Spanner インスタンスに負荷をかけるための処理を実行します。 # 並行処理でクエリを実行し、Spanner インスタンスに負荷をかける $ go run main.go concjoin コマンド実行後少し待つと、Spanner の CPU 使用率がターゲット値を超過し、Managed autoscaler によってノードのスケールアウトが行われます。 Managed autoscaler によるスケールアウト その後、CPU 使用率が下がってからしばらく待つと、ノードのスケールインが行われます。スケールアウトと比較して、ターゲット値を下回ってからスケールインが行われるまでに少し長めの間隔があることがわかります。 Managed autoscaler によるスケールイン 後処理 Spanner は個人の検証目的としては高価なサービスのため、動作確認後は忘れずにインスタンスを削除します。 # Spanner インスタンスを削除する $ gcloud spanner instances delete test-instance 参考: Spanner pricing 佐々木 駿太 (記事一覧) G-gen最北端、北海道在住のクラウドソリューション部エンジニア 2022年6月にG-genにジョイン。Google Cloud Partner Top Engineer 2025 Fellowに選出。好きなGoogle CloudプロダクトはCloud Run。 趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。 Follow @sasashun0805
アバター
G-gen の出口です。当記事では、Google Kubernetes Engine(GKE)にデプロイした Web アプリケーション Ingress でインターネット公開する方法、またそのアプリに Cloud Armor ポリシーを設定して、アクセス元 IP アドレスを制限する方法を解説します。 概要 検証の概要 Google Kubernetes Engine とは Ingress とは Cloud Armor とは Firestore の準備 データベースの作成 データの準備 アプリケーションの準備 ソースコードの作成 main.py templates/index.html requirements.txt Dockerfile Artifact Registry の作成 Artifact Registry にアップロード GKE クラスタの設定 GKE クラスタの作成 サービスアカウントの設定 ServiceAccount リソースの作成 権限の付与 GKE クラスタにアプリケーションをデプロイ Ingress を設定してアプリケーションを公開 Cloud Armor による アクセス制限を適用 Cloud Armor のセキュリティポリシーを設定 BackendConfig を作成 Service と BackendConfig の関連付け 動作確認 概要 検証の概要 当記事で検証した構成は、以下のとおりです。 この構成では、GKE 上で動作するアプリケーションが、Firestore に保存されたユーザー情報を、入力されたユーザ ID に基づいて表示します。GKE クラスタに対しては、 Ingressリソースとして外部アプリケーションロードバランサを作成します。そのロードバランサに対して、Cloud Armor を用いて IP アドレスによるアクセス制限を適用します。 Google Kubernetes Engine とは Google Kubernetes Engine (以下、GKE)は、Google Cloud(旧称 GCP)が提供する Kubernetes のマネージドサービスです。 以下の記事で GKE について解説していますので、ご参照ください。 blog.g-gen.co.jp Ingress とは Ingress は、Kubernetes クラスタ外部からクラスタ内部への HTTP(S) アクセスを管理する Kubernetes の API オブジェクトです。この Ingress と Service を組み合わせることで、Service の背後にある Pod にデプロイされているアプリケーションへ外部からアクセスできるようになります。 参考 : Ingress | Kubernetes GKE には、組み込みの GKE Ingress コントローラが用意されています。GKE で Ingress リソースを作成すると、このコントローラによってアプリケーションロードバランサが GKE クラスタ外部に自動的に構成されます。 Cloud Armor とは Cloud Armor は、Google Cloud が提供するフルマネージドの WAF(Web Application Firewall)サービスです。Cloud Armor のセキュリティポリシーを作成してアプリケーションロードバランサに関連付けることで、アクセス制限をかけることができます。 以下の記事で Cloud Armor について解説していますので、ご参照ください。 blog.g-gen.co.jp Firestore の準備 データベースの作成 Firestore で (default) データベースを作成します。 (default) データベースは Firestore のデフォルトとなるデータベースで、Firestore クライアントライブラリや Google Cloud CLI から接続するときにデータベース ID を指定しない場合、自動的に (default) データベースに接続されます。 gcloud firestore databases create \ --database =" (default) " \ --location = asia-northeast1 \ --type = firestore-native データの準備 作成した (default) データベースに、コレクション ID が users で、 age , id , name という3つのフィールドを持っているドキュメントを追加します。 アプリケーションの準備 ソースコードの作成 GKE 上で動作するアプリケーションのソースコードを作成します。 ディレクトリ構成は以下の通りです。 . ├── main.py ├── requirements.txt ├── Dockerfile └── templates └── index.html main.py ソースコードは以下のとおりです。 PROJECT_ID には、ご自身のプロジェクト ID を設定してください。 from flask import Flask, render_template, request from google.cloud import firestore PROJECT_ID = "プロジェクト ID に置き換えてください" app = Flask(__name__) # Firestore インスタンス初期化 db = firestore.Client(project=PROJECT_ID) COLLECTION_NAME = "users" # Firestore コレクション名 ID_FIELD_NAME = "id" # Firestore IDフィールド名 @ app.route ( "/" , methods=[ "GET" , "POST" ]) def index (): data = None message = None if request.method == "POST" : try : user_id = request.form.get( "user_id" ) if not user_id: message = "IDを入力してください。" return render_template( 'index.html' , data=data, message=message) doc_ref = db.collection(COLLECTION_NAME).where(ID_FIELD_NAME, "==" , user_id).get() if doc_ref: data = doc_ref[ 0 ].to_dict() else : message = "指定されたIDのデータは見つかりませんでした。" except Exception as e: message = f "エラーが発生しました:{str(e)}" return render_template( "index.html" , data=data, message=message) if __name__ == "__main__" : app.run(host= "0.0.0.0" , port= 8080 , debug= True ) templates/index.html ユーザ ID を入力するフォームが搭載されていて、そのユーザ ID を Firestore で検索して受け取った結果を表示する HTML ファイルを作成します。 <!DOCTYPE html> < html > < head > < title > Firestore Viewer </ title > </ head > < body > < h1 > Firestore Data Viewer </ h1 > < form method = "POST" > < label for = "user_id" > IDを入力: </ label > < input type = "text" id = "user_id" name = "user_id" > < button type = "submit" > 検索 </ button > </ form > < br > {% if data %} < h2 > データ: </ h2 > < p > 名前: {{ data.name }} </ p > < p > 年齢: {{ data.age }} </ p > {% elif message %} < p > {{ message }} </ p > {% endif %} </ body > </ html > requirements.txt 使用するライブラリを、以下の通りに定義します。 Flask==3.1.0 google-cloud-firestore==2.19.0 Dockerfile GKE へデプロイするために Docker イメージを用意する必要があるため、Dockerfile を作成します。 FROM python:3.12-slim WORKDIR /usr/src/app COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 8080 CMD [ "python", "./main.py" ] Artifact Registry の作成 Docker イメージを保存するための Artifact Registry 標準リポジトリを作成します。 以下のコマンドで、 firestore-app という名前のリポジトリを作成します。 gcloud artifacts repositories create firestore-app \ --repository-format = docker \ --location = asia-northeast1 Artifact Registry にアップロード Cloud Build を利用して Docker イメージをビルドし、作成した Artifact Registry にプッシュします。 プロジェクト ID に置き換えてください の部分を、ご自身のプロジェクト ID に置き換えて、Dockerfile を作成したディレクトリで以下のコマンドを実行します。 PROJECT = " プロジェクト ID に置き換えてください " gcloud builds submit --tag asia-northeast1-docker.pkg.dev/ ${PROJECT} /firestore-app/firestore-app GKE クラスタの設定 GKE クラスタの作成 以下のコマンドで、 firestore-app という名前の Autopilot モードの GKE クラスタを作成します。 Autopilot モードではノード、スケーリング、セキュリティといったクラスタ構成が Google Cloud によって管理されます。GKE のベスト プラクティスと推奨事項を遵守されたクラスタ構成が提供されます。 gcloud container clusters create-auto firestore-app \ --location = asia-northeast1 \ --project = ${PROJECT} サービスアカウントの設定 今回の構成では、GKE クラスタ上で実行されるワークロードから Firestore へのアクセスが必要になります。 GKE Autopilot モード では Workload Identity Federation が常に有効化されており、GKE の ServiceAccount リソースを IAM プリンシパルとして直接関連付けることができます。この機能を利用して、Firestore へのアクセス権を付与します。 Workload Identity Federation についてや、その他の認証方法については以下の記事で解説しておりますので、ご参照ください。 blog.g-gen.co.jp blog.g-gen.co.jp ServiceAccount リソースの作成 以下のコマンドで、Kubernetes ServiceAccout リソース firestore-app を作成します。 kubectl create serviceaccount firestore-app 権限の付与 作成した ServiceAccout を参照する IAM ポリシーを作成します。 以下のコマンドで、作成した ServiceAccout に対して Cloud Datastore 閲覧者 ( roles/datastore.viewer ) ロールを付与します。 プロジェクト番号に置き換えてください の部分を、ご自身のプロジェクト番号に置き換えてください。 PROJECT_NUMBER = " プロジェクト番号に置き換えてください " gcloud projects add-iam-policy-binding projects/ ${PROJECT} \ --role = roles/datastore.viewer \ --member = principal://iam.googleapis.com/projects/ ${PROJECT_NUMBER} /locations/global/workloadIdentityPools/ ${PROJECT} .svc.id.goog/subject/ns/default/sa/firestore-app GKE クラスタにアプリケーションをデプロイ 以前の手順で Artifact Registry にアップロードしたコンテナイメージを使用して、アプリケーションを GKE クラスタに登録します。 以下のマニフェストファイル deployment.yaml を GKE クラスタに適用し、Deployment リソースを作成します。 # deployment.yaml apiVersion : apps/v1 kind : Deployment metadata : name : firestore-app-deployment namespace : default labels : app : firestore-app spec : replicas : 3 selector : matchLabels : app : firestore-app template : metadata : labels : app : firestore-app spec : serviceAccountName : firestore-app # 作成した ServiceAccout の名前 containers : - name : firestore-app image : asia-northeast1-docker.pkg.dev/(プロジェクトID)/firestore-app/firestore-app:latest ports : - containerPort : 8080 resources : requests : cpu : 50m memory : 52Mi 続いて、アプリケーションを公開するための Service を GKE クラスタに登録します。 以下のマニフェストファイル service.yaml を GKE クラスタに適用し、Service リソースを作成します。 # service.yaml apiVersion : v1 kind : Service metadata : name : firestore-app-service namespace : default annotations : cloud.google.com/neg : '{"ingress": true}' spec : selector : app : firestore-app ports : - port : 8080 protocol : TCP targetPort : 8080 type : NodePort Ingress を設定してアプリケーションを公開 最初に Cloud Armor のセキュリティポリシーを構成せずに、アクセス元の制限を設定してしない状態で Ingress リソースを作成してみます。 以下のマニフェストファイル ingress.yaml を GKE クラスタに適用します。 # ingress.yaml apiVersion : networking.k8s.io/v1 kind : Ingress metadata : name : firestore-app-ingress namespace : default annotations : kubernetes.io/ingress.class : "gce" spec : defaultBackend : service : name : firestore-app-service port : number : 8080 今回の検証では、Ingress によって作成されるアプリケーションロードバランサは HTTP によってアクセスされます。 HTTPS を使用する場合は、SSL/TLS 証明書を Ingress と関連付ける必要があります。詳細は、以下の記事をご参照ください。 blog.g-gen.co.jp Ingress によって作成されたアプリケーションロードバランサの外部 IP アドレスを確認し、アクセスすると Firestore Viewer というタイトルのアプリケーションの画面が表示されます。 Firestore に追加したユーザ ID を入力すると、そのユーザ ID に対応するユーザ情報が表示されることが確認できます。 Cloud Armor による アクセス制限を適用 Cloud Armor のセキュリティポリシーを設定 アクセス元の IP アドレスを制限する Cloud Armor のセキュリティポリシーを作成します。 まず以下のコマンドで、 firestore-app-policy という名前のセキュリティポリシーを作成します。 gcloud compute security-policies create firestore-app-policy 次に、作成したセキュリティポリシーのデフォルトのルール (優先度 2,147,483,647) を更新し、すべてのアクセス元からのアクセスを制限します。 gcloud compute security-policies rules update 2147483647 \ --security-policy = firestore-app-policy \ --action =" deny-403 " 特定の IP アドレス範囲からのアクセスを許可するルールを作成します。 ルールの優先度はデフォルトのルールよりも高く設定します。以下の例では、優先度 1000 で設定しています。 gcloud compute security-policies rules create 1000 \ --security-policy = firestore-app-policy \ --src-ip-ranges =" <許可する IP アドレス範囲> " \ --action =" allow " BackendConfig を作成 Ingress と Cloud Armor のセキュリティポリシーを関連付けるために、GKE のカスタムリソースである BackendConfig リソースを作成します。 以下のマニフェストファイル backend.yaml を GKE クラスタに適用します。 apiVersion : cloud.google.com/v1 kind : BackendConfig metadata : name : firestore-app-backendconfig spec : securityPolicy : name : firestore-app-policy # 作成したセキュリティポリシーの名前 Service と BackendConfig の関連付け BackendConfig は Ingress リソースに対してではなく、 Service リソースの Service ポートに関連付けられます。GKE Ingress コントローラはアプリケーションロードバランサを作成する際に、この関連付けられた BackendConfig の設定を利用します。 マニフェストファイル service.yaml を以下のように更新して、 GKE クラスタに適用します。 # service.yaml apiVersion : v1 kind : Service metadata : name : firestore-app-service namespace : default annotations : cloud.google.com/neg : '{"ingress": true}' cloud.google.com/backend-config : '{"ports": {"8080":"firestore-app-backendconfig"}}' # 追記 spec : selector : app : firestore-app ports : - port : 8080 protocol : TCP targetPort : 8080 type : NodePort 動作確認 まず、Cloud Armor のセキュリティポリシーで許可していない IP アドレス範囲からアクセスしてみます。 Ingress によって作成されたアプリケーションロードバランサの外部 IP アドレスにアクセスすると、以下のようにアクセスが拒否されることが確認できます。 次に、ポリシーで許可された IP アドレス範囲からアクセスしてみます。 すると、以下のように Firestore Viewer アプリケーションの画面が表示されることが確認できます。 出口 晋太朗 (記事一覧) クラウドソリューション部 2024年7月にG-genに入社。 福岡在住で、Google Cloud をマスターするため日々エンジニアとして修行中。
アバター
G-gen の三浦です。当記事では Microsoft OneDrive から Google ドライブへの移行ツールの検証結果を紹介します。 概要 Microsoft OneDrive からのデータ移行とは 前提条件 制約 検証概要 検証環境 検証の流れ 設定手順 [Google Workspace] 移行用の csv の準備 [Google Workspace] データ移行の実施 [Microsoft 365] 移行後に OneDrive のファイルを更新 [Google Workspace] 差分移行の実施と確認 概要 Microsoft OneDrive からのデータ移行とは 本機能は Google Workspace の管理機能であり、Microsoft OneDrive(以下、OneDrive)のデータを Google ドライブのマイドライブにコピーできます。 参考 : OneDrive からファイルを移行する方法 前提条件 当機能で移行を実施するには、以下2つの上限があります。 Google Workspace 側では 特権管理者ロール が、Microsoft365 側では グローバル管理者ロール が必要です。 以下の特定の Google Workspace エディションでのみ利用可能です。 Business Starter / Standard / Plus Enterprise Standard / Plus Education Fundamentals / Standard / Plus, Teaching and Learning Upgrade Essentials Starter, Essentials, Enterprise Essentials, Enterprise Essential Plus Nonprofits G Suite Basic / Business 制約 当機能には以下のような制限があります。 外部ユーザーが作成したファイルやフォルダは移行できません。 共有ドライブへの移行はできず、マイドライブにのみ移行されます。 その他の制約については、以下の公式ドキュメントを確認してください。 参考 : ファイル移行で移行されるデータ 検証概要 検証環境 検証環境は以下のとおりです。実際の移行ケースを想定し、OneDrive と Google ドライブのドメインおよびユーザー情報を統一した環境で検証しました。 プラットフォーム ドメイン名 ユーザー名 ライセンス Google Workspace miurak-test.com admin@miurak-test.com Google Workspace Business Starter Microsoft 365 miurak-test.com admin@miurak-test.com Microsoft 365 Business Basic OneDrive の構成は以下の通りです。 OneDrive構成1 OneDrive構成2 検証の流れ 以下の手順でデータの移行を実施します。 項目 作業 プラットフォーム 1 移行用の csv の準備 Google Workspace 2 データ移行の実施 Google Workspace 3 移行後に OneDrive のファイルを更新 Microsoft 365 4 差分移行の実施と確認 Google Workspace 設定手順 [Google Workspace] 移行用の csv の準備 Google Workspace の管理コンソール( https://admin.google.com )にログインします。 参考 : 管理コンソールにログインする [データ] > [データのインポートとエクスポート] > [データ移行(新規)] から Microsoft OneDrive の [移行] を選択します。 OneDrive の移行を選択 [手順 2] の [サンプル csv をダウンロード] を選択します。 サンプルcsvのダウンロード ダウンロードした csv を開き、以下のとおりに移行対象の OneDrive のユーザーのメールアドレス を入力し、保存します。 ユーザー移行用の csv の編集 [手順 3] の [サンプル csv をダウンロード] を選択します。 サンプルcsvのダウンロード ダウンロードした csv を開き、以下のとおりに OneDrive と Google ドライブのユーザー紐づけ を入力し、保存します。 Source Email :OneDrive のユーザーのメールアドレス Destination Email :Google Workspace のユーザーのメールアドレス ユーザー紐づけ用の csv の編集 [Google Workspace] データ移行の実施 OneDrive の移行の [手順 1] で [Microsoft OneDriveに接続] を選択し、移行ツールに権限を付与します。 Microsoft OneDriveに接続 Microsoftアカウントにサインイン アクセス許可内容を確認して承諾 [手順2] の [CSV をアップロード] を選択し、前の手順で作成した csv を選択します。 csvをアップロード csvアップロード完了 [手順3] の [CSV をアップロード] を選択し、前の手順で作成した csv を選択します。 csvをアップロード csvアップロード完了 [ステップ4] の [移行を開始] を選択します。 移行を開始 移行が完了したことを確認します。詳細は [移行レポートをエクスポート] または [ユーザーレポートをエクスポート] から確認できます。 移行完了確認 ユーザーレポート Google ドライブのマイドライブを確認し、ファルダとファイルが移行されていることを確認します。 マイドライブ確認1 マイドライブ確認2 [Microsoft 365] 移行後に OneDrive のファイルを更新 データの移行後に OneDrive のフォルダとファイルを追加します。 OneDrive更新1 OneDrive更新2 [Google Workspace] 差分移行の実施と確認 OneDrive の移行の [ステップ 4] の [差分移行を実行] を選択します。 差分移行を実行 移行が成功したことを確認します。 差分移行の成功確認 ユーザーレポート マイドライブを確認し、前手順で追加したフォルダとファイルが存在することを確認します。 差分移行確認1 差分移行確認2 全ての移行が完了したら、[移行を終了する] > [移行を終了して削除] を選択し、移行を終了します。 移行を終了するを選択 移行を終了して削除 三浦 健斗 (記事一覧) クラウドソリューション部 2023年10月よりG-genにジョイン。元オンプレ中心のネットワークエンジニア。ネットワーク・セキュリティ・唐揚げ・辛いものが好き。
アバター
G-gen の佐々木です。当記事では Cloud Run から Secret Manager に格納したシークレットを利用する方法を解説します。 事前知識 Cloud Run Secret Manager Cloud Run で Secret Manager を利用する ユースケース 2つの方法 事前準備 シェル変数の設定 シークレットの準備 シークレット作成時に読み込むファイルを作成する シークレットを作成する サービスアカウントの準備 サービスアカウントを作成する サービスアカウントに権限を付与する 環境変数を使用したアクセス サンプルコード(Go) コンテナイメージのビルド Cloud Run のデプロイ 動作確認 ボリュームマウントを使用したアクセス サンプルコード(Go) コンテナイメージのビルド Cloud Run のデプロイ 動作確認 シークレット更新時の動作検証 シークレット更新前の確認 シークレットの更新 動作確認 シークレットをボリュームマウントしたサービスの動作 シークレットを環境変数として読み込むサービスの動作 事前知識 Cloud Run Cloud Run は Google Cloud のマネージドなコンテナ実行環境でアプリケーションを実行することができる、サーバレス コンテナコンピューティング サービスです。 Cloud Run には Cloud Run services、Cloud Run jobs、Cloud Run functions(旧称:Cloud Functions)の3種類がありますが、当記事の内容はこれら3種類で共通のため、記事内では区別せずに Cloud Run と表記しています。 当記事では、 Cloud Run services を例として手順を説明していきます。 それぞれの詳細については以下の記事を参照してください。 参考 : Cloud Runを徹底解説! - G-gen Tech Blog 参考 : Cloud Run jobsを徹底解説! - G-gen Tech Blog 参考 : Cloud Run functionsを徹底解説! - G-gen Tech Blog Secret Manager Secret Manager は、API キーやパスワード、証明書といった機密情報( シークレット )を安全に格納するためのサービスです。Secret Manager に格納されたシークレットはバージョン管理され、IAM を用いてアクセス制御を行うことができます。 Secret Manager に格納されたすべてのシークレットはデフォルトで AES256ビット暗号化が施され、読み取りアクセスはすべて TLS で暗号化されます。 参考 : Secret Manager の概要 Cloud Run で Secret Manager を利用する ユースケース Cloud Run 上のアプリケーションからデータベースにアクセスする場合や、外部 API を利用する場合などの認証情報は、Cloud Run の環境変数に格納することができます。この場合、Cloud Run の設定を閲覧できるユーザーであれば、誰でも認証情報にアクセスすることができてしまいます。 環境変数の代わりに Secret Manager のシークレットとして認証情報を管理することで、そのシークレットに対する IAM 権限を持つプリンシパル(ユーザー、アプリケーションなど)のみにアクセスを制限することができます。また、Cloud Run 側の設定を変えることなく、シークレットのバージョニングやローテーションを容易に行うことができます。 参考 : サービスのシークレットを構成する (Cloud Run services) 参考 : ジョブのシークレットを構成する (Cloud Run jobs) 2つの方法 Cloud Run で Secret Manager を使用する場合、以下に示す2種類の方法のいずれかを用いてシークレットを読み込むことができます。 シークレットの読み込み方法 特徴 Cloud Run の環境変数として読み込む プログラムから環境変数を読み取ることでシークレットの値にアクセスできる。 シークレットの値はコンテナインスタンス起動時に環境変数として読み込まれるため、 シークレットの更新は起動中のコンテナインスタンスに反映されない 点に注意が必要。 シークレットのバージョンを latest ではなく特定のバージョンで固定することで、コンテナインスタンスごとに異なる値が参照されないようにすることが推奨される。 Cloud Run のボリュームとしてマウント シークレットをコンテナインスタンスにボリュームとしてマウントし、ファイルシステム経由で値を読み込む。 シークレットの値は、起動中のインスタンスであっても常に最新のものが読み込まれる。 シークレットを環境変数として読み込む場合、シークレットの値を更新したときにすぐに反映されず、データベース接続不可などの障害を引き起こしてしまう可能性があります。そのため、Cloud Run 上のアプリケーションが頻繁に呼び出されるユースケースではボリュームマウントの使用が推奨されます。 バッチ処理など Cloud Run を定期的に実行するようなユースケースでは、都度コンテナインスタンスが起動されるため、シークレットを環境変数として読み込む方法を使用しても更新時の影響は起こりにくいでしょう。 当記事では、それぞれの設定方法を紹介し、シークレット更新時の動作についても実際に確認してみます。 事前準備 シェル変数の設定 当記事では gcloud CLI を使用して各種リソースの作成を行っていきます。gcloud CLI のインストールについては ドキュメント を参照してください。 まず、実行するコマンドで何度か使用する値をシェル変数として設定しておきます。 PROJECT_ID = { プロジェクトID } # リソースを作成するプロジェクトの ID SERVICE_ACCOUNT_NAME = { サービスアカウントの名前 } # 任意の文字列 REPO_NAME = { Artifact Registry リポジトリの名前 } # 使用するリポジトリの名前 REGION =asia-northeast1 # 東京リージョン(別のリージョンを使いたい場合は変更する) Cloud Run のコンテナイメージを格納する Artifact Registry リポジトリがない場合は事前に作成してください。 参考 : 標準リポジトリを作成する 当記事では、リポジトリが東京リージョン(asia-northeast1)に存在する前提で進めていきます。 シークレットの準備 シークレット作成時に読み込むファイルを作成する まず、シークレットを作成する際に読み込むテキストファイルを作成します。このファイルには、シークレットの値を記述しておきます。 # シークレットの値を記述したファイルを作成 $ echo " hello " > secret.txt シークレットの値はシークレット作成時に直接指定することもできますが、入力した値はプロセスのリストに平文で表示され、コマンドの実行履歴としても残ってしまいます。そのため、ファイルから値を読み込む方法が推奨されています。 シークレットを作成する 作成したテキストファイルを使用して、Cloud Run からアクセスする Secret Manager のシークレットを作成します。 当記事では mysecret という名前でシークレットを作成します。このシークレットの名前は、値を参照する際にキーとして使用されます。 # ファイルを指定してシークレットを作成する $ gcloud secrets create mysecret \ --project = ${PROJECT_ID} \ --data-file = secret.txt 参考: gcloud secrets create サービスアカウントの準備 サービスアカウントを作成する Cloud Run に設定するサービスアカウントを作成します。 # サービスアカウントを作成する $ gcloud iam service-accounts create ${SERVICE_ACCOUNT_NAME} \ --project = ${PROJECT_ID} 参考: gcloud iam service-accounts create サービスアカウントに権限を付与する 作成したサービスアカウントに対して以下の IAM ロールを紐付け、シークレットのアクセス権限を付与します。 Secret Manager のシークレット アクセサー ( roles/secretmanager.secretAccessor ) # サービスアカウントに対してシークレットへのアクセス権を付与する $ gcloud secrets add-iam-policy-binding mysecret \ --member =" serviceAccount: ${SERVICE_ACCOUNT_NAME} @ ${PROJECT_ID} .iam.gserviceaccount.com " \ --role =" roles/secretmanager.secretAccessor " 環境変数を使用したアクセス サンプルコード(Go) まずは、シークレットを Cloud Run の環境変数として読み込む方法を試してみます。 以下のサンプルコード( main.go )は、環境変数 SECRET から読み込んだ値を表示するだけのウェブサーバーを実行します。 // main.go package main import ( "fmt" "net/http" "os" ) func main() { http.HandleFunc( "/" , func (w http.ResponseWriter, r *http.Request) { // Read the secret from the environment variable SECRET secretVal := os.Getenv( "SECRET" ) fmt.Fprintf(w, "Environment Secret: %s" , secretVal) }) http.ListenAndServe( ":8080" , nil ) } コンテナイメージのビルド Cloud Build を使用してコンテナイメージをビルドし、Artifact Registry のリポジトリにプッシュします。 先ほどの main.go ファイルがあるディレクトリで、以下のコマンドを実行します。コンテナイメージ名は env-secret とします。 # Cloud Build で Buildpack を使用してコンテナイメージをビルドする $ gcloud builds submit --pack image = ${REGION} -docker.pkg.dev/ ${PROJECT_ID} / ${REPO_NAME} /env-secret このコマンドでは Buildpack を使用することで、Dockerfile を用意することなく、ソースコードからコンテナイメージをビルドしています。 参考: Buildpack を使用してアプリケーションをビルドする Cloud Run のデプロイ Artifact Registry にプッシュしたコンテナイメージを使用して、Cloud Run サービスをデプロイします。サービス名はコンテナイメージと同じ env-secret とします。 # Secret を環境変数として読み込む Cloud Run サービスをデプロイする $ gcloud run deploy env-secret \ --image = ${REGION} -docker.pkg.dev/ ${PROJECT_ID} / ${REPO_NAME} /env-secret \ --project = ${PROJECT_ID} \ --region = ${REGION} \ --service-account = ${SERVICE_ACCOUNT_NAME} @ ${PROJECT_ID} .iam.gserviceaccount.com \ --allow-unauthenticated \ --set-secrets = SECRET =mysecret:latest シークレットは --set-secrets フラグを使用して、以下の形式で設定することができます。 --set-secrets={任意の環境変数名}={シークレットの名前}:{シークレットのバージョン} Cloud Run の環境変数を確認すると、値としてシークレットが設定されていることがわかります。この環境変数のキー( SECRET )を使用してシークレットの値を読み込むことができます。 シークレットを環境変数として読み込む場合 参考: gcloud run deploy 動作確認 curl コマンドやブラウザを使用して、env-secret サービスにアクセスしてみます。 # env-secret の URL にアクセスする $ curl $( gcloud run services describe env-secret \ --project = ${PROJECT_ID} \ --region = ${REGION} \ --format =' value(status.url) ' ) 環境変数から読み込まれたシークレットの値を含む、以下のレスポンスが返ってきます。 Environment Secret: hello ボリュームマウントを使用したアクセス サンプルコード(Go) 次に、シークレットを Cloud Run のコンテナインスタンスにボリュームマウントし、ファイルシステムからシークレットの値を読み込む方法を試してみます。 以下のコード( main.go )は、 /mnt ディレクトリにマウントしたシークレットの値を読み込み、表示するだけのウェブサーバーを実行します。 // main.go package main import ( "fmt" "net/http" "os" ) func main() { http.HandleFunc( "/" , func (w http.ResponseWriter, r *http.Request) { // Read the secret from the file /mnt/secret secretVal, err := os.ReadFile( "/mnt/secret" ) if err != nil { fmt.Fprintf(w, "Error reading secret: %v" , err) return } fmt.Fprintf(w, "Mount Secret: %s" , secretVal) }) http.ListenAndServe( ":8080" , nil ) } コンテナイメージのビルド main.go があるディレクトリで以下のコマンドを実行し、コンテナイメージをビルドします。イメージ名は mnt-secret とします。 # Cloud Build で Buildpack を使用してコンテナイメージをビルドする $ gcloud builds submit --pack image =asia-northeast1-docker.pkg.dev/ ${PROJECT_ID} / ${REPO_NAME} /mnt-secret Cloud Run のデプロイ サービス名をコンテナイメージと同じ mnt-secret として、新たな Cloud Run サービスをデプロイします。 # Secret をボリュームマウントする Cloud Run サービスをデプロイする $ gcloud run deploy mnt-secret \ --image = ${REGION} -docker.pkg.dev/ ${PROJECT_ID} / ${REPO_NAME} /mnt-secret \ --project = ${PROJECT_ID} \ --region = ${REGION} \ --service-account = ${SERVICE_ACCOUNT_NAME} @ ${PROJECT_ID} .iam.gserviceaccount.com \ --allow-unauthenticated \ --set-secrets = /mnt/ secret =mysecret:latest シークレットをボリュームマウントする場合、 --set-secrets フラグを使用して、以下の形式で設定することができます。 --set-secrets={マウントするパス}={シークレットの名前}:{シークレットのバージョン} シークレットは Cloud Run の環境変数ではなく、ボリュームとしてマウントされています。当記事の設定の場合、マウントパス /mnt/secret からシークレットの値を読み込むことができます。 シークレットをボリュームマウントする場合 動作確認 curl コマンドやブラウザを使用して、mnt-secret サービスにアクセスしてみます。 # mnt-secret の URL にアクセスする $ curl $( gcloud run services describe mnt-secret \ --project = ${PROJECT_ID} \ --region = ${REGION} \ --format =' value(status.url) ' ) ボリュームマウントされたシークレットの値を含む、以下のレスポンスが返ってきます。 Mount Secret: hello シークレット更新時の動作検証 シークレット更新前の確認 シークレットの読み込み方法ごとの、シークレット更新時の動作を確認してみます。 まず、シークレット更新前にそれぞれのサービスにアクセスし、コンテナインスタンスを起動状態にします。 # env-secret の URL にアクセスする $ curl $( gcloud run services describe env-secret \ --project = ${PROJECT_ID} \ --region = ${REGION} \ --format =' value(status.url) ' ) # mnt-secret の URL にアクセスする $ curl $( gcloud run services describe mnt-secret \ --project = ${PROJECT_ID} \ --region = ${REGION} \ --format =' value(status.url) ' ) シークレットの更新 シークレットの新しい値を記述したファイルを用意します。 # シークレットの値を記述したファイルを作成する $ echo " world " > newsecret.txt 以下のコマンドで、シークレットに新しいバージョンを追加します。 # シークレットを更新する $ gcloud secrets versions add mysecret \ --project = ${PROJECT_ID} \ --data-file = newsecret.txt Cloud Run からはシークレットの latest バージョンを参照するようにしているため、サービスを編集することなくシークレットの更新が自動で反映されます。 動作確認 シークレットをボリュームマウントしたサービスの動作 先に、mnt-secret の動作確認を行います。以下のコマンドでサービスにアクセスします。 # mnt-secret の URL にアクセスする $ curl $( gcloud run services describe mnt-secret \ --project = ${PROJECT_ID} \ --region = ${REGION} \ --format =' value(status.url) ' ) レスポンスを確認すると、以下のように更新後のシークレットの値が表示されます。このように、 シークレットをボリュームマウントした場合はシークレットの値は常に最新のものが読み込まれます。 Mount Secret: world シークレットを環境変数として読み込むサービスの動作 env-secret の動作確認を行います。以下のコマンドでサービスにアクセスします。 # env-secret の URL にアクセスする $ curl $( gcloud run services describe env-secret \ --project = ${PROJECT_ID} \ --region = ${REGION} \ --format =' value(status.url) ' ) レスポンスを確認すると、以下のように 更新前 のシークレットの値が表示されます。 シークレットの値はコンテナインスタンス起動時に環境変数として読み込まれる ため、起動中のコンテナインスタンスは更新前の値を使用してしまいます。 Environment Secret: hello しばらく待機し、コンテナインスタンスがすべて停止したあと改めてサービスにアクセスすると、更新後のシークレットが読み込まれることがわかります。 Environment Secret: world 佐々木 駿太 (記事一覧) G-gen最北端、北海道在住のクラウドソリューション部エンジニア 2022年6月にG-genにジョイン。Google Cloud Partner Top Engineer 2025 Fellowに選出。好きなGoogle CloudプロダクトはCloud Run。 趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。 Follow @sasashun0805
アバター
G-gen の杉村です。Google Cloud の Cloud Run functions を使い、Slack のスラッシュコマンドを作ってみました。主に Google Cloud 側の開発に関する概要を解説します。 はじめに 当記事について 免責事項 構成 構成図 レシーバー関数とバックエンド関数を分ける理由 Slack の署名検証 Slack へのメッセージ返信 レシーバー関数の開発 Slack からの HTTP リクエスト ソースコード Pub/Sub クライアントの生成 Slack からの署名を検証 Slack からのリクエスト body を取得 環境変数からトピック ID を取得 エラーメッセージ バックエンド関数の開発 Pub/Sub トリガー関数のデプロイ Pub/Sub から受け取るメッセージ ソースコード Pub/Sub メッセージの取得 response_url への返信 Slack 側の設定 はじめに 当記事について Google Cloud(旧称 GCP)の Cloud Run functions で Slack のスラッシュコマンドを開発した際の事例を紹介します。なお当記事では Slack アプリの設定方法の詳細などは解説せず、Cloud Run functions 側のソースコードを中心に解説します。 Cloud Run functions (旧称 Cloud Functions)は、サーバーレスなプログラム実行基盤です。ソースコードを開発してアップロードするだけで、最長60分間(第2世代、HTTP 関数の場合)のプログラム実行が可能です。詳細は以下の記事をご参照ください。 blog.g-gen.co.jp スラッシュコマンド とは、Slack から / で始まるコマンドを実行することで、様々なタスクを実行できる Slack の機能です。組み込み済みのスラッシュコマンドの例として、指定した時間にユーザーにリマインダー通知をしてくれる /remind などがあります。ユーザーはバックエンドプログラムを用意することで、独自のカスタムコマンドを定義できます。 参考 : Enabling interactivity with Slash commands 参考 : 組み込みショートカット 免責事項 当記事で紹介するプログラムのソースコードは、ご自身の責任のもと、使用、引用、改変、再配布して構いません。 ただし、同ソースコードが原因で発生した不利益やトラブルについては、当社は一切の責任を負いません。 当記事で紹介するプログラムのソースコードは検証のために作成されたものであり、セキュリティやエラーハンドリング等の運用性が十分考慮されたものではありません。利用する際はこれらを十分考慮の上、ご自身の状況にあわせてご利用ください。 構成 構成図 当記事では、以下のような環境を開発しました。 Slack にはアプリを設定し、スラッシュコマンドから呼び出せるように設定します。スラッシュコマンドのバックエンドプログラムとして、Slack からのリクエストを受け取る「レシーバー関数」を配置します。レシーバー関数はメッセージキューである Pub/Sub トピックにメッセージを送信します。メッセージを検知すると、「バックエンド関数」が起動します。バックエンド関数はメインの処理を行い、Slack に返信を返します。 構成図 レシーバー関数とバックエンド関数を分ける理由 途中にメッセージキューを挟み、レシーバー関数とバックエンド関数を分けている理由は、スラッシュコマンドのタイムアウト仕様にあります。スラッシュコマンドは、バックエンドプログラムに処理を送ってから 3秒以内 に HTTP 200のレスポンスを受け取らないと、タイムアウトしてエラー終了します。 これを防ぐため、まずレシーバー関数でスラッシュコマンドを受け取り、いったんメッセージキューに処理要求を送ってから、Slack に HTTP 200を返します。これにより、バックエンド関数は3秒以上の処理を行うことができます。なおバックエンド関数は返信先のチャンネルやユーザーを、メッセージ内の情報から知ることができます。 なお、Cloud Run functions がコールドスタート(ゼロスケールから最初のコンテナインスタンスが起動するまでの遅延)する際に3秒のタイムアウトに抵触する場合があります。コールドスタート時の初回レスポンスを早くするには、function の割り当て CPU 量を増やしたり、重い処理を避けたり、Python の場合は不要な import を避けるなどの対策をしてください。 Slack の署名検証 Slack のスラッシュコマンドがバックエンドプログラムに HTTP リクエストを送信するとき、Slack は Signing Secret を使ってリクエストを署名し、 x-slack-signature ヘッダーに格納します。Signing Secret は Slack アプリごとに発行されます。この署名をバックエンドプログラム側(当環境ではレシーバー関数)で検証することで、リクエストが確かに想定した Slack アプリから発信されていることを確かめられます。これにより、想定しない利用者からのリクエストを拒否することができます。 当環境では、Signing Secret を Secret Manager に格納して Cloud Run functions から参照しています。Signing Secret は、Slack アプリ作成後に「Basic Information」欄から取得できます。 参照 : Verifying requests from Slack この署名検証があるため、Cloud Run functions に認証をかける必要はありません。Cloud Run functions は未認証リクエスト許可する HTTP トリガー関数としてデプロイします。 Slack へのメッセージ返信 Slack からバックエンドプログラムに送信される HTTP リクエストには、channel_id、user_id、command(スラッシュコマンドのコマンドライン)、text(コマンドラインに付加されたパラメータ)などに加え、 response_url と呼ばれる HTTP エンドポイント URL が含まれています。 この response_url は、スラッシュコマンドが実行されるたびにユニークに発行される一時的な URL です。30分間のみ有効で、この URL に対して POST リクエストを送信することで、認証なしで、スラッシュコマンドの実行者にだけ見える形式で表示されます(「 あなただけに表示されています 」)。 後者が response_url で投稿されたコメント 当環境ではこの response_url を使い、Slack の認証情報(トークン)を保持することなく、バックエンド関数から Slack にコメントを投稿しています。 なお全員から見える通常のコメントとして返信したい場合は、OAuth トークンを使い認証したうえでコメントを投稿します。 参照 : Handling user interaction in your Slack apps レシーバー関数の開発 Slack からの HTTP リクエスト Slack のスラッシュコマンドからレシーバー関数に送られる HTTP POST リクエストの body は、以下のようになります(Slack 公式ドキュメントから引用)。 token =gIkuvaNzQIHg97ATvDxqgjtO & team_id =T0001 & team_domain =example & enterprise_id =E0001 & enterprise_name =Globular%20Construct%20Inc & channel_id =C2147483705 & channel_name =test & user_id =U2147483697 & user_name =Steve & command= /weather & text = 94070 & response_url =https://hooks.slack.com/commands/ 1234 / 5678 & trigger_id = 13345224609 . 738474920 .8088930838d88f008e0 & api_app_id =A123456 参考 : Enabling interactivity with Slash commands - 2. Preparing your app to receive commands このうち、 command=/weather の部分が入力されたコマンド本体で、 text の部分がそれに続いて入力された引数です。 response_url が、返信に使える response_url であり、この URL に以下のように POST リクエストを送ることで、チャンネルに返信することができます。 POST https://hooks.slack.com/commands/ 1234 / 5678 Content-type: application/json { " text " : " 返信内容のテキスト " } ソースコード 以下は、レシーバー関数のソースコードです。前掲の「免責事項」をご確認のうえご利用ください。 GitHub - slack-slash-commands-with-cloud-run-functions/backend-example/ なお、ソースコードは Python 3.12.3 の環境で開発されています。 以下で、重要なポイントのみを解説します。 Pub/Sub クライアントの生成 28-30行目 # 環境変数の取得、Pub/Sub クライアントの生成 PROJECT_ID = os.environ.get( "PROJECT_ID" , None ) PUBSUB_CLIENT = google.cloud.pubsub_v1.PublisherClient() PUBSUB_CLIENT をグローバルスコープで生成しています。コストが高い代わりに結果を再利用できる処理は、グローバルスコープで実行することで、Cloud Run functions のコンテナインスタンスが残っている限り再利用できるため、パフォーマンスが向上します。 参考 : グローバル変数を使用して将来の呼び出しでオブジェクトを再利用する Slack からの署名を検証 33-40行目 # Slack からの署名を検証する関数 def verify_signature (request): request.get_data() verifier = SignatureVerifier(os.environ[ "SLACK_SIGNING_SECRET" ]) if not verifier.is_valid_request(request.data, request.headers): raise ValueError ( "Invalid request/credentials." ) Slack からの署名を検証するために、関数 verify_signature を呼び出しています。同関数では、Cloud Run functions 環境変数 SLACK_SIGNING_SECRET を取得し、POST リクエストの署名を検証して、正当な署名を確認できなければ ValueError を返します。 SLACK_SIGNING_SECRET は環境変数に直接定義するのではなく、Secret Manager から取得するのが望ましいでしょう。 参考 : シークレットを構成する なお、この関数の実装は Google Cloud が公開するチュートリアルドキュメントとソースコードを参考にしました。使用するライブラリは Slack 公式の slackclient です。 参考 : Slack のチュートリアル - スラッシュ コマンド 参考 : PyPI - Python slackclient また、この関数のを呼び出し元の50-62行目では、テストモードのときに例外を無視するコードを入れています。これは functions_framework を使いローカルでテストする場合を想定しています。 blog.g-gen.co.jp Slack からのリクエスト body を取得 64-66行目 # Slack からのリクエストを辞書型変数と JSON に格納 body_dict = request.form.to_dict(flat= True ) body_json = json.dumps(body_dict) この部分で、POST リクエストの body を辞書型変数および JSON 形式の文字列として変数に格納しています。このレシーバー関数では、Slack からのリクエスト body を JSON 形式にしてそのまま Pub/Sub にパブリッシュしています。JSON は、のちにバックエンド関数がパースして処理に使います。 環境変数からトピック ID を取得 69-72行目 # コマンド名に応じた環境変数から Pub/Sub トピック ID を取得 command = body_dict[ "command" ].lstrip( "/" ).replace( "-" , "_" ).upper() ENV_NAME = f "TOPIC_ID_{command}" TOPIC_ID_FOR_COMMAND = os.environ.get(ENV_NAME, None ) レシーバー関数を、複数のスラッシュコマンドとバックエンド関数のために使い回せる汎用的なものにするために、リクエスト内のスラッシュコマンドに応じた Pub/Sub トピック ID を取得できるようにしています。規模が大きくなればコマンド名とトピック ID の対応を Firestore などのデータベースに保持しても良いですが、ここでは簡略化のために環境変数に保持しています。 エラーメッセージ 74-77行目 # 環境変数が定義されていない場合はエラー終了。Slack にメッセージを返すため 200 で終了 if TOPIC_ID_FOR_COMMAND is None : logger.exception(f "環境変数 {ENV_NAME} が設定されていません。" ) return f ":warning: コマンド {body_dict['command']} は未対応です。" , 200 87-89目 except Exception as e: # Slack にメッセージを返すため 200 で終了 logger.exception(e) return f ":bomb: 予期せぬエラーが発生しました。エラーメッセージ : {e}" , 200 ここで、エラー(例外)であるにも関わらずレスポンスのステータスコードとして 200 を使用しているのには理由があります。Slack のスラッシュコマンドでは、バックエンドプログラムが 200 以外のステータスコードを返した場合、関数からのレスポンスは Slack チャンネル側に表示されず、 /(コマンド名) はエラー「dispatch_failed」により失敗しました というメッセージに統一されてしまいます。 ここでは Slack 側に任意のメッセージを返すために、ステータスコードを 200 としています。逆に認証エラーやメソッド違反の場合は、Slack にメッセージを返すことが適切ではありませんので、400番台のステータスコードを返しています。 ステータスコード 200 でレスポンスした場合 ステータスコード 400 でレスポンスした場合 なお上記のスクリーンショットからわかるように、バックエンドプログラムからのレスポンスはコマンドの実行者にだけ見える形式で表示されます(「 あなただけに表示されています 」)。 バックエンド関数の開発 Pub/Sub トリガー関数のデプロイ レシーバー関数が Pub/Sub にパブリッシュしたメッセージをトリガーとしてバックエンド関数を起動するには、バックエンド関数を Pub/Sub トリガーの関数としてデプロイします。gcloud コマンドでのデプロイ方法を例に挙げると、以下のようになります。 FUNCTION = " backend-sample " PROJECT_ID = " my-project " TOPIC_ID = " backend-sample " TRIGGER_SA = " receive-slash-command " gcloud functions deploy ${FUNCTION} \ --gen2 \ --project = ${PROJECT_ID} \ --region = asia-northeast1 \ --runtime = python312 \ --memory = 128Mi \ --entry-point = main \ --trigger-topic = ${TOPIC_ID} \ --trigger-service-account =" ${TRIGGER_SA} @ ${PROJECT_ID} .iam.gserviceaccount.com " このコマンドを使ってデプロイすると、Eventarc トリガーというオブジェクトが作成されます。この Eventarc トリガーが、 --trigger-topic で指定した Pub/Sub トピックとCloud Run functions を仲介して、関数を起動します。Eventarc トリガーは --trigger-service-account で指定したサービスアカウントの認証情報を利用して関数を起動しますので、このサービスアカウントには Cloud Run サービス起動元( roles/run.servicesInvoker )ロールが必要です。ここでは、レシーバー関数にアタッチしたサービスアカウントを使うように指定していますが、独立したサービスアカウントを作成しても構いません。 Pub/Sub から受け取るメッセージ バックエンド関数は、以下のようなメッセージを Pub/Sub から受信し、main 関数の引数の cloud_event として受け取ります。 [ { " ackId ": " BhYsXUZIUTcZCGhRDk9eIz81IChFFwkDxxxxx.... ", " message ": { " data ": " ewogICJ0b2tlbiI6ICJnSWt1dmFOelFJSGc5N0FUdkR4cWdqdE8iLAogICJ0ZWFtX2lkIjogIlQw MDAxIiwKICAidGVhbV9kb21haW4iOiAiZXhhbXBsZSIsCiAgImNoYW5uZWxfaWQiOiAiQzIxNDc0 ODM3MDUiLAogICJjaGFubmVsX25hbWUiOiAidGVzdCIsCiAgInVzZXJfaWQiOiAiVTIxNDc0ODM2 OTciLAogICJ1c2VyX25hbWUiOiAiU3RldmUiLAogICJjb21tYW5kIjogIi93ZWF0aGVyIiwKICAi dGV4dCI6ICI5NDA3MCIsCiAgImFwaV9hcHBfaWQiOiAiQTEyMzQ1NiIsCiAgImlzX2VudGVycHJp c2VfaW5zdGFsbCI6ICJmYWxzZSIsCiAgInJlc3BvbnNlX3VybCI6ICJodHRwczovL2hvb2tzLnNs YWNrLmNvbS9jb21tYW5kcy8xMjM0LzU2NzgiLAogICJ0cmlnZ2VyX2lkIjogIjEzMzQ1MjI0NjA5 LjczODQ3NDkyMC44MDg4OTMwODM4ZDg4ZjAwOGUwIiwKfQo =", " messageId ": " 13511712435836909 ", " publishTime ": " 2025-01-12T05:21:28.259Z " } } ] data の内容は base64 エンコードされています。上記の data を base64 でデコードすると、以下のような JSON になります。Slack からのリクエスト body が、そのまま JSON になっています。バックエンド関数では、これをパースすればよいことになります。 { " token ": " gIkuvaNzQIHg97ATvDxqgjtO ", " team_id ": " T0001 ", " team_domain ": " example ", " channel_id ": " C2147483705 ", " channel_name ": " test ", " user_id ": " U2147483697 ", " user_name ": " Steve ", " command ": " /weather ", " text ": " 94070 ", " api_app_id ": " A123456 ", " is_enterprise_install ": " false ", " response_url ": " https://hooks.slack.com/commands/1234/5678 ", " trigger_id ": " 13345224609.738474920.8088930838d88f008e0 " , } ソースコード 以下は、バックエンド関数のソースコードです。前掲の「免責事項」をご確認のうえご利用ください。 GitHub - slack-slash-commands-with-cloud-run-functions/backend-example/ 以下、重要なポイントのみ解説します。 Pub/Sub メッセージの取得 28-32行目 @ functions_framework.cloud_event def main (cloud_event): Pub/Sub から受け取ったメッセージの data を JSON として取得して辞書型に変換 request = base64.b64decode(cloud_event.data[ "message" ][ "data" ]).decode() request_dict = json.loads(request) ここでは前述のとおり、Pub/Sub から受け取ったメッセージを base64 デコードして、辞書型変数として格納しています。 response_url への返信 45-48行目 # response_url に対して返信 headers = { 'Content-type' : 'application/json' } data = { 'text' : post_text} requests.post(response_url, headers=headers, data=json.dumps(data)) ここでは、response_url に対して HTTP POST リクエストを送信して、Slack チャンネルにコメントを投稿しています。 Content-type を application/json にし、 {'text': '投稿する内容'} とするのが決まりです。response_url は30分間限定で認証なしでコメントを受け付ける URL なので、Slack の認証情報は必要ありません。 前者がレシーバー関数からのレスポンス、後者がバックエンド関数から投稿されたコメント ただし、この response_url を使って送信された返信は、コマンド実行者にだけ「あなただけに表示されています」と表示されるメッセージです。チャンネル全体に見えるコメントを投稿するには、OAuth トークンを使って Slack API に対してコメントを投稿します。その方法はこの記事では詳細は解説しませんが、公式ドキュメント等をご参照ください。 参考 : Send or schedule a message Slack 側の設定 Slack 側の設定については、インターネット上に多くの解説があるため、当記事では深く触れません。大まかに言うと、以下の手順となります。 Slack アプリを作成(作成後、Signing Secret 等が取得可能になる) アプリにスラッシュコマンドを追加 Slack ワークスペースにアプリをインストール 以下の公式ドキュメントも参考にしてください。 参考 : Slack - Enabling interactivity with Slash commands 参考 : Google Cloud - Slack のチュートリアル - スラッシュ コマンド 杉村 勇馬 (記事一覧) 執行役員 CTO / クラウドソリューション部 部長 元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 12資格、Google Cloud認定資格11資格。X (旧 Twitter) では Google Cloud や AWS のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-gen の杉村です。Google ドライブの 共有ドライブ でファイルやフォルダを、他の共有ドライブやマイドライブに移動するために必要な権限について紹介します。 概要 はじめに 共有ドライブの権限 同一共有ドライブ内 マイドライブから共有ドライブ 共有ドライブからマイドライブ 共有ドライブ間 概要 はじめに 当記事では、Google ドライブの 共有ドライブ でファイルやフォルダを、他の共有ドライブやマイドライブに移動するために必要な権限について紹介します。 移動する対象がファイルであるか、フォルダであるかによって、必要な権限が異なります。また、移動元や移動先がマイドライブであるか、共有ドライブであるかによっても異なります。 公式ドキュメントには、マイドライブから共有ドライブへファイルやフォルダを移動するときに必要な権限については記載があります。しかし、逆に共有ドライブからマイドライブへの移動の場合や、共有ドライブから他の共有ドライブへの移動の場合については、記載がありません。そのため当記事では、当社で実施した検証の内容も含まれます(検証は2025年2月に実施)。 参考 : 組織のコンテンツを共有ドライブに移動する 参考 : 共有ドライブにファイルやフォルダを移動する 共有ドライブの権限 共有ドライブには、 メンバー として、Google アカウントや Google グループを追加できます。その際に、閲覧者、閲覧者(コメント可)、投稿者、コンテンツ管理者、管理者の中から、メンバーに与える権限を選択します。 共有ドライブの権限 各権限では、以下のような作業を行うことができます。 名称 含まれる権限の概要 閲覧者 ファイルやフォルダの閲覧 閲覧者(コメント可) 上記に加え、コメントの追加 投稿者 上記に加え、ファイルやフォルダの新規作成、 編集、ファイルへの権限追加 コンテンツ管理者 上記に加え、ファイルやフォルダの削除、 共有ドライブ内でのファイルやフォルダの移動、 フォルダへの権限追加 管理者 上記に加え、ほとんどの権限 参考 : 共有ドライブのファイルへのアクセスの仕組み 同一共有ドライブ内 1つの共有ドライブの中でファイルやフォルダを移動するには、 コンテンツ管理者 権限が必要です。 共有ドライブに対してコンテンツ管理者権限を持っていれば、その共有ドライブ内で自由にファイルやフォルダを移動可能です。 マイドライブから共有ドライブ ファイル をマイドライブから共有ドライブへ移動するには、移動先の共有ドライブに 投稿者以上 の権限が必要です。移動元は、自分のマイドライブのほか、編集者権限が付与されていれば他人のマイドライブのファイルも移動できます。 移動先\移動元 自分のマイドライブ 他人のマイドライブ(共有アイテム) 管理者 ◯ ◯ コンテンツ管理者 ◯ ◯ 投稿者 ◯ ◯ 一方で フォルダ の場合は、移動先の共有ドライブに 管理者 の権限が必要です。ファイルの場合は投稿者以上があれば十分でしたが、フォルダの移動にはより強い権限が必要になっています。 移動先\移動元 自分のマイドライブ 他人のマイドライブ(共有アイテム) 管理者 ◯ ◯ コンテンツ管理者 ✕ ✕ 投稿者 ✕ ✕ 共有ドライブからマイドライブ ファイルやフォルダを共有ドライブからマイドライブへ移動するには、移動元の共有ドライブに 管理者 の権限が必要です。移動先としては自分のマイドライブが選択できるほか、自分に編集者が付与されていれば他人のマイドライブにあるフォルダも選択できます。 移動先\移動元 管理者 コンテンツ管理者 投稿者 自分のマイドライブ ◯ ✕ ✕ 他人のマイドライブ(共有されたフォルダ) ◯ ✕ ✕ 移動の対象がファイルであるかフォルダであるかによって、必要な権限は変わりません。 共有ドライブ間 ファイル を共有ドライブから別の共有ドライブへ移動するには、移動元の共有ドライブには 管理者 権限が、移動先の共有ドライブには 投稿者以上 の権限が必要です。 移動先\移動元 管理者 コンテンツ管理者 投稿者 管理者 ◯ ✕ ✕ コンテンツ管理者 ◯ ✕ ✕ 投稿者 ◯ ✕ ✕ 移動の対象が フォルダ の場合、共有ドライブから別の共有ドライブへ移動するには、移動元と移動先の両方に 管理者 の権限が必要です。ファイルの場合は、移動先の共有ドライブには投稿者以上の権限があれば十分だったのに対して、フォルダの場合はより強い権限が必要です。 移動先\移動元 管理者 コンテンツ管理者 投稿者 管理者 ◯ ✕ ✕ コンテンツ管理者 ✕ ✕ ✕ 投稿者 ✕ ✕ ✕ なお、移行元の共有ドライブの権限が投稿者である場合、「移動」のメニューがグレーアウトしていて選択できません。投稿者には、そもそもファイルやフォルダの移動権限がないためです。 投稿者で移動を試みた場合 移行元にコンテンツ管理者を持っている場合、「移動」自体は選択できるものの、移動先の選択ダイアログで他の共有ドライブがグレーアウトされて選択できないようになっています。 コンテンツ管理者で移動を試みた場合 なお当記事で紹介したファイル移動は、 異なる Google Workspace 組織(ドメイン)間 でも実行可能です。 杉村 勇馬 (記事一覧) 執行役員 CTO / クラウドソリューション部 部長 元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 12資格、Google Cloud認定資格11資格。X (旧 Twitter) では Google Cloud や AWS のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-gen の杉村です。2025年1月のイチオシ Google Cloud(旧称 GCP)アップデートをまとめてご紹介します。記載は全て、記事公開当時のものですのでご留意ください。 はじめに 2つの新しい Google Cloud 認定資格が一般公開(GA)に Vertex AI RAG Engine が一般公開(GA) Vertex AI Search for retail が 〜 for commerce に改名 Cloud Run からコンテナイメージの暗黙的な読み取り権限が終了 Cloud Run jobs でサイドカーコンテナのデプロイが可能に(Preview) VPC で RDMA 対応 NIC が使用可能に Google Workspace で AI 機能が標準に。同時に大幅な料金改定 Compute Engine で C4A インスタンスタイプが登場 BigQuery Data Transfer Service が MySQL と PostgreSQL に対応(Preview) BigQuery でコンソール画面から個人別の設定が可能に BigQuery metastore が Public Preview 公開 Gemini in BigQuery の有償化が延期 Gemini サイドパネルで日本語での画像生成が可能に Google Sheets の Gemini でデータ説明やチャート生成が可能に Spanner に index advisor が登場(GA) Imagen 3 の新バージョン「imagen-3.0-generate-002」 Cloud DNS で DNS64 機能が Preview 公開 はじめに 当記事では、毎月の Google Cloud(旧称 GCP)や Google Workspace(旧称 GSuite)のアップデートのうち、特に重要なものをまとめます。 また当記事は、Google Cloud に関するある程度の知識を前提に記載されています。前提知識を得るには、ぜひ以下の記事もご参照ください。 blog.g-gen.co.jp リンク先の公式ガイドは、英語版で表示しないと最新情報が反映されていない場合がありますためご注意ください。 2つの新しい Google Cloud 認定資格が一般公開(GA)に Google Cloud 認定資格 (2025-01) 以下の2つの新しい Google Cloud 認定資格が一般公開(GA)になった。いずれも Associate レベルの試験。 Associate Google Workspace Administrator Associate Data Practitioner いずれも、G-gen Tech Blog で対策記事が公開されている。 blog.g-gen.co.jp blog.g-gen.co.jp Vertex AI RAG Engine が一般公開(GA) Introducing Vertex AI RAG Engine: Scale your Vertex AI RAG pipeline with confidence (2025-01-10) Vertex AI RAG Engine が一般公開(GA)。Gemini 等を使った生成 AI アプリケーションから RAG を行うための API。 Cloud Storage、Google ドライブ、Vertex AI Search データストア等の情報を使ってグラウンディング。 Vertex AI RAG Engine Vertex AI Search for retail が 〜 for commerce に改名 Vertex AI Search for commerce release notes - January 10, 2025 (2025-01-10) Vertex AI Search for retail が改名して「Vertex AI Search for commerce」になった。かつては Retail Search と呼ばれていた。名称変遷は Retail Search → Vertex AI Search for retail(VAISR)→ Vertex AI Search for commerce。 Vertex AI Search for commerce は、EC サイトなど小売向けの検索エンジン。商品カタログをもとに意味論検索を実装できる。 Cloud Run からコンテナイメージの暗黙的な読み取り権限が終了 Cloud Run release notes - January 13, 2025 (2025-01-13) 以前から予告されていたとおり、Cloud Run 管理者ロールとCloud Run デベロッパーロールがもともと持っていた Artifact Registry のコンテナイメージに対する暗黙的な読み取り権限が消滅した。 適切に対応していないと、CI/CD パイプラインなどが権限不足でエラー終了する可能性がある。詳細は以下の記事を参照。 blog.g-gen.co.jp Cloud Run jobs でサイドカーコンテナのデプロイが可能に(Preview) Deploy multiple containers to a job (sidecars) (2025-01-14) Cloud Run jobs でサイドカーコンテナのデプロイが可能に(Preview)。 これまでは Cloud Run services のみ、サイドカーコンテナに対応していた。Prometheus によるモニタリングなどがユースケース。 VPC で RDMA 対応 NIC が使用可能に RDMA network profile (2025-01-15) Google Cloud の VPC で RDMA 対応 NIC が使えるようになった。 RDMA(Remote Direct Memory Access)とは、別々の筐体に搭載されたメモリ間で、ネットワークを経由し、かつ CPU や OS をバイパスして直接データを転送する技術。HPC や AI ワークロードで、分散処理のための高速なメモリ間データ共有に使われる。 Google Workspace で AI 機能が標準に。同時に大幅な料金改定 Google Workspace Business エディションの AI 機能と料金改定 (2025-01-16) Business Starter や Enterprise Starter など一部のエディションを除き、AI 機能(Gemini for Google Workspace)がアドオンライセンス不要になる。これにより Gmail や Docs、Sheets、Meet などでの Gemini 機能が標準になる。また、Gemini Advanced とのチャット、Gems、Notebook LM Plus なども含まれる。 機能は順次ロールアウト。 これにより Gemini アドオンライセンスは2025年1月31日以降、請求されなくなる。 また、Google Workspace ライセンスが全体的に価格改定される。 Compute Engine で C4A インスタンスタイプが登場 C4A machine series (2025-01-16) Compute Engine で C4A インスタンスタイプが登場(GA)。 Google が開発した Arm ベースの CPU である Axion を搭載。まず Singapore、Iowa リージョン等で利用可能に。東京・大阪未対応。 BigQuery Data Transfer Service が MySQL と PostgreSQL に対応(Preview) What is BigQuery Data Transfer Service? (2025-01-17) BigQuery Data Transfer Service で MySQL と PostgreSQL をデータ転送元としてサポート(Preview)。これらの DB から BigQuery へ容易にデータ転送ジョブを設定できる。 BigQuery Data Transfer Service が他に対応しているデータソースは、Cloud Storage、Azure Blob Storage、Amazon S3、Amazon Redshift、Oracle、Salesforce、Salesforce Marketing Cloud など。 BigQuery でコンソール画面から個人別の設定が可能に BigQuery release notes - January 17, 2025 (2025-01-17) BigQuery でコンソール画面(BigQuery Studio)から個人別の設定が可能に(Preview)。 組織やプロジェクトから継承されたデフォルト設定値をオーバーライドできる。デフォルトロケーション、キャッシュ無効化、バイト数制限、Gemini 補助有効化などを設定可能。 BigQuery metastore が Public Preview 公開 Introducing BigQuery metastore, a unified metadata service with Apache Iceberg support (2025-01-23) BigQuery metastore が Public Preview 公開。 Apache Spark、Hive、Iceberg 等に対応したメタデータ管理サービス。異なるメタストアのデータを BigQuery 側でテーブル再定義なしに統合管理してクエリ可能。 Gemini in BigQuery の有償化が延期 Gemini in BigQuery Pricing Overview (2025-01-27) Gemini in BigQuery の有償化は 2025-01-27 からと予告されていたが、無償期間が延長。 Gemini in BigQuery では、生成AIによるSQL生成やデータキャンバス、推奨事項などの機能が利用可能。いつまで延期されるかは明示されていない。 Gemini サイドパネルで日本語での画像生成が可能に Use Gemini in the side panel of Workspace apps to generate images in seven additional languages (2025-01-29) Gemini サイドパネルで日本語での画像生成が可能に。Gmail、ドキュメント、スプレッドシート、ドライブのサイドパネルが対象。 今後、順次ロールアウトされる。ただし Google スライドのサイドパネルでは、引き続き英語のみ対応のため注意。 Google Sheets の Gemini でデータ説明やチャート生成が可能に Generate charts and valuable insights using Gemini in Google Sheets (2025-01-29) Google スプレッドシートで Gemini によるデータのインサイト説明やチャート(図表)の生成が可能に。 スプシの中のデータにもとづき分析してくれたり、図や表を生成してくれる。今後、順次ロールアウトされる。 Spanner に index advisor が登場(GA) Use the Spanner index advisor (2025-01-30) Spanner に index advisor が登場(GA)。 クエリを分析して適切なセカンダリインデックスを推奨してくれる。GoogleSQL-dialect と PostgreSQL-dialect の両方のデータベースに対応。 Imagen 3 の新バージョン「imagen-3.0-generate-002」 Prompt enhancement using prompt rewriter (2025-01-30) Vertex AI で画像生成AIモデル Imagen 3 の新バージョン「imagen-3.0-generate-002」が使用可能になった。 Prompt enhancement 機能があり、自動的にプロンプトに詳細を追加して、画像生成の質を向上する。Prompt enhancement はデフォルトで有効化。 Cloud DNS で DNS64 機能が Preview 公開 DNS64 (2025-01-30) Cloud DNS で DNS64 機能が Preview 公開。 IPv6-only な Compute Engine VM が A レコードしかない名前を解決しようとすると、合成 IPv6 アドレスに解決され、Cloud NAT を通して IPv4 アドレスの宛先に通信できる。 杉村 勇馬 (記事一覧) 執行役員 CTO / クラウドソリューション部 部長 元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 12資格、Google Cloud認定資格11資格。X (旧 Twitter) では Google Cloud や AWS のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-gen の佐々木です。当記事では、 gcloud config set コマンドでデフォルトのリージョンやゾーンを設定する際に表示される警告メッセージについて解説します。 はじめに デフォルトのリージョン・ゾーン設定時の警告メッセージ 警告メッセージの意味 対処法 はじめに 当記事では、以下のバージョンの Google Cloud SDK で検証を実施しています。 $ gcloud version Google Cloud SDK 502 . 0 . 0 デフォルトのリージョン・ゾーン設定時の警告メッセージ gcloud config set コマンドでは、gloud コマンドを実行する際に指定するリージョンやゾーンなどのプロパティの デフォルト値 を事前に設定しておくことができます。 デフォルト値を設定しておくことで、 --region フラグや --zone フラグを省略してコマンドを実行することができます。 たとえば、以下のコマンドを実行することで、Cloud Run のリソースを操作(作成、更新、削除など)する際、デフォルト値に設定したリージョンを使いたい場合に限り --region フラグを指定する必要がなくなります。 # gcloud run コマンドのデフォルトのリージョンを設定 $ gcloud config set run/region asia-northeast1 Updated property [ run/region ] . ところで、gcloud config set コマンドでデフォルト値を設定しようとすると、以下のような警告が表示される場合があります。 WARNING: Property validation for compute/region was skipped. この警告文は、たとえば gcloud compute コマンドのデフォルトのリージョンやゾーンを設定する場合などに表示されます。 # gcloud compute コマンドのデフォルトのリージョンを設定 $ gcloud config set compute/region asia-northeast1 WARNING: Property validation for compute/region was skipped. Updated property [ compute/region ] . # gcloud compute コマンドのデフォルトのゾーンを設定 $ gcloud config set compute/zone asia-northeast1-b WARNING: Property validation for compute/zone was skipped. Updated property [ compute/zone ] . 警告は出るものの、デフォルトの値は問題なく設定されます。 # デフォルトの値を確認(出力抜粋) $ gcloud config list [ compute ] region = asia-northeast1 zone = asia-northeast1-b 警告メッセージの意味 このメッセージは、gcloud config set コマンドで指定した値が、実際に使用できる値かどうかの検証はされていない、ということを示しています。 たとえば、gcloud compute コマンドのデフォルトのリージョンとして、実際に存在しないリージョンを設定してみます。指定した値が正しいリージョン名かどうかは検証されないため、エラーは発生せず、デフォルトの値として設定できてしまいます。 # 存在しないリージョンをデフォルトのリージョンとして設定する $ gcloud config set compute/region hokkaido WARNING: Property validation for compute/region was skipped. Updated property [ compute/region ] . # 存在しないリージョンでも設定できてしまう(出力抜粋) $ gcloud config list [ compute ] region = hokkaido zone = asia -northeast1 -b ちなみに、コマンドによっては警告メッセージが出ない場合もあります。記事の冒頭に記載した gcloud run コマンドのデフォルトのリージョンを設定するコマンドでは。警告メッセージが出ません。 # gcloud run コマンドのデフォルトのリージョンを設定 $ gcloud config set run/region asia-northeast1 Updated property [ run/region ] . しかし、この場合でも、存在しないリージョンを設定できてしまいます。 # 存在しないリージョンをデフォルトのリージョンとして設定する $ gcloud config set run/region ggen-northeast1 Updated property [ run/region ] . # 警告が出ない場合もエラーが出ずに設定できてしまう(出力抜粋) $ gcloud config list [ run ] region = ggen-northeast1 対処法 警告メッセージはどうしても気になってしまいますが、設定値が正しくても誤っていても警告メッセージは表示されるため、気にする必要はありません。 たとえ設定値が誤っている場合でもコマンドは成功してしまいますので、十分に気をつけましょう。 利用可能なリージョンの名称は、 gcloud {サービス} regions list コマンドで確認できます。たとえば、Cloud Run が利用できるリージョンは以下のように確認できます。 # Cloud Run を利用できるリージョンの一覧を表示する $ gcloud run regions list NAME africa-south1 asia-east1 asia-east2 asia-northeast1 asia-northeast2 asia-northeast3 asia-south1 asia-south2 asia-southeast1 asia-southeast2 australia-southeast1 australia-southeast2 europe-central2 europe-north1 europe-southwest1 europe-west1 europe-west10 europe-west12 europe-west2 europe-west3 europe-west4 europe-west6 europe-west8 europe-west9 me-central1 me-central2 me-west1 northamerica-northeast1 northamerica-northeast2 southamerica-east1 southamerica-west1 us-central1 us-east1 us-east4 us-east5 us-south1 us-west1 us-west2 us-west3 us-west4 佐々木 駿太 (記事一覧) G-gen最北端、北海道在住のクラウドソリューション部エンジニア 2022年6月にG-genにジョイン。Google Cloud Partner Top Engineer 2025 Fellowに選出。好きなGoogle CloudプロダクトはCloud Run。 趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。 Follow @sasashun0805
アバター
G-gen の佐々木です。当記事では Kubernetes のためのオープンソースのログビューアである、 Kubernetes History Inspector を使用してみます。 Kubernetes History Inspector とは KHI に必要な IAM 権限 クエリの実行 KHI ファイルのインポート 事前準備 当記事で利用する環境 シェル変数の設定 Pod 用の ServiceAccount リソースの作成 Workload Identity Federation の設定 IAM ロールの付与 Pod のデプロイ KHI の Pod にアクセス KHI の操作 ログのクエリ ビューの表示 KHI ファイルのエクスポート・インポート Kubernetes History Inspector とは Kubernetes History Inspector (以下、 KHI )は Google Cloud が OSS(オープンソースソフトウェア)として公開している Kubernetes クラスタ用のログ可視化ツールです。 Kubernetes はシステムコンポーネントも含め非常に多くのログを出力するため、クラスタ上で問題が発生した際には、膨大なログとリソースの関連性を読み解く労力が必要です。 KHI を使用することで、クラスタから出力される大量のログをインタラクティブな GUI でクエリ・可視化し、問題のトラブルシューティングを効率的に行うことができます。 Kubernetes History Inspector の GUI KHI には以下の特徴があり、Google Cloud で Google Kubernetes Engine(GKE)を利用している環境では手軽に導入することができます。 クラスタに対するエージェント等の導入は不要(事前設定不要) GUI を使用した簡素なクエリ実行・ログの可視化 ログがバックエンド(Cloud Logging)に保存されている限り、過去に遡ったログの分析が可能 KHI ファイルを使用したクエリ結果の保存・共有 また、ログ可視化の対象は GKE だけでなく、Cloud Composer、GKE on AWS、GKE on Azure などの環境にも対応しています。 KHI は Google Cloud の商用プロダクトではなく、GitHub リポジトリでソースコードが公開されています。KHI は、Docker イメージもしくはソースコードから実行することができます。 GitHub - Kubernetes History Inspector KHI に必要な IAM 権限 クエリの実行 クエリの実行には、GKE クラスタのログが記録されている Cloud Logging に対する閲覧者権限が必要です。当記事では ログ閲覧者 ( roles/logging.viewer )ロールを付与した Google アカウントで操作しています。 Cloud Logging の閲覧権限がない場合、以下のようにクエリ実行時にエラーが出てしまいます。 Cloud Logging の閲覧権限がない場合、クエリが失敗する 当記事では Kubernetes Engine Cluster 閲覧者 ( roles/container.clusterViewer )ロールも使用しますが、こちらは必須ではありません。クラスタの閲覧権限があると、クエリ設定で対象クラスタを入力する際に、候補となるクラスタが表示されます。この権限がなくてもクラスタ名は手動で入力することができ、クエリの実行も成功します。 クラスタの閲覧権限がないと、クエリ対象のクラスタ候補が表示されない(クエリ実行は可能) KHI ファイルのインポート クエリした結果は KHI ファイル としてエクスポートすることで、クエリ結果の保存、共有を簡単に行うことができます。 KHI ファイルをインポートする際は Cloud Logging に対するクエリが実行されないため、 Cloud Logging の読み取り権限を持っていなくてもビュー(クエリ結果)を確認することができます 。つまり、KHI を実行することができる環境であれば、同じビューを表示できるということになります。 このことから、KHI ファイルはログを外部に共有する際に役立ちますが、エクスポートしたファイルの取り扱いには十分な注意が必要となります。 事前準備 当記事で利用する環境 当記事では、KHI の Docker イメージを使用して、GKE クラスタ上の Pod としてデプロイしていきます。 Kubernetes は以下のバージョンを使用しています。 $ kubectl version Client Version: v1. 29 . 2 Server Version: v1. 30 .8-gke. 1128000 シェル変数の設定 事前準備で何度か使用する値を、シェル変数として設定しておきます。 # シェル変数の設定 PROJECT_ID = { プロジェクトID } SERVICE_ACCOUNT =khi-serviceaccount NAMESPACE =default Pod 用の ServiceAccount リソースの作成 KHI は Cloud Logging からログを読み込むため、Pod 上で実行する場合は、Pod に紐付けるサービスアカウントに対して IAM 権限を付与する必要があります。 まず、GKE クラスタ上に Pod に紐付けるための ServiceAccount リソースを作成します。 # ServiceAccount リソースを作成 $ kubectl create serviceaccount ${SERVICE_ACCOUNT} Workload Identity Federation の設定 Workload Identity Federation を使用し、先ほど作成した ServiceAccount に対して IAM 権限を付与します。 GKE における Workload Identity Federation の詳細については、以下の記事をご一読ください。 blog.g-gen.co.jp もし Kubernetes History Inspector の Pod に default 以外の Namespace を使用する場合は、 NAMESPACE 変数の値も変更してください。 Workload Identity Federation の設定にはプロジェクト番号を使用する必要があるため、以下のコマンドでプロジェクト番号も取得して変数に設定しておきます。 # シェル変数にプロジェクト番号を設定する $ PROJECT_NUM = $( gcloud projects describe ${PROJECT_ID} --format =" value(projectNumber) " ) IAM ロールの付与 Workload Identity Federation を使用して、ServiceAccount に IAM ロールを付与していきます。 まず、ログ取得のための ログ閲覧者 ( roles/logging.viewer )ロールを付与します。 # ServiceAccout にログ閲覧者ロールを紐づけ $ gcloud projects add-iam-policy-binding projects/ ${PROJECT_ID} \ --role = roles/logging.viewer \ --member = principal://iam.googleapis.com/projects/ ${PROJECT_NUM} /locations/global/workloadIdentityPools/ ${PROJECT_ID} .svc.id.goog/subject/ns/ ${NAMESPACE} /sa/ ${SERVICE_ACCOUNT} また、ログ取得対象のクラスタの情報を取得するため、 Kubernetes Engine Cluster 閲覧者 ( roles/container.clusterViewer )ロールも付与します。前述したように、このロールは付与しなくても問題ありません。 # ServiceAccout に Kubernetes Engine Cluster 閲覧者ロールを紐づけ $ gcloud projects add-iam-policy-binding projects/ ${PROJECT_ID} \ --role = roles/container.clusterViewer \ --member = principal://iam.googleapis.com/projects/ ${PROJECT_NUM} /locations/global/workloadIdentityPools/ ${PROJECT_ID} .svc.id.goog/subject/ns/ ${NAMESPACE} /sa/ ${SERVICE_ACCOUNT} Pod のデプロイ 以下のマニフェストファイルを使用して、Kubernetes History Inspector を実行する Pod を GKE クラスタ上にデプロイします。 # khi-pod.yaml apiVersion : v1 kind : Pod metadata : name : khi-pod spec : serviceAccountName : khi-serviceaccount containers : - name : khi-container image : asia.gcr.io/kubernetes-history-inspector/release:latest ports : - containerPort : 8080 KHI の Pod にアクセス Kubernetes では、LoadBalancer や Ingress などのリソースを使用しなくても、ポートフォワードを使用して Service や Pod にアクセスすることができます。 以下のコマンドを実行し、 127.0.0.1:8080 から Kubernetes History Inspector の Pod にポートフォワードできるようにします。 $ kubectl port-forward pods/khi-pod 8080:8080 ブラウザから 127.0.0.1:8080 にアクセスすると、KHI の GUI が表示されます。 ブラウザから KHI の GUI にアクセスする KHI の操作 ログのクエリ ユーザーガイド に従って操作を進めていきます。 [New inspection] からログのクエリを行います。 [New inspection] を選択する 当記事では GKE のログをクエリするため、クラスタタイプとして「Google Kubernetes Engine」を選択します。 「Google Kubernetes Engine」を選択する 次の画面では、取得対象のログの種類を選択します。Kubernetes リソースの作成や GKE クラスタ自体の監査ログや、ワーカーノードのログ、コンテナ上のアプリケーションログなどのカテゴリから、必要となる種類のログをここで選択します。当記事ではデフォルトの設定値のまま進めていきます。 クエリ対象のログの種類を選択して [Next] を押下する 最後に、ログを取得する期間と、対象のプロジェクト、GKE クラスタ名、名前空間などの情報を設定します。 End time 項目で「いつまでのログを取得するか」を指定し、 Duration 項目で「Endtime に設定した時間からどれくらい遡ってログを取得するか」を指定します。 たとえば、Endtime に 2025-01-29T20:30:00+09:00 、Duration に 1h を設定すると、 2025-01-29T19:30:00+09:00 ~ 2025-01-29T20:30:00+09:00 のログを取得することになります。 ログ取得対象の期間を入力する 同じ画面で、対象の GKE クラスタや名前空間などの情報を入力します。プロジェクト ID を入力すると、候補となるクラスタの一覧が表示されます。 ログ取得対象のクラスタの情報を入力する [Run] を押下すると、ここまで入力した情報を元にクエリが実行されます。クエリが完了するまで待ちます。 クエリの実行状況が表示される クエリが完了したら、[Open] からビューを開きます。 [Open] からビューを開く ビューの表示 ビューは タイムラインビュー 、 ログビュー 、 ヒストリービュー の3つのコンポーネントから構成されています。 コンポーネント 説明 タイムラインビュー ログ取得時に指定した期間を タイムライン として帯状に表示し、クラスタ上のリソースごとのステータスやログの発生状況を可視化する。 ログビュー クラスタ上で発生したログの内容を表示する。タイムラインビューでリソースを選択すると、選択したリソースでフィルタリングされたログビューが表示される。 ヒストリービュー タイムラインビューで選択したリソースの変更履歴が差分表示される。 ビューのコンポーネント 例として、あらかじめクラスタにデプロイしていた Deployment リソースをタイムラインビューで選択し、ヒストリービューを確認してみます。ここでは事前にレプリカ数の変更を行っていたため、それを行った時刻・ユーザーの情報と、変更差分がヒストリービューに表示されています。 ヒストリービューの表示例 各コンポーネントの詳細な説明については、以下のユーザーガイドも参照してください。 Kubernetes History Inspector - ユーザーガイド KHI ファイルのエクスポート・インポート クエリした結果は KHI ファイル としてエクスポートすることで、クエリ結果の保存、共有を簡単に行うことができます。 メニュー画面から、対象のビューの KHI ファイルをエクスポートします。 メニュー画面から KHI ファイルをエクスポートする 過去のクエリ結果を削除するため、一度 KHI の Pod を削除してから再作成します。 メニュー画面から [Open .khi file] を選択し、先ほどエクスポートした KHI ファイルをインポートします。 [Open .khi file] から KHI ファイルをインポートする インポート後、クエリが実行されることなく、インポートしたビューが即座に表示されます。 佐々木 駿太 (記事一覧) G-gen最北端、北海道在住のクラウドソリューション部エンジニア 2022年6月にG-genにジョイン。Google Cloud Partner Top Engineer 2025 Fellowに選出。好きなGoogle CloudプロダクトはCloud Run。 趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。 Follow @sasashun0805
アバター
G-gen の杉村です。料金が安くなることを期待して Cloud Storage オブジェクトのオブジェクトクラス変更を実施したところ、料金が安くなるどころか逆に高くなってしまいました。この事象の原因と、対処方法をご共有します。 事象 原因 対処法 検証(手動でストレージクラスを変更) オブジェクトのアップロード ストレージクラスの変更 Soft delete 状態のオブジェクトの確認 削除ができないことを確認 検証(オブジェクトライフサイクルで変更) オブジェクトのアップロード ライフサイクルルールの設定 Soft delete 状態のオブジェクトの存在確認 事象 Cloud Storage バケット上の複数(数百程度)のオブジェクトに対して、gcloud コマンドを使って Standard クラスから Nearline クラスへのストレージクラス変更を行いました。 $ gcloud storage objects update gs:// ${BUCKET_NAME} / ${OBJECT_NAME} --storage-class = nearline これにより、以降はより安価な Nearline クラスの単価で課金されるようになることを期待しました。 しかし、数日後に請求先アカウントの課金レポートを確認したところ、Standard クラスの保管料金と Nearline クラスの保管料金の 両方が課金されている ことが確認されました。料金が安価になることを期待したのに、二重に課金されているような状態となっています。 なお前述のコマンド例では gcloud storage コマンドを利用していますが、gsutil rewrite コマンドでも同様の事象が発生しました。 原因 gcloud storage objects update や gsutil rewrite によるオブジェクトのストレージクラスの変更は、 オブジェクトの書き換え という挙動になります。 この挙動は「変更後のストレージクラスでオブジェクトを上書きする」という処理を行っています。これにより、上書き前の古いオブジェクトは Soft delete 状態 で、数日間(デフォルトで7日間)残り続けます。 Soft delete は、削除または上書きされた Cloud Storage オブジェクトを一定期間保持し、復元可能にする機能です。デフォルトでは、7日間の保持期間が設定されており、7日間から90日間の間で設定できるほか、明示的に無効にすることもできます。Soft delete が有効化されているバケットでは、上書きまたは削除された古いオブジェクトは Soft delete 状態として保持されます。 なお Soft delete は日本語ドキュメントで「削除(復元可能)」と表記されますが、当記事ではわかりやすくするため Soft delete という表記で統一します。 参考 : 削除(復元可能) Soft delete 状態のオブジェクトには、課金が発生します。今回のケースでは、コマンドによりオブジェクトを上書きしてストレージクラスを変更したため、 Standard クラスの古いオブジェクトが Soft delete 状態で残り続けて いました。そのため Soft delete 状態の Standard クラスの古いオブジェクトと、Nearline クラスの新しいオブジェクトが同時に存在していることになり、両方に課金が発生していました。 対処法 Soft delete 状態のオブジェクトを明示的に削除する方法はありません。バケットに設定した Soft delete 期間が経過すると、Soft delete 状態のオブジェクトは自然に削除されます。 あとからバケットの Soft delete を無効化したり、Soft delete 期間を短くしても、オブジェクトを削除または上書きしたときに設定されていた Soft delete 期間の設定が有効なため、当初に設定されていた Soft delete 期間の経過を待つ必要があります。 この事象の発生を 予防 するには、ライフサイクルルールや Autoclass 機能を使ってストレージクラスを変更する必要があります。 オブジェクトのライフサイクル は、事前に定義したルールに基づいて、例えば「作成から30日間経過したオブジェクトは Nearline クラスに移行する」「90日間経過したオブジェクトは削除する」のような自動処理を定義できる機能です。 参考 : オブジェクトのライフサイクル管理 Autoclass は、オブジェクトのアクセス状況に基づいて、自動的にオブジェクトのストレージクラスを変更する機能です。 参考 : Autoclass いずれの機能も、ストレージクラスの変更は「オブジェクトの書き換え」とは異なる処理で行われるため、オブジェクトが Soft delete 状態になることはなく、二重課金を回避できます。またいずれの機構も、オブジェクト取得料金や早期削除料金が発生しないなどのコストメリットがあります。よって 大量の (またはサイズが大きい) オブジェクトのストレージクラスを変更する場合は、ライフサイクルルールや Autoclass 機能を使うことが推奨 されます。 検証(手動でストレージクラスを変更) オブジェクトのアップロード 以下のコマンドで、ローカルマシンにあるテスト用ファイルを Cloud Storage バケットにアップロードします。 $ gcloud storage cp ./test-object.txt gs://my-test-bucket Copying file://./test-object.txt to gs://my-test-bucket/test-object.txt Completed files 1 / 1 | 21 .0B/ 21 .0B ls コマンドで、オブジェクトが正しくアップロードできていることを確認します。また describe コマンドで、オブジェクトのストレージクラスを確認します。このバケットはデフォルトのストレージクラスが Standard なので、アップロードしたオブジェクトのストレージクラスも Standard になっています。 $ gcloud storage ls gs://my-test-bucket gs://my-test-bucket/test-object.txt $ $ gcloud storage objects describe gs://my-test-bucket/test-object.txt --format =" value(storage_class) " STANDARD ストレージクラスの変更 update コマンドで、オブジェクトのストレージクラスを Nearline に変更します。 $ gcloud storage objects update gs://my-test-bucket/test-object.txt --storage-class = nearline Rewriting gs://my-test-bucket/test-object.txt... Completed 1 $ $ gcloud storage objects describe gs://my-test-bucket/test-object.txt --format =" value(storage_class) " NEARLINE Soft delete 状態のオブジェクトの確認 gcloud storage objects update コマンドでオブジェクトのストレージクラスを変更したため、オブジェクトは上書きされ、Standard クラスの古いオブジェクトが Soft delete 状態で残っているはずです。 ls コマンドに --soft-deleted オプションを付けることで、Soft delete 状態のオブジェクトのみを一覧表示できます。 $ gcloud storage ls gs://my-test-bucket --soft-deleted --recursive gs://my-test-bucket/: gs://my-test-bucket/test-object.txt# 1732163813118979 上記のように、 test-object.txt#1732163813118979 という名称で、Soft delete 状態のオブジェクトが存在していることが確認できました。このオブジェクトのストレージクラスを以下のコマンドで確認します。 $ gcloud storage objects describe gs://my-test-bucket/test-object.txt# 1732163813118979 --soft-deleted --format =" value(storage_class) " STANDARD Soft delete 状態のオブジェクトが Standard クラスであることが確認できました。このSoft-delete 状態のオブジェクトは、Nearline クラスに変更した新オブジェクトとは 別のオブジェクトとして存在 しているため、Nearline に変更した新オブジェクトと、Standard の旧オブジェクトで二重課金状態になっていることがわかります。 この検証により、 gcloud storage objects update によるオブジェクトクラスの変更を行うと、既存オブジェクトが新しいストレージクラスで上書きされ、古いオブジェクトが Soft delte 状態で残ることが確認できました。 削除ができないことを確認 なお、この Soft delte 状態のオブジェクトは gcloud storage rm コマンド等で削除することはできません。保持日数が経過するのを待つ必要があります。 $ gcloud storage rm gs://my-test-bucket/test-object.txt# 1732163813118979 Removing objects: Completed 0 ERROR: ( gcloud.storage. rm ) The following URLs matched no objects or files: gs://my-test-bucket/test-object.txt# 1732163813118979 $ $ gcloud storage rm gs://my-test-bucket/test-object.txt# 1732163813118979 --soft-deleted ERROR: ( gcloud.storage. rm ) unrecognized arguments: --soft-deleted To search the help text of gcloud commands, run: gcloud help -- SEARCH_TERMS 検証(オブジェクトライフサイクルで変更) オブジェクトのアップロード 次に、オブジェクトライフサイクル機能を用いてストレージクラスを変更した場合を検証してみます。 以下のコマンドで、ローカルマシンにあるテスト用ファイルを Cloud Storage バケットにアップロードします。 $ gcloud storage cp ./test-object-lifecycle.txt gs://my-test-bucket Copying file://./test-object-lifecycle.txt to gs://my-test-bucket/test-object-lifecycle.txt Completed files 1 / 1 | 21 .0B/ 21 .0B $ gcloud storage objects describe gs://my-test-bucket/test-object-lifecycle --format =" value(storage_class) " STANDARD アップロード直後は、対象オブジェクトのストレージクラスが Standard であることも確認します。 ライフサイクルルールの設定 バケットのオブジェクトライフサイクルを、以下のように設定します。 特定日付より以前に作成されたオブジェクトを Nearline クラスに変更するルールとしました。即時にルールを適用したいので、検証を行った日は2024-11-21ですが、それより先の日付を指定日付としました。 ルールを設定してから、実際に適用されるまでは最大で24時間程度のラグがあります。 Soft delete 状態のオブジェクトの存在確認 しばらく待ったあと、ライフサイクルルールが適用され、オブジェクトのストレージクラスが Nearline に変更されたことを確認します。 $ gcloud storage objects describe gs://my-test-bucket/test-object-lifecycle.txt --format =" value(storage_class) " NEARLINE 以下のように、Soft delete 状態のオブジェクトがあるかどうかを確認します。 $ gcloud storage ls gs://my-test-bucket --soft-deleted --recursive gs://my-test-bucket/: Soft delete 状態のオブジェクトが1つも存在しないことが確認できました。つまり、ライフサイクルルールによってオブジェクトのストレージクラスが変更された場合、オブジェクトの書き換えとは異なる動作のため、Soft delete 状態のオブジェクトは生まれないことがわかりました。 gcloud コマンド等によるストレージクラスの変更は「オブジェクトの書き換え」の動作であり、古いオブジェクトの削除が発生することに対して、ライフサイクルルールは違う挙動であるということは、以下のドキュメントにも記載されています。 参考 : SetStorageClass の費用に関する考慮事項 ただし、オブジェクトのストレージ クラスを手動で変更する場合と異なり、SetStorageClass を使用してもオブジェクトは書き換えられません。 またライフサイクルルールによるストレージクラスの変更では、以下のようなその他の料金面でのメリットがあることも記述されています。 ストレージ クラスの変更に関連するリージョン間のレプリケーション料金、取得料金、早期削除料金は発生しません。 なおライフサイクルルールでオブジェクトクラスを変更されたオブジェクトを describe すると、以下のように、 creation_time は最初にオブジェクトをアップロードした時間のまま変わりませんが、 storage_class_update_time が変更されています。オブジェクトの上書きを行わずに、ストレージクラスのみが変更されていることがわかります。 $ gcloud storage objects describe gs://my-test-bucket/test-object-lifecycle.txt bucket: my-test-bucket content_type: text/plain crc32c_hash: Sd5KXw = = creation_time: 2024-11-21T03:00:34+ 0000 etag: CKKH9cK37IkDEAI = generation: ' 1732158034887586 ' md5_hash: QGEgRtde1doCj1rGmxWK6w = = metageneration: 2 name: test-object-lifecycle.txt size: 80 storage_class: NEARLINE storage_class_update_time: 2024-11-21T06:58:34+ 0000 storage_url: gs://my-test-bucket/test-object-lifecycle.txt# 1732158034887586 update_time: 2024-11-21T06:58:34+ 0000 杉村 勇馬 (記事一覧) 執行役員 CTO / クラウドソリューション部 部長 元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 12資格、Google Cloud認定資格11資格。X (旧 Twitter) では Google Cloud や AWS のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-gen の杉村です。当記事では、Google Cloud の請求先アカウントに標準付属されている 異常検知 (Anomaly Detection)機能について紹介します。 異常検知(Anomaly Detection)とは 異常検知 検知結果の閲覧 異常しきい値 通知 メール通知内容 通知の宛先 通知の頻度 異常検知(Anomaly Detection)とは Google Cloud(旧称 GCP)の請求先アカウントには、 異常検知 (Anomaly Detection)機能があります。 異常検知は、Google Cloud の突発課金を検知できる機能です。請求先アカウント単位で過去の使用傾向が機械学習により学習され、普段と異なるパターンの課金が発生すると異常(anomaly)として検知されます。検知結果は、E メールや Pub/Sub に通知することができます。異常が検知されるのは、 6ヶ月間以上の利用実績があるプロジェクトのみ です。 検知された異常には、根本原因(root cause)が表示されます。根本原因として、どの SKU が課金に関係しているか、どのリージョンのどのサービスか、などが表示されます。 参考 : View and manage cost anomalies なお、請求先アカウントの仕組み等の基礎知識については、以下の記事をご参照ください。 blog.g-gen.co.jp 異常検知 検知結果の閲覧 検知された異常は、指定した通知先にメール等で発報することもできますし、Google Cloud コンソール画面から確認することもできます。 Google Cloud コンソールの「お支払い>異常」から、検知された異常の一覧が確認できます。 検知した異常の一覧 異常の詳細画面では、 根本原因の分析 (root cause analysis、RCA)が閲覧できます。ここでは、発生した課金額、その SKU の内訳、通常レベルだと想定される課金額などが表示されます。また、Google の製品改善のために、実際にこの検知が想定外の課金であるかどうか、フィードバックするボタンもあります。 根本原因の分析(RCA) 異常しきい値 コンソールからアクセスできる設定画面には「 異常しきい値 」を設定する箇所があります。このしきい値を設定すると、異常が検知されても、費用への影響(機械学習が推定した通常の費用と、実際の費用の差)が設定したしきい値より下回った場合、その検知は表示されません。 このしきい値はあくまで、検知された異常のリストをフィルタリングするために使われます。この値を設定しても、 検知のしきい値自体が変わるわけではありません 。異常検知はあくまで機械学習によって過去実績に応じて行われます。 しきい値の設定 しきい値設定は、金額の絶対値で指定することもできますし、通常の想定費用とのずれの割合(%)で指定することもできます。また過去の使用パターンに基づいて毎日自動的に更新されるよう「しきい値の自動生成」を設定することもできます。 しきい値を設定すると、コンソール画面の異常の一覧がその値でフィルタリングされます。フィルタを削除すれば、すべての異常が表示されます。ただし、設定したしきい値は E メールや Pub/Sub 通知にも適用されます 。しきい値を下回る検知は、一覧から非表示になるだけでなく、E メール通知等が行われなくなるため、注意が必要です。 フィルタ 通知 メール通知内容 異常が検知されると、以下のような E メールが指定した宛先に送信されます。 異常検知の E メール 通知の宛先 宛先は、以下のいずれかから選択できます。 通知先 説明 Pub/Sub 選択した Pub/Sub トピックに通知 課金管理者 当該請求先アカウントに「請求先アカウント管理者」ロールを持っているアカウントに通知 重要な連絡先(エッセンシャルコンタクト) エッセンシャルコンタクトで「課金」カテゴリの対象になっているアカウントに通知 プロジェクト オーナー 異常課金が発生したプロジェクトに対して「オーナー」ロールを持つアカウントに通知 以下は、通知の設定画面です。 通知の設定 Pub/Sub トピックに通知すると、後続処理として Cloud Run functions を動作することができるため、チャットツールやチケットシステムなどへの通知に繋げられます。 課金管理者、重要な連絡先(エッセンシャルコンタクト)、プロジェクト オーナーにはそれぞれ「個別の異常」を通知するか、「1 日のまとめ」を通知するかが選択できます。 なお重要な連絡先(エッセンシャルコンタクト)の「個別の異常」を選んだ場合はプロジェクトレベルに設定したエッセンシャルコンタクトの「課金」カテゴリの連絡先に、「1 日のまとめ」を選んだ場合は組織レベルのエッセンシャルコンタクトの「課金」カテゴリの連絡先に、それぞれ通知が発報されます。 エッセンシャルコンタクトについては、以下の記事も参照してください。 blog.g-gen.co.jp 通知の頻度 以下の公式記事では「コスト異常検出は支出を 1 時間ごとに監視するため、ほとんどのサービスで 24 時間以内に予期しない上昇スパイクを識別し、ほぼリアルタイムで異常を検出できます。」の旨の記載があります。 参考 : Reduce unexpected costs with the new AI-powered Cost Anomaly Detection ただし2024年10月の当社検証では、突発課金が発生してから通知されるまで、1日程度のラグがありました。正確なラグについてはドキュメントに記載がなく、幅があると想定されます。 杉村 勇馬 (記事一覧) 執行役員 CTO 元警察官という経歴を持つ IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 認定資格および Google Cloud 認定資格はすべて取得。X(旧 Twitter)では Google Cloud や Google Workspace のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-gen の杉村です。Google Cloud リソースへの詳細なアクセス制御を実現する VPC Service Controls には、Ingress rules(内向きルールまたは上りルール)と Egress rules(外向きルールまたは下りルール)の設定が存在します。これらの仕様と、適切な設定方法を解説します。 はじめに 境界とルール Ingress rules Ingress rules とは Ingress rules の設定値 Egress rules Egress rules とは Egress rules の設定値 サンプルアーキテクチャ 概要 アクセスユースケース1. 境界内リソースへのアクセス アクセスユースケース2. 境界外リソースへのアクセス(失敗パターン) アクセスユースケース3. 境界外リソースへのアクセス(成功パターン) Google ストアなど一部 Web サイトへのアクセス異常 はじめに VPC Service Controls は、Google Cloud リソースへの詳細なアクセス制御を実現するサービスです。詳細は、以下の記事で解説しています。当記事は、以下の記事の内容を概ね理解している前提で記載されています。 blog.g-gen.co.jp VPC Service Controls には、内向き(上り)ルールと外向き(下り)ルールの設定が存在します。英語では、内向きルールは Ingress rules 、外向きルールは Egress rules と表記されます。表記揺れを防ぐため、当記事ではこれ以降、英語版表記の Ingress rules、Egress rules という言葉を用います。 参考 : Service perimeter details and configuration 参考 : Ingress and egress rules 当記事では、はじめに Ingress rules と Egress rules の仕様を解説し、その後、理解を深めるためにサンプルアーキテクチャを用いて図説します。 境界とルール VPC Service Controls の 境界 (perimeter)でプロジェクトを保護すると、境界の外から中への API リクエストや、中から外への API リクエストが拒否されます。これにより、データの持ち出しを防ぐことができます。 境界には、 Ingress rules や Egress rules を追加することができます。Ingress rules と Egress rules は、いずれも「本来拒否されるはずの境界をまたいだ API リクエストを例外的に許可するためのルール」です。Ingress rules や Egress rules を追加すると、境界に例外を設けて、境界の中から外、または外から中への API リクエストを許可することができます。 Ingress rules Ingress rules とは Ingress rules(または上りルール、内向きルール)は、境界 外 の API クライアントから境界 内 の Google Cloud リソースへの API リクエストを許可するルールです。 例えば、ある Google Cloud プロジェクトを境界で保護し、VPC 内部やオンプレミスからのアクセスだけに制限するとします。しかし、特定の外部ベンダーの開発チームだけは境界内へのアクセスを許可したいとします。このような場合は、境界の外から中へのリクエストが発生するため、Ingress rules を設定します。 Ingress rules の例 Ingress rules の設定値 Ingress rules には From 属性 と To 属性 を設定することができます。 From 属性には、API リクエストを行うクライアントの属性を指定します。以下の設定項目があります。 設定項目 説明 Identity(ID) 許可する Google アカウントやサービスアカウント、Google グループ等を指定 ソース 許可する API リクエストの発信元として以下のいずれかを指定 ・すべて ・アクセスレベル ・プロジェクト ・VPC ネットワーク なおアクセスレベルとは、Access Context Manager で作成する、許可条件の設定オブジェクトのことです。特定の IP アドレス帯やデバイスポリシーなどを許可条件として指定できます。 To 属性には、アクセス先のリソースの存在するプロジェクトや、Google Cloud API、そのメソッドなどを指定します。以下の設定項目があります。 設定項目 説明 プロジェクト 許可する Google Cloud プロジェクトを指定。All projects を指定すると境界内の全プロジェクトがアクセス先として許可される サービス・メソッド 許可する Google Cloud API やメソッドを指定。IAM ロールを指定して、そのロールに紐づくすべてのメソッドを許可することも可能 これらの設定により、例えばあるプロジェクトの Cloud Storage API の google.storage.objects.list と google.storage.objects.get へのリクエストを許可する、といった指定の仕方ができます。許可対象の API メソッドは「ストレージ管理者( roles/storage.admin )ロール」のようにロール単位で指定することもできます。 また、プロジェクトや API メソッドを限定せず、境界内の全プロジェクト・全サービス・全メソッドへのアクセスを許可するといった設定も可能です。 Egress rules Egress rules とは Egress rules(または下りルール、外向きルール)は、境界 内 の API クライアントから境界 外 のリソースへの API リクエストを許可するルールです。 例えば、ある Google Cloud プロジェクトを境界で保護するとします。境界内の VM 等の上で動作するクライアント(アプリケーションや gcloud コマンドなど)は、境界外のプロジェクトにある Google Cloud リソースにアクセスすることはできません。境界外のプロジェクトの Cloud Storage バケットにアクセスしたい場合は、Egress rules を設定する必要があります。 Egress rules の例 Egress rules の設定値 Egress rules にも、 From 属性 と To 属性 を設定します。 From 属性には、API リクエストを行うクライアントの属性を指定します。以下の設定項目があります。 設定項目 説明 Identity(ID) 許可する Google アカウントやサービスアカウント、Google グループ等を指定 アクセスレベル 許可するアクセスレベルを指定 Ingress rules の From 属性にはプロジェクトが指定できましたが、Egress rules では接続元プロジェクトは指定できず、境界内の全プロジェクトに対してルールが適用されます。From 属性には許可対象とするアカウント(API リクエスト主体)を指定するのと同時に、任意でアクセスレベルを指定できます。アクセスレベルとは前述のとおり、Access Context Manager で作成する許可条件の設定オブジェクトであり、接続元 VPC を指定したり、デバイスポリシーを指定できます。「サンプルアーキテクチャ」の項でも述べますが、境界内には Private Service Connect や限定公開の Google アクセスを用いてオンプレミスのデバイスを含めることができます。このときに、デバイスポリシーを満たしたデバイスだけを接続元とすることができます。 To 属性には、アクセス先のリソースの存在する場所を指定します。アクセス先として「Google Cloud サービス/リソース」「外部リソース」から選択します。 「Google Cloud サービス/リソース」には以下の設定項目があり、Ingress rules と同様です。 設定項目 説明 プロジェクト 許可する Google Cloud プロジェクトを指定。All projects を指定すると境界内の全プロジェクトがアクセス先として許可される サービス・メソッド 許可する Google Cloud API やメソッドを指定 一方の「外部リソース」には以下の設定項目があります。 設定項目 説明 外部リソース Google Cloud 外部のリソースを指定。Amazon S3 のバケット名や Azure Blob Storage のコンテナー名が指定可能 サービス・メソッド 許可する Google Cloud API やメソッドを指定。IAM ロールを指定して、そのロールに紐づくすべてのメソッドを許可することも可能 なお外部リソースとして指定できるのは、2025年1月現在では Amazon S3 バケットと Azure Blob Storage コンテナーのみです。 サンプルアーキテクチャ 概要 ここでサンプルとして、あるマルチクラウド環境のアーキテクチャを例に取り、Egress rules が必要なケースを解説します。 以下のような環境があります。 サンプルアーキテクチャ AWS 環境と Google Cloud 環境が、インターネット VPN で接続されています。図中の「Cloud VPN」「AWS Site-to-Site VPN」はいずれも IPSec VPN のサービスで、前者は Google Cloud の、後者は AWS のサービスです。このアーキテクチャでは AWS とインターネット VPN を用いましたが、 オンプレミスや専用線の場合でも同様の結果になる と考えて差し支えありません。 AWS と接続された Google Cloud プロジェクト project-01 には Private Service Connect エンドポイント が設置されています。この仕組みにより、AWS の EC2 インスタンス(仮想マシン)上で稼働するクライアント(gcloud コマンドや Google Cloud クライアントライブラリなど)は、Private Service Connect エンドポイントを経由して、プライベートネットワーク内で Google Cloud APIs にアクセスできます。同様の仕組みは Private Service Connect のほか、「限定公開の Google アクセス」という仕組みでも実現できます。 Private Service Connect の詳細や、これを使って AWS やオンプレミスから Google Cloud APIs へプライベート接続する方法については、以下の記事も参照してください。 blog.g-gen.co.jp Google Cloud プロジェクト project-01 は VPC Service Controls 境界によって保護されています。また、境界の外にある project-02 も用意されています。各プロジェクトには、Cloud Storage バケットを準備しました。 この構成において、AWS の EC2 インスタンス上で稼働する gcloud コマンド等の API クライアントから、境界内外のリソースへアクセスさせるための設定を、いくつかのケースにわけて解説します。 アクセスユースケース1. 境界内リソースへのアクセス 重要なポイントとして、境界内部にある Private Service Connect エンドポイント経由で AWS やオンプレミス等から Google Cloud APIs にリクエストした場合、リクエストは 境界内からのリクエストとして扱われます 。 先ほどの構成が適切に設定されている場合、EC2 インスタンス上のクライアントからのリクエストは Private Service Connect エンドポイント経由のため、境界内からのリクエストとしてみなされます。アクセス先が境界内リソースであれば、 Ingress rules も Egress rules も必要ありません 。 境界内から境界内リソースへは例外ルールなしでアクセス可能 上記の図では矢印が簡易化されていますが、実際には EC2 インスタンス ←→ Private Service Connect エンドポイント ←→ Cloud Storage バケットという L 字型のアクセス経路です。 アクセスユースケース2. 境界外リソースへのアクセス(失敗パターン) では、EC2 インスタンスから、境界外の Google Cloud プロジェクト上のリソースへのアクセスはどうなるでしょうか。 境界内から境界外のリソースへのリクエストは原則拒否 上記の図のように、境界内から境界外のリソースへのリクエストは拒否されます。図では矢印が簡易化されていますが、実際には EC2 インスタンス ←→ Private Service Connect エンドポイント ←→ project-02 の Cloud Storage バケットというアクセス経路です。 このようなリクエストがされた場合は、以下のようなエラーメッセージが表示されます。 { " protoPayload ": { " @type ": " type.googleapis.com/google.cloud.audit.AuditLog ", " status ": { " code ": 7 , " message ": " PERMISSION_DENIED ", " details ": [ { " @type ": " type.googleapis.com/google.rpc.PreconditionFailure ", " violations ": [ { " type ": " VPC_SERVICE_CONTROLS ", " description ": " (略) " } ] } , { " @type ": " type.googleapis.com/google.rpc.ErrorInfo ", " reason ": " SECURITY_POLICY_VIOLATED ", " domain ": " googleapis.com ", " metadata ": { " uid ": " (略) ", " service ": " storage.googleapis.com " } } ] } , " authenticationInfo ": {} , " requestMetadata ": { " callerIp ": " 192.168.2.3 ", " callerNetwork ": " //compute.googleapis.com/projects/project-01/global/networks/__unknown__ ", " requestAttributes ": {} , " destinationAttributes ": {} } , " serviceName ": " storage.googleapis.com ", " methodName ": " google.storage.objects.get ", " resourceName ": " projects/(project-01のプロジェクト番号) ", " metadata ": { " @type ": " type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata ", " violationReason ": " NETWORK_NOT_IN_SAME_SERVICE_PERIMETER ", " vpcServiceControlsUniqueId ": " (略) ", " securityPolicyInfo ": { " servicePerimeterName ": " accessPolicies/(略)/servicePerimeters/my_vpcsc_perimeter ", " organizationId ": " (略) " } , " deviceState ": " Unknown ", " resourceNames ": [ " projects/_/buckets/my-bucket-external/objects/test.txt " ] , " egressViolations ": [ { " targetResource ": " projects/(project-02のプロジェクト番号) ", " source ": " projects/(project-01のプロジェクト番号) ", " sourceType ": " Network ", " servicePerimeter ": " accessPolicies/(略)/servicePerimeters/my_vpcsc_perimeter ", " targetResourcePermissions ": [ " storage.objects.get " ] } ] , " vpcServiceControlsTroubleshootToken ": " (略) " } } , " insertId ": " (略) ", " resource ": { " type ": " audited_resource ", " labels ": { " project_id ": " project-01 ", " method ": " google.storage.objects.get ", " service ": " storage.googleapis.com " } } , " timestamp ": " 2024-12-06T09:50:20.644751574Z ", " severity ": " ERROR ", " logName ": " projects/project-01/logs/cloudaudit.googleapis.com%2Fpolicy ", " receiveTimestamp ": " 2024-12-06T09:50:20.844464826Z " } このログの、 protoPayload.metadata.egressViolations に注目してください。 egressViolations は、外向きのアクセス設定に違反していることを指しています。境界内クライアントから境界外リソースへのアクセスのため、アクセスが 境界によって拒否 されたことを示しています。 アクセスユースケース3. 境界外リソースへのアクセス(成功パターン) 前項のようなアクセスを許可するには、Egress rules を追加します。 以下のように、From 属性を「任意の ID(ANY_IDENTITY)」とし、To 属性に宛先プロジェクトと、今回のアクセス先である storage.googleapis.com を指定しました。このような設定を追加すれば、アクセスは許可されます。 Egress rules を追加することでアクセス可能 なお、任意の ID とせずに、クライアントに設定したサービスアカウントを明示的に指定することもできます。また、Workload Identity で連携した AWS の IAM ユーザー(グループ)を指定することもできます(2025年1月現在、Preview)。 参考 : Configure identity groups and third-party identities in ingress and egress rules Google ストアなど一部 Web サイトへのアクセス異常 なお、今回の構成では Private Service Connect の設定に伴い、 *.googleapis.com が Private Service Connect エンドポイントの IP アドレスへ名前解決されるように、DNS が設定されています。 このようなときに Egress rules が設定されていない場合、一部の Google のウェブサイト等へのアクセスがうまくいかないことが分かっています。 例えば、Google ストア( https://store.google.com/ )はその1つです。Google ストアのトップページでは https://mannequin.storage.googleapis.com/ から静的ファイルを取得しているため、境界内からこのサイトへアクセスすると、境界外へのアクセスとみなされて、VPC Service Controls 境界によりリクエストがブロックされます(403 Forbidden)。 静的ファイルが取得できず表示が不完全 Egress rules の From 属性で「任意の ID」、To 属性で「すべてのプロジェクト」「Cloud Storage API」「get メソッド」を許可すると、リクエストが成功し、Web サイトが完全に表示されます。 Egress rules の追加により表示が成功 ただし、この Egress rule を追加することで、境界内の API クライアントは境界外のバケットからデータを持ち込むことが可能になります。メソッドが get 等に限定されていれば情報流出のリスク増大にはなりませんが、仕様とリスクを十分に理解して設定してください。 杉村 勇馬 (記事一覧) 執行役員 CTO / クラウドソリューション部 部長 元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 12資格、Google Cloud認定資格11資格。X (旧 Twitter) では Google Cloud や AWS のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-genの福井です。Google Cloud の IAM の一機能である プリンシパルアクセス境界ポリシー (Principal access boundary)を用いたリソースへのアクセス制御について解説します。 概要 プリンシパルアクセス境界ポリシーとは アクセス可否の評価 ユースケース PAB ポリシーの構造 ポリシーの例 ルール(rules) 適用バージョン(enforcementVersion) ポリシーバインディング 設定手順 概要 必要な権限 事前確認 ポリシーを作成 PAB 画面へ遷移 境界ルールを追加 ポリシー名と適用バージョンを設定 ポリシーバインディング バインディング追加画面へ遷移 バインディングを追加 動作確認 概要 プリンシパルアクセス境界ポリシーとは プリンシパルアクセス境界ポリシー (Principal access boundary policies、以下 PAB ポリシー)とは、Google アカウントがアクセスできる Google Cloud リソースを、特定の Google Cloud 組織のリソースだけに制限するなどの強力なコントロールを実現するための仕組みです。PAB ポリシーによるアクセスのブロックは、IAM の許可ポリシーよりも優先されます。 PAB の設定は、プリンシパル(Google Cloud APIs の実行主体)に対して紐づけます。たとえばある Google Workspace 組織の全アカウントに対して PAB ポリシーを紐づけたり、あるいは特定プロジェクトに所属するサービスアカウントにポリシー紐づけたりすることができます。2025年1月現在、ポリシーを適用する対象として Google グループを指定することはできません。 参考 : プリンシパル アクセス境界ポリシー アクセス可否の評価 プリンシパルが Google Cloud リソースにアクセスを試みる際、IAM は 「許可ポリシー」、「拒否ポリシー」、そして「PAB ポリシー」 をすべて評価して、アクセスを許可するか拒否するかを決定します。 これら3つのポリシーがすべて評価され、いずれかのポリシーでアクセスが拒否されている場合は、IAM はアクセスを拒否します。 以下は、評価のロジックをフロー図化したものです。当社の解釈によるものであり、実際の内部的な評価順序と一致していない可能性がある点にはご留意ください。 評価フロー Google Cloud では、すべてのリソースへのアクセスはデフォルトで拒否されます。 アクセスの許可を設定できるのは、3つのポリシーの中では「許可ポリシー」だけです。またアクセス拒否を設定できるのは、「拒否ポリシー」と「PAB ポリシー」 の2つです。 よって、プリンシパルがリソースにアクセスできるようにするには、「許可ポリシー」が必須です。ここで許可されたアクセスに対して、「拒否ポリシー」や「PAB ポリシー」 がアクセスの拒否を追加する形になります。 上記フローのとおり、プリンシパルに複数の PAB ポリシーが紐づけられている場合、(アクセスが許可ポリシーで許可されており、また拒否ポリシーで拒否されていない前提で)いずれか1つの PAB ポリシーでアクセスが許可されていれば、アクセスは最終的に許可されます。これを「PAB ポリシーの評価は累積的である」といいます。すなわち、ある PAB ポリシーでアクセスを許可している場合、別の PAB ポリシーでアクセスの禁止をすることはできません。 ユースケース 複数の組織や複数のプロジェクトを利用している会社等では、従業員が自社組織外の Google Cloud リソースにアクセスできてしまうリスクを抑えたいケースが存在します。 しかしながら Google Cloud の IAM(Identity and Access Management)では通常、「許可ポリシー」と「拒否ポリシー」の2つを組み合わせてアクセス制御を行います。他の Google Cloud 組織において Google アカウントに IAM 権限が付与されてしまった場合、これらのポリシーだけでは他組織のクラウドリソースに対するアクセスを制限することはできません。このような場合に、PAB ポリシーが利用できます。 参考 : Google CloudのIAMを徹底解説! - G-gen Tech Blog - IAM の仕組み PAB ポリシーを利用することで、例として以下のようなメリットを享受することができます。 メリット 説明 データ流出の抑止 他組織のリソースや不要なプロジェクトへのアクセスを一律に制限できるため、データの流出やフィッシング攻撃などのリスクの低減を期待できます。 既存の IAM ポリシーの上書き たとえ許可ポリシーで権限を付与していても PAB ポリシーが優先されるため、強い強制力でリソースへのアクセスをブロックできます。 PAB ポリシーの構造 ポリシーの例 以下は、公式ドキュメントから引用した PAB ポリシーの例です。以下は JSON 形式で表記されていますが、Google Cloud コンソールでポリシーを作成、編集する場合、コンソールにはわかりやすく表示されます。ここではポリシーの構造の理解のために、JSON 形式で表記します。 { " name ": " organizations/0123456789012/locations/global/principalAccessBoundaryPolicies/example-policy ", " uid ": " puid_0123456789012345678 ", " etag ": " W/ \" Gh/PcTdJD/AWHUhPW45kdw== \" ", " displayName ": " Example policy ", " annotations ": { " example-key ": " example-value " } , " createTime ": " 2024-01-02T15:01:23Z ", " updateTime ": " 2024-01-02T15:01:23Z ", " details ": { " rules ": [ { " description ": " Example principal access boundary policy rule ", " resources ": [ " //cloudresourcemanager.googleapis.com/organizations/0123456789012 " ] , " effect ": " ALLOW " } ] , " enforcementVersion ": " 1 " } } 参考 : プリンシパル アクセス境界ポリシーの構造 ルール(rules) ルール(rules)は、「どのリソースに対してアクセスが許可されるか」をリストアップしたものです。 前掲の例にある "resources": [ "//cloudresourcemanager.googleapis.com/organizations/0123456789012" ] のように、組織やフォルダ、プロジェクトを指定します。 "effect" には "ALLOW" (許可)のみが指定できます。 なお、PAB ポリシーが複数存在する場合、その評価は 累積的 です。すなわち、すでにある PAB ポリシーでアクセスを許可している場合、別の PAB ポリシーでアクセスの禁止をすることはできません。 参考 : プリンシパル アクセス境界ポリシー間の相互作用 適用バージョン(enforcementVersion) 適用バージョン(enforcementVersion)は、PAB ポリシーがブロックできる権限のセットが定義されたバージョン番号です。 これは PAB ポリシー機能自体のバージョンを示しています。機能は Google により随時アップデートされており、バージョンが上がるたびに PAB がサポートする(ブロックできる)権限の範囲が広がります。値に latest を指定することで常に最新バージョンを使うことも可能ですが、これまで行使できていた権限が予期せずブロックされるリスクがあります。 参考 : プリンシパル アクセス境界の適用バージョン 参考 : プリンシパル アクセス境界ポリシーによってブロックされる権限 ポリシーバインディング PAB ポリシーをどのプリンシパルに対して適用するかを定義する設定を、ポリシーバインディングといいます。PAB ポリシーとプリンシパルを紐づける設定であるため、前掲の PAB ポリシーの JSON 中には含まれておらず、別の設定オブジェクトです。 ポリシーバインディングでは適用ターゲットとして、組織ドメインに所属するすべてのアカウントや、特定プロジェクトに所属するサービスアカウントなどを指定することができます。また、Workforce Identity プールや Workload Identity プールを指定することができます。2025年1月現在、Google グループをターゲットとして指定することはできません。 ポリシーバインディングでは条件式( condition )で細かな条件付けを行い、特定のユーザーを除外するといった制御が可能です。 参考 : ポリシー バインディングの構造 設定手順 概要 Google Cloud コンソールで PAB ポリシーを設定する手順をご紹介します。 この手順では、自らの組織外のリソースへのアクセスを禁止し、自組織配下のリソースのみアクセスを許可します。 必要な権限 この手順を行うには、操作者の Google アカウントに以下の IAM ロールが必要です。 組織に対する、プリンシパル アクセス境界管理者 ( roles/iam.principalAccessBoundaryAdmin ) 組織に対する、Workspace プール IAM 管理者 ( roles/iam.workspacePoolAdmin ) なお設定する制限によって必要とする IAM ロールは異なります。詳細は以下の公式ドキュメントをご参照ください。 参考 : プリンシパル アクセス境界ポリシーの適用に必要なロール 事前確認 Google Workspace ドメインに属するユーザーアカウントに対して、別組織(別ドメイン)の Cloud Storage バケットに対する閲覧権限をあらかじめ与えておきました。 PAB ポリシー適用前は以下のように、Cloud Storage バケット内のファイル一覧が表示されています。ポリシー適用後は、アクセスできなくなることが期待されます。 ポリシーを作成 PAB 画面へ遷移 Google Cloud コンソールのリソースとして組織を選択し、メニューの「IAMと管理」>「プリンシパル アクセス境界」を押下します。この画面の「ポリシーを作成」を押下すると、ポリシーの新規作成画面が表示されます。 境界ルールを追加 「どのリソースに対するアクセスを許可するか」を設定します。リソースに設定できる値は「組織」「フォルダ」「プロジェクト」のいずれかです。 ポリシー名と適用バージョンを設定 表示名と適用バージョンを設定し「作成」を押下します。表示名を入力すると、ポリシー ID が自動で生成されるため、必要に応じて変更します。 ポリシーバインディング バインディング追加画面へ遷移 Google Cloud コンソールメニューの「IAMと管理」>「プリンシパル アクセス境界」>「作成したポリシー」を押下します。 「バインディングを追加」を押下すると、バインディング追加画面が表示されます。 バインディングを追加 「どのプリンシパルに、どの PAB ポリシーを適用するか」を設定します。表示名、バインディング ID、ターゲットプリンシパルセットを設定して「追加」を押下します。 ここではプリンシパルセットとして「Workspace プール ID」を指定したため、指定された Google Workspace ドメイン内のすべての ID が制限の対象となります。 なおこの ID は組織の顧客 ID と呼ばれる英数字です。通常、 C01abc123 のような形式です。顧客 ID の調べ方は、以下の記事を参照してください。 blog.g-gen.co.jp その他のプリンシパルセットの ID の形式等は、以下のドキュメントを参照してください。 参考 : サポートされているプリンシパル セット 動作確認 ポリシー適用後は、Cloud Storage バケットへアクセスした際に以下のようなエラーが表示され、ファイル一覧が表示されないようになりました。 test@g-gen.co.jp does not have storage.objects.list access to the Google Cloud Storage bucket. Operations on resource are denied due to an IAM Principal Access Boundary Policy. test@g-gen.co.jp does not have storage.objects.list access to the Google Cloud Storage bucket. Operations on resource are denied due to an IAM Principal Access Boundary Policy. 福井 達也 (記事一覧) カスタマーサクセス課 エンジニア 2024年2月 G-gen JOIN 元はアプリケーションエンジニア(インフラはAWS)として、PM/PL・上流工程を担当。G-genのGoogle Cloudへの熱量、Google Cloudの魅力を味わいながら日々精進
アバター
G-gen の堂原です。当記事では、 Google ドライブ をデータソースとする Vertex AI Search が提供するウィジェットを、 Cloud Run で構築したウェブサイトに埋め込む手順を紹介します。 はじめに 当記事について 留意点 前提知識 権限設計 Vertex AI Search の設定 事前準備 ドメインの許可設定 OAuth 同意画面作成 OAuth 2.0 クライアント ID 作成 Cloud Run サービス作成 処理の流れ ソースコード ディレクトリ構造 Cloud Run サービスのデプロイコマンド index.html main.py 動作確認 はじめに 当記事について 当記事では、Google Cloud(旧称 GCP)が提供する検索エンジンサービスである Vertex AI Search において、 Google ドライブ をデータソースとする Vertex AI Search アプリが提供するウィジェットを、 Cloud Run + Flask で構築したウェブサイトに埋め込む手順を紹介します。 留意点 当記事で紹介するソースコードは、ウェブサイトに上でウィジェットを表示する方法の紹介だけを目的としています。そのため、紹介するソースコードを そのまま本番環境に用いることは推奨しません 。 実際に本番環境に組み込む際は、例として以下のようなことを考慮する必要があります。 Flask の secret_key や OAuth クライント ID のクライント ID・クライアントシークレットを Secret Manager で管理する OAuth アクセストークンの有効期限をケアする 前提知識 Vertex AI Search は Google Cloud の生成 AI 関連サービスである Vertex AI Agent Builder の1機能です。Vertex AI Search を用いることで Google がマネージドで提供している検索エンジンを利用し、以下のようなデータソースに対して検索を行うことが出来ます。 Cloud Storage や BigQuery といった Google Cloud サービス Google ドライブや Box、Slack などといった Google Cloud 外部のツール 特定のウェブサイト また、Gemini を用いて検索結果を要約する機能も提供されています。 詳しくは、以下の記事をご参照ください。 blog.g-gen.co.jp 権限設計 当記事で構築するウェブサイトは、 OAuth 認証 を用いて、サイトにアクセスしたユーザの権限で Vertex AI Search の検索を実行します。 また、サイトにアクセスするユーザは Google Cloud プロジェクト上において、「ディスカバリー エンジン閲覧者( roles/discoveryengine.viewer )」ロールを持っている必要があります。 Vertex AI Search の設定 事前準備 はじめに、Vertex AI Agent Builder の Vertex AI Search で Google ドライブをデータソースとするデータストアとアプリを作成してください。 詳細な手順については、当記事では記述しません。 作成後、Google Cloud コンソールの検索プレビューで正しく検索ができることを確認してください。 ドメインの許可設定 Vertex AI Search のウィジェットをウェブサイトに埋め込むためには、Vertex AI Search でそのサイトのドメインを許可する必要があります。 許可設定は、Google Cloud コンソールの Vertex AI Search アプリの「統合」画面の「ウィジェット」タブにて行います。 今回は Cloud Run で自動で払い出される URL を用いてアクセスするため、ドメイン「 asia-northeast1.run.app 」を許可しておきます。 また、ページ下部の HTML をウェブサイトに書き込むことで、ウィジェットを埋め込むことになります。 OAuth 同意画面作成 OAuth 認証に必要な OAuth 同意画面を作成します。 以下にパラメータを記載します。記載の無いパラメータについては未入力でも設定可能です。 設定項目 小項目 設定値 補足 アプリ情報 アプリ名 任意の名前 同意画面で表示されるアプリ名となります ユーザー サポートメール 任意のメールアドレス デベロッパーの連絡先情報 メールアドレス 任意のメールアドレス ユーザーの種類 内部 組織の Google Workspace に属する Google アカウントのみがアクセス可能となります 非機密のスコープ ・ https://www.googleapis.com/auth/userinfo.email ・openid 機密性の高いスコープ https://www.googleapis.com/auth/cloud-platform OAuth 2.0 クライアント ID 作成 ウェブサイトで OAuth 認証処理を実装する際に必要となる OAuth 2.0 クライアント ID を作成します。 以下にパラメータを記載します。記載の無いパラメータについては未入力でも設定可能です。 設定項目 設定値 補足 アプリケーションの種類 ウェブ アプリケーション 名前 任意の名前 Google Cloud コンソール上で識別するためだけに用いるため、クライアントに表示されることはありません。 承認済みのリダイレクト URI https://test-search-widget- {プロジェクト番号}.asia-northeast1.run.app/oauth2callback 「test-search-widget」は後に作成する Cloud Run のサービス名となります 作成後、作成したクライアント ID のコンソール画面より、「クライアント ID」と「クライント シークレット」の値を確認しておいてください。 Cloud Run サービス作成 処理の流れ Cloud Run で実行するプログラムの大まかな処理の流れは、以下のとおりです。 OAuth アクセストークンを取得 Python ライブラリである「 google_auth_oauthlib 」を用いて OAuth 認可リクエスト用のパラメータを作成する 認可エンドポイントへリダイレクト ユーザに同意処理を行わせ、認可レスポンスをクライント ID で設定した URL へリダイレクトさせる 認可コードを用いてアクセストークンを取得する アクセストークン含めた認証情報をセッションに保管する アクセストークンを埋め込んだ index.html を返却する ソースコードは、主に以下の公式ドキュメントを参考としています。 参考 : ウェブサーバー アプリケーションに OAuth 2.0 を使用する ソースコード ディレクトリ構造 Cloud Run サービスにデプロイする各種ファイルのディレクトリ構造は以下のとおりです。 / ├ main.py ├ requirements.txt └ templates/   └ index.html Cloud Run サービスのデプロイコマンド Cloud Run サービスのデプロイには以下の gcloud コマンドを用います。このコマンドを main.py と同じディレクトリ上で実行します。 gcloud run deploy test-search-widget \ --project { プロジェクト ID } \ --region asia-northeast1 \ --service-account { Cloud Run サービスにアタッチするサービスアカウント } \ --source . \ --allow-unauthenticated \ --session-affinity \ --set-env-vars PROJECT_ID = { プロジェクト ID } \ --set-env-vars OAUTH_CLIENT_ID = { OAuth 2 . 0 クライント ID のクライント ID } \ --set-env-vars OAUTH_CLIENT_SECRET = { OAuth 2 . 0 クライント ID のクライアントシークレット } \ --set-env-vars OAUTH_REDIRECT_URI =https://test-search-widget- { プロジェクト番号 } .asia-northeast1.run.app なお、当記事で構築するウェブサイトにおいては、Cloud Run サービスにアタッチするサービスアカウントに権限を付与する必要はありません。 index.html Vertex AI Search のウィジェット画面に記載されていた HTML を埋め込みます。 <!doctype html> < html > < head > < meta charset = "utf-8" > < title > Test Page </ title > </ head > < body > <!-- Widget JavaScript bundle --> < script src = "https://cloud.google.com/ai/gen-app-builder/client?hl=ja" ></ script > <!-- Search widget element is not visible by default --> < gen-search-widget configId= "xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" triggerId= "searchWidgetTrigger" > </ gen-search-widget > <!-- Element that opens the widget on click. It does not have to be an input --> < input placeholder = "ここで検索" id = "searchWidgetTrigger" /> < script > // Set authorization token. const searchWidget = document . querySelector ( 'gen-search-widget' ) ; searchWidget . authToken = "{{ token }}" ; </ script > </ body > </ html > searchWidget.authToken は Flask の render_template で値を挿入するため、 "{{ token }}" としておきます。 main.py 「処理の流れ」に記載したとおり、ユーザからのリクエストを処理します。 import flask import google.auth import google_auth_oauthlib.flow import google.oauth2.credentials import os app = flask.Flask(__name__) app.secret_key = "xxxxx" CLIENT_CONFIG = { "web" : { "client_id" : os.environ.get( "OAUTH_CLIENT_ID" ), "project_id" : os.environ.get( "PROJECT_ID" ), "auth_uri" : "https://accounts.google.com/o/oauth2/auth" , "token_uri" : "https://oauth2.googleapis.com/token" , "auth_provider_x509_cert_url" : "https://www.googleapis.com/oauth2/v1/certs" , "client_secret" : os.environ.get( "OAUTH_CLIENT_SECRET" ), "redirect_uris" : [ os.environ.get( "OAUTH_REDIRECT_URI" ) ] }} SCOPES = [ "https://www.googleapis.com/auth/userinfo.email" , "openid" , "https://www.googleapis.com/auth/cloud-platform" ] def credentials_to_dict (credentials) -> dict : """google.oauth2.credentials.Credentialsをdict型に変換する""" return { "token" : credentials.token, "refresh_token" : credentials.refresh_token, "token_uri" : credentials.token_uri, "client_id" : credentials.client_id, "client_secret" : credentials.client_secret, "granted_scopes" : credentials.granted_scopes } @ app.route ( "/oauth2callback" ) def oauth2callback (): """認可レスポンスのリダイレクト先となる関数""" # stateを用いて整合性を検証しつつ、Flowオブジェクトを再生成 state = flask.session[ "state" ] flow = google_auth_oauthlib.flow.Flow.from_client_config( CLIENT_CONFIG, scopes=SCOPES, state=state ) flow.redirect_uri = flask.url_for( "oauth2callback" , _external= True , _scheme= "https" ) # 認可レスポンスに含まれる認可コード取得 authorization_response = flask.request.url.replace( "http" , "https" , 1 ) # アクセストークン含む認証情報を取得 flow.fetch_token(authorization_response=authorization_response) credentials = flow.credentials credentials = credentials_to_dict(credentials) flask.session[ "credentials" ] = credentials return flask.redirect( "/" ) @ app.route ( "/" , methods=[ "GET" ]) def webapp (): if "credentials" in flask.session: credentials = google.oauth2.credentials.Credentials( **flask.session[ "credentials" ]) # アクセストークンを埋め込んだindex.htmlを返す return flask.render_template( "index.html" , token=credentials.token) else : # OAuth 2.0の認証プロセスを管理するためのFlowオブジェクトを作成 flow = google_auth_oauthlib.flow.Flow.from_client_config( CLIENT_CONFIG, scopes=SCOPES ) flow.redirect_uri = flask.url_for( "oauth2callback" , _external= True , _scheme= "https" ) # 認可エンドポイントのURL取得 authorization_url, state = flow.authorization_url( access_type= "offline" , include_granted_scopes= "true" , prompt= "consent" ) flask.session[ "state" ] = state return flask.redirect(authorization_url) if __name__ == "__main__" : app.run(debug= True , host= "0.0.0.0" , port= 8080 ) 動作確認 Cloud Run サービスのデプロイ後、Cloud Run サービスに付与される URL にアクセスし動作確認を行います。 アクセスするとまず Google へのログインが求められ、ログイン後に OAuth 同意画面が表示されます。 同意画面にてスコープの許可を行うことで作成したウェブサイトにリダイレクトされます。 すると、ウィジェットが埋め込まれたページが現れ、Google ドライブを対象とした検索を行うことが可能となります。 堂原 竜希 (記事一覧) クラウドソリューション部クラウドエクスプローラ課。2023年4月より、G-genにジョイン。 Google Cloud Partner Top Engineer 2023, 2024, 2025に選出 (2024年はRookie of the year、2025年はFellowにも選出)。休みの日はだいたいゲームをしているか、時々自転車で遠出をしています。 Follow @ryu_dohara
アバター
G-gen の杉村です。BigQuery Data Transfer Service で Cloud SQL にホストされた PostgreSQL のデータを転送する検証を行いましたので、共有します。 はじめに BigQuery Data Transfer Service とは 当記事について 環境のセットアップ Cloud SQL インスタンスの起動 テーブルとデータの準備 転送の作成 検証 初回転送 レコードの追加(差分転送) レコードの更新 レコードの削除 挙動のまとめ はじめに BigQuery Data Transfer Service とは BigQuery Data Transfer Service は BigQuery に備え付きの、フルマネージドなデータ転送サービスです。設定したスケジュールに基づいて、各種取得元からデータを取得して BigQuery のテーブルにデータを取り込みます。容易に実装することができるうえ、料金も一部のコネクタを除いて無料です。 参考 : What is BigQuery Data Transfer Service? 以下の記事も参考にしてください。 参考 : BigQueryを徹底解説!(基本編) - BigQuery Data Transfer Service 当記事について 2025年1月に、BigQuery Data Transfer Service はデータの転送元として PostgreSQL や MySQL に対応しました(2025年1月現在、Preview)。 2025年1月現在、公式ドキュメントには、これらのデータベースからの転送を繰り返しジョブとして実行した際に、レコードの追加に対する差分転送やレコードの更新、削除がどのように転送先に反映されるかについての記述がありませんでした。これを検証するため、当記事では Cloud SQL にホストした PostgreSQL データベースから BigQuery データセットへのデータ転送を検証します。 結論からいうと、転送ジョブを複数回実行すると、レコードの追加、更新、削除はいずれも転送先の BigQuery テーブルに反映されました。内部的には WRITE_TRUNCATE ジョブが実行され、毎回データの全件洗い替えが行われます。 参考 : PostgreSQL transfers 環境のセットアップ Cloud SQL インスタンスの起動 Cloud SQL for PostgreSQL インスタンスを起動します。 スペックは最小限とし、Public IP アドレスを付与、また許可する接続元 IP アドレス範囲である「承認済みネットワーク」に 0.0.0.0/0 を追加します。 今回は簡易的な検証目的であるためこのように設定しましたが、インターネットのどのような場所からでもアクセスできるような設定は、 本来は推奨されません 。BigQuery Data Transfser Service から Cloud SQL に接続させる場合は、本来は以下のような手順を踏みます。 Cloud SQL インスタンスと Private Service Connect で接続された VPC ネットワークに踏み台 VM を作成する 踏み台 VM に Cloud SQL プロキシを起動する BigQuery Data Transfer Service のプロジェクトにネットワークアタッチメントを作成する BigQuery Data Transfer Service の転送でネットワークアタッチメントを紐づける つまり BigQuery Data Transfer Service から直接、Cloud SQL インスタンスにプライベート接続することは現時点ではできません。Cloud SQL プロキシを起動した VPC ネットワーク内の Compute Engine インスタンスを踏み台とする必要があります。 参考 : Configure Cloud SQL instance access テーブルとデータの準備 Cloud SQL のデータベースには、Google Cloud コンソールの Cloud SQL Studio と呼ばれる Web コンソール画面から接続し、直接 SQL を実行することができます。 以下のように、サンプルテーブルとデータを準備しました。 CREATE TABLE " public " .my_table ( id INT , data TEXT ); INSERT INTO " public " .my_table (id, data) VALUES ( 1 , ' this is a message. ' ), ( 2 , ' this is the second message. ' ); Cloud SQL Studio の画面 一方で BigQuery 側には、転送先のデータセットのみを Cloud SQL インスタンスと同じリージョンに用意しました。テーブルは作成しません。また、後述しますが転送先のデータセットは、Cloud SQL インスタンスと同じリージョンである必要はありません。 転送の作成 BigQuery Data Transfer Service で転送ジョブを作成します。Cloud SQL インスタンスのパブリック IP アドレス、ポート番号、データベース名、スキーマ名などを指定します。また転送先の BigQuery データセットや、転送元の PostgreSQL のテーブルも指定しました( postgres/public/my_table )。 転送の作成 実行頻度として、検証のため定期実行ではなく、指示したときに起動する オンデマンド としました。 検証 初回転送 初回の転送を実施してみます。 作成した転送ジョブの画面で「今すぐ転送を実行」を実行しました。 以下のように、データセットにテーブルが生成されました。あらかじめ BigQuery データセットにテーブルを作成していたわけではありませんが、自動的に適切なスキーマ( id INTEGER, data STRING )を持つテーブルが生成されました。ジョブ開始のログから終了ログの出力まで、約2分30秒ほどかかりました。 BigQuery にテーブルが初回転送された レコードの追加(差分転送) PostgreSQL のテーブルに、以下のように新しいレコードを挿入します。 INSERT INTO " public " .my_table (id, data) VALUES ( 3 , ' this is the third message. ' ), ( 4 , ' may the force be with you. ' ); その後、転送ジョブを再度実行します。以下のように、差分のみが BigQuery テーブルに転送されました。 追加されたレコードのみが BigQuery に転送された レコードの更新 PostgreSQL のテーブルのレコードを以下のように更新します。 UPDATE " public " .my_table SET data = ' you were the chosen one! ' WHERE id = 1 ; その後、転送ジョブを再度実行します。以下のように、更新されたレコードが BigQuery テーブルに反映されました。 レコードの更新が反映された レコードの削除 PostgreSQL のテーブルから、以下のようにレコードを削除し、さらに別のレコードを追加します。 DELETE FROM " public " .my_table WHERE id = 2 ; INSERT INTO " public " .my_table (id, data) VALUES ( 5 , ' this is the fifth element. ' ); その後、転送ジョブを再度実行します。以下のように、レコードの削除と追加がともに BigQuery テーブルに反映されました。 レコードの削除が反映された 挙動のまとめ 非常に簡単ではありますが、初回転送、レコードの追加、更新、削除を検証しました。いずれも BigtQuery Data Tranfser Service の転送ジョブが実行されるたびに、BigQuery テーブルに反映されました。 なお、転送ジョブによって実行された BigQuery ジョブのログを Cloud Logging で確認すると、 "writeDisposition": "WRITE_TRUNCATE" になっています。また転送終了後には次のようなログが出力されます。 Job 1234567890:postgresql_xxxxx-0000-xxxx-xxxx-xxxx (table my_table) completed successfully. Number of records: 4, with errors: 0. 転送ジョブは、毎回テーブルを TRUNCATE してデータを全件転送しなおしていることがわかります。もし転送元データベースが Google Cloud の外部にある場合、ネットワーク帯域やクラウドの Egress データ転送料金などに注意が必要です。 今回はいずれも少量のレコードの転送でした。いずれの実行の際も、ジョブ実行が開始されてから概ね1分後に実際の転送が開始された旨のログが出力され、その1分後に転送が完了した旨のログが出力されました。完了のログの約30秒後に、ジョブの完了を示す最終的なログが出力されました。 なお、転送先の BigQuery データセットは、転送元の Cloud SQL インスタンスと同じリージョンである必要はありません。異なるリージョンのデータセットを指定しても、転送は成功しました。 杉村 勇馬 (記事一覧) 執行役員 CTO / クラウドソリューション部 部長 元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 12資格、Google Cloud認定資格11資格。X (旧 Twitter) では Google Cloud や AWS のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-gen の杉村です。Google が提供するブラウザベースの IDE である Cloud Shell エディタや、コーディング支援 AI ツールである Gemini Code Assist を使い、Chromebook 上で開発環境を整備してみました。 はじめに 当記事について Cloud Shell エディタとは Gemini Code Assist とは ブラウザベースの IDE ブラウザ版 VS Code で開発する Cloud Shell エディタで開発する Cloud Code との統合 Gemini Code Assist の利用開始 利用開始手順 サブスクリプションの購入 ライセンスの割り当て Google Cloud プロジェクトで Gemini for Google Cloud API を有効化 Cloud Shell エディタで Gemini Code Assist を使う 有効化 コード生成 コード補完 スマートアクション チャットでの指示 その他 はじめに 当記事について G-gen では一部の部署を除き、従業員の作業端末として Chromebook を採用しています。Chromebook は、ChromeOS を搭載したノート型パソコン製品です。 ChromeOS とは、Google が開発した軽量な OS です。Linux カーネルをベースとしており、Google Chrome ブラウザを主なユーザーインターフェースとした、いわばブラウザベースの OS です。 Chromebook はブラウザベースの OS であることから、ローカルにインストールできるアプリケーションは限定的です。そのため当社のエンジニアは、Web アプリベースの IDE や、組み込みの Linux ターミナルを利用して開発を行っています。 当記事では、ブラウザから利用可能な Cloud Shell エディタや、Chromebook 上で生成 AI によるコーディング支援ツールである Gemini Code Assist などを活用しつつ、ソフトウェア開発のための環境整備を行う試みについて紹介します。 参考 : G-genの流儀。クラウドネイティブな10の働き方とは? Chromebook Cloud Shell エディタとは Cloud Shell エディタ は、Google Cloud コンソールに組み込みの、Web ブラウザベースの IDE です。仮想的な Linux 環境である Cloud Shell と連携しており、Cloud Shell で管理されるファイルやコードベース、バイナリなどと連携したソースコード開発が可能です。Cloud Shell と連携しているため Google Cloud(旧称 GCP)との連携も容易であり、特に Google Cloud と関連する開発に力を発揮します。 Cloud Shell エディタは Code OSS をベースにしています。Code OSS は Microsoft が開発したオープンソースの IDE であり、VS Code はこれをベースにしています。つまり Cloud Shell エディタは、VS Code ライクなインターフェイスを備えていると言えます。 参考 : Cloud Shell エディタを起動する Cloud Shell エディタ Gemini Code Assist とは Gemini Code Assist は、Google が提供するコーディング支援 AI ツールです。VS Code、JetBrains IDE(IntelliJ、PyCharm など)、Cloud Workstations、Cloud Shell エディタなどに対応しており、Bash、C++、C#、Go、Java、PHP、Python、Ruby、SQL など多くのプログラミング言語に対応しています。英語はもちろん、日本語にも対応しており、コード補完やコメントからのコード生成、デバッグ支援、ドキュメント化支援などを行います。 Gemini Code Assist には Standard と Enterprise の2ティアがあり、使用可能な機能と料金に差があります。 参考 : Gemini Code Assist の概要 また、Gemini Code Assist には無償プランもあり、基本的なコーディング補助であれば一定の制限のもとで無料で使うことができます。 参考 : Gemini Code Assist: AI coding assistance for any language ブラウザベースの IDE ブラウザ版 VS Code で開発する ブラウザベースで利用可能な最も有名な IDE として、 ブラウザ版 VS Code があります。 https://vscode.dev/ にアクセスするだけで起動します。ローカルのファイルシステムとも連携可能であり、Chromebook 上で起動する Linux ターミナルのファイルを閲覧、編集できます。 参考 : https://vscode.dev/ ブラウザ版 VS Code はデスクトップ版と比較して一部の機能が制限されており、対応していない拡張機能(Extensions)も多いです。例として GitHub Copilot や Gemini Code Assist は、ブラウザ版 VS Code では利用できません。 ブラウザ版 VS Code Cloud Shell エディタで開発する 当記事では前述のとおり、Cloud Shell エディタを主なエディタとして利用します。 Cloud Shell エディタは、Google Cloud の一部として提供されています。Cloud Shell エディタを起動するには、Google アカウントにログインした状態で Google Cloud コンソール( https://console.cloud.google.com/ )を開き、右上の Cloud Shell ターミナルボタンを押下してターミナルを開いたうえで、「エディタを開く」ボタンを押下します。 Cloud Shell ターミナルを開き、エディタを開く Cloud Shell エディタが開いたところ 「新しいウインドウで開く」ボタンを押下することで、Google Cloud コンソールとは独立して、単一のウインドウ(タブ)としてエディタを起動することもできます。このとき、Cloud Shell エディタと Cloud Shell コンソールを同一ウインドウ内に表示したり、片方を非表示にすることができます。 「新しいウインドウで開く」ボタン エディタとターミナルを1画面に表示。片方を非表示にもできる また Cloud Shell エディタ( https://ide.cloud.google.com/ )と Cloud Shell コンソール( https://shell.cloud.google.com/ )のそれぞれの URL からアクセスすることで、Cloud Shell エディタと Cloud Shell コンソールをそれぞれ別のウインドウで開くこともできます。 参考 : Cloud Shell エディタのインターフェースの概要 Cloud Code との統合 Cloud Shell エディタはデフォルトで Cloud Code と統合されています。Cloud Code は Google が提供する IDE 用プラグインであり、Google Cloud での開発を支援するツール群です。IDE のエディタ画面の中から Cloud Run、Google Kubernetes Engine(GKE)、BigQuery データセット、Secret Manager などのリソースをブラウジングしたり、これらのリソースに対するデプロイの支援がされます。 参考 : Cloud Code and Gemini Code Assist IDE Plugins Gemini Code Assist の利用開始 利用開始手順 生成 AI による開発支援ツールである Gemini Code Assist の利用開始手順も見ていきましょう。Cloud Shell Editor には、Gemini Code Assist の無料枠が付帯しています。Cloud Shell Editor 上では、 週に50時間まで無料 で Gemini Code Assist を利用できます。 参考 : Gemini Code Assist: AI coding assistance for any language - Prototype with a no-cost environment from Google Cloud もし有償版を購入したい場合、サブスクリプションを購入してユーザーに割り当てます。Gemini Code Assist はユーザーごとに課金される月額または年額のサブスクリプション形式を取っています。2025年1月現在、Standard ライセンスの月額費用は $22.8 / ユーザー です。 参考 : Gemini Code Assist pricing overview ライセンスの費用は、Google Cloud の 請求先アカウント に紐づきます。ライセンス購入作業を行うには、請求先アカウントに対して請求先アカウント管理者( roles/billing.admin )ロールもしくは Consumer Procurement Order 管理者( roles/consumerprocurement.orderAdmin )ロールが必要です。請求先アカウントの詳細は以下の記事を参照してください。 blog.g-gen.co.jp ここからは、実際の利用開始手順を解説します。当記事で紹介する手順やスクリーンショットは2025年1月現在のものです。ユーザーインターフェイスは変更される可能性がありますので、最新の手順については以下の公式ドキュメントを参照してください。 参考 : Gemini Code Assist ライセンスを管理する サブスクリプションの購入 Google Cloud コンソールで「Gemini の管理」>「GEMINI CODE ASSIST を管理」に遷移して、「サブスクリプションを管理」ボタンを押下し、サブスクリプションの管理画面へ遷移します。そこで、サブスクリプションのティアとライセンスの購入数を決定できます。この画面で、ライセンス費用の試算も確認できます。 参考 : サブスクリプション内の Gemini Code Assist ライセンス数を変更する サブスクリプションの購入画面 ライセンスの割り当て サブスクリプションの管理から、購入したライセンスをユーザー(Google アカウント)に割り当てます。ライセンスの自動割り当てを有効にすることもできます。自動割り当てが有効な場合、ライセンスの残数がある限り、新規ユーザーが Gemini Code Assist にアクセスした際にライセンスが自動的に割り当てられます。また指定した日数の間、非アクティブだったユーザーからは自動的にライセンスが剥奪されます。 参考 : Gemini Code Assist ライセンスを個々のユーザーに手動で割り当てる 参考 : Gemini Code Assist ライセンスを自動的に割り当てる ライセンスを割り当てられたユーザーはこれ以降、Gemini Code Assist を利用できます。 ユーザーへのライセンス割り当て画面 Google Cloud プロジェクトで Gemini for Google Cloud API を有効化 次に、Google Cloud プロジェクトで Gemini for Google Cloud API を有効化します。 Google Cloud コンソールで、 Gemini for Google Cloud の API 管理画面 に遷移します。画面左上のプロジェクトセレクタで対象のプロジェクトが選択されていることを確認して、「有効にする」ボタンを押下します。 参考 : Google Cloud プロジェクトで Gemini for Google Cloud API を有効にする Cloud Shell エディタで Gemini Code Assist を使う 有効化 Cloud Shell エディタで Gemini Code Assist の機能を使い始めるには、まず有効化作業が必要です。 最初に、Cloud Code の機能により、エディタと Google Cloud プロジェクトをリンクします。 ライセンスを割り当てたユーザーで Cloud Shell エディタを開き、画面下部の雲のマークの横に「Cloud Code - Sign in」と表示されている箇所をクリックします。Google Cloud API への認証を求められたら、「承認」を押下します。 次に、画面右下の Gemini マーク(星型のマーク)をクリックし、プルダウンメニューから「Gemini Code プロジェクトを選択」して Gemini for Google Cloud API を有効化したプロジェクトを選択します。斜め線が入っていた星型マークから、斜め線が消えたら準備完了です。 参考 : Gemini Code Assist によるコード Cloud Shell での Gemini Code Assist 有効化 コード生成 ソースコードに、実装したい処理を説明するコメントを入力し、Enter で改行した後に、Control + Enter を押下します。コードの提案がグレーの文字で表示されるので、提案を採用する場合は tab キーを押下します。 コメントでプロンプトを与えるコード生成 また、画面左側のメニューで Gemini の星型マークを選択し、チャット欄を表示させたうえで、ソースコードの特定の部分を選択して Gemini にチャットで指示を与え、新たなコードを生成させることもできます。 コード部分を選択したうえでのコード生成 コード補完 ソースコードを記述している途中に、Gemini Code Assist は自動的にコードの続きを提案します。提案を適用するには、tab キーを押下します。 自動的なコード補完 スマートアクション ソースコードの中で、該当するソースコード部分を選択すると電球マークが表示されます。この電球マークをクリックすると、「ユニットテストを生成する」など、その部分に関する様々なアクションが提案されます。 スマートアクション チャットでの指示 画面左側のメニューで Gemini の星型マークを選択し、チャット欄を表示させることで、様々な指示を与えることができます。ソースコードを説明させたり、ソースコードを生成させたり、あるいはテスト環境の構築に必要な gcloud コマンドラインを生成させたりすることもできます。 チャットで Gemini に指示を与える その他 その他に、Google Cloud を基盤とするアプリケーションの開発などに役立つ情報を記載します。 Google Cloud APIs をローカル PC や Cloud Shell 上から呼び出す際は、認証情報の設定が必要です。gcloud CLI を実行するときと、Python 等のクライアントライブラリを使ったプログラムを実行するときで、認証情報の設定方法が異なります。以下の記事では、自分の Google アカウントの認証情報をローカルのプログラムに設定する方法について解説しています。 blog.g-gen.co.jp Google Cloud のサーバーレスプログラム実行環境である Cloud Run functions でアプリケーションを開発する際に、 Functions Framework を使うことで、ローカル PC や Cloud Shell 上でテスト実行することができます。以下の記事では、Functions Framework の使い方について解説しています。 blog.g-gen.co.jp 杉村 勇馬 (記事一覧) 執行役員 CTO / クラウドソリューション部 部長 元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 認定資格および Google Cloud 認定資格はすべて取得。X(旧 Twitter)では Google Cloud や Google Workspace のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター