🍽️

Secrets in Tofu (Terraform)

2024/08/19に公開

TR;DL

シークレットをこう扱ってみた。の話。
参考としたページ(下記URL)から、こう考えてこういう構成にした。の記事
これは Tofu と Google Cloud Platform を前提としたものになります。

Reference

こう理解して

参考記事を元に以下の点を考慮する。

  1. 外だしする(環境変数、変数ファイル)(.tfファイル内に含めない)

    プレインテキストでコードにシークレット情報が埋め込まれる事を防ぐ

  2. 暗号・復号化する

    シークレット情報を含む情報が漏洩しても復号化されなければ問題ない状態にする

  3. リポジトリ外に保持する

    シークレット情報保持サービスを利用して、情報のアクセス制御をシークレット情報単位で可能にする

  4. Tofu(Terraform)で扱わない

    暗号化、情報保持を行えるツールを利用する

こう考えた

項目 適用度 備考
1. 外だしする 環境変数を利用する
2. 暗号・復号化する ⚪︎ dotenvx で暗号化する
3. リポジトリ外に保持する .env.keyを secret manager に保存する。
4. Tofu(Terraform)で扱わない ⚪︎ dotenvx で GCP/AWS への依存をなくす、
KMSコマンドのちょっと面倒な引数設定を回避(個人の主観)

* 適用度は個人の主観

構成するものとして以下の3つが必要と理解した。

  • Secret Store: SecretInfoを保存するもの
  • Cipher Tool: 暗号化したい気持ち
  • Secret Info: 実際の情報

用途に合致して、楽なのを選択する。

やったこと

  1. dotenvx で環境変数とkeyファイルを作成
  2. Tofu で必要な Google API をアクティブにする
  3. Tofu でGCPに保存用のSecretManagerを作成する
  4. .env.key を保存をSecretManagerに保存する
  5. 実際必要なリソースを作成する

コード、コマンドとか

  1. Variable 定義を作る
    variable "example" {
      type = object({ id = string, token = string })
    }
    
  2. .env を編集する
    TF_VAR_example='{ id = "example_id", token = "ex_token"}'
    
  3. 暗号化する
    # 暗号化
    dotenvx encrypt
    # 確認
    ls .env .env.keys && cat .env
    #/-------------------[DOTENV_PUBLIC_KEY]--------------------/
    #/            public-key encryption for .env files          /
    #/       [how it works](https://dotenvx.com/encryption)     /
    #/----------------------------------------------------------/
    DOTENV_PUBLIC_KEY="見せられないよ"
    
    # .env
    
    
    # Terraform variables
    TF_VAR_example="encrypted:BPBaDR3UC5TyuQvuVoyNqnCpMながーい文字列"
    
  4. SecretManager 準備、保存
    • コード
      resource "google_secret_manager_secret" "env-secrets" {
        secret_id = "project-env-secrets"
      
        replication {
          auto {}
        }
      }
      
      resource "google_secret_manager_secret_version" "env-secrets-version" {
        secret      = google_secret_manager_secret.env-secret.id
        secret_data = file("${path.module}/.env.keys")
      }
      
    • コマンド
      dotenvx run --quiet -- sh -c 'tofu validate'
      # 以下 dotenvx コマンドを省略
      tofu plan -target "google_secret_manager_secret.env-secrets" \
            -target "google_secret_manager_secret_version.env-secrets-version"
      tofu apply -target "google_secret_manager_secret.env-secrets" \
            -target "google_secret_manager_secret_version.env-secrets-version"
      
  5. 内容の確認
    dotenvx run --quiet -- sh -c 'echo "var.example" | tofu console'
    {
      "id" = "example_id"
      "token" = "ex_token"
    }
    

その他

  • .env の更新の時
    • .env 復号化する
    dotenvx decrypt
    
    • .env を編集
    vim .env
    
    #              ↓ ダブルクオートになっているのでシングルに変更が必要
    TF_VAR_example="{ id = "example_id", token = "ex_token"}"
    

個人的な感想

ソースコード・リポジトリに機密情報が入らないようにするために、事前準備が多すぎてダルい
解決策を考えたい・・・

TODO 面倒な気持ちとか

  • 実行の前にとか暗号化復号化とか書かないといけないのでIaCとか関係なく面倒

あとでTODOを更新したい

Discussion