09. Key Vault
Azure Key Vault は 「シークレット・キー・証明書」 を一元保管する金庫。AWS では Secrets Manager + KMS + ACM を統合した存在です。RBAC モードと Access Policy モードの 2 種類に注意。
3 つの保管対象
| 種別 | 内容 | 用途 |
|---|---|---|
| Secrets | 任意の文字列(最大 25KB) | DB パスワード、API キー、接続文字列 |
| Keys | 暗号化キー(RSA / EC / oct) | SSE-KMS 相当。Storage Account 暗号化等 |
| Certificates | TLS 証明書(X.509) | Web アプリの SSL 証明書管理 |
Key Vault の作成
data "azurerm_client_config" "current" {}
resource "azurerm_key_vault" "main" {
name = "kv-myapp-prd-jpe" # 全世界一意、3-24 文字
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "standard" # standard or premium (HSM)
# ソフト削除(必須、無効化不可)
soft_delete_retention_days = 30
purge_protection_enabled = true # 本番では true 推奨(即時削除を完全禁止)
# RBAC モードを使う(推奨)
enable_rbac_authorization = true
# ネットワーク制限
public_network_access_enabled = false
network_acls {
default_action = "Deny"
bypass = "AzureServices"
ip_rules = ["203.0.113.0/24"]
virtual_network_subnet_ids = [azurerm_subnet.private.id]
}
tags = local.common_tags
}
purge_protection_enabled は一度有効化すると戻せない
ソフト削除中の Key Vault を即時削除する権限を 恒久的に 失います。本番では必須、テスト環境では off のままで良い。
RBAC モード vs Access Policy
Key Vault のアクセス制御方式は 2 種類:
| RBAC モード(推奨) | Access Policy モード(旧) | |
|---|---|---|
| 設定 | enable_rbac_authorization = true | 同 false(デフォルト) |
| 権限付与 | Azure RBAC(azurerm_role_assignment) | azurerm_key_vault_access_policy |
| 粒度 | Vault 全体/個別 Secret 単位 | Vault 全体のみ |
| 監査 | Activity Log で統一 | 個別に確認 |
2026 年は RBAC モード一択。以下 RBAC 前提で進めます。
Secrets
resource "random_password" "db" {
length = 32
special = true
}
resource "azurerm_key_vault_secret" "db_password" {
name = "db-password"
value = random_password.db.result
key_vault_id = azurerm_key_vault.main.id
content_type = "password"
expiration_date = "2027-12-31T23:59:59Z"
tags = local.common_tags
}
# 取り出す(data ソース)
data "azurerm_key_vault_secret" "db_password" {
name = "db-password"
key_vault_id = azurerm_key_vault.main.id
}
# 使い方: data.azurerm_key_vault_secret.db_password.value
state に平文で残る
Terraform で値を取得すると state に書き込まれます。state は必ず暗号化バックエンドへ。可能ならアプリ側で Managed Identity 経由 で取得し、Terraform は値を読まない設計に。
Keys(暗号化キー)
resource "azurerm_key_vault_key" "app" {
name = "myapp-cmk"
key_vault_id = azurerm_key_vault.main.id
key_type = "RSA"
key_size = 2048
key_opts = [
"decrypt", "encrypt", "sign", "unwrapKey", "verify", "wrapKey",
]
rotation_policy {
automatic {
time_before_expiry = "P30D" # 期限 30 日前にローテーション
}
expire_after = "P90D"
notify_before_expiry = "P7D"
}
}
# Storage Account の CMK 暗号化に使う
resource "azurerm_storage_account_customer_managed_key" "data" {
storage_account_id = azurerm_storage_account.data.id
key_vault_id = azurerm_key_vault.main.id
key_name = azurerm_key_vault_key.app.name
}
Certificates
resource "azurerm_key_vault_certificate" "site" {
name = "myapp-com"
key_vault_id = azurerm_key_vault.main.id
certificate_policy {
issuer_parameters {
name = "Self" # 本番は DigiCert / GlobalSign など
}
key_properties {
exportable = true
key_size = 2048
key_type = "RSA"
reuse_key = true
}
secret_properties {
content_type = "application/x-pkcs12"
}
x509_certificate_properties {
subject = "CN=myapp.com"
validity_in_months = 12
key_usage = ["digitalSignature", "keyEncipherment"]
}
}
}
他リソースから参照
# Container App で Key Vault のシークレットを使う
resource "azurerm_container_app" "main" {
# ...
identity {
type = "UserAssigned"
identity_ids = [azurerm_user_assigned_identity.app.id]
}
secret {
name = "db-password"
identity = azurerm_user_assigned_identity.app.id
key_vault_secret_id = azurerm_key_vault_secret.db_password.id # 直接参照
}
}
# MI に「Key Vault Secrets User」を付与
resource "azurerm_role_assignment" "app_kv_secret" {
scope = azurerm_key_vault.main.id
role_definition_name = "Key Vault Secrets User"
principal_id = azurerm_user_assigned_identity.app.principal_id
}
この方式なら Terraform は値を読まず、Container App がランタイムで MI 経由で取得する。state に残らない。