0
0

Bicep デプロイ時に Azure Key Vault を使用して、セキュリティで保護されたパラメーター値を渡したメモ

Last updated at Posted at 2024-08-24

概要

BicepでFunctionsを作成した。
Functionsでデータベースの接続文字列を環境変数に格納したが、secureにデプロイするためKey Vaultを使いたい。

ソースコード

KeyVaultのシークレット作成

infra/bin/.env
# ;が含まれているので "" で囲む
DATABASE_URL="sqlserver://hoge.database.windows.net:1433;database=fuga;user=piyo;password=piyopiyo;encrypt=true"
RESOURCE_GROUP_NAME='async-ttrpg-hogehoge'
KEY_VAULT_NAME='AsyncTrpgKeyVault'
KEY_VAULT_SECRET_NAME='AsyncTrpgDatabaseURL'
infra/bin/addKeyVault.sh
#!/bin/bash

# ディレクトリパス取得
BIN_DIR=$(cd $(dirname $0) && pwd)
BICEP_DIR=$(cd $BIN_DIR/../biceps && pwd)

# 環境変数読み込み
source $BIN_DIR/.env
LOCATION=japaneast
keyVaultName=$KEY_VAULT_NAME
keyVaultSecretName=$KEY_VAULT_SECRET_NAME
subscriptions=$(az account show | jq -r '.id')
userObjectId=$(az ad signed-in-user show | jq -r '.id')

if az keyvault list --query "[?contains(name, '$keyVaultName')].name" -o tsv | grep -q "$keyVaultName"; then
  echo "Key Vault '$keyVaultName' が既に存在します。"
  exit 0
fi

az keyvault create --name $keyVaultName --location $LOCATION --enabled-for-template-deployment true --resource-group $RESOURCE_GROUP_NAME

# Key Vaultが作成されるまで待機
echo "Waiting for Key Vault to be available..."
while true; do
  kv=$(az keyvault show --name $keyVaultName --resource-group $RESOURCE_GROUP_NAME --query "properties.provisioningState" -o tsv)
  if [ "$kv" == "Succeeded" ]; then
    echo "Key Vault is available."
    break
  fi
  echo "Key Vault is not yet available. Waiting..."
  sleep 5
done

az role assignment create --role "Key Vault Secrets Officer" --assignee $userObjectId --scope /subscriptions/$subscriptions/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.KeyVault/vaults/$keyVaultName
az keyvault secret set --vault-name $keyVaultName --name $keyVaultSecretName --value $DATABASE_URL --output none
設定不足によるエラー

key vaultの作成後、利用できるまでの間にシークレットを使おうとするとエラーとなる。

Resource provider 'Microsoft.KeyVault' used by this operation is not registered. We are registering for you. 
If role assignments, deny assignments or role definitions were changed recently, please observe propagation time. 
Cannot set policies to a vault with '--enable-rbac-authorization' specified 

Azure Functions作成

infra/biceps/main.parameters.json
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "functionsRuntime": {
      "value": {
        "runtime": "node",
        "linuxFxVersion": "Node|20",
        "kind": "functionapp,linux",
        "extensionVersion": "~4"
      }
    }
  }
}
main/biceps/main.bicep
param location string = resourceGroup().location
param keyVaultName string
@description('The runtime version of the Azure Functions app.')
param functionsRuntime object

var storageAccountName = '${uniqueString(resourceGroup().id)}azfunctions'

resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' existing = {
  name: keyVaultName
}

module myFunctionsStorage 'core/storage/storage-account.bicep' = {
  name: 'myFunctionsStorage'
  params: {
    location: location
    storageAccountName: storageAccountName
  }
}

module myFunctions 'core/host/functions.bicep' = {
  name: 'myFunctions'
  params: {
    location: location
+    databaseUrl: keyVault.getSecret('AsyncTrpgDatabaseURL')
    storageAccountName: storageAccountName
    kind: functionsRuntime.kind
    linuxFxVersion: functionsRuntime.linuxFxVersion
    extensionVersion: functionsRuntime.extensionVersion
  }
}

output appServiceAppHostName string = myFunctions.outputs.appServiceAppHostName
infra/core/host/functions.bicep
param storageAccountName string
param location string
param kind string
param linuxFxVersion string
param extensionVersion string
+ @secure()
param databaseUrl string

var functionAppName = '${uniqueString(resourceGroup().id)}azfunctionsapp'

resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' existing = {
  name: storageAccountName
}

resource functionApp 'Microsoft.Web/sites@2022-09-01' = {
  name: functionAppName
  location: location
  kind: kind
  properties: {
    reserved: true
    siteConfig: {
      linuxFxVersion: linuxFxVersion
      appSettings: [
        {
          name: 'AzureWebJobsStorage'
          value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccountName};EndpointSuffix=${environment().suffixes.storage};AccountKey=${storageAccount.listKeys().keys[0].value}'
        }
        {
          name: 'WEBSITE_CONTENTSHARE'
          value: toLower(functionAppName)
        }
        {
          name: 'FUNCTIONS_EXTENSION_VERSION'
          value: extensionVersion
        }
        {
          name: 'FUNCTIONS_WORKER_RUNTIME'
          value: 'node'
        }
        {
          name: 'DATABASE_URL'
          value: databaseUrl
        }
      ]
    }
  }
}

output appServiceAppHostName string = functionApp.properties.defaultHostName

実行

infra/bin/createFunction.bash
#!/bin/bash

# ディレクトリパス取得
BIN_DIR=$(cd $(dirname $0) && pwd)
BICEP_DIR=$(cd $BIN_DIR/../biceps && pwd)

# 環境変数読み込み
source $BIN_DIR/.env
LOCATION=japaneast

cd $BICEP_DIR && az deployment group create \
  --name functionsDeployment \
  --template-file main.bicep \
  --parameters main.parameters.json \
  --parameters \
    keyVaultName=$KEY_VAULT_NAME \
  -g $RESOURCE_GROUP_NAME

参考

Bicep デプロイ時に Azure Key Vault を使用して、セキュリティで保護されたパラメーター値を渡す
演習:パラメーターを使用して再利用可能な Bicep テンプレートを構築する

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0