みんなのウェディングのインフラエンジニア横山です。
今回は、itamae利用時の機密情報管理をGoogle スプレッドシートから yaml_vault に移行したのでそのことについて書きます。
機密情報とは何か
みんなのウェディングの環境では、ryotaraiさんが作成した itamae によるインフラのコード管理を行っています。
itamaeには任意のテンプレートファイルをサーバに配置する機能(https://github.com/itamae-kitchen/itamae/wiki/template-resource) があり、こちらの機能を使って様々なファイルをレポジトリで管理しています。
そういった管理対象のファイルの中には以下に挙げるような、レポジトリへのコミットを控えたほうが良いが、なにかしらの手段で管理しておくべき情報が存在します。
- DBのパスワード
- アプリが利用するAPIのシークレットキー
- AWSの認証情報
ここではこれらの情報を機密情報と呼びたいと思います。
これまでの機密情報管理の仕方
機密情報の管理はしておきたいが、レポジトリへのコミットは控えたいという要求を満たすため、弊社ではこれまで管理にGoogle スプレッドシートを利用していました。
使い方は以下の通りです。
1.itamaeのテンプレートファイルの中で以下のように変数を指定。
GOOGLE_CLIENT_ID=<%= node[:spreadsheet][:google_client_id] %>
GOOGLE_CLIENT_SECRET=<%= node[:spreadsheet][:google_client_secret] %>
2.「itamae変数管理台帳」と呼ばれるスプレッドシートに変数名と値を記載。
※アクセス権はインフラエンジニアとリーダーのみに設定。
3.itamaeを実行。
※itamae実行をrakeタスク化し、スプレッドシートの変数名と値のnode[:spreadsheet]への格納処理をrakeタスクのヘルパーの中で行っています。
以上により、機密情報をレポジトリへコミットせずに管理するという要求を満たすことができました。
スプレッドシートの問題点
変数が少ないうちはこの方法で問題なかったのですが、運用していくにつれて以下のような問題が出てきました。
階層化して管理しづらい。
運用ルールが整備されていないため、新規の変数を追加する際は、以前の変数との関連性を考えずなんとなく最後の行に続けて書くだけになっていました。 これにより、各種変数の関係性が一目でわかるような階層管理ができていませんでした。
管理というより、おもちゃ箱にかたっぱしからおもちゃを突っ込んでいくようなそんな感じになりがちでした。
また、運用ルールを作るにしても、そもそもスプレッドシートはデータの階層構造を表しやすいように設計されていないので、ルールの運用が面倒になりそうでした。GitHubのプルリクエストベースでの変更管理ができない。
itamae変数管理台帳への変更はGitHubのプルリクエストと関連していないため、変更の理由を追いにくいという問題がありました。
また、プルリクエストでレポジトリに変更を加えたのに、itamae変数管理台帳への変更を忘れることもありました。
現在の機密情報管理の仕方
スプレッドシートからjoker1007さん作成の yaml_vault に管理方法を変更しました。
sue445さん作成のitamae-plugin-resource-encryptedremotefileも検討しましたが、機密情報を変数化して一つのファイルにまとめて記載することで、複数箇所で同一の変数を使えるというitamae変数管理台帳のメリットを無くしたくなかったので yaml_vault を選択しました。
itamae-plugin-resource-encryptedremotefileだと機密情報をそのまま記載したファイルを作成し、1ファイルずつ暗号化する必要があったため、複数ファイルで同一の変数を使っている弊社の環境で使うには適しませんでした。
yaml_vault を利用することで機密情報をyamlファイルとして管理し、暗号化することができます。 これにより、暗号化されていない機密情報をレポジトリへコミットせずに管理する、という要求を満たしながら、前述したスプレッドシートによる管理の課題をクリアすることができます。
使い方はこれまでと大きく変わらず以下の通りです。
1.itamaeのテンプレートファイルの中で以下のように変数を指定。
GOOGLE_CLIENT_ID=<%= node[:secret][:vault][:wedding_dot_env][:production][:google_client_id] %>
GOOGLE_CLIENT_SECRET=<%= node[:secret][:vault][:wedding_dot_env][:production][:google_client_secret] %>
2.レポジトリにコミットしてある暗号化済みファイルを複合化。
bundle exec yaml_vault decrypt encrypted_secrets.yml -o secrets.yml
3.変数名と値を複合化したyamlファイルに追記
---
vault:
wedding_dot_env:
production:
google_client_id: abcdef
google_client_secret: 123456
4.複合化したyamlファイルを再び暗号化。
bundle exec yaml_vault encrypt encrypted_secrets.yml -o secrets.yml
5.変更のプルリクエストを作成。
6.プルリクエストをマージする。
7.itamae実行。
※itamae実行をrakeタスク化し、yamlファイルの複合化処理・変数名と値のnode[:secret]への格納処理をrakeタスクのヘルパーの中で行っています。
今後
現状、 yaml_vault で暗号化したファイルのパスワード自体はitamae変数管理台帳に書いています。
yaml_vault では暗号化にAWSのKMSを利用できるようなので今後はKMSによる暗号化を行い、itamae変数管理台帳からの完全移行を目指したいと思います。
まとめ
yaml_vault を利用することで手軽に効率的に機密情報を管理することができました。 今後も自社サービスに活かせそうなOSSツールを積極的に利用し、チャンスがあれば開発への参加も行っていきたいと思います。
みんなのウェディングでは一緒に働く仲間を募集中です。
サービスの成長に携わっていきたい方や、0からサービスを作りたい、チームでサービスをもっと成長させてみたいエンジニアやデザイナーの方は、ぜひお気軽に遊びに来て下さい!
たまに人狼ゲームやボードゲーム会もやってます🐺