1️⃣

1Password の情報を基に .dev.vars を作成する

2024/02/08に公開

Cloudflare Workers の環境変数のドキュメントを読むと分かりますが wrangler.toml に記述した環境変数をローカル環境のみ .dev.vars に記述した環境変数で上書きしてくれます。

ここで、ローカルから外部の API を叩いて API の動作を確認したいケースがありますが、皆さんはどのようにして API キーなどの共有をされてますか?

NOT A HOTEL では 1Password に開発環境用のクレデンシャルを保存してチームで共有しています。.dev.vars は以下のようになってます。

.dev.vars
GCP_SERVICE_ACCOUNT='{"type":"service_account","project_id"...}'
OPENAI_API_KEY="sk-gET5lej..."
FIREBASE_AUTH_DOMAIN="localhost:8788"
GITHUB_APP_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMI..."

これは 1 つ 1 つ丁寧に記述したわけではなく Deno で記述したスクリプトと 1Password の CLI を利用して作成されます。作成に使っているスクリプトです。

import { parse, stringify } from 'https://deno.land/std@0.214.0/dotenv/mod.ts';

// `op inject` コマンドを実行して環境変数を取得
async function getEnvVars(): Promise<Record<string, string>> {
  const decoder = new TextDecoder();
  const command = new Deno.Command('op', {
    args: ['inject', '--in-file', '.dev.vars.template'],
  });

  const { code, success, stdout, stderr } = await command.output();
  if (!success) {
    console.error('failed to run op command');
    console.error(`code: ${code}`);
    console.error(`stderr:\n${decoder.decode(stderr)}`);
    Deno.exit(1);
  }

  const result = decoder.decode(stdout);
  const vars = parse(result);

  return vars;
}

// .dev.vars ファイルを更新
async function updateDevVars(envVars: Record<string, string>): Promise<void> {
  const devVars = '.dev.vars';
  /** check if file exists */
  try {
    await Deno.stat(devVars);
  } catch (error) {
    console.error('file does not exist');
    await Deno.copyFile(`${devVars}.template`, devVars);
  }
  const content = await Deno.readTextFile(devVars);
  const currentVars: Record<string, string> = parse(content);
  const mergedVars = Object.assign(currentVars, envVars);
  const output = stringify(mergedVars);

  await Deno.writeTextFile(devVars, output);
}

async function main() {
  const envVars = await getEnvVars();
  await updateDevVars(envVars);
}

main();

スクリプトでは標準の dotenv モジュールを利用しています。.dev.vars は名前からは分かりませんが、実体としては dotenv です。これは wrangler のコードを読むと分かります。

このスクリプトを .dev.vars.template をベースに .dev.vars を手元の .dev.vars に無い環境変数を追加してくれます。リポジトリには .dev.vars.template をコミットし、各自手元で上記のスクリプトを実行するだけで共有が可能になってます。とても便利です!

.dev.vars.template
GCP_SERVICE_ACCOUNT='op://foo/gcp-service-account'
OPENAI_API_KEY="op://foo/openai-api-key"
FIREBASE_AUTH_DOMAIN="localhost:8788"
GITHUB_APP_PRIVATE_KEY="op://foo/u4qn46adhzuclask5yl7pra6xa/private_key"

また .envrc を追加して、direnv を利用することで、カレントディレクトリがプロジェクトルートであれば、これらの環境変数も使っているシェルに読み込めるように設定もしています。

dotenv .dev.vars
NOT A HOTEL

Discussion