Best Practicesを意訳してみた。
たぶん誤訳もある。Google翻訳の精度が向上したことをすごく感じた。
Content Organization
次の章では、playbookを構成するさまざまな方法の1つを示します。
要望に合う形で改変してください。
なにがどうあってもroleは必ず利用してください!
Directory Layout
production # inventory file for production servers staging # inventory file for staging environment group_vars/ group1 # here we assign variables to particular groups group2 # "" host_vars/ hostname1 # if systems need specific variables, put them here hostname2 # "" library/ # if any custom modules, put them here (optional) filter_plugins/ # if any custom filter plugins, put them here (optional) site.yml # master playbook webservers.yml # playbook for webserver tier dbservers.yml # playbook for dbserver tier roles/ common/ # this hierarchy represents a "role" tasks/ # main.yml # <-- tasks file can include smaller files if warranted handlers/ # main.yml # <-- handlers file templates/ # <-- files for use with the template resource ntp.conf.j2 # <------- templates end in .j2 files/ # bar.txt # <-- files for use with the copy resource foo.sh # <-- script files for use with the script resource vars/ # main.yml # <-- variables associated with this role defaults/ # main.yml # <-- default lower priority variables for this role meta/ # main.yml # <-- role dependencies library/ # roles can also include custom modules lookup_plugins/ # or other types of plugins, like lookup in this case webtier/ # same kind of structure as "common" was above, done for the webtier role monitoring/ # "" fooapp/ # ""
Alternative Directory Layout
inventories/ production/ hosts # inventory file for production servers group_vars/ group1 # here we assign variables to particular groups group2 # "" host_vars/ hostname1 # if systems need specific variables, put them here hostname2 # "" staging/ hosts # inventory file for staging environment group_vars/ group1 # here we assign variables to particular groups group2 # "" host_vars/ stagehost1 # if systems need specific variables, put them here stagehost2 # "" library/ filter_plugins/ site.yml webservers.yml dbservers.yml roles/ common/ webtier/ monitoring/ fooapp/
別の方法としてinventoryファイルとgroup_vars/host_varsを分割することが可能。
group_vars/host_vars がproductionとstagingで共通である必要が無い時はこちらの構成のほうが便利。
メリットは、より広い環境での柔軟性と異なる環境間での変数の完全な分離が可能であること。
デメリットは、ファイルが増えているため保守が難しいこと。
Use Dynamic Inventory With Clouds
クラウドを利用しているのであれば、Dynamic Inventoryを利用したほうがよい。
クラウドだけでなくシステムからサーバリストを出力できるような場合も、
Dynamic Inventoryを利用することができる。
(参考:Ansible dynamic inventory + Zabbix APIで監視対象を動的に構成管理)
How to Differentiate Staging vs Production
inventoryファイル分類方法をよく聞かれる。以下はそのよい例である。
グループ化方法を動的インベントリに適用することもできます。
以下の例ではすべての本番ホストがひとつのinventoryファイルに含まれています。
ホストの目的、データセンターの場所などに基づいてのグループ定義をオススメします。
# file: production [atlanta-webservers] www-atl-1.example.com www-atl-2.example.com [boston-webservers] www-bos-1.example.com www-bos-2.example.com [atlanta-dbservers] db-atl-1.example.com db-atl-2.example.com [boston-dbservers] db-bos-1.example.com # webservers in all geos [webservers:children] atlanta-webservers boston-webservers # dbservers in all geos [dbservers:children] atlanta-dbservers boston-dbservers # everything in the atlanta geo [atlanta:children] atlanta-webservers atlanta-dbservers # everything in the boston geo [boston:children] boston-webservers boston-dbservers
Group And Host Variables
グループ化することですべてうまくいくわけではありません。変数を割り当てることも可能です。
例えばアトランタには独自のNTPサーバがある場合、
--- # file: group_vars/atlanta ntp: ntp-atlanta.example.com backup: backup-atlanta.example.com
WEBサーバ専用の変数は
--- # file: group_vars/webservers apacheMaxRequestsPerChild: 3000 apacheMaxClients: 900
もしデフォルト値が存在する場合は
--- # file: group_vars/all ntp: ntp-boston.example.com backup: backup-boston.example.com
特定のハードウェアのみに適用する場合は(必要がなければ避けたほうがよいが)
--- # file: host_vars/db-bos-1.example.com foo_agent_port: 86 bar_agent_port: 99
Dynamic Inventoryを利用する場合は、自動的にグループが作成されるため要注意。
Top Level Playbooks Are Separated By Role
site.yml:インフラストラクチャ全体を定義するplaybookが含まれている。そのためとても短い。
--- # file: site.yml - include: webservers.yml - include: dbservers.yml
webservers.ymlなどはグループとroleを指定するだけにすること。
--- # file: webservers.yml - hosts: webservers roles: - common - webtier
webserversでの実行は2つの方法がある
ansible-playbook site.yml --limit webservers ansible-playbook webservers.yml
Task And Handler Organization For A Role
以下はNTPサーバを設定するtaskファイルです。
--- # file: roles/common/tasks/main.yml - name: be sure ntp is installed yum: name=ntp state=installed tags: ntp - name: be sure ntp is configured template: src=ntp.conf.j2 dest=/etc/ntp.conf notify: - restart ntpd tags: ntp - name: be sure ntpd is running and enabled service: name=ntpd state=started enabled=yes tags: ntp
以下がhandlerファイルとなります。タスクに変更があった場合最後に実行されます。
--- # file: roles/common/handlers/main.yml - name: restart ntpd service: name=ntpd state=restarted
What This Organization Enables (Examples)
実行例について。
すべての構成を反映させる場合
ansible-playbook -i production site.yml
NTPのみを再構成する場合
ansible-playbook -i production site.yml --tags ntp
webserversを再構成する場合
ansible-playbook -i production webservers.yml
ボストンのwebserversを再構成する場合
ansible-playbook -i production webservers.yml --limit boston
10ホストずつ再構成する場合
ansible-playbook -i production webservers.yml --limit boston[1-10] ansible-playbook -i production webservers.yml --limit boston[11-20]
基本的な使い方も可能
ansible boston -i production -m ping ansible boston -i production -m command -a '/sbin/reboot'
有用なコマンドも覚えておくべき
# confirm what task names would be run if I ran this command and said "just ntp tasks" ansible-playbook -i production webservers.yml --tags ntp --list-tasks # confirm what hostnames might be communicated with if I said "limit to boston" ansible-playbook -i production webservers.yml --limit boston --list-hosts
Deployment vs Configuration Organization
上記の設計モデルは典型的なもの。複数層でのデプロイが必要な場合はplaybookが追加され、
site.yml は deploy_exampledotcom.yml といったplaybookが追加されるかもしれないが、上記設計モデルと構成は変わらない。
1つのplaysにこだわらず、状況や目的に合わせてplaysを作成したほうがよい。
同じツールを利用してデプロイできるため、グループを再利用し、アプリケーション設定とは別のplaybookにOS設定を保存すればよい。
Staging vs Production
すでに記載しているがステージング環境と本番環境を別々にするためには inventory ファイルを別々にしたほうがよい。
1つのinventoryファイルにしてしまうと、予期せぬ動作をする可能性がある。
本番環境の前にステージング環境で試すことは非常に良いこと。サイズが違う場合は、グループ変数で制御すること。
Rolling Updates
‘serial’ キーワードを理解すること。これを利用して、制御すること。
Delegation, Rolling Updates, and Local Actions
Always Mention The State
stateパラメーターは多くのモジュールで利用されている。
‘state=present’や‘state=absent’についてplaybookに明示的に記載しておいたほうがよい。
Group By Roles
システムには複数のグループがある。
playbookは役割ごとに作成することが大切。
Operating System and Distribution Variance
異なるOS間でことなるパラメーターを利用する場合、group_by モジュールの利用がオススメ。
inventoryで定義しなくても、特定の条件に一致する動的なグループが作成される。
--- # talk to all hosts just so we can learn about them - hosts: all tasks: - group_by: key=os_{{ ansible_distribution }} # now just on the CentOS hosts... - hosts: os_CentOS gather_facts: False tasks: - # tasks that only happen on CentOS go here
これによりすべてのホストがOSに基づいた動的グループに分類される。
グループ特有の設定が必要な場合は、以下のように設定します。
--- # file: group_vars/all asdf: 10 --- # file: group_vars/os_CentOS asdf: 42
上の例では、CentOSマシンはasdfに42の値を取得しますが、他のマシンは10になる。
これは変数の設定だけでなく、特定のシステムに特定の役割を適用するためにも使用できる。
変数だけが必要な場合は、OS名に基づいて変数が取り込むことも可能。
- hosts: all tasks: - include_vars: "os_{{ ansible_distribution }}.yml" - debug: var=asdf
Bundling Ansible Modules With Playbooks
libraryディレクトリがある場合、自動的にansibleのモジュールパスとして認識される。
playbookで実行されるモジュールを保持するためのよい方法。
Whitespace and Comments
空白を利用してわかりやすくすること、#でのコメントを推奨。
Always Name Tasks
タスクの名前は記載しなくてもよいが、タスクの目的を記載することを推奨。
playbook実行時に表示される。
Keep It Simple
とくかくシンプルに。ansibleのすべての機能を1度に使い分けてはいけない。
必要ないもの(vars,vars_files,vars_prompt,–extra-vars )は利用しないこと。
Version Control
gitなどのバージョン管理システムを利用し、変更した理由がわかるようにしておくこと。
Variables and Vaults
一般的な管理方法として、変数を見つけるためにgrepなどのツールが利用されます。
暗号化などで覆い隠されているときは、間接的に作業する必要があります。
playbook実行時に暗号化されていないファイルから変数を取得し
機密変数は暗号化されたファイルから取得します。
ベストプラクティスとして、group_vars/ のサブディレクトリを利用する。
vars と vault という2つのファイル名やプレフィックスを利用する。