Cloudflare Workerのコード単体と環境設定を分けてデプロイしたい

Cloudflare Worker を利用していて、Terraformによる環境変数やシークレットの設定、サービスバインディングを設定して、 実装したソースコードはTerraformでデプロイせずに、API経由でデプロイします。

有効なパターン

この考え方は、こんな場合に有効かもしれません

  • ソースの変更サイクルと、インフラの更新サイクルが異なるので、デプロイタイミングを分離したい
  • マルチクラウド環境で、AWSのシークレットをTerraformで環境変数にセットしたい
  • ローカルでWranglerを利用して二重管理にしたくない、上書きしたくない

やり方

  1. Workersの名前をハードコードする可能性を許容する
  2. TerrafromにWorkerworkerとHelloWorldコードをデプロイするversion,deployを作成
    • 以降、変更しません。Workersの箱を作るのみです
  3. TerraformにWorkerについて、シークレットなどのバインディングを行うversion,deployを作成
    • 初回のみ実行をスキップする(count=0にする)
      • Terrafrom外部から初回デプロイ時かどうかを判定する変数を流してください
      • 例: Terraform実行前にAPI経由でWorkersの名前を検索してフラグを準備します
    • versionのソースコードはlatestのバージョンから取得してください
      • main_module,moduleのみで良いはずです
      • lifecycleでソースコードの変更をignoreします
      • ※初回スキップはlatestを初回に取ることができないためです
  4. コードのデプロイは、https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/workers/scripts エンドポイントを利用します
    • -F ‘metadata={“main_module”:“index.js”};type=application/json’
    • -F “index.js=@dist/index.js;type=application/javascript+module”
  5. wrangler.jsoncは開発時のみに利用します
    • 最悪、設定内容が本番と同期していなくても、デプロイに利用されず上書きなどの事故はないです

結果

  • 環境変数の設定やシークレットの更新のみ、Terrafromにdiffが発生します
  • コードの変更によってTerraformのdiffは発生しません
  • お互いに上書き巻き戻しが発生しません

まとめ

wranglerの設定事項を唯一の信頼源とするというCloudflare推奨からは外れます。 ソースコード以外はTerraformが唯一信頼します。 ソースコードとデプロイ先のミスだけには気をつけてください。

なにかの参考までにお願いします。

以上!

Cognitoのユーザプールに対するテストのモック化を辞めてテスト専用プールを作った

Goで AWS Cognitoのユーザプールに対して直接テストを実行するようにしました。

おもに利用するAPIはAdminGetUser AdminUpdateUserAttributes で、以前はオンメモリでモック書いていました。 サービスが大きくなるにつれて項目も増えていき、プロフィール関連のデータから、Stripe/プラン関連、外部アカウント連携情報などになりました。 そうすると、Cognitoの実装に間違えがあると、最悪複数の機能に影響することになり、テストの導入を検討しました。

インフラとして、様々なエミュレートサービスやOSSを検討しましたが、サービスの性質上、すべての機能を網羅することが難しいようでした。 APIごとに互換があるかどうかの検討が挟まることは、開発のスピード感を損ねてしまう可能性を残しそうでした。

そのため、実際のCognitoのユーザプールに対してテストを実行するようにしました。テストの信頼性が上がりますし、ユーザプールに対する操作である限り、何も考慮が不要のメリットは大きいと思いました。

インフラ構成がちょっと手間がかかりました。 terraformリソースに、新しい./modules/cognito/ モジュールを作成して、既存リソースはmoved、CIテスト環境用にenviromentを作成。 GitHub ActionsでのGoのテスト実行中に、該当のユーザプールの操作が可能なロールを作成。 CIのワークフローでは、go test前に、CI用のユーザプールのデプロイ(ロール必要)。

このコストがどの程度になるのかは未知で、CIの実行プロセス、またはCognitoに対するテスト設計(条件付の実行)などを考える必要があるかもです。

サービスがスタートしたばかりで、なるべくCognitoに情報を詰めることは、フロントエンドでのログインユーザの情報同期をほとんど考えなくて良いので快適でした。 今回、テストを追加して信頼できるバックエンドとなりました。開発のスピード感維持しつつ要所に堅牢なテストを導入できたのかなという総括です。

SOPSを使って.envファイルを暗号化してコミット

SOPSというファイルの暗号化ツール/暗号化エディタを使い始めました。

主に .env ファイルに利用しています。

以前から、ローカル用のコミットできないような環境変数は、基本ローカルに .env を非管理で置いていました。 ただ、開発マシンをクラウドに立てたりすると、このファイルをイチイチコピペや送信しなくてはならず、かつ同期も手作業でした。 また、ローカルマシンにしか大事なファイルがないのは、心理的にも負担でした。

そこで、SOPSを導入して暗号化したファイルをコミットしていく方針を取りました。

主な構成ですが、基本的に.sops.yamlに2つの鍵を指定します。 日常利用用の AWS KMS で発行した鍵(のエイリアスのARN)と、バックアップ用のage-keygenで発行した公開鍵です。 これで、AWS にアクセスできれば、暗号化されたファイルを復号できます。AWSが死んだ場合に備えて、紙に書いたバックアップも保管しています。

こんな感じで、ひとまずローカルの .env ファイルが安全に管理されるようになりました。 CI/CDとの統合などは、また追って必要があれば検討していきます。

dev  SOPS