LoginSignup
5
1

More than 5 years have passed since last update.

AnsibleでplaybookをDRYに書くために、全部やってくれるroleを作った

Last updated at Posted at 2016-12-12

Ansible Advent Calendar 2016 の13日目の記事です。

シチュエーション

APIサーバーと管理ツールをともにrailsで作っている。
ansibleで構成管理をしている。
APIサーバーと管理ツールの配信方法はほぼ同じで、配置ディレクトリやrubyのバージョンなどわずかに違う点がある。

やってみたこと

全部をやってくれるroleを作って、playbookではそのroleを引数付けて呼ぶだけにする

api-server.yml
---

- hosts: api-server
  roles:
    - { role: web-apps-requirements, become: yes }
  vars:
    app_name: api_server

呼ぶ側のplaybookは上記のような簡潔なもの。
roleの中では、一部の設定ファイルや環境変数の展開も行っているが、主には後述の通り依存関係にある別のroleを呼び出している(という言い方は適切じゃないかもしれない)。
「一部の設定ファイルや環境変数の展開」も、理想的にはroleに切り出すべきかもしれない。

meta/main.ymlにrole間の依存関係を書く

roles/web-apps-requirements/meta/main.yml
---

dependencies:
  - { role: rbenv, become: no }
  - { role: ruby, become: no, version: '{{ ruby_version }}' }
  - { role: nginx }
  - { role: passenger }

metaのdependencies設定を書けば、別のroleに依存していることを記述できる。
記述しておくと、依存しているroleを先に実行してくれる。
それぞれ、roleの名前のものをインストールするだけのシンプルなroleになっている。
このような構成にしておくことで、「全部やってくれる」と言いつつ、1つ1つのroleが煩雑になることを避けられている。

変数名を変数で引く

roles/web-apps-requirements/vars/main.yml
---

port: "{{ inventories[app_name].port }}"
server_name: "{{ inventories[app_name].server_name }}"
ruby_version: "{{ inventories[app_name].ruby_version }}"
deploy_to: "/var/www/{{ app_name }}"
group_vars/development.yml
---

inventories:
  api_server:
    port: 10080
    server_name: 192.168.1.100
    ruby_version: 2.3.3
  admin_tool:
    port: 80
    server_name: 192.168.1.101
    ruby_version: 2.3.3

ansibleの変数はrubyで言うところのHashie::Mashのようなもので、.でも[]でも引くことができる。
これを利用して、変数を上記のような構成にして、変数名を変数で引くようにすることで、変数名などを短くシンプルに維持できる。

終わりに

ansibleは設定を整理するためのアプローチが多いのと、変数の仕組みが複雑なので、こういう整理を行う時は非常に悩ましく、このやり方も問題に対して最適であったかどうかはあんまり自信はありません。
より良いやり方などあれば、教えてもらえると嬉しいです。

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1