【入門編】Chefでシークレット情報を安全に管理する!encrypted_data_bagの使い方とAWS Secrets Manager連携 – インフラ構成管理(IaC)活用バイブル

こんにちは。インフラの深淵を覗き込み、自動化の果てを目指すエンジニアの皆さん。

今日はChefにおける「禁断の果実」、すなわちシークレット情報の扱いについて話をしましょう。Chef初心者にとって最大の壁であり、かつ最も事故が起きやすいのが「認証情報」の管理です。

「リポジトリにAPIキーをコミットしてしまった」……この悪夢を回避し、かつChefの強力な冪等性を損なわないための設計思想を伝授します。

—

1. なぜ「Encrypted Data Bag」なのか?

Chefにおいて、設定ファイルやレシピを抽象化する「Data Bag」は便利ですが、平文で保存するとセキュリティリスクが極大化します。ここで登場するのがEncrypted Data Bagです。

これは「共通鍵(Shared Secret)」を用いてData Bagの値を暗号化し、実行時にその鍵を使って復号するという仕組みです。

準備:シークレットキーの作成

まずは、暗号化のための鍵ファイルを生成します。このファイルは絶対にGit管理下(リポジトリ)に置いてはいけません。

32バイトのランダムなキーを生成(これが暗号化の要です)
openssl rand -base64 512 > /etc/chef/encrypted_data_bag_secret

2. Encrypted Data Bagの作成(HelloWorld的実践)

まずは「db_password」というシークレットを持つData Bagを作成してみましょう。

‘passwords’ という名前のData Bagを作り、その中に ‘db’ というアイテムを作成
knife data bag create passwords db –secret-file /etc/chef/encrypted_data_bag_secret

実行するとエディタが開きます。以下のように入力してください。

{
“id”: “db”,
“password”: “super-secret-password-123”
}

これで、ローカルの `data_bags/passwords/db.json` には暗号化された文字列が保存されます。これなら、リポジトリにプッシュしても安全です。

—

3. レシピでの利用方法

レシピ側でこの値を読み出すのは非常に簡単です。Chefの「直感性」がここで活きます。

レシピ内での読み込み
秘密鍵の場所を自動的に見つけ出し、復号してハッシュとして取得します
my_secret = data_bag_item(‘passwords’, ‘db’)

template ‘/etc/myapp/config.conf’ do
source ‘config.conf.erb’
variables(
password: my_secret[‘password’] # 安全に値を取り出す
)
end

—

4. 【深淵】AWS Secrets Managerとの連携

ここからが本題です。実は、大規模な現場では「共通鍵ファイルを各ノードに配布する」ことすら運用コストが高いと感じるようになります。鍵が漏洩した際のローテーションが地獄だからです。

そこで、AWS Secrets Manager を「信頼の源(Source of Truth)」とする設計がベストプラクティスです。

なぜ移行すべきか?

1. IAMロールによる制御: キーファイル配布不要。ノードのIAM権限のみでアクセス可能。
2. 自動ローテーション: Chefのコードを書き換えずに、AWS側でパスワードを更新できる。
3. 監査ログ: 「誰が・いつ」取得したかがCloudTrailに残る。

実装のヒント:Chefのカスタムリソース化

`knife-vault` を使う手もありますが、現代的なSREとしては、RubyのAWS SDKを使い、レシピの実行時に直接Secrets Managerを叩くのが最もシンプルで堅牢です。

事前に chef-client に aws-sdk-secretsmanager gem を入れておくこと
require ‘aws-sdk-secretsmanager’

def get_secret(secret_id)
client = Aws::SecretsManager::Client.new(region: ‘ap-northeast-1’)
resp = client.get_secret_value(secret_id: secret_id)
JSON.parse(resp.secret_string)
end

レシピ内での利用
db_creds = get_secret(‘production/db/password’)

file ‘/etc/myapp/.db_pass’ do
content db_creds[‘password’]
mode ‘0600’
sensitive true # Chefのログに値が出ないようにする重要フラグ
end

—

5. 現場で生き残るための鉄則

最後に、これだけは覚えて帰ってください。

1. `sensitive true` を忘れない: Chefのログは非常に詳細です。秘匿情報を扱うリソースでは、必ず `sensitive true` を記述してください。これを怠ると、Chefの実行ログにパスワードが平文で出力されます。
2. 鍵管理の分離: `encrypted_data_bag_secret` をChefサーバーのファイルシステムに置くのは過渡期の手法です。最終的にはKMSやSecrets Managerへ完全に移行しましょう。
3. コードは常にクリーンに: セキュリティは「魔法」ではなく「規律」です。シークレット情報をハードコーディングする誘惑に負けず、常に外部ストレージから注入する設計を貫いてください。

これをマスターすれば、あなたの管理するインフラは「自動化されている」だけでなく、「堅牢に守られている」状態になります。毎日のデプロイが少しだけ怖くなくなる……それがプロフェッショナルの仕事です。

次は、このシークレットをどうローテーションさせるか、自動化のその先を一緒に考えましょう。応援していますよ。

タイトルとURLをコピーしました