AnsibleのRole入門

ANSIBLE

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Ansibleは選れた構成管理ツールですが、構成する内容が複雑になればなるほど辛くなります。 これはプログラム(ソースコード)と同じです。 複雑になった構成を整理し、可読性再利用性を高めることが求められてきます。 今回はplaybookを整理する時に、最初に覚えなければならないRoleについてまとめます。

Roleとは?

Roleは、一言で言えばplaybookで読み込むモジュールです。 playbookは複数のRoleを読み込むことができるため、構成する内容を適切な粒度のRoleに分割し、それをインクルードする形でplaybookを構成するのです。 言い換えれば、Roleはクラス・モジュール・ソースファイルと言った概念と変わりません。 肥大化する構成を適切な粒度で分割するための道具です。

Roleの単位

Roleをどのような単位で作成するかは、ケースバイケースです。 詰め込みすぎたロールは、Managerクラスのような「良くわからないRole」になるでしょう。 また、細かく分割しすぎると見通しが悪くなるのも事実です。

一般的にミドルウェア単位などが適切だと思います。 アンチパターンとしてはサーバ単位にRoleを作成することです。 この場合、再利用性が乏しく、かつコピペが多くなりがちです。

Roleの構造

Roleはrolesディレクトリ配下に作成します。 例えば、apache2 Roleは、roles/apache2 ディレクトリの下に定義します。

各Roleの下には、tasks, defaults, vars, files, templates, mata, handlersと言ったディレクトリを作成して、Roleの定義を記述します。 この中で必須なのはtasksだけです。 tasks/main.yml が基本定義となるので、残りは随時覚えていきましょう。

site.yml
roles/
   apache2/
     files/
     templates/
     tasks/
     handlers/
     vars/
     defaults/
     meta/

今回は各ディレクトリの簡単な説明だけを行います。

tasks

roleで実行されるtaskを定義します。 main.ymlが読み込まれ、残りのファイルはmain.ymlなどからincludeされでしょう。

defaults

main.ymlにroleで利用される変数のデフォルト値を定義します。 後述のvarsとの違いは、group_varsなどで変数を上書きできる点です。

vars

main.ymlにroleで利用される変数を定義します。 基本的に環境毎に変わる固定値などを記述し、group_varsなどで変数を上書きできません(厳密にはできるが、優先順位的にvarsはかなり強いため、扱い難い)。

files

copyモジュールでセットアップされるファイルを配置します。 テキストファイルでもバイナリファイルでも構いません。 シェルスクリプトのようなテキストファイルは後述のtemplatesに配置する方がベターでしょう。

templates

templateモジュールでセットアップされるJinja2形式のテキストファイルを配置します。 Jinja2形式のテキストファイルは、変数を埋め込むことができる点がfilesの下のファイルとの違いです。 変数がない場合であっても、後日変数化したい場合も多いので、最初からtemplatesに配置する方がベターでしょう。

mata

Roleのメタ情報を配置します。 実質的に、main.ymlにRoleの依存関係を記述することになります。 このRoleを実行するには依存するミドルウェアをインストールする別のRoleが必要、といったイメージです。

handlers

handlersには、主にサービスの再起動といった特定の条件で発火するイベントtaskを定義します。 別のRoleにて、Apacheの設定ファイルを変更した後、Apacheを再起動したいといったケースで利用します。 この場合、別のRoleからhandlerの「restart apache2 service」をnotifyすれば、期待する挙動となるのです。

簡単なRoleの作成

Apache2をインストールする簡単なRoleを作成してみます。

ディレクトリの作成

roles/apache2/tasks を作成します。

tasks/main.ymlの定義

RedHatとDebianに対応してみましょう。

---
- name: Install apache2 (RedHat).
  yum: name=httpd
  when: "ansible_os_family == 'RedHat'"

- name: Install apache2 (Debian).
  apt: name=apache2
  when: "ansible_os_family == 'Debian'"

Playbookの作成

site.ymlを作成します。

#
# site.yml
#
- hosts: all
  sudo: yes
  remote_user: "{{ ansible_remote_user_name }}"
  roles:
    - apache2

まとめ

AnsibleのRoleを活用することで、肥大化するPlaybookを適切な単位に分割して整理することができます。 また、構造が決まっているため、どの情報がどこに書いてあるかを追いやすくなります。 ただし、構造や使い方を覚えなければなりません。