TerraformからKeyVaultに格納されているサーバ証明書をAppServiceにインポートする際に発生するエラーへの対処について

TerraformからKeyVaultに格納されているサーバ証明書をAppServiceにインポートする際に
下記エラーが発生し、デプロイすることができませんでした。
`The service does not have access to '…vault' Key Vault. Please make sure that you have granted necessary permissions to the service to perform the request operation.`
色々調べた結果、エラーを解消することが出来ましたので、対処方法を記載します。

## 実行内容
TerraformからKeyVaultに格納されているサーバ証明書をAppServiceにインポートするために、
下記Terraform Templateを実行しました。

```sample1.tf
resource "azurerm_template_deployment" "sample" {
  name                = "sample"
  resource_group_name = "sample"
  deployment_mode     = "Incremental"

  template_body = <<DEPLOY
{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "sslCertificateName": {
            "type": "string"
        },
        "keyVaultId": {
            "type": "string"
        },
        "servicePlanId": {
            "type": "string"
        },
        "appServiceName": {
            "type": "string"
        },
        "appServiceFQDN": {
            "type": "string"
        }
    },
    "resources": [
        {
            "type":"Microsoft.Web/certificates",
            "name":"[parameters('sslCertificateName')]",
            "apiVersion":"2016-03-01",
            "location":"[resourceGroup().location]",
            "properties":{
                "keyVaultId":"[parameters('keyVaultId')]",
                "keyVaultSecretName":"[parameters('sslCertificateName')]",
                "serverFarmId": "[parameters('servicePlanId')]"
            }
        },
        {
            "type":"Microsoft.Web/sites/hostnameBindings",
            "name":"[concat(parameters('appServiceName'), '/', parameters('appServiceFQDN'))]",
            "apiVersion":"2016-03-01",
            "location":"[resourceGroup().location]",
            "properties":{
                "sslState":"SniEnabled",
                "thumbprint": "[reference(resourceId('Microsoft.Web/certificates', parameters('sslCertificateName'))).Thumbprint]"
            },
            "dependsOn": [
                "[concat('Microsoft.Web/certificates/',parameters('sslCertificateName'))]"
            ]
        }
    ]
}
DEPLOY

  parameters {
    "appServiceName"     = "sample"
    "appServiceFQDN"     = "sample"
    "servicePlanId"      = "sample"
    "sslCertificateName" = "sample"
    "keyVaultId"         = "sample"
  }
}
```


## 実行結果
下記エラーが発生し、デプロイすることが出来ませんでした。
`The service does not have access to '…vault' Key Vault. Please make sure that you have granted necessary permissions to the service to perform the request operation.`

## 対処方法
調べた結果、KeyVaultのアクセスポリシーにAppServiceのサービスプリンシパルIDを登録し、
Secrets、Certificatesへの読み取り許可を与える必要があることが分かりました。

> テンプレートに TLS/SSL バインディングの Microsoft.Web/certificates リソースが含まれ、証明書が Key Vault に格納されている場合、App Service の ID が証明書にアクセスできることを確認する必要があります。
グローバル Azure では、App Service サービス プリンシパルの ID は abfa0a7c-a6b6-4736-8310-5855508787cd です。

https://docs.microsoft.com/ja-jp/azure/app-service/deploy-resource-manager-template?ns-enrollment-type=Collection&ns-enrollment-id=04jycp8k8yk0em#deploy-web-app-certificate-from-key-vault

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177177/e03b001a-55dd-1e32-3105-5a6b7f15c306.png)

下記Terraform Templateを追加で記載し、再度terraform applyしました。
無事にKeyVaultに格納されているサーバ証明書をAppServiceにインポートすることができました。
```sample2.tf
data "azuread_service_principal" "MicrosofAzureAppService" {
  application_id = "abfa0a7c-a6b6-4736-8310-5855508787cd" # AppServiceのService PrincipalのアプリケーションID 
}

resource "azurerm_key_vault_access_policy" "sample" {
  key_vault_id = "sample" 
  tenant_id = "sample"
  object_id = data.azuread_service_principal.MicrosofAzureAppService.object_id # AppServiceのService PrincipalのオブジェクトID

  secret_permissions = [
    "get"
  ]

  certificate_permissions = [
    "get"
  ]
}
```

## おわり
最後まで記事を読んでくださり、ありがとうございました。
同じエラーに遭遇し、対処方法に悩んでいる方々の助けになれれば幸いです。

## 参考文献
- [TerraformでAzure Web AppsにKey Vault内の証明書を設定する](https://blog.azure.moe/2020/05/02/terraform%E3%81%A7azure-web-apps%E3%81%ABkey-vault%E5%86%85%E3%81%AE%E8%A8%BC%E6%98%8E%E6%9B%B8%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B/)
- [Unable to access certificate in keyvault to bind it in app service](https://github.com/hashicorp/terraform-provider-azurerm/issues/8746)