Role を使ったAnsibleのチュートリアル

2015.11.10

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

渡辺です。 このところのマイブームはAnsibleです。 serverspecも利用したりして、汎用Roleを作りメンテすることが楽しい日々です。

さて、今回はAnsibeのRoleのチュートリアルとしてみました。 AmazonLinuxのサーバにApache2.4をインストールし、confファイルをセットアップする手順を紹介します。

Step1 Apacheをインストールし、サービスを有効化する

はじめにApacheのセットアップを行うためのRoleを作成します。 コマンドで実行するのであれば、次のようなフローです。

$ sudo yum -y install httpd24
$ sudo chkconfig httpd on
$ sudo service httpd start

これをRole「apache24」として定義していきましょう。

はじめにディレクトリroles/apache24 を作成し、tasks/main.ymlに必要なタスクを定義します。

# roles/apache24/tasks/main.yml
- name: install apache24
  yum: name=httpd24 state=present
- name: start httpd service
  service: name=httpd state=started enabled=yes

このRoleを実行するためのPlaybookを作成します。

# site.yml
- hosts: all
  sudo: yes
  remote_user: ec2-user
  roles:
    - apache24

実行してみましょう。

$ ansible-playbook site.yml 

PLAY [all] ******************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [test]

TASK: [apache24 | install apache24] ******************************************* 
changed: [test]

TASK: [apache24 | start httpd service] **************************************** 
changed: [test]

PLAY RECAP ******************************************************************** 
test                       : ok=3    changed=2    unreachable=0    failed=0

roles/apache24/tasks/main.ymlに定義したタスクが実行されているのが解ると思います。

このようにRoleはタスクをある程度まとまった単位に定義することで、再利用しやすくする仕組みです。

他のOSへの対応

今回はAmazonLinux前提のRoleとしています。 このままだと、CentOS7やUbuntuで実行しても期待する結果を得られません。 とはいえ、特定のプロジェクトでAnsibleを利用するような場合であれば、複数のOSにRoleを対応する必要はないでしょう。 もし、汎用的なRoleを作る場合は、OSを判定してyumとaptを使い分ける・パッケージ名をバージョンによって切り替えるなどの工夫が必要となります。

Step2 confファイルを設定する

次のステップとして、Apacheの設定ファイルをサーバに設定します。 以下のファイルを/etc/httpd/conf.d/example.com.conf に配置しましょう。

サーバにファイルを配置する場合、fileモジュールtemplateモジュールを利用します。

fileモジュールとtemplateモジュールの差は変数を埋め込めるかの違いになります。 テキストファイルを扱う場合はtemplateモジュールにしておけば問題ありません。 バイナリファイルの場合はfileモジュールを利用すると考えて良いでしょう。

templateモジュールではJinja2というテンプレートエンジンのフォーマットで記述しますが、変数を埋め込まない場合はそのままのテキストファイルでOKです。 次のファイルを roles/apache24/templates/example.com.conf.j2 として作成します(拡張子j2はJinja2のファイル形式ですが、付与しなくても大丈夫です)。

<VirtualHost *:80>
  DocumentRoot /www/public/html
  ServerName www.example.com
</VirtualHost>

templateモジュールは次のように、apache24/tasks/main.ymlに追記します。

# roles/apache24/tasks/main.yml
- name: install apache24
  yum: name=httpd24 state=present
- name: start httpd service
  service: name=httpd state=started enabled=yes
- name: setup conf file
  template: src=example.com.conf.j2 dest=/etc/httpd/conf.d/example.com.conf

これで再度実行すればexample.com.confが作成されることになりますが、それだけではApacheに反映できません。 restartまたはreloadが必要です。

restartが必要な場合は、handlerを利用するのが定石です。 handlerは他のタスクが実行されchangeになった時、notifyで実行される特別なタスクです。 handlerはまとめて最後に実行されるため、confファイルなどが増えた場合でも、どこかひとつのファイルが変更された場合のみrestartされることになるので便利に利用できます。 roles/apache24/handlers/main.yml を次のように定義してください。

# roles/apache24/handlers/main.yml
- name: restart apache24 service
  service: name=httpd state=restarted

最後にtemplateがchangedになった時、このhandlerを呼び出すように設定します。

# roles/apache24/tasks/main.yml
- name: install apache24
  yum: name=httpd24 state=present
- name: start httpd service
  service: name=httpd state=started enabled=yes
- name: setup conf file
  template: src=example.com.conf dest=/etc/httpd/conf.d/example.com.conf
  notify: restart apache24 service

Playbookを実行してください。 confファイルが作成され、Apacheが再起動されるでしょう。

$ ansible-playbook site.yml 

PLAY [all] ******************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [test]

TASK: [apache24 | install apache24] ******************************************* 
ok: [test]

TASK: [apache24 | start httpd service] **************************************** 
ok: [test]

TASK: [apache24 | setup conf file] ******************************************** 
changed: [test]

NOTIFIED: [apache24 | restart apache24 service] ******************************* 
changed: [test]

PLAY RECAP ******************************************************************** 
test                       : ok=5    changed=2    unreachable=0    failed=0

Step3 設定ファイルに変数を埋め込む 最後に設定ファイルに変数を設定し、埋め込めるようにしていきます。 roles/apache24/templates/example.com.conf.j2 を編集し、ServerNameを埋め込み変数のフォーマットで書き換えてください。

<VirtualHost *:80>
  DocumentRoot /www/public/html
  ServerName {{ apache24_server_name }}
</VirtualHost>

apache24_server_nameが変数名となります。 {{と}}で囲んだ部分が変数で置き換わります。 注意したいのは、Ansibleでは変数のスコープの概念がなく、すべてグローバル変数的に振る舞うことです。 suffixにRole名を付けるなど、一意になるように工夫してください。

変数の定義方法としては、group変数・コマンドライン引数など幾つかの方法があります。 ここではplaybookに定義してみましょう。

# site.yml
- hosts: all
  sudo: yes
  remote_user: ec2-user
  vars:
    apache24_server_name: test.example.com
  roles:
    - apache24

inventoryファイルを検証環境と本番環境でわければ、設定ファイルの差異をテンプレートで吸収することも容易です。

まとめ

今回はAnsibleのRoleを使い、Apacheのインストールと設定を行ってみました。 これだけの知識でも、パッケージインストーラでインストールできるミドルウェアであれば、十分に設定できるかと思います。