Ansible での include の良い書き方
よくある書き方の問題点
例えば include_tasks でググってみると、こういう感じの書き方をよく見かけます。
### tasks/main.yml
- name: Include tasks (RedHat 6)
include_tasks: install_redhat_6.yml
when: ansible_os_family == 'RedHat' and ansible_distribution_major_version|int == 6
- name: Include tasks (RedHat 7)
include_tasks: install_redhat_7.yml
when: ansible_os_family == 'RedHat' and ansible_distribution_major_version|int == 7
- name: Include tasks (Amazon Linux)
include_tasks: install_amazon.yml
when: ansible_os_family == 'RedHat' and ansible_distribution == 'Amazon'
この書き方で各種ロールを運用していく中で、いろいろ悩みが出てきました。
- ぱっと見で when がわかりにくい
- OS・ディストロを追加するたびに include_tasks が増えていく
- 例えば RedHat と CentOS で分けたいときに when が更にややこしくなる
- どれにも当てはまらない場合のエラーハンドリングがしにくい
良い書き方
### tasks/main.yml
- name: Include tasks
include_tasks: '{{ include_yml }}'
loop_control:
loop_var: include_yml
with_first_found:
- files:
- 'install-d-{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml'
- 'install-d-{{ ansible_distribution }}.yml'
- 'install-f-{{ ansible_os_family }}-{{ ansible_distribution_major_version }}.yml'
- 'install-f-{{ ansible_os_family }}.yml'
- 'install.yml'
skip: false
ポイント
- with_first_found を使う事で、基本的にファイル追加のみで OS・ディストロの追加ができる
- ループ対象は条件がきついものが最初にあるので、 "RedHat 系だけど CentOS は特別な処理をしたい" 的な事に対応しやすい
- 当てはまるものがない場合の動きを skip パラメタで指定できる
- include した先でループ変数にデフォルトの
item
を使いたいだろう事を考慮し、include_yml
という変数名にしておく
例: Docker CE のインストール
- RedHat 7 系 は公式リポジトリからインストール
- Amazon Linux はアマゾンのリポジトリからインストール
### tasks/install-d-Amazon.yml
- name: Install docker
yum: name=docker state=present
- name: Install pip
yum: name=python27-pip state=present
- name: Install docker-py
pip: name=docker-py state=latest
### tasks/install-f-RedHat-7.yml
- name: Install packages
yum: name='{{ item }}' state=present
with_items:
- device-mapper-persistent-data
- lvm2
- name: Install Docker CE repository
get_url: >
url='https://download.docker.com/linux/centos/docker-ce.repo'
dest='/etc/yum.repos.d/docker-ce.repo'
checksum='sha256:6650718e0fe5202ae7618521f695d43a8bc051c539d7570f0edbfa5b4916f218'
- name: Install docker-ce
yum: name=docker-ce state=present
- name: Install pip
yum: name=python-pip state=present enablerepo=epel
- name: Install docker-py
pip: name=docker-py state=present
最後に
もちろん、include_tasks だけじゃなく include_vars 等にも使えます。
この書き方にしてから見通しがよくなって、運用しやすくなりました。