Ansibleを業務で使っていると、色々な要望を叶えながらPlaybookを作成することになるよね。
そんな中、色々な条件が重なり結果的にハマってしまった事例をちょっと書いておく。
環境
- 作業マシン:Macbook (MacOS High Sierra)
- ansibleバージョン(作業マシン):2.4.1.0
- Vagrantゲストマシン:CentOS6.7
- ansibleバージョン(Vagrantゲストマシン内):2.3.2.0
「Chefで構築されたVagrantをAnsibleに書き直してほしい」というタスクのため、上記の環境で作業。
また、Ansibleの実行はVagrantのゲストマシン自身が叩く。そのため、vm.provisonはansible_localで実施した。
group_varsが読み込まれない
普段Ansibleするとき、変数の格納はここに入れている。
たとえばこういう構成で、allの中に格納している。
└── aws
├── README.md
├── group_vars
│ └── all
├── hosts
├── playbook.retry
├── playbook.yml
└── roles
├── change-instance
│ └── tasks
│ └── main.yml
├── ec2-build
│ └── tasks
│ └── main.yml
├── group-build
│ └── tasks
│ └── main.yml
├── rds-build
│ └── tasks
│ └── main.yml
├── volume-up
│ └── tasks
│ └── main.yml
└── vpc-build
└── tasks
└── main.yml
次がVagrantで作成した構成。
同じようにgroup_vars内にallを作成し、Playbook内で使用する変数を格納していた。
├── Vagrantfile
└── ansible
├── callback_plugins
│ ├── slack.py
│ └── slack.pyc
├── group_vars
│ └── all
├── hosts
├── playbook.retry
├── playbook.yml
└── roles
├── common
│ └── tasks
│ └── main.yml
├── h2o
│ └── tasks
├── input-test
│ ├── tasks
│ │ └── main.yml
│ └── template
│ └── your_name.yml
├── mysql
│ └── tasks
│ └── main.yml
├── php7
│ └── tasks
│ └── main.yml
└── slack
└── tasks
└── main.yml
しかし、これでvagrant upやvagrant provisionをしても、変数が定義されてないよと怒られる。
※この環境の場合、ansibleディレクトリに移って、ansible-playbook -i host playbook.ymlを打てば問題なくgroup_varsを読んでくる。
ただし、あくまでvagrant upのコマンドひとつで環境を立ち上げるという要件があるので、これはイケてない。
extra_varsを使え
extra_varsを使うことで、変数を優先的に読み込むという記述を発見!
あくまでvagrant upから立ち上げる場合、変数はVagrantfileの中に書くことになった。
果たしてこれがベストプラクティスなのか?はわからないが、Playbook内の変数定義はこれでなんとか解決できる。
ansible.extra_vars = {
"MYSQL_VERSION" => "http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm",
"PHP_REMI" => "http://rpms.famillecollet.com/enterprise/remi-release-6.rpm",
"PHP_EPEL" => "https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm"
}
handlersが読み込まれない(キックされない)
ご存知、ミドルウェアに対してchangedがかかった時だけhandlersに記述したコードがキックされるこの仕組み。
下の画像で言う所の、「タスクとタスクの間でhandlersが起動してhttpdが再起動する」ものだとばかり思っていた。

結論から言うと、handlersは「すべてのタスクが実行された後、最後にキックする」
わかりやすいなーと思った記事様がこちら
つまりこの段階では再起動はされず、万が一途中で処理が失敗した場合はミドルウェアの再起動はされない。
※ちなみに私はgroup_varsが読み込まれない事態も経験した上、この仕様を知らず、挙句処理に失敗したために「vagrantのansible_localはhandlersが読み込まれないのか??」と考える始末だった。
まとめ
VagrantがキックするAnsibleであっても、AnsibleはAnsibleということを忘れない。
特別なことはなく、もしあるとすればVagrantによる環境依存だろうか。
参考