Azure API Management にカスタムドメインを適用する

⏱️約4分
シェア:

Azure API Management は、既存のバックエンドのサービスに対して一貫性のある最新の API ゲートウェイを迅速に作成する手段です1。 本記事では、この API Management にカスタムドメインを適用する方法を説明します。また、SSL 化を独自の証明書を使って行う方法を説明します。 さらに、デプロイは CI/CD を意識して、ARM Template 2を使います。

1. Key Vault をデプロイする

まずは証明書を保持するための Key Vault をデプロイしましょう。

json
1{
2 "$schema": "https://schema.management.azure.com/schemas/2018-05-01/deploymentTemplate.json#",
3 "contentVersion": "1.0.0.0",
4 "parameters": {
5 "keyVaultName": {
6 "type": "string",
7 "metadata": {
8 "description": "Key Vault Name"
9 }
10 },
11 "apiMgmtName": {
12 "type": "string",
13 "metadata": {
14 "description": "API Management Name"
15 }
16 },
17 "commanderObjectId": {
18 "type": "securestring",
19 "metadata": {
20 "description": "Object id of azure cli command executor."
21 }
22 }
23 },
24 "variables": {},
25 "resources": [
26 {
27 "name": "[parameters('apiMgmtName')]",
28 "type": "Microsoft.ApiManagement/service",
29 "apiVersion": "2019-01-01",
30 "properties": {
31 "notificationSenderEmail": "apimgmt-noreply@mail.windowsazure.com",
32 "hostnameConfigurations": [],
33 "publisherEmail": "ch241.sample@example.com",
34 "publisherName": "mark241"
35 },
36 "sku": {
37 "name": "Developer"
38 },
39 "identity": {
40 "type": "SystemAssigned"
41 },
42 "location": "[resourceGroup().location]"
43 },
44 {
45 "name": "[parameters('keyVaultName')]",
46 "type": "Microsoft.KeyVault/vaults",
47 "apiVersion": "2018-02-14",
48 "location": "[resourceGroup().location]",
49 "dependsOn": [
50 "[resourceId('Microsoft.ApiManagement/service', parameters('apiMgmtName'))]"
51 ],
52 "properties": {
53 "tenantId": "[subscription().tenantId]",
54 "sku": {
55 "family": "A",
56 "name": "standard"
57 },
58 "accessPolicies": [
59 {
60 "tenantId": "[subscription().tenantId]",
61 "objectId": "[reference(resourceId('Microsoft.ApiManagement/service', parameters('apiMgmtName')), '2019-01-01', 'Full').identity.principalId]",
62 "permissions": {
63 "keys": [],
64 "secrets": ["get"],
65 "certificates": ["get"],
66 "storage": []
67 }
68 },
69 {
70 "tenantId": "[subscription().tenantId]",
71 "objectId": "[parameters('commanderObjectId')]",
72 "permissions": {
73 "keys": [],
74 "secrets": [],
75 "certificates": ["import"],
76 "storage": []
77 }
78 }
79 ],
80 "enabledForDeployment": false,
81 "enabledForDiskEncryption": false,
82 "enabledForTemplateDeployment": false
83 },
84 "resources": []
85 }
86 ]
87}

上記の Template には、Key Vault と API Management のリソースが含まれています。 まずは、API Management を見てみましょう。

json
1{
2 "name": "[parameters('apiMgmtName')]",
3 "type": "Microsoft.ApiManagement/service",
4 "apiVersion": "2019-01-01",
5 "properties": {
6 "notificationSenderEmail": "apimgmt-noreply@mail.windowsazure.com",
7 "hostnameConfigurations": [],
8 "publisherEmail": "ch241.sample@example.com",
9 "publisherName": "mark241"
10 },
11 "sku": {
12 "name": "Developer"
13 },
14 "identity": {
15 "type": "SystemAssigned"
16 },
17 "location": "[resourceGroup().location]"
18}

この時点で API Management を先に作成する理由について簡単に説明します。 後述の Key Vault のデプロイでは、Key Vault の参照権限を API Management に付与します。 これは、Key Vault に保存される証明書を API Management が取得するためのものです。 この権限付与のためには事前に API Management が存在し、その Managed Id が存在している必要があります。 Managed Id の詳細については、公式ドキュメント3を参照してください。 簡単に言えば、API Management を識別するための ID で、権限管理をこの ID を使って行います。 上記の Template でいうと

json
1"identity": {
2 "type": "SystemAssigned"
3 }

の部分で、API Management の Managed Id が生成されています。 その他の詳細については公式ドキュメント4を参照してください。

次に Key Vault のリソースを見てみましょう。

json
1{
2 "name": "[parameters('keyVaultName')]",
3 "type": "Microsoft.KeyVault/vaults",
4 "apiVersion": "2018-02-14",
5 "location": "[resourceGroup().location]",
6 "dependsOn": [
7 "[resourceId('Microsoft.ApiManagement/service', parameters('apiMgmtName'))]"
8 ],
9 "properties": {
10 "tenantId": "[subscription().tenantId]",
11 "sku": {
12 "family": "A",
13 "name": "standard"
14 },
15 "accessPolicies": [
16 {
17 "tenantId": "[subscription().tenantId]",
18 "objectId": "[reference(resourceId('Microsoft.ApiManagement/service', parameters('apiMgmtName')), '2019-01-01', 'Full').identity.principalId]",
19 "permissions": {
20 "keys": [],
21 "secrets": ["get"],
22 "certificates": ["get"],
23 "storage": []
24 }
25 },
26 {
27 "tenantId": "[subscription().tenantId]",
28 "objectId": "[parameters('commanderObjectId')]",
29 "permissions": {
30 "keys": [],
31 "secrets": [],
32 "certificates": ["import"],
33 "storage": []
34 }
35 }
36 ],
37 "enabledForDeployment": false,
38 "enabledForDiskEncryption": false,
39 "enabledForTemplateDeployment": false
40 },
41 "resources": []
42}

Key Vault のリソースでのポイントはaccessPolicyでアクセス権管理を行う点です。 accessPolicy に 2 つの権限が記載されていると思います。

json
1{
2 "tenantId": "[subscription().tenantId]",
3 "objectId": "[reference(resourceId('Microsoft.ApiManagement/service', parameters('apiMgmtName')), '2019-01-01', 'Full').identity.principalId]",
4 "permissions": {
5 "keys": [],
6 "secrets": ["get"],
7 "certificates": ["get"],
8 "storage": []
9 }
10}

1 つ目は、API Management に対して、get の権限を付与しています。前述のように証明書を取得するための権限です。

json
1"objectId": "[reference(resourceId('Microsoft.ApiManagement/service', parameters('apiMgmtName')), '2019-01-01', 'Full').identity.principalId]"

上記の記述により、API Management の Managed Id を指定し、権限を付与します。 権限としては、secretscertificatesに対して、getを付与します。

json
1"permissions": {
2 "keys": [],
3 "secrets": ["get"],
4 "certificates": ["get"],
5 "storage": []
6 }

2 つ目は、後述の Key Vault へ証明書をインポートするための権限です。

json
1{
2 "tenantId": "[subscription().tenantId]",
3 "objectId": "[parameters('commanderObjectId')]",
4 "permissions": {
5 "keys": [],
6 "secrets": [],
7 "certificates": ["import"],
8 "storage": []
9 }
10}

本記事では Azure CLI を使って証明書を Key Vault にインポートします。したがって、Azure CLI の実行者(サービスプリンシパルやユーザー)に対して import の権限を付与する必要があります。 commanderObjectIdに対象のサービスプリンシパルやユーザーのオブジェクトIDを指定し、certificatesに対してimport権限を付与しておきましょう。

2. 証明書を Key Vault へインポートする

次に、証明書を Key Vault へインポートします。 ここでは、Azure CLI のコマンドを使いましょう。

powershell
1az keyvault certificate import --file $certFile --name $secretName --vault-name $keyVaultName --password $certPass
  • --file: 証明書ファイルのパス。.pfx 形式。
  • --name: 証明書を格納する Key Vault のリソース名
  • --vault-name: 証明書を格納する Key Vault の名前
  • --password: 証明書のパスワード

ここで、先ほど作成した Key Vault を指定すれば、証明書がインポートされます。 先ほど、インポート権限を付与した実行者の権限で上記コマンドを実行しましょう。

3. API Management のカスタムドメインをデプロイする

最後に API Management を再度デプロイします。

json
1{
2 "$schema": "https://schema.management.azure.com/schemas/2018-05-01/deploymentTemplate.json#",
3 "contentVersion": "1.0.0.0",
4 "parameters": {
5 "apiMgmtName": {
6 "type": "string",
7 "metadata": {
8 "description": "Service name of API Management"
9 }
10 },
11 "hostName": {
12 "type": "string",
13 "metadata": {
14 "description": "Host name of API Management"
15 }
16 },
17 "keyVaultName": {
18 "type": "string",
19 "metadata": {
20 "description": "Key Vault name"
21 }
22 },
23 "secretName": {
24 "type": "string",
25 "metadata": {
26 "description": "Secret name"
27 }
28 }
29 },
30 "variables": {
31 "keyVaultResourceId": "[resourceId(resourceGroup().name, 'Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('secretName'))]"
32 },
33 "resources": [
34 {
35 "name": "[parameters('apiMgmtName')]",
36 "type": "Microsoft.ApiManagement/service",
37 "apiVersion": "2019-01-01",
38 "properties": {
39 "notificationSenderEmail": "apimgmt-noreply@mail.windowsazure.com",
40 "hostnameConfigurations": [
41 {
42 "type": "Proxy",
43 "hostName": "[parameters('hostName')]",
44 "keyVaultId": "[reference(variables('keyVaultResourceId'), '2018-02-14').secretUriWithVersion]"
45 }
46 ],
47 "publisherEmail": "ch241.sample@example.com",
48 "publisherName": "mark241"
49 },
50 "sku": {
51 "name": "Developer"
52 },
53 "identity": {
54 "type": "SystemAssigned"
55 },
56 "location": "[resourceGroup().location]"
57 }
58 ]
59}

先ほど API Management をデプロイしたときと似てますが、違いは、hostnameConfigurationsの部分です。 先ほどはカスタムドメインを適用してなかったので空の配列でしたが、今回はカスタムドメインの設定が含まれています。

  • type: 対象のサービスのタイプ。Proxy, Portal, Scm, Management の 4 つがある。
  • hostName: カスタムドメインの FQDN
  • keyVaultId: 先ほど証明書をインポートした Key Vault の uri

type には Proxy を指定しましょう。これは API Gateway(<api management name>.azure-api.net)にカスタムドメインを適用する場合の type です。 keyVaultId は上記のように、secretUtiWithVersionというプロパティで取得できます。

スクリプト

最後に上記すべての Template をデプロイするスクリプトを載せておきます。 お使いの CI/CD 環境に合わせて適宜変更してください。

powershell
1Param(
2 [parameter(mandatory = $true)][String]$resourceGroup,
3 [parameter(mandatory = $true)][String]$keyVaultName,
4 [parameter(mandatory = $true)][String]$apiMgmtName,
5 [parameter(mandatory = $true)][String]$objectId,
6 [parameter(mandatory = $true)][String]$certFile,
7 [parameter(mandatory = $true)][String]$certPass,
8 [parameter(mandatory = $true)][String]$secretName,
9 [parameter(mandatory = $true)][String]$hostName
10)
11
12# 1. Deploy Key Vault
13try{
14 az group deployment create --resource-group $resourceGroup --template-file ./keyvault.json --parameters keyVaultName=$keyVaultName apiMgmtName=$apiMgmtName commanderObjectId=$objectId
15}
16catch {
17 $message = $_.Exception.message
18 Write-Error "Failed to deploy key vault: ${message}"
19}
20
21# 2. Import a certificate
22try{
23 az keyvault certificate import --file $certFile --name $secretName --vault-name $keyVaultName --password $certPass
24}
25catch {
26 $message = $_.Exception.message
27 Write-Error "Failed to import certificate: ${message}"
28}
29
30# 3. Deploy API Management
31try {
32 az group deployment create --resource-group $resourceGroup --template-file ./apimgmt.json --parameters apiMgmtName=$apiMgmtName hostName=$hostName keyVaultName=$keyVaultName secretName=$secretName
33}
34catch {
35 $message = $_.Exception.message
36 Write-Error "Failed to deploy api management: ${message}"
37}

まとめ

本記事では ARM Template を使って API Management のカスタムドメインを適用する方法を説明しました。

  1. Key Vault のデプロイ
  2. 証明書のインポート
  3. API Management にカスタムドメインを適用

上記の手順でカスタムドメインを適用することができましたね。

Footnotes

  1. API Management のドキュメント

  2. Azure Resource Manager のドキュメント

  3. Azure リソースの Azure AD マネージド ID

  4. Microsoft. ApiManagement service template reference

シェア:

関連記事