Ansible における抽象/具体モデルと誰が/何をするの考え方

Ansible の group と host, role と task の関係が 公式ドキュメント からだと個人的にわかりにくかったのでまとめた図です。頭の中でなんとなく理解していたことを図や表に起こしてみることで理解が促進されました(公式ドキュメントにこういった説明があれば助かりましたが... たとえば以下の定義だけだと他のエンティティとどう結びついているのがわかりづらい)

抽象/具体の 2 軸に分類して考える

Ansible の主要なエンティティは group, host, role, task, inventory です。それぞれをまず抽象と具体の 2 軸で分類すると以下になります。

  • 抽象的なエンティティ: group, role
  • 具体的なエンティティ: host, task

抽象的なエンティティである group, role は実際に存在するわけではなく「集合」としての概念です。例えば redisservers という group は redisservers という具体的な host を指しているわけではありません。redis01, redis02, redis03 という実在する具体的な host を集合として抽象化したのが group です。

同様に roles も実際に存在するわけではなく「集合」としての概念です。例えば commonPackges という role は commopnPackages という 具体的な task を指しているわけではありません。install git, install gcc という実在する具体的な task を集合として抽象化したのが role です。

「誰が」「何をする」の 2 軸を追加して考える

もう一歩考えを進めて、抽象/具体モデルにもうひとうの軸「誰が」「何をする」を追加してみます。こうすると、それぞれ抽象的なレベルと具体的なレベルそれぞれで「誰が」「何をする」がわかりやすくなります。そしてこの抽象と具体を結びつけているのが inventory です。

誰が 何をする
抽象 group role
具体 host task
抽象/具体の関連付けファイル inventory [groupname].yml
  • group の例) redisservers, webservers
  • host の例) redis01, redis02, redis03, web01, web02, web03
  • role の例) commonPackges, tuningKernelParams
  • task の例) install git, install gcc, modify sysctl.conf, load sysctl
  • inventory の例) development, staging, production
  • [groupname].yml の例) redisservers.yml, webservers.yml

f:id:kyagi:20220218222605p:plain

抽象化することで「個」ではなく「集合」を扱える

抽象レベルで記述することの最大の利点は結果的に「個(host, task)」ではなく「集合(group, role)」を扱うことにより記述量が少なくなることです。同様の考え方はデータベースでもオブジェクト志向プログラミングでもクラウドのリソース管理/設計でも見つけることができるはずです。

f:id:kyagi:20220218222620p:plain

抽象レベルで記述したことを具体レベルまで落とし込んでいくと以下のようになります。

  • 誰が

    • host: redis01(具体) は group: redisservers(抽象) に属している
  • 何をする

    • task: yum install redis(具体) は role: redis(抽象) に属している
    • task: yum install git(具体) は role: commonPackages(抽象) に属している

よって「redis01」は「yum install redis」「yum install git」を行える「(... 省略 ...)」を行う(「誰が」「何をする」)

参考情報

docs.ansible.com