チュートリアル:製品を作成して発行する

適用対象: すべての API Management レベル

Azure API Management の "製品" には、少なくとも 1 つの API と、使用量クォータや利用規約が含まれています。 製品が発行された後、開発者は製品をサブスクライブして、製品の API の利用を開始できます。

このチュートリアルでは、以下の内容を学習します。

  • 製品を作成して発行する
  • 製品に API を追加する
  • 製品の API にアクセスする

ポータルにおける API Management の製品

前提条件

製品を作成して発行する

  1. Azure portal にサインインして、API Management インスタンスに移動します。

  2. 左側のナビゲーション ペインで、[製品]>[+ 追加] を選択します。

    Azure portal で製品を追加する

  3. [製品の追加] ウィンドウで、以下の表に記載されている値を入力して製品を作成します。

    製品ウィンドウを追加する

    名前 説明
    表示名 開発者ポータルで表示する名前です。
    説明 製品の目的、アクセスできる API、その他の詳細など、製品に関する情報を入力します。
    都道府県 開発者ポータルに製品を発行する場合は、[発行済み] を選択します。 製品に含まれる API を開発者が検出できるようにするには、あらかじめ製品を発行しておく必要があります。 既定では、新しい製品は発行されません。
    サブスクリプションを要求する ユーザーが製品を使用するためにサブスクライブする必要があり (製品が "保護されて" おり)、サブスクリプション キーを使用して製品の API にアクセスする必要がある場合に選択します。 サブスクリプションが必要ない (製品が "オープン" である) 場合、製品の API にアクセスするためにサブスクリプション キーは必要ありません。 この記事の後半の「製品の API にアクセスする」を参照してください。
    承認が必要 この製品に対するサブスクリプションの申し込みを管理者の審査の下で承認または拒否する場合はオンにします。 オフの場合、サブスクリプションの申し込みは自動承認されます。
    サブスクリプション数の制限 必要に応じて、複数同時に利用できるサブスクリプションの数を制限します。
    法的条項 サブスクライバーが製品を使用するにあたって同意する必要がある製品の使用条件を入力できます。
    API 1 つまたは複数の API を選択します。 製品の作成後に API を追加することもできます。 詳細については、「製品への API の追加」を参照してください。

    製品がオープンである (サブスクリプションが必要ない) 場合は、別のオープンな製品に関連付けられていない API のみを追加できます。
  4. [作成] を選択して新しい製品を作成します。

注意事項

サブスクリプションを必要としない製品を構成する場合は注意が必要です。 この構成では制限が過度に緩められ、製品の API が特定の API セキュリティの脅威に対してより脆弱になるおそれがあります。

構成をさらに追加する

製品を保存した後、続けてその構成を行います。 API Management インスタンスで、 [製品] ウィンドウから製品を選択します。 次の項目を追加または更新します。

アイテム 説明
設定 製品のメタデータと状態
API 製品に関連付けられている API
ポリシー 製品の API に適用されるポリシー
アクセス制御 開発者またはゲストに向けた製品の可視性
サブスクリプション 製品のサブスクライバー

製品への API の追加

製品には、1 つまたは複数の API が関連付けられています。 多数の API を組み込み、開発者ポータルを通じてそれらを開発者に提供できます。 製品の作成中、既存の API を追加することができます。複数の API を追加することも可能です。 製品には後から API を追加できます。 [設定] ページを使用して追加することも、API の作成時に追加することもできます。

既存の製品に API を追加する

  1. API Management インスタンスの左側のナビゲーションで [製品] を選択します。
  2. 製品を選択してから、[API] を選択します。
  3. [+ API の追加] を選択します。
  4. 少なくとも 1 つの API を選択してから、[選択] を選択します。

既存の製品に API を追加する

製品の API にアクセスする

製品が発行された後、開発者は API にアクセスできます。 製品の構成方法によっては、アクセスのために製品をサブスクライブする必要があります。

  • 保護された製品 - 開発者は、保護された製品の API にアクセスするために、まずその製品をサブスクライブする必要があります。 サブスクライブすると、その製品の API にアクセスできるサブスクリプション キーを受け取ります。 API Management インスタンスを作成した場合は、既に管理者になっているため、既定ですべての製品をサブスクライブしています。 詳細については、「Azure API Management のサブスクリプション」を参照してください。

    クライアントが有効な製品サブスクリプション キーを使用して API 要求を作成すると、API Management では要求を処理し、製品のコンテキストでのアクセスを許可します。 製品のために構成されたポリシーとアクセス制御規則を適用できます。

    ヒント

    REST API または PowerShell コマンドを通じてカスタム サブスクリプション キーを使用して、製品へのユーザーのサブスクリプションを作成または更新できます。

  • オープンな製品 - 開発者は、サブスクリプション キーを使用せずにオープンな製品の API にアクセスできます。 ただし、OAuth 2.0クライアント証明書呼び出し元 IP アドレスの制限など、API へのクライアント アクセスをセキュリティで保護する他のメカニズムを構成することもできます。

    Note

    オープンな製品は、開発者が学習したりサブスクライブしたりするための開発者ポータルには表示されません。 これらは、管理者グループにのみ表示されます。 サブスクリプション キーなしでアクセスできる API について開発者に通知するには、別のメカニズムを使用する必要があります。

    クライアントでサブスクリプション キーを使用せずに API 要求を行う場合:

    • API Management では、API がオープンな製品に関連付けられているかどうかを確認します。 API は、最大 1 つのオープンな製品に関連付けることができます。

    • オープンな製品が存在する場合は、そのオープンな製品のコンテキストで要求を処理します。 オープンな製品のために構成されたポリシーとアクセス制御規則を適用できます。

詳細については、サブスクリプション キーを使用する場合としない場合の API Management での要求の処理方法に関する記事をご覧ください。

次の手順

このチュートリアルでは、次の作業を行う方法を学びました。

  • 製品を作成して発行する
  • 製品に API を追加する
  • 製品の API にアクセスする

次のチュートリアルに進みます。

この記事では、Terraform を使用して、Azure API Management インスタンス、API、製品、グループに加え、製品と API、製品とグループの間の関連付けを作成します。

Terraform を使用すると、クラウド インフラストラクチャの定義、プレビュー、およびデプロイを行うことができます。 Terraform を使用する際は、HCL 構文を使って構成ファイルを作成します。 HCL 構文では、Azure などのクラウド プロバイダーと、クラウド インフラストラクチャを構成する要素を指定できます。 構成ファイルを作成したら、"実行プラン" を作成します。これにより、インフラストラクチャの変更をデプロイ前にプレビューすることができます。 変更を確認したら、実行プランを適用してインフラストラクチャをデプロイします。

  • Terraform の必要なバージョンと必要なプロバイダーを指定します。
  • リソース グループ名のプレフィックス、リソース グループの場所、API 定義インポートのコンテンツ形式と値の変数を定義します。
  • ランダムな名前のリソース グループを作成します。
  • ランダムな名前の API Management サービスを作成します。
  • ランダムな名前の API を作成します。
  • API Management サービスでランダムな名前の製品を作成します。
  • ランダムな名前のグループを作成します。
  • API を製品に関連付けます。
  • グループを製品に関連付けます。
  • リソース グループ、API Management サービス、API、製品、グループの名前などのランダム化された値を出力します。

前提条件

Terraform コードを実装する

注意

この記事のサンプル コードは、Azure Terraform GitHub リポジトリにあります。 Terraform の現在および以前のバージョンのテスト結果を含むログ ファイルを表示できます。

Terraform を使用して Azure リソースを管理する方法を示すその他の記事とサンプル コードを参照してください。

  1. サンプル Terraform コードをテストして実行するディレクトリを作成し、それを現在のディレクトリにします。

  2. main.tf という名前のファイルを作成し、次のコードを挿入します。

    resource "random_pet" "rg_name" {
      prefix = var.resource_group_name_prefix
    }
    
    resource "azurerm_resource_group" "rg" {
      location = var.resource_group_location
      name     = random_pet.rg_name.id
    }
    
    resource "random_string" "apim_service_name" {
      length  = 8
      lower   = true
      numeric = false
      special = false
      upper   = false
    }
    
    resource "azurerm_api_management" "apim_service" {
      name                = "${random_string.apim_service_name.result}-apim-service"
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
      publisher_name      = "Example Publisher"
      publisher_email     = "publisher@example.com"
      sku_name            = "Developer_1"
      tags = {
        Environment = "Example"
      }
      policy {
        xml_content = <<XML
        <policies>
          <inbound />
          <backend />
          <outbound />
          <on-error />
        </policies>
    XML
      }
    }
    
    resource "random_string" "api_name" {
      length  = 8
      lower   = true
      numeric = false
      special = false
      upper   = false
    }
    
    resource "random_string" "content_value" {
      length  = 8
      lower   = true
      numeric = false
      special = false
      upper   = false
    }
    
    resource "azurerm_api_management_api" "api" {
      name                = "${random_string.api_name.result}-api"
      resource_group_name = azurerm_resource_group.rg.name
      api_management_name = azurerm_api_management.apim_service.name
      revision            = "1"
      display_name        = "${random_string.api_name.result}-api"
      path                = "example"
      protocols           = ["https", "http"]
      description         = "An example API"
      import {
        content_format = var.open_api_spec_content_format
        content_value  = var.open_api_spec_content_value
      }
    }
    
    resource "random_string" "product_name" {
      length  = 8
      lower   = true
      numeric = false
      special = false
      upper   = false
    }
    
    resource "azurerm_api_management_product" "product" {
      product_id            = "${random_string.product_name.result}-product"
      resource_group_name   = azurerm_resource_group.rg.name
      api_management_name   = azurerm_api_management.apim_service.name
      display_name          = "${random_string.product_name.result}-product"
      subscription_required = true
      approval_required     = false
      published             = true
      description           = "An example Product"
    }
    
    resource "random_string" "group_name" {
      length  = 8
      lower   = true
      numeric = false
      special = false
      upper   = false
    }
    
    resource "azurerm_api_management_group" "group" {
      name                = "${random_string.group_name.result}-group"
      resource_group_name = azurerm_resource_group.rg.name
      api_management_name = azurerm_api_management.apim_service.name
      display_name        = "${random_string.group_name.result}-group"
      description         = "An example group"
    }
    
    resource "azurerm_api_management_product_api" "product_api" {
      resource_group_name = azurerm_resource_group.rg.name
      api_management_name = azurerm_api_management.apim_service.name
      product_id          = azurerm_api_management_product.product.product_id
      api_name            = azurerm_api_management_api.api.name
    }
    
    resource "azurerm_api_management_product_group" "product_group" {
      resource_group_name = azurerm_resource_group.rg.name
      api_management_name = azurerm_api_management.apim_service.name
      product_id          = azurerm_api_management_product.product.product_id
      group_name          = azurerm_api_management_group.group.name
    }
    
  3. outputs.tf という名前のファイルを作成し、次のコードを挿入します。

    output "resource_group_name" {
      value = azurerm_resource_group.rg.name
    }
    
    output "apim_service_name" {
      value = azurerm_api_management.apim_service.name
    }
    
    output "api_name" {
      value = azurerm_api_management_api.api.name
    }
    
    output "product_name" {
      value = azurerm_api_management_product.product.product_id
    }
    
    output "group_name" {
      value = azurerm_api_management_group.group.name
    }
    
    output "service_id" {
      description = "The ID of the API Management Service created"
      value       = azurerm_api_management.apim_service.id
    }
    
    output "gateway_url" {
      description = "The URL of the Gateway for the API Management Service"
      value       = azurerm_api_management.apim_service.gateway_url
    }
    
    output "service_public_ip_addresses" {
      description = "The Public IP addresses of the API Management Service"
      value       = azurerm_api_management.apim_service.public_ip_addresses
    }
    
    output "api_outputs" {
      description = "The IDs, state, and version outputs of the APIs created"
      value = {
        id             = azurerm_api_management_api.api.id
        is_current     = azurerm_api_management_api.api.is_current
        is_online      = azurerm_api_management_api.api.is_online
        version        = azurerm_api_management_api.api.version
        version_set_id = azurerm_api_management_api.api.version_set_id
      }
    }
    
    output "product_id" {
      description = "The ID of the Product created"
      value       = azurerm_api_management_product.product.id
    }
    
    output "product_api_id" {
      description = "The ID of the Product/API association created"
      value       = azurerm_api_management_product_api.product_api.id
    }
    
    output "product_group_id" {
      description = "The ID of the Product/Group association created"
      value       = azurerm_api_management_product_group.product_group.id
    }
    
  4. providers.tf という名前のファイルを作成し、次のコードを挿入します。

    terraform {
      required_version = ">=1.0"
      
      required_providers {
        azurerm = {
          source  = "hashicorp/azurerm"
          version = "~>3.0"
        }
        random = {
          source  = "hashicorp/random"
          version = "~>3.0"
        }
      }
    }
    
    provider "azurerm" {
      features {}
    }
    
  5. variables.tf という名前のファイルを作成し、次のコードを挿入します。

    variable "resource_group_name_prefix" {
      type        = string
      default     = "rg"
      description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription."
    }
    
    variable "resource_group_location" {
      type        = string
      default     = "eastus"
      description = "Location of the resource group."
    }
    
    variable "open_api_spec_content_format" {
      type        = string
      default     = "swagger-link-json"
      description = "The format of the content from which the API Definition should be imported. Possible values are: openapi, openapi+json, openapi+json-link, openapi-link, swagger-json, swagger-link-json, wadl-link-json, wadl-xml, wsdl and wsdl-link."
      validation {
        condition     = contains(["openapi", "openapi+json", "openapi+json-link", "openapi-link", "swagger-json", "swagger-link-json", "wadl-link-json", "wadl-xml", "wsdl", "wsdl-link"], var.open_api_spec_content_format)
        error_message = "open_api_spec_content_format must be one of the following: openapi, openapi+json, openapi+json-link, openapi-link, swagger-json, swagger-link-json, wadl-link-json, wadl-xml, wsdl and wsdl-link."
      }
    }
    
    variable "open_api_spec_content_value" {
      type        = string
      default     = "http://conferenceapi.azurewebsites.net/?format=json"
      description = "The Content from which the API Definition should be imported. When a content_format of *-link-* is specified this must be a URL, otherwise this must be defined inline."
    }
    

Terraform を初期化する

terraform init を実行して、Terraform のデプロイを初期化します。 このコマンドによって、Azure リソースを管理するために必要な Azure プロバイダーがダウンロードされます。

terraform init -upgrade

重要なポイント:

  • -upgrade パラメーターは、必要なプロバイダー プラグインを、構成のバージョン制約に準拠する最新バージョンにアップグレードします。

Terraform 実行プランを作成する

terraform plan を実行して、実行プランを作成します。

terraform plan -out main.tfplan

重要なポイント:

  • terraform plan コマンドは、実行プランを作成しますが、実行はしません。 代わりに、構成ファイルに指定された構成を作成するために必要なアクションを決定します。 このパターンを使用すると、実際のリソースに変更を加える前に、実行プランが自分の想定と一致しているかどうかを確認できます。
  • 省略可能な -out パラメーターを使用すると、プランの出力ファイルを指定できます。 -out パラメーターを使用すると、レビューしたプランが適用内容とまったく同じであることが確実になります。

Terraform 実行プランを適用する

terraform apply を実行して、クラウド インフラストラクチャに実行プランを適用します。

terraform apply main.tfplan

重要なポイント:

  • terraform apply コマンドの例は、以前に terraform plan -out main.tfplan が実行されたことを前提としています。
  • -out パラメーターに別のファイル名を指定した場合は、terraform apply の呼び出しで同じファイル名を使用します。
  • -out パラメーターを使用しなかった場合は、パラメーターを指定せずに terraform apply を呼び出します。

結果を確認する

az apim show を実行して Azure API Management を表示します。


az apim show --<apim_service_name> --<resource_group_name>

リソースをクリーンアップする

Terraform を使用して作成したリソースが不要になった場合は、次の手順を実行します。

  1. terraform plan を実行して、destroy フラグを指定します。

    terraform plan -destroy -out main.destroy.tfplan
    

    重要なポイント:

    • terraform plan コマンドは、実行プランを作成しますが、実行はしません。 代わりに、構成ファイルに指定された構成を作成するために必要なアクションを決定します。 このパターンを使用すると、実際のリソースに変更を加える前に、実行プランが自分の想定と一致しているかどうかを確認できます。
    • 省略可能な -out パラメーターを使用すると、プランの出力ファイルを指定できます。 -out パラメーターを使用すると、レビューしたプランが適用内容とまったく同じであることが確実になります。
  2. terraform apply を実行して、実行プランを適用します。

    terraform apply main.destroy.tfplan
    

Azure での Terraform のトラブルシューティング

Azure で Terraform を使用する場合の一般的な問題のトラブルシューティング

次のステップ