ハクソク

世界を動かす技術を、日本語で。

Show HN: Enroll、サーバーをAnsible構成管理に逆エンジニアリングするツール

概要

Enrollは、サーバーの現状を収集し、AnsibleのロールやPlaybookへ即座に変換可能。
ローカルリモートどちらでも利用でき、災害復旧や構成の再現性確保に最適。
差分検出・通知機能も備え、構成管理の抜け漏れもカバー。
JinjaTurtle連携でテンプレート化も自動化可能。
Debian系・Redhat系のサーバーに対応。

Enrollの基本的な使い方

  • サーバーの現状を一括収集し、Ansibleロール/Playbook/インベントリへ変換
    • enroll single-shot --harvest ./harvest --out ./ansible
    • 収集後、ansible-playbook -i "localhost," -c local ./ansible/playbook.ymlでローカル適用
  • 災害復旧スナップショットや「この1台を再現したい」用途、「ゴールデンロール」の作成に最適
  • JinjaTurtleをインストールし、--jinjaturtleオプションで構成ファイルをテンプレート化
    • 自動検出にも対応

リモート収集とローカル変換

  • SSH経由でリモートサーバーから情報収集し、ローカルでAnsible化
    • enroll single-shot
      --remote-host myhost.example.com
      --remote-user myuser
      --harvest /tmp/enroll-harvest
      --out ./ansible
      --fqdn myhost.example.com
  • sudo権限不要の場合は--no-sudoを追加(ただし収集精度は低下)

マルチサイト・複数サーバー対応

  • 複数サーバーの状態を一括収集し、ホスト固有の状態をインベントリで管理
    • enroll harvest --out /tmp/enroll-harvest
    • enroll manifest --harvest /tmp/enroll-harvest --out ./ansible --fqdn "$(hostname -f)"
  • サーバーごとのPlaybook実行
    • ansible-playbook ./ansible/playbooks/"$(hostname -f)".yml
  • 運用指針
    • シングルサイト:1台・可読性重視
    • --fqdn運用:多台数・抽象度重視・迅速な導入

差分検出と通知

  • 2つの収集データを比較し、人間に分かりやすいレポート出力
    • enroll diff --old /path/to/harvestA --new /path/to/harvestB --format markdown
  • Webhook通知で変更検知を自動化
    • enroll diff
      --old /path/to/harvestA
      --new /path/to/harvestB
      --webhook https://example.net/webhook
      --webhook-format json
      --webhook-header 'X-Enroll-Secret: ...'
      --exit-code

Enrollの特徴・活用例

  • 構成管理未導入サーバーの現状把握・再現性確保
  • インストール済みパッケージ稼働中サービス初期状態から差分のあるファイル独自データの収集
  • 収集データはSBOM的にも活用可能、Ansibleロール/Playbook/Inventoryへ即変換
  • ローカル/リモート両対応、Debian系・Redhat系サポート
  • diffモードで構成ドリフト検知(現状は通知のみ、強制適用は未対応)
  • 既存Ansible運用中でも「記載漏れ」の検出に有用
  • DR戦略として「普段は手作りAnsible、バックグラウンドでEnrollによる全体スナップショット」運用も推奨
  • JinjaTurtle連携で設定ファイルのJinja2テンプレート化も可能

まとめ・コメント

  • Enrollはサーバー現状の可視化・再現性確保・差分検知を高速・簡単に実現
  • 構成管理の導入・強化災害復旧運用抜け漏れ防止に最適
  • 詳細なデモやドキュメントは公式Webサイト参照

Hackerたちの意見

すごい!これで遊んでみるよ。今までAnsibleを触ったことはなかったけど、自動化に関係してるのは知ってる。こういうツールがあれば、Ansibleを試すのがもっと簡単になるかもね。いつか試してみるよ、ありがとう!でも、このツールはどれくらい正確なんだろう?サーバーをセットアップするためにいくつかコマンドを実行して、それをAnsibleと一緒に使えるのかな?これがうまく使えるならいいけど、間違った抽象化でcloud-initみたいなものを再発明するだけになっちゃうのかな。(公平に言うと、cloud-initについて気になるのは、実行したいコマンドや変更のリストが必要になること。historyコマンドに問題があったり、ファイルを書いたりすると、ちょっとごちゃごちゃになっちゃうことがあるからね。)cloud-initとAnsibleの両方をあまり触ったことはないけど、enrollや他のことについてもっと知りたいな。すごく面白そうだし!
いい質問だね!OPだけど、下で答えるね。 > このツールはどれくらい正確なんだろう?サーバーをセットアップするためにいくつかコマンドを実行して、それをAnsibleと一緒に使えるのかな? うん、まさにその通り。例えば、VPSをプロビジョニングして、いくつかのものをインストールしたり、設定をしたり、crontabを作成したり、ユーザーアカウントを作ったりする。そこで'enroll harvest'を実行すれば、それをすべて検出して、'enroll manifest'がその'harvest'をAnsibleのロールやプレイブックに変換してくれるよ。 > これがうまく使えるならいいけど、間違った抽象化でcloud-initみたいなものを再発明するだけになっちゃうのかな。 (公平に言うと、cloud-initについて気になるのは、実行したいコマンドや変更のリストが必要になること。historyコマンドに問題があったり、ファイルを書いたりすると、ちょっとごちゃごちゃになっちゃうことがあるからね。) うん、その点については君の直感は正しいよ。AnsibleとCloud-initは、どちらもマシン上に何が存在すべきかを宣言する「宣言型」システムという点で似てる。Ansibleは、現在のセットアップと比較して、何かを変更する必要があるかどうかを確認するという利点がある。Cloud-initは(私の経験では)ちょっと粗い感じで、「マシンが初めて起動したときにこれを実行するだけ」って感じだね。使い方はいろいろあると思うけど、私の経験ではcloud-initは「一度だけ実行する」ために設計されてる。例えば、TerraformやOpenTofuでマシンをプロビジョニングして、cloud-initを渡すと、後でcloud-initのデータを変更すると、マシンを壊して再構築したがる(それをしないように明示的に設定しない限り、cloud-initに変更を「無視」するように指示する必要がある)。一方、Ansibleを使えば、少なくとも時間をかけて拡張できるし、初期セットアップ後にサーバーに変更を加える必要が出てくるだろう。Ansibleに不慣れなら、EnrollはAnsibleの設定をすぐに使えるようにする手っ取り早い方法だし、学びながらそこから適応していけるよ。正直言うと、いろんなケースに対応するために(または異なるLinuxディストリビューションをサポートするために)、Enrollが生成するAnsibleコードは「オーダーメイド」のプレイブックと比べるとちょっと読みづらいけど、正しいコードだし、良いプラクティスの構文にすぐに触れられるよ。試してみたら教えてね!
Ansibleを使って構築したマシンが結構あるんだ…機会があったら、それを逆にして、IaCと結果を比較してみるよ。
これ、Ansibleを学ぶのにもいい方法だね。ランダムな例と一緒に学ぶんじゃなくて、自分のサーバーをセットアップして、Ansibleでどうなるかを見ることができる。素晴らしい!
これがJinja2テンプレートとAnsible変数に設定を変換するためのツール、JinjaTurtleの動画だよ:https://asciinema.org/a/765293 Enrollは、$PATHにjinjaturtleがあれば、自動的にテンプレートを生成するよ。
Nixにも似たようなツールがあるのかな?宣言型システム管理で有名だから、サーバーのプロビジョニングにかなり適してるよね。
Nixでシステムを作るのは、まずそのシステムの設定がないと難しいよね。
他のコメントが一部答えてるけど、NixOSシステムには実際には必要ないよ。通常、マシン上のストアを参照して(すべての遷移依存関係のグラフを再帰的に構築できる)、世代と一緒に設定を保存するシステムがあるから(オプション`system.copySystemConfiguration`やフレークベースのシステムは、設定をストア自体に保存する)。ストアも設定(コンテナイメージ)もないシステムは、メタデータが欠けすぎて再構築が難しいよ。
すごいね。WSL2のインスタンスの状態を保存して、GitHubにプッシュしたよ。驚くほど簡単だった。ちなみに、--harvestを追加する必要があったんだけど、君のクイックスタートにはそれが抜けてるみたい?つまり、私はこう使ったよ:uvx enroll single-shot --harvest ./harvest --out ./ansible
おっと、ありがとう!その例を修正するよ!確かに、single-shotを使うときは、--remoteモードを使わない限り(その場合、harvestはマシン生成のパスにローカルでプルされる)、harvestのパスを指定する必要があるんだ。そうしないと、内部で'manifest'の部分が何を使うか分からないからね。(対照的に、'enroll harvest'コマンドだけを使って、--outオプションを省略すると、デフォルトで~/.cache/enroll/harvest/xxxxxxxのランダムなディレクトリにharvestが保存されるよ。)試してくれてありがとう!
これ、めっちゃ可愛いツールだね。インストールせずに以下のコマンドで実行してみたよ:uv tool run enroll single-shot --harvest ./harvest --out ./ansible。ほぼ千個のロールが生成されて、ぱっと見た感じ、予想してた変更点もあれば、予想外のものもあった。
そうそう、結構圧倒されるよね。システムで何を検出したかによる!state.jsonには、なぜ何かを「収穫」したのかが説明されてることが多いよ(例えば、実行中のsystemdサービスを見つけたからとか、手動でインストールされたパッケージを検出したからとか)。--excludeオプションも役立つかもしれないし、enroll.iniファイルを定義してフラグを管理すれば、もっと楽になるよ。それ以外にも、ansibleディレクトリやプレイブックからロールを削除することもできるし。もっと簡単にスキップできるオプションを考え続けるつもりだよ。特に、収穫の一部としてすでに検出された他のパッケージの依存関係だけの「lib」パッケージは省略できると思う。(依存関係グラフを基本的に構築する必要があるけど)試してくれてありがとう!
すごい取り組みだね!手動設定をAnsibleに収穫して、新しいマシンを作って、それが古いマシンの機能的な表現になっているかどうかを確認するために、どれくらいテストしたの?興味があるのは、何年も稼働している古いマシンやマイナーなマシンに対して、このツールにどれだけの信頼を置けるかってことなんだ。
こういうの探してた!リモートマシンにSSHで接続する時、sudoパスワードプロンプト用にTTYを割り当てないのは想定通りなのかな?それ以外の使い方はどうすればいいの?
わお、めっちゃいいね!これ、DevOpsのAnsibleの例に追加しなきゃ。素晴らしいアイデアだね、いろんなケースで手動設定を自動化に移行するのに役立ちそう。