Terraform で Azure Key Vault をユーザー割り当てマネージド ID で参照する Azure Logic Apps を作成してみた

Azure Logic Apps を Azure ポータル上からトリガーやアクションを追加して開発していたとします。その開発した Azure Logic Apps を別のサブスクリプションにも作成する必要が出てきました。GUI で開発したものは JSON コードになっているので、コピペして環境固有のサブスクリプション ID を書き換えて、、、とやっていけば何とか移植完了です。ところが、移植環境が複数あったり手作業だと、ミスも増える可能性があります。そこで今回は、Terraform で Azure Key Vault をユーザー割り当てマネージド ID で参照する Azure Logic Apps を作成してみました。

## 検証用 Terraform コード

```terraform:main.tf
terraform {
  required_providers {
    azapi = {
      source = "azure/azapi"
    }
  }
}

provider "azurerm" {
  features {
    key_vault {
      purge_soft_delete_on_destroy    = true
      recover_soft_deleted_key_vaults = true
    }
  }
}

provider "azapi" {}

variable "prefix" {
  type    = string
  default = "mnrlga"
}

data "azurerm_client_config" "current" {}

resource "azurerm_resource_group" "rg" {
  name     = "${var.prefix}-rg"
  location = "japaneast"
}

resource "azurerm_user_assigned_identity" "uai" {
  name                = "${var.prefix}-uai"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
}

resource "azurerm_key_vault" "kv" {
  name                = "${var.prefix}-kv"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  tenant_id           = data.azurerm_client_config.current.tenant_id
  sku_name            = "standard"
}

resource "azurerm_key_vault_access_policy" "kv" {
  key_vault_id = azurerm_key_vault.kv.id
  tenant_id    = data.azurerm_client_config.current.tenant_id
  object_id    = data.azurerm_client_config.current.object_id

  key_permissions = [
    "Get", "List", "Update", "Create", "Import", "Delete", "Recover", "Backup", "Restore", "GetRotationPolicy", "SetRotationPolicy", "Rotate",
  ]
  secret_permissions = [
    "Get", "List", "Set", "Delete", "Recover", "Backup", "Restore",
  ]
  certificate_permissions = [
    "Get", "List", "Update", "Create", "Import", "Delete", "Recover", "Backup", "Restore", "ManageContacts", "ManageIssuers", "GetIssuers", "ListIssuers", "SetIssuers", "DeleteIssuers",
  ]
}

resource "azurerm_key_vault_access_policy" "lga" {
  key_vault_id = azurerm_key_vault.kv.id
  tenant_id    = data.azurerm_client_config.current.tenant_id
  object_id    = azurerm_user_assigned_identity.uai.principal_id

  secret_permissions = [
    "Get", "List",
  ]
}

resource "azapi_resource" "kv" {
  type      = "Microsoft.Web/connections@2018-07-01-preview"
  name      = "keyvault"
  location  = azurerm_resource_group.rg.location
  parent_id = azurerm_resource_group.rg.id
  schema_validation_enabled = false

  body = jsonencode({
    "properties": {
      "api": {
        "id": "${data.azurerm_managed_api.kv.id}"
      },
      "parameterValueSet": {
        "name": "oauthMI",
        "values": {
          "vaultName": {
            "value": "${azurerm_key_vault.kv.name}"
          }
        }
      },
      "displayName": "keyvault"
    }
  })
}

data "azurerm_managed_api" "kv" {
  name     = "keyvault"
  location = azurerm_resource_group.rg.location
}

resource "azapi_resource" "lga" {
  type      = "Microsoft.Logic/workflows@2019-05-01"
  name      = "${var.prefix}-test"
  location  = azurerm_resource_group.rg.location
  parent_id = azurerm_resource_group.rg.id

  identity {
    type         = "UserAssigned"
    identity_ids = [azurerm_user_assigned_identity.uai.id]
  }

  body = jsonencode({
    "properties" = {
      "definition" : {
        "$schema" : "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
        "contentVersion" : "1.0.0.0",
        "parameters" : {
          "$connections" : {
            "defaultValue" : {},
            "type" : "Object"
          }
        },
        "triggers" : {
          "manual" : {
            "inputs" : {
              "schema" : {}
            },
            "kind" : "Http",
            "type" : "Request"
          }
        },
        "actions" : {
          "シークレットの取得" : {
            "inputs" : {
              "host" : {
                "connection" : {
                  "name" : "@parameters('$connections')['keyvault']['connectionId']"
                }
              },
              "method" : "get",
              "path" : "/secrets/@{encodeURIComponent('secret-name')}/value"
            },
            "runAfter" : {},
            "type" : "ApiConnection"
          }
        },
        "outputs" : {}
        },
        "parameters" : {
          "$connections" : {
            "value" : {
              "keyvault" : {
                "connectionId" : "${azapi_resource.kv.id}"
                "connectionName" : "keyvault",
                "connectionProperties" : {
                  "authentication" : {
                    "identity" : "${azurerm_user_assigned_identity.uai.id}",
                    "type" : "ManagedServiceIdentity"
                  }
                },
                "id" : "${data.azurerm_managed_api.kv.id}"
              }
            }
          }
      }
    }
  })
}
```