Google Marketplaceベンダー開発をシンプルに
Dave Cavalettoとの共著
Google Marketplaceで販売するソリューションの開発自体は、技術的にそれほど難しいものではありません。本当の難しさは、これがエンタープライズ型の統合だという点にあります。Google Cloud Platformで公開されているAPIに自由にアクセスするのとは違い、もう一方の企業であるGoogleの業務システムに接続する必要があるのです。統合を作り始める前にGoogleからGCPプロジェクトの承認を得る必要があり、リリース直前にはソリューション自体も改めて承認を受けなければなりません。
DoiT-Easilyは、DoiTのエンジニアが作成した、実際に動作するサンプル統合を公開しているオープンソースプロジェクトです。動作はしますが、本番運用に耐える製品ではなく、サポート提供の対象でもありません。あくまで学習用のクイックスタート例として、また本番ソリューション開発のたたき台としてご活用いただくことを想定しています。

製品の市場投入をもっと速く。
以前の投稿では、Marketplace向け製品の作成について全体像をご紹介しました。本記事ではDoiT-Easilyについてさらに踏み込み、主要なアーキテクチャ要素や開発時に直面しがちな課題を取り上げます。Marketplace統合に必須ではないがDoiT-Easilyに実装されている機能、逆に他のMarketplace統合では見られるがDoiT-Easilyには含まれていない機能についても触れていきます。詳細は、DoiT-EasilyのGitHubプロジェクトのドキュメントとコード、ならびにGoogleのMarketplace公式ドキュメントをご参照ください。
フロー
以下の図は、主要な2つのフロー、すなわち新規ユーザー作成と新規エンタイトルメント(購入)作成を分解して示したものです。エンタイトルメントの新規作成、変更、キャンセルはいずれも同じフローで処理されます。新規ユーザーが同時にエンタイトルメントにサインアップする場合は、両方のフローが並行して実行されます。
フロー図の後に、コンポーネントの図と解説を掲載しています。
新規ユーザー
新規ユーザーフロー
新規エンタイトルメント
エンタイトルメントフロー
コンポーネント
以下のDoiT-Easilyのアーキテクチャ図には、統合を構成するコンポーネントと、連携するGoogle APIが示されています。
下半分が自社側の機能コンポーネント、上半分がGoogleのAPIです。
Googleと統合する自社のSaaS本体は、この例には含まれていません。SaaSサーバーは別のGoogleプロジェクトにデプロイすることも、統合システムと同じプロジェクトにデプロイすることもできます。
以下、これらのコンポーネントを詳しく見ていきます。
DoiT-Easilyのアーキテクチャ
フロントエンド
図中のフロントエンド統合は、クライアントとサーバーから成るWebアプリです。DoiT-Easilyでは、HTMLテンプレートを用いたHTML/AJAXのクライアントを実装しています。サーバーはPythonで実装され、Cloud Runにデプロイされます。もちろん、自社の実装では別の技術を選んでも問題ありません。
フロントエンドクライアントは、サインアップフロー中にGCP Marketplaceから転送された購読者がリダイレクトされてくるランディングページを表示します。フロントエンドはリクエスト内のJWTを検証し、Googleからの正当なリクエストであることを確認します。ユーザーがサインアップすると、フロントエンドサーバーはGoogleのProcurement APIに通知し、購読者のProcurementアカウントを作成します。フロントエンド統合のサーバーロジックはすべてlogin()関数にまとめられており、/activateまたは/loginパスからアクセスできます。
バックエンド
バックエンド統合も、Cloud Runにデプロイされるサーバーです。DoiT-Easilyでは同じCloud Runサービスにまとめていますが、自社のアプリケーションではフロントエンドとバックエンドを別サービスに分けることもできます。バックエンドは、エンタイトルメントを通知するPub/SubメッセージをGoogleから受信します(「エンタイトルメント」は、自社製品のサブスクリプションを指すGoogleの用語です)。
Cloud Runアプリケーションの中核となるapi.pyファイルには、ほとんど使われないWebエンドポイントも数多く含まれているため、メインフローに絞って読むのがおすすめです。メインフローは、handle_subscription_message()関数で処理されるプッシュサブスクリプションを通じてPub/Subから起動され、/v1/notificationパスからアクセスできます。
バックエンドUI
DoiT-Easilyでは、基本的なMarketplace統合アーキテクチャでは必須ではない、バックエンド向けの追加UIも提供しています。これは、保留中のエンタイトルメントを一覧表示し、自動承認の仕組みを備えていない場合に手動で承認するために使えます。サーバーコードはapp.pyの/appパスで確認でき、Identity-Aware Proxy(IAP)で保護されています。
app.pyには、このアプリを支える複数のエンドポイントが用意されています。アプリのメインページに加え、エンタイトルメントの一覧・承認・拒否、およびアカウントの一覧を行うメソッドが含まれています。
その他のエンドポイント
api.pyファイル内の他のエンドポイントはすべて、Procurement APIに対する認証付きプロキシとして利用可能です。これにより、独自に作成したソリューションがProcurement APIに直接アクセスせず、DoiT-Easily経由でやり取りできるようになります。
Usage Reporter
Usage ReporterはDoiT-Easilyには含まれていませんが、製品の顧客利用状況をGoogleのService Control APIに報告するためのコンポーネントです。処理データ量やソリューションへの呼び出し回数といったリソース単位で課金する場合に必要となります。一方、無料提供や月額サブスクリプション制のソリューションでは不要であり、これがDoiT-Easilyに含まれていない理由です。
Usage Reporterを実装するなら、エンタイトルメント(自社製品の購読者)を追跡する独自のデータストアを用意し、そのレコードをもとにGoogleへ利用状況を報告する形が一般的です。DoiT-Easily自体はデータストアを持たず、すべてのエンタイトルメントとその状態をProcurement API側に保持させる構成になっています。
ISVプロビジョニングサービス
新規顧客ごとにSaaSソリューション側で新たなリソース要件が発生する場合は、それらを管理するためのコンポーネントを作成できます。たとえば顧客ごとにGoogle Kubernetes Engineの専用Podや名前空間を割り当てるようなケースでは、ISVプロビジョニングサービスがそのセットアップを担います。多くのSaaSソリューションでは必須ではないため、DoiT-Easilyには含まれていません。
その他のクラウドコンポーネント
図中のクライアント・サーバーコンポーネントに加えて、DoiT-Easilyには以下のクラウドインフラリソースが含まれます。特に断りがない限り、DoiT-Easily内のTerraformモジュールがこれらをデプロイします。
Google Marketplaceで定められているもの
- IAM:複数のGoogleサービスアカウントに対し、自社プロジェクトへの権限を付与します。自社のサービスアカウントがGoogleにアクセスする側の権限はここでは定義せず、Producer Portalから申請します(「セットアップ」のステップ5、詳細はこちら)。
- Pub/Sub:エンタイトルメントイベントに関するメッセージをGoogleが配信するトピックです。このトピックはGoogle所有のプロジェクト内にあり、後述の「セットアップ」を進める際にGoogleが作成します。自社のバックエンドはこのトピックを購読します。
その他のクラウドサービス
DoiT-Easilyでは以下のクラウド技術を使用しています。同等の機能を備えていれば、別の選択肢でも構いません。
- 前述のとおり、フロントエンドおよびバックエンド用のCloud Runサービス。
- Cloud DNSゾーン:各Marketplaceリスティングは独自のパブリックアドレスを持ち、Google Marketplaceはサインアップリクエストをそのアドレスへ転送します。これらのドメインを提供するのがDNSゾーンです。Terraformはこのリソースを作成しません。既存のゾーンがあることを前提としています。
- ロードバランサーは、Google Marketplaceから転送されたものを含むリクエストを受け取り、該当するMarketplaceリスティングのサービスへルーティングします。ロードバランサーには、関連するパブリックIPアドレス、TLS証明書、IAP、ルーティングルールが紐付きます。
- Cloud Run用の構成ファイル(GCP Secret ManagerにSecretとして保存)。TerraformがSecretオブジェクトを作成します。DoiT-Easilyをデプロイする際は、必要に応じてSecret Manager内の値を更新してください。更新するとバージョン番号が上がるため、tfvars側でも合わせて更新する必要があります。構成ファイルには、機密として扱うべき環境値と、利便性のために含めているそうでない値の両方が含まれます。
デプロイ手順
DoiT-Easilyのセットアップは以下のフェーズで進めます。一部にはTerraformモジュールが用意されています。example.tfvarsをterraform.tfvarsにコピーして値を編集し、terraform initとterraform applyを実行してください。
事前準備
事前準備フェーズという名称は、Googleがプロジェクトを承認する前段階で行うことに由来します。Terraformはプロジェクト本体に加え、GoogleのサービスアカウントがプロジェクトにアクセスするためのIAMロール、デプロイを実行するユーザー向けのロールを作成します。
Googleとのセットアップ
承認申請のフォームを提出してプロジェクトをセットアップします。承認には数週間かかることもあります(進め方に不安があればぜひDoiTにご相談ください)。承認後はProducer Portalで、価格、製品情報、Googleが権限を付与するサービスアカウントなど、リスティングの内容を最終確定させます。
デプロイ
Cloud BuildでCloud Runアプリをビルドし、イメージをArtifact Registryにプッシュします。続いて、DNSゾーンやロードバランサーといった必要なクラウドリソースとあわせて、Terraformでアプリをデプロイします。
テスト
開発中は、DoiT-Easilyをローカルで実行し、付属のユニットテストを走らせることができます。
ソリューションのデプロイ後は、Marketplaceプロジェクト上でユーザー登録、購入、承認のステップを順に実行しながら手動でテストできます(リスティングが公開されるまでは、プライベートプレビュー状態となります)。
Googleが提供する自動統合テストフレームワークも利用可能で、Googleはこのテストの合格を公開の前提条件としています。
プライベートオファーのみを提供する場合、自動テストは決して成功しません。このステップをスキップしてもリスティングを公開できます。
公開
公開の最終ステップでは、Googleの手動承認を申請します。これは、継続的デプロイのように1日に何度も本番反映して細かく修正・改善するというやり方ができないことを意味します。新バージョンごとに、承認待ちで数日のラウンドトリップが発生する可能性があります。
制限事項
DoiT-Easilyに限らず、Marketplace統合の実装には、一般的なクラウドアプリケーションと比べて避けて通れない制限がいくつかあります。また、DoiT-Easilyにはあえて実装していない機能もあります。
プロジェクトごとに承認が必要
事前準備を済ませた後、Googleからプロジェクトの承認を得る必要があります。つまり、ソリューションを動かせるプロジェクトは1つに限られ、開発・テスト・ステージング・本番のプロジェクトを別々に持つことはできません。
プロジェクトを利用する前に承認が必要となるリソースは、簡単に削除して再作成することができません。そのため、スクリプトで新しいサンドボックスプロジェクトを作成してアプリケーションをセットアップし、テストを実行した後にすべてを削除する、といったエンドツーエンドのテストは行えません。同様に、Marketplaceプロジェクト内のリソースをすべて一掃して最初からやり直すこともできません。Marketplaceに組み込まれたテスト・プレビュー機能を使ったテストは可能ですが、まっさらな状態で開始・終了するテストにはなりません。
同じ理由で、開発チームのメンバーごとに新しい開発環境を個別に用意することもできません。代わりにメンバー間でプロジェクトを共有することになりますが、その場合は各メンバーがそれぞれ別のリスティングを作成するアーキテクチャを設計する必要があります。プロジェクト、IAM設定、ロードバランサー、Pub/Subトピック、DNSゾーンといった他のインフラはすべて共有されます。各アプリはPub/Subトピックを購読したうえで、自分宛てのメッセージだけを処理する必要があります。なお、DoiT-Easilyでは複数リスティング対応は完全には実装されておらず、複数リスティングの作成自体は妨げられないものの、Terraformのデプロイコードがそれを前提とした作りになっていません。
これは、DoiT-Easilyを動かす場合も他のMarketplace統合と同じく、Googleの承認を経た正式なMarketplaceプロジェクトが必要であることを意味します。
代替シナリオ
DoiT-Easilyは特定の1シナリオを示すために作られていますが、エンタープライズ型のB2B統合では珍しくないことに、Marketplaceソリューションはカスタムのバリエーションで構築されることがよくあります。一例がプライベートオファー専用のソリューションです。これによりベンダーは販売プロセスをよりコントロールでき、前述のフロントエンドも不要になります。ただしプライベートオファーを管理する社内ツールが必要となるため、多くのベンダーは社内向けWebアプリを構築しています。
DoiT-Easilyは実際に動作するものの、1本のスクリプトで完全な機能を備えたシステムを構築できるようなターンキーソリューションではありません。理由の1つは、Googleとの複数ステップのプロセスに手作業が必要になること。もう1つは、各ベンダーのニーズに合わせたカスタム開発がソリューションごとに必要になることです。それでも、Google Marketplace統合を独自に開発するうえでのクイックスタートおよび土台として活用できます。DoiTには、このプロセスをお客様と共に進めてきた豊富な経験があります。お気軽にdoit.com/supportまでお問い合わせください。