アドオンの構築
最終更新日 2024年02月06日(火)
Table of Contents
この記事では、Heroku Elements Marketplace のアドオンを開発するための基本的な手順について説明します。アドオンの開発に関するその他の高度なトピックについては、「高度な統合」を参照してください。
アドオンはクラウドサービスであるため、希望するどのような言語またはフレームワークでも開発できます。アドオンは Heroku 上で実行する必要はありません。
アドオンの主な技術要件は次のとおりです。
- HTTPS リクエストを受信できる必要があります。
- JSON を解析できる必要があります。
この記事は、ユーザーが、最新であり、かつすべての新しい統合で使用されている Add-on Partner API v3 を使用していることを前提に記述されています。アドオンが 2018 年 4 月より前に作成された場合は、v1 のもとでの高レベルのプロセスが記載されているこの記事の従来のバージョンが必要である可能性が最も高くなります。アドオンで使用している Add-on Partner API のバージョンは、パートナーポータルの 「Settings」 (設定) -> 「Provisioning API」 (API のプロビジョニング) で確認できます。
アドオンのライフサイクルについて
Heroku は、ユーザーが作成して操作するエンドポイントに HTTPS で送信される JSON リクエスト経由でアドオンサービスと通信します。顧客がアドオンに関連したアクションを実行すると、関連するパラメータを使用して、ユーザーが操作するエンドポイントへのリクエストが作成されます。その後、ユーザーはこれらの顧客リクエストに応答するために、インフラストラクチャ内の必要な変更を調整します。
アドオンは、プロビジョニングリクエストが送信された時点から、秒単位で課金されます。詳細は、「使用時間と請求」を参照してください。
実装する必要があるアクションは次のとおりです。
- アドオンの新しいインスタンスのプロビジョニング
- OAuth トークンの交換
- アドオンインスタンスのプロビジョニング解除
実装できるオプションのアクションには、次のものが含まれます。
- プランのアップグレードまたはダウングレード
- アドオンリソースに関連付けられているアプリでの Webhook の作成
- Heroku の顧客が提供されているダッシュボードにログインできるようにするための SSO の実装
- パートナー向け Platform API を経由した、顧客またはそのアプリ環境に関する追加情報の要求
OAuth トークンの交換は、基本的な統合に技術的に必要というわけではありませんが、それがないと、非同期プロビジョニング またはパートナー向け Platform API を使用できなくなります。
アドオンサービスのプランやその他の多くの属性は、アドオンパートナーポータルで設定されます。
開始する前に: アドオンパートナーとして登録する
まだアカウントがない場合、まず、無料の Heroku アカウントを作成します。
アカウントを作成したら、パートナーポータルにアクセスし、必要に応じてログインします。パートナーポータルへのアクセスおよびその使用は、Heroku Elements Marketplace の salesforce.com ライセンスおよびディストリビューション契約によって管理され、イタリア在住の場合、Heroku Elements Marketplace プロバイダーのための追加規約によって管理されます。Heroku Elements Marketplace の salesforce.com ライセンスおよびディストリビューション契約の目的は、パートナー会社と Heroku とのビジネス関係を築くことです。これには、次のものが含まれます。
- Heroku Elements Marketplace 経由での製品の配信。
- 両者の知的財産の保護。
- 支払い、報告、監査を含む収益共有の条件。
- 価格変更のルール。
- パートナー会社と Heroku が、次に予定している製品の機能や使用状況メトリクスなどに関する詳細を共有できるようにする機密性。
- 技術サポートとマーケティングの責任。
サインアップする前に、該当する契約およびポリシーの契約条件に精通しておくようにしてください。
手順 1: アドオンマニフェストを生成する
すべてのアドオンには、アドオンのメタデータ、設定、資格情報が含まれる addon-manifest.json
ファイルがあります。アドオンマニフェストは、Heroku の addons-admin CLI プラグインを使用して作成します。
まず、Heroku CLI がインストールされ、heroku login
経由でログインしていることを確認します。
次に、addons-admin プラグインをインストールします。
$ heroku plugins:install addons-admin
その後、次のコマンドを使用して、アドオンのルートディレクトリにマニフェストを生成できます。
$ heroku addons:admin:manifest:generate
addon-manifest.json
ファイルが現在の作業ディレクトリに作成されます。マニフェストには秘密情報が含まれているため、ソース管理にチェックインしないでください。
生成されたマニフェストは、デフォルト値やプレースホルダー値を含むスケルトンです。機能するアドオンサービスを作成するには、マニフェスト内の一部の属性を変更する必要があります。
マニフェストファイルを編集し、id
フィールドを、開発者が CLI 経由で操作する場合に指定するアドオンの識別子に設定します。この識別子は [Heroku Elements] ページへのパスでも使用され、不変の値です。
id
はアドオン slug
とも呼ばれます。
たとえば、製品の名前が “MySQL-o-Matic” である場合は、id
として mysqlomatic
を指定できます。後で、パートナーポータルを使用して、Heroku Elements Marketplace の人間が理解できる表示名とマーケティングコピーを指定できます。
マニフェストのフィールドの詳しい説明は、アドオンマニフェストの形式 を参照してください。
アドオンパートナーが、アドオンの -staging
バージョンを作成して新機能の “フルスタック” をテストし、この -staging
アドオンを自身が管理する統合インフラストラクチャのステージングバージョンにすることは一般的です。これを新しいアドオンの構築中に行って、統合のマイルストーンに到達したときにテストするための安全な場所を確保することもできます。
手順 2: Add-on Partner API と統合する
Heroku の顧客がアドオンに関連した特定の管理アクション (そのプロビジョニングや、その現在のプランの変更など) を実行すると、ユーザーが必要なアクションを実行できるように、Heroku は登録されているエンドポイントにリクエストを送信します。これらのリクエストは Add-on Partner API の一部です。
Add-on Partner API のリクエストを適切に受信および処理するように、アドオンを設定する必要があります。SSL 、べき等性、リクエスト本体の検証、ヘッダーのバージョン管理、エラー処理に関するガイドラインは、「Add-on Partner API」を参照してください。
基本認証
Partner API に関する Heroku からのリクエストでは、すべての操作に対して HTTPS での基本認証を使用します。アドオン統合エンドポイントに基本認証を構築する必要があります。Heroku が送信するユーザー名はマニフェスト内の id
(以前に選択した識別子) 、パスワードはマニフェストで設定されている password
フィールドになります。
use Rack::Auth::Basic, "Heroku API" do |username, password|
Rack::Utils.secure_compare(::Digest::SHA256.hexdigest(username), ::Digest::SHA256.hexdigest("<id from manifest>")) &
Rack::Utils.secure_compare(::Digest::SHA256.hexdigest(password), ::Digest::SHA256.hexdigest("<password from manifest>"))
end
プロビジョニングリクエスト
顧客がアドオンをプロビジョニングするためのリクエストを作成すると、Heroku は、アドオンマニフェストで設定されているドメインにある /heroku/resources
エンドポイントに JSON ペイロードを含む POST
リクエストを送信します。
一般に、アドオンインスタンスは resource
と呼ばれます。
Heroku からプロビジョニングリクエストを受信したアドオンでは、次のことを行う必要があります。
- 正常な HTTP ステータスコードで応答します。
- アドオンリソースを一意に識別するために必要な関連するメタデータを保存します。
- リソースをプロビジョニングします。
- 安全なスコープ指定されたパートナー向け Platform API アクセスを可能にするために、OAuth トークンを交換します。
- 所有アプリの環境に含められる関連する設定値を使用して更新を申請します。
これは非同期的に行うことも、同期的に行うことも可能です。それは、プロビジョニングプロセスにかかる時間によって異なることがあります。
リクエストの例
# POST /heroku/resources
{
"callback_url": "https://api.heroku.com/addons/01234567-89ab-cdef-0123-456789abcdef",
"name": "acme-inc-primary-database",
"oauth_grant": {
"code": "01234567-89ab-cdef-0123-456789abcdef",
"expires_at": "2016-03-03T18:01:31-0800",
"type": "authorization_code"
},
"options": { "foo" : "bar", "baz" : "true" },
"plan": "basic",
"region": "amazon-web-services::us-east-1",
"uuid": "01234567-89ab-cdef-0123-456789abcdef",
... Some fields omitted
}
実装の擬似コードの例
以下の応答の例は、非同期プロビジョニング を使用していることを前提としています。同期プロビジョニング では、一部のプロセスを結合したり、リクエストを省略したりできます。
post '/heroku/resources' do
# The OAuth client secret for your add-on service can be retrieved from the partner
# portal and should be stored encrypted at rest.
oauth_client_secret = config.get('oauth_client_secret')
# Create an instance of your add-on for the app uuid in the request
resource = Resource.create!(
plan: json_params[:plan],
region: json_params[:region],
oauth_grant_code: json_params[:oauth_grant][:code],
oauth_grant_expires_at: parse_time(json_params[:oauth_grant][:expires_at]),
oauth_grant_type: json_params[:oauth_grant][:type],
heroku_uuid: json_params[:uuid] # The resource uuid used in all related requests
)
# Exchanging tokens could be done in a background job
access_token_response = ExchangeGrantCode.exchange(
grant_code: resource.oauth_grant_code,
oauth_client_secret: oauth_client_secret
)
response = {
# Unique identifier, which can (and probably should) be the UUID we provide
id: resource.heroku_uuid,
message: "Your add-on is being provisioned. It will be available shortly."
}
status 202
response.to_json
end
応答の例
{
"id": "37136775-c6f6-4d29-aa6b-12d1dad4febb",
"message": "Your add-on is being provisioned. It will be available shortly."
}
非同期プロビジョニングプロセスを完了するには、引き続き設定値を更新し、プロビジョニングを完了とマークする必要があります。
プロビジョニング解除リクエスト
顧客がアドオンを削除すると、DELETE
リクエストが Heroku から登録されている統合エンドポイントに送信されます。このリクエストには、プロビジョニングリクエストと同様に HTTPS および HTTP 基本認証が使用されます。詳細は、「Add-on Partner API リファレンス」の記事のプロビジョニング解除のセクションを参照してください。
DELETE
リクエストにはリクエスト本体が含まれていません。URL から heroku_uuid
を解析する必要があります。
リクエストの例
DELETE /heroku/resources/:heroku_uuid HTTP/1.1
Host: <your-addon.example.com>:443
Authorization: Basic YWRkb24tc2x1ZzpzdXBlci1zZWNyZXQ=
Content-Type: application/json
Accept: application/vnd.heroku-addons+json; version=3
実装例
delete '/heroku/resources/:heroku_uuid' do
Resource.find_by(heroku_uuid: params[:heroku_uuid]).destroy
status 204
end
応答の例
リクエストを正常に受信して処理したことを知らせるには、204 No Content
応答を返します。
プラン変更リクエスト (アップグレード/ダウングレード)
顧客がその現在のアドオンプランを変更すると、 PUT
リクエストが Heroku からアドオン統合 API エンドポイントに送信されます。このリクエストには、Heroku の顧客が変更先として希望するプラン slug が含まれています。
アドオンはプラン変更リクエストを受信した場合、次のことを行う必要があります。
- リクエストに応じていずれかの機能と設定をアップグレードまたはダウングレードする
- 必要なすべての状態 (データベースの内容など) を自動的に移行するこれを行うことができない場合は、アドオンの Dev Center ドキュメントで、顧客がこれを手動で行うための方法を詳細に記載する
- 新しいプランで使用するすべての新しい設定値で応答する
リクエストの例
PUT /heroku/resources/:heroku_uuid HTTP/1.1
Host: <your-addon.example.com>:443
Authorization: Basic YWRkb24tc2x1ZzpzdXBlci1zZWNyZXQ=
Content-Type: application/json
Accept: application/vnd.heroku-addons+json; version=3
実装例 (Ruby)
put '/heroku/resources/:heroku_uuid' do
resource = Resource.find_by(heroku_uuid: params[:heroku_uuid])
original_plan = resource.plan
resource.change_plan(json_params[:plan])
result = {
config: {
ADDON_SLUG_URL: resource.url
},
message: "Successfully changed from #{original_plan} to #{resource.plan}"
}
result.to_json
end
応答の例
{
"config": {
"ADDON_SLUG_URL": "https://user:password@service.example.com/new-url"
},
"message": "Successfully changed from original_plan to another_plan"
}
シングルサインオン
シングルサインオン (SSO) 統合を実装すると、アドオンの顧客に Web UI コントロールパネルを提供できます。SSO を実装するための詳細なガイドを参照してください。
手順 3: アドオンをデプロイする
サービスが正常に動作するようになったら、それをインターネットからアクセスできるどこかの場所にデプロイします。(もちろん可能ですが) 必ずしも Heroku にデプロイする必要はありません。
アドオンをデプロイしたら、addon-manifest.json
ファイルで production
属性内の base_url
と sso_url
の値を変更して、デプロイされたアプリを指すようにします。
最後に、更新した addon-manifest.json
ファイルを Heroku にプッシュしてアドオンを登録します。アドオンのパートナー向けサービス利用規約に同意したアカウントで Heroku CLI にログインしている必要があります。
$ heroku addons:admin:manifest:push
この時点では、アドオンはその公開者 (のみ) がプロビジョニングのためにアクセスできる状態です。公開者はパートナーポータルでアドオンの詳細を管理したり、Heroku Dashboard または CLI からアドオンをインストールしたりできます。
次のステップ
プランの管理や Heroku Elements Marketplace でのアドオンのリリースに関連したその他のトピックについては、「アドオンのリリース」を参照してください。
高度な統合
Heroku との統合により、他にも多くのことを実現できます。より高度な統合についての詳細は、以下の記事をご覧ください。
次の記事: アドオンのリリース