やっさん的Ansible role開発をmolecule使って始めるテンプレ
adventar.org この記事は、上記の6日目の記事です。
ロールを追加する際に、 molecule を使うと非常に便利です。テスト(verify)を書かないにしても、テストドライバーを使ってdockerやvagrantなどの仮想環境にroleを適用してみて途中でエラーになったり、templateの生成が想定が違うなどを実際に確認出来るので、まずははじめることをオススメします。
いつもroleを作成する際にやってる一連の流れを紹介。 XXは〇〇すると良いよ!など、アドバイスあれば教えて下さい!
前提
OS:CentOS7 or Ubuntu 20.04 LTS
molecule 3.2.1 using python 3.8 ansible:2.10.4 delegated:3.2.1 from molecule docker:0.2.4 from molecule_docker vagrant:0.6.1 from molecule_vagrant
また、roleを含むリポジトリは Roles — Ansible Documentation にあるように以下の構成とします。
# playbooks site.yml group_vars/ group_xxx/ host_vars/ xxxx.example.com/ roles/ xxx/ defaults/ files/ handlers/ library/ meta/ tasks/ templates/ vars/ yyy/ :
初期構築
Installation — Molecule documentation を参考に、OSに合せて必要なpackageをインストール。
$ sudo yum install -y gcc python3-pip python3-devel openssl-devel python3-libselinux
仮想環境(venv)の用意
実行するansibleのバージョンやroleやmoduleで利用するpipが異ならないように仮想環境を用意して合わせるようにします(追加するpipはansibleを含め requirements.txt
に定義します)。
とは言え、venvの用意が毎度めんどいので、以下の様にMakefileを用意して make init-molecule
で準備できるようにします。
また、ついでに、バージョンチェックしてコマンド実行時にエラーにならないか簡単にチェックしています。
これは、CIなどからも呼び出しすると簡略化出来るので便利。
SHELL=/bin/bash # 初回構築用 .PHONY: init-molecule init-molecule: python3 -m venv .venv && .venv/bin/pip install --upgrade pip && .venv/bin/pip install -r requirements.txt .venv/bin/pip --version ; source .venv/bin/activate && \ .venv/bin/molecule --version && \ .venv/bin/ansible --version && \ deactivate
参考:私がよく使ってる requirements.txt
はこちら。
ansible ~= 2.10.0 cryptography jmespath pyyaml setuptools virtualenv ansible-lint molecule[lint] molecule-docker molecule-vagrant
※自分の組織合せて、ansibleだけでなく ansible-lint や molecule* についてはバージョンを固定することを推奨します(特にCIとは同じにしておく方が良いです)。
始めるとき
始めるときは以下の流れではじめてます。
# roleのリポジトリに入る $ make init-molecule $ source .venv/bin/activate (何らかの対応) # 終わる場合 $ deavtivate
roleのテンプレを使って初回分を作成
moleculeにはroleのテンプレを作成するコマンドが以下の通り存在しています。
$ molecule init role --help Usage: molecule init role [OPTIONS] ROLE_NAME Initialize a new role for use with Molecule. Options: --dependency-name [galaxy] Name of dependency to initialize. (galaxy) -d, --driver-name [delegated|docker|vagrant] Name of driver to initialize. (delegated) --lint-name [yamllint] Name of lint to initialize. (yamllint) --provisioner-name [ansible] Name of provisioner to initialize. (ansible) --verifier-name [ansible|testinfra] Name of verifier to initialize. (ansible) --help Show this message and exit.
なので、 roles/
に移動後に以下の様に初回分を作成します。
# `role` があるディレクトリまで移動 $ cd roles # defaultシナリオのテストドライバーは Docker、テストの記述は Ansible の場合 ※通常はこっち $ molecule init role new_role -d docker --verifier-name ansible --dependency-name galaxy # defaultシナリオのテストドライバーは vagrant、テストの記述は Ansible の場合 $ molecule init role new_role -d vagrant --verifier-name ansible --dependency-name galaxy # defaultシナリオのテストドライバーは Docker、テストの記述は Testinfra の場合 $ molecule init role new_role -d docker --verifier-name testinfra --dependency-name galaxy
とまぁ、面倒くさいので以下の様にMakefileに追加します。
: driver := docker : # 新規role追加 # # ex) make add-role role=hoge driver=vagrant .PHONY: add-role add-role: cd roles && molecule init role $(role) -d $(driver) --verifier-name ansible --dependency-name galaxy
すると、 site.yml
がある場所( roles/
と同じ階層 )にて、hugaロールを追加したい場合は以下のようにするだけになります。
# defaultシナリオのテストドライバーは Docker、テストの記述は Ansible の場合 make add-role role=huga
roleにシナリオを追加する場合
デフォルト以外のシナリオを追加したい場合も同様にmoleculeコマンド使います。
$ molecule init scenario --help Usage: molecule init scenario [OPTIONS] [SCENARIO_NAME] Initialize a new scenario for use with Molecule. If name is not specified the 'default' value will be used. Options: --dependency-name [galaxy] Name of dependency to initialize. (galaxy) -d, --driver-name [delegated|docker|vagrant] Name of driver to initialize. (delegated) --lint-name [yamllint] Name of lint to initialize. (ansible-lint) --provisioner-name [ansible] Name of provisioner to initialize. (ansible) -r, --role-name TEXT Name of the role to create. --verifier-name [ansible|testinfra] Name of verifier to initialize. (ansible) --help Show this message and exit.
なので、以下のようにして追加出来ます
# 「driver: docker、verifier: ansible、シナリオ名:piyo」の場合 $ molecule init scenario -d docker --verifier-name ansible --dependency-name galaxy piyo # 「driver: vagrant、verifier: testinfra、シナリオ名:vagrant」の場合 $ molecule init scenario -d vagrant --verifier-name testinfra --dependency-name galaxy vagrant
また、CIの場合など特定のシナリオだけ実行したい場合を考慮して、 ロール以下で、 make test
だけで実行出来るように、ロール直下に以下のようなMakefileを作成しています。
SHELL=/bin/bash # 複数シナリオの場合にはここに半角スペースでシナリオ名をつなげていく TEST_SCENARIO := default .PHONY: test test: for TEST in $(TEST_SCENARIO); do\ molecule test -s $$TEST --destroy always; \ done
こうすることで TEST_SCENARIO
に TEST_SCENARIO := default piyo
のようにして、defaultとpiyoシナリオだけ実行する事が make test
だけで簡単に出来るようになります(CIではvagrantのシナリオは実行したくないとか)。
さいごに
今回紹介した以外にも、 Ansible Galaxyを使った開発方法もあります。
cf. Galaxy Developer Guide — Ansible Documentation
ただ、 v2.9 から正式に使えるようになったroleやmodule、pluginも含めた Collections と、これまであったroleのみのものもあってroleは消えていくのか?それとも共存するのかよく分からないので詳しいひと教えて下さい(ぁ
あと、公開できない roleやcollections の場合、AWXと組み合わせて使うにはどうするのか?とか。。。
以上、 Ansible Advent Calendar 2020 - Adventar の6日目の記事でした。
参考
- User Guide — Ansible Documentation
- Frequently Asked Questions — Ansible Documentation
- Roles — Ansible Documentation
- Tests — Ansible Documentation
最終的なMakefle
リポジトリ直下のMakefile
SHELL=/bin/bash .PHONY: init-molecule init-molecule: python3 -m venv .venv && .venv/bin/pip install --upgrade pip && .venv/bin/pip install -r requirements.txt .venv/bin/pip --version ; source .venv/bin/activate && \ .venv/bin/molecule --version && \ .venv/bin/ansible --version && \ deactivate
各ロール直下のMakefile
SHELL=/bin/bash # 複数シナリオの場合にはここに半角スペースでシナリオ名をつなげていく TEST_SCENARIO := default .PHONY: test test: for TEST in $(TEST_SCENARIO); do\ molecule test -s $$TEST --destroy always; \ done
作成したロールのディレクトリツリー
: ├── Makefile ├── roles │ └── new_role │ ├── Makefile │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── files │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── molecule │ │ ├── default │ │ │ ├── converge.yml │ │ │ ├── molecule.yml │ │ │ └── verify.yml │ │ └── piyo │ │ ├── converge.yml │ │ ├── molecule.yml │ │ └── verify.yml │ ├── tasks │ │ └── main.yml │ ├── templates │ ├── tests │ │ ├── inventory │ │ └── test.yml │ └── vars │ └── main.yml └── site.yml