以前にansibleでvim,zshの設定を自動化する記事(http://qiita.com/nl0_blu/items/428656c1147775faefd1)
を書いたが、これはvagrantの仮想マシンなど様々な場面で利用できた。
しかし、CentOS7とUbuntu16.04など環境が違う場合に、パッケージをインストールするコマンドが異なるためplaybookの中身を変更する必要があった。
そのため本記事では、その改善案としてPlaybookのディレクトリ構造やYAMLの中身などを変えることで、上記の手間をなくしたい。
##OSをどう判別するか
setup_moduleの結果で得られる変数はplaybookに利用できることから、これを利用する。
$ ansible -m setup 192.168.12.183
:
:
かなり長い出力です。
この中の
- ディストリビューションを示す: "ansible_distribution"
- ディストリビュションのバージョンを示す: "ansible_distribution_major_version"
をplaybook内で利用する。
完成したディレクトリ
├Vagrantfile
└provisioning/
├ hosts #Inventoryファイル(対象サーバーのIP等)
├ site.yml #マスタープレイブック
├ centos6.yml #centos6用のロールをまとめたプレイブック
├ centos7.yml #centos7用のロールをまとめたプレイブック
├ ubuntu16.yml #ubuntu16用のロールをまとめたプレイブック
├ files #テンプレートとなるファイルなど
└ .vimrc
└ .zshrc
└ roles
├ vim_centos #centos用のvim設定ロール
└ tasks
└ main.yml
├ zsh_centos #centos用のzsh設定ロール
└ tasks
└ main.yml
├ vim_ubuntu #ubuntu用のvim設定ロール
└ tasks
└ main.yml
├ zsh_ubuntu #ubuntu用のzsh設定ロール
└ tasks
└ main.yml
Inventoryファイル、YAMLの中身の例
Inventoryファイル(hosts)
[hostname]
192.168.33.12
# 対象がcentos6であると想定
# centos6 only group
[centos6:children]
hostname
#以下は今回は利用しないのでコメントアウト
#centos7 only group
#[centos7:children]
#hostname
#ubuntu16 only group
#[ubuntu16:children]
#hostname
#all group
#[all:children]
#hostname
site.ymlでは、先ほどの方法でOSを判定してincludeするプレイブックを決める
---
# centos6 specific tasks
- include: centos6.yml
when:
- ansible_distribution == "CentOS"
- ansible_distribution_major_version == "6"
# centos7 specific tasks
- include: centos7.yml
when:
- ansible_distribution == "CentOS"
- ansible_distribution_major_version == "7"
#Ubuntu specific tasks
- include: ubuntu16.yml
when:
- ansible_distribution == "Ubuntu"
- ansible_distribution_major_version == "16"
centos6と判定されたら、vim_centosとzsh_centosのロールを実行することをcentos6.ymlに記述する(centos7.ymlも同様)
---
- hosts: centos6
user: vagrant
sudo: yes
roles:
- vim_centos
- zsh_centos
ubuntu16と判定されたら、vim_ubuntuとzsh_ubuntuのロールを実行することをubuntu16.ymlに記述する
以下は各タスクの中身、centosとubuntuでコマンドが違うことがポイント。
コードは突っ込みどころありです。
---
- name: vim requires install by yum
yum: name={{ item }} state=latest
with_items:
- gcc
- git
- mercurial
- ncurses-devel
- lua
- lua-devel
- perl
- perl-devel
- perl-ExtUtils-Embed
- python
- python-devel
- libselinux-python
- name: install vim by yum
yum: name=vim state=present
- name: copy .vimrc file to dest home
copy: src="../../../files/.vimrc" dest="~vagrant/.vimrc" owner=vagrant group=vagrant mode="u=rw,g=r,o=r"
---
- name: install zsh by yum
yum: name=zsh state=present
- name: set zsh as default shell for root
command: chsh -s '/bin/zsh' root
- name: copy .zshrc file to dest home
copy: src="../../../files/.zshrc" dest="~vagrant/.zshrc" owner=vagrant group=vagrant mode="u=rw,g=r,o=r"
---
- name: vim requires install by apt
apt: name={{ item }} state=latest update_cache=yes
with_items:
- gcc
- git
- mercurial
- perl
- python
- name: Install vim by apt
apt: name=vim state=present
- name: copy .vimrc file to dest home
copy: src="../../../files/.vimrc" dest="~vagrant/.vimrc" owner=vagrant group=vagrant mode="u=rw,g=r,o=r"
---
- name: install zsh by apt
apt: name=zsh state=present
- name: set zsh as default shell for vagrant
command: chsh -s '/bin/zsh' vagrant
- name: copy .zshrc file to dest home
copy: src="../../../files/.zshrc" dest="~vagrant/.zshrc" owner=vagrant group=vagrant mode="u=rw,g=r,o=r"
##まとめ
簡単にテストしたところ、大丈夫そうだった。(バグあったら修正します)
$ ansible-playbook site.yml -i hosts -u vagrant --check
また、今回はAnsibleの本格的なイメージの理解として、ansibleのベストプラクティスを参考にした。
http://docs.ansible.com/ansible/playbooks_best_practices.html
この構造にすることで、OSにより処理が異なる設定(例えばDockerのインストール)に対しても、roleを書いて各OSのPlaybookに含ませることで対処できる。