Key Vaultで設定したシークレットをAzure Functionsから作成・更新する。

2022年12月29日

以前にKey Vaultについて記事を書きました。
今回の記事は以前の記事を理解した前提で書いています。

こちらを参考に進めました。

https://learn.microsoft.com/ja-jp/azure/key-vault/secrets/quick-create-node

Functionsを準備

KeyVault側でアクセスポリシーを設定する

作成したFunctionsでKeyVaultのアクセスポリシーを設定する。この時、取得だけだと権限エラーとなるのでいくつか必要となるアクセス許可を付与しておく。

KeyVaultでシークレットを作成する

ここもFunctions経由で可能ですが、今回は更新するというのが目的だったので、まずはシークレットを作っておきました。

Functionsに以下ソースをデプロイする

Functionsにアクセスポリシーをセットしているので、ローカルで実行しても失敗します。
ローカルでやっていきたいという場合は、Azure ADを登録して、その情報を環境変数に設定してやる必要がありそう。以下参考になりそう。

https://learn.microsoft.com/ja-jp/dotnet/api/overview/azure/identity-readme?view=azure-dotnet#defaultazurecredential

import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import { SecretClient } from "@azure/keyvault-secrets";
import { DefaultAzureCredential } from "@azure/identity";

const httpTrigger: AzureFunction = async function (
  context: Context,
  req: HttpRequest
): Promise<void> {
  // const secret = process.env.KEY_VAULT_SECRET;
  // context.log.error(secret);
  const credential = new DefaultAzureCredential();
  context.log.error("test");
  context.log.error(credential);
  const url = "https://xxx.vault.azure.net";
  const client = new SecretClient(url, credential);
  context.log.error(client);

  // シークレットを作成する場合
  const uniqueString = new Date().getTime();
  const secretName = "mysecret";
  const result = await client.setSecret(secretName, `${uniqueString}`);
  context.log.error("result: ", result);

  // シークレットを名称から取得
  const secret = await client.getSecret(secretName);
  context.log.error("secret: ", secret);

  // シークレットのバージョンを指定して更新(当該シークレットを使えなくする)
  // if (secret.properties.version != null) {
  //   const updatedSecret = await client.updateSecretProperties(
  //     secretName,
  //     secret.properties.version,
  //     {
  //       enabled: false,
  //     }
  //   );
  //   console.log("updated secret: ", updatedSecret);
  // }

  context.res = {
    // status: 200, /* Defaults to 200 */
    body: "Hello, World!",
  };
};
export default httpTrigger;

シークレットの中身について

シークレットを作成したり、取得したりした場合は、KeyVaultSecret型のオブジェクトが取得されます。
以下部分でログを出してます。

 // シークレットを名称から取得
  const secret = await client.getSecret(secretName);
  context.log.error("secret: ", secret);

上記で出力されるオブジェクトは以下のような感じです。

secret:  {
  value: 'MySecretValue',
  name: 'secret1672218113098',
  properties: {
    expiresOn: undefined,
    createdOn: 2022-12-28T09:01:55.000Z,
    updatedOn: 2022-12-28T09:01:55.000Z,
    enabled: true,
    notBefore: undefined,
    recoverableDays: 90,
    recoveryLevel: 'Recoverable+Purgeable',
    id: 'https://func-xxxx.vault.azure.net/secrets/secret1672218113098/hogehoge',
    contentType: undefined,
    tags: undefined,
    managed: undefined,
    vaultUrl: 'https://func-xxxx.vault.azure.net',
    version: 'cbafc0e4f3fd4961b81092b6a673357f',
    name: 'secret1672218113098',
    certificateKeyId: undefined
  }
}

シークレットの更新

シークレットの更新は以下部分でやってます。

  // シークレットを作成する場合
  const uniqueString = new Date().getTime();
  const secretName = "mysecret";
  const result = await client.setSecret(secretName, `${uniqueString}`);
  context.log.error("result: ", result);

最初、setSecretでは作成だけと思ってメソッドを探していたのですが見つからず。
仕方ないのでソースを追いかけていると以下部分を発見。
setSecret メソッドは、Azure Key Vault にシークレットまたはシークレットバージョンを追加します。指定されたシークレットがすでに存在する場合、Azure Key Vaultはそのシークレットの新しいバージョンを作成します。

    /**
     * The setSecret method adds a secret or secret version to the Azure Key Vault. If the named secret
     * already exists, Azure Key Vault creates a new version of that secret.
     * This operation requires the secrets/set permission.
     *
     * Example usage:
     * ```ts
     * let client = new SecretClient(url, credentials);
     * await client.setSecret("MySecretName", "ABC123");
     * ```
     * Adds a secret in a specified key vault.
     * @param secretName - The name of the secret.
     * @param value - The value of the secret.
     * @param options - The optional parameters.
     */
    setSecret(secretName: string, value: string, options?: SetSecretOptions): Promise<KeyVaultSecret>;

Httpリクエストを投げる

更新されることを確認しました。