Ansible 2.4
ベストプラクティス
AnsibleとAnsibleのプレイブックを最大限に活用するためのヒントを紹介します。
これらのベストプラクティスを例示したいくつかのプレーブックは、私たちの非実例リポジトリで見つけることができます 。 (注:これらの機能は、最新のリリースの機能のすべてを使用するわけではありませんが、優れた参考資料です)。
- コンテンツ構成
- ステージング対プロダクション
- ローリングアップデート
- 常に国を言及する
- 役割別グループ
- オペレーティングシステムと配布差異
- PlayBookで不可能なモジュールをバンドルする
- 空白とコメント
- 常にタスクに名前を付ける
- 単純にする
- バージョン管理
- 変数と格納域
コンテンツ構成
次のセクションでは、プレイブックコンテンツを構成するさまざまな方法の1つを示します。
あなたのAnabilitiesの使用法は私たちのものではなくあなたのニーズに合っていなければなりませんので、このアプローチを変更して適切に整理してください。
プレイブックのコンテンツを編成する重要な方法の1つは、メインプレイブックのページの一部として文書化されているAnipalの「役割」の組織機能です。 ここで利用できるロールのドキュメント(ロール)を読み、理解する時間が必要です。
ディレクトリレイアウト
ディレクトリの最上位には次のようなファイルとディレクトリが含まれます:
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)
module_utils/ # if any custom module_utils to support 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
module_utils/ # roles can also include custom module_utils
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/ # ""
代替ディレクトリレイアウト
あるいは、各インベントリファイルをgroup_vars
/ host_vars
とともに別のディレクトリに置くこともできます。 これは、あなたのgroup_vars
/ host_vars
が異なる環境で共通していない場合に特に便利です。 レイアウトは次のようになります。
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/
module_utils/
filter_plugins/
site.yml
webservers.yml
dbservers.yml
roles/
common/
webtier/
monitoring/
fooapp/
このレイアウトにより、大規模な環境での柔軟性が向上し、異なる環境間での在庫変数の完全な分離が可能になります。 欠点は、より多くのファイルが存在するため、維持するのが難しいことです。
クラウドで動的インベントリを使用する
クラウドプロバイダを使用している場合は、静的ファイルでインベントリを管理しないでください。 Dynamic Inventoryを参照してください。
これは雲にのみ適用されるものではありません。インフラストラクチャ内にシステムの標準リストを維持している別のシステムがある場合、動的インベントリの使用は一般的には素晴らしいアイデアです。
ステージングとプロダクションを区別する方法
静的な在庫を管理する場合は、さまざまなタイプの環境を区別する方法がよく尋ねられます。 次の例は、これを行う良い方法を示しています。 同様のグループ化方法を動的インベントリに適用することもできます(たとえば、AWSタグ "environment:production"の適用を検討すると、ec2_tag_environment_productionという名前のシステムが自動的に検出されます)。
しかし、静的な在庫の例を示してみましょう。 以下では、 本番ファイルには、すべての本番ホストのインベントリが含まれています。
ホストの目的(役割)と地理またはデータセンターの場所(該当する場合)に基づいてグループを定義することをお勧めします。
# 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
グループおよびホスト変数
このセクションは前の例にも及んでいます。
グループは組織にはいいですが、それはすべてのグループがうまくいくわけではありません。 変数を割り当てることもできます! たとえば、atlantaには独自のNTPサーバーがあるので、ntp.confを設定するときは、それらを使用する必要があります。 今それらを設定しましょう:
---
# file: group_vars/atlanta
ntp: ntp-atlanta.example.com
backup: backup-atlanta.example.com
変数は地理情報だけではありません! たぶんWebサーバーには、データベースサーバーにとって意味のないいくつかの構成があります。
---
# file: group_vars/webservers
apacheMaxRequestsPerChild: 3000
apacheMaxClients: 900
デフォルト値がある場合、または普遍的に真である場合は、それらをgroup_vars / allというファイルに入れます。
---
# file: group_vars/all
ntp: ntp-boston.example.com
backup: backup-boston.example.com
host_varsファイル内のシステムで特定のハードウェア分散を定義することはできますが、
---
# file: host_vars/db-bos-1.example.com
foo_agent_port: 86
bar_agent_port: 99
繰り返しますが、動的インベントリソースを使用している場合、多くのダイナミックグループが自動的に作成されます。 したがって、 "class:webserver"のようなタグは "group_vars / ec2_tag_class_webserver"ファイルから自動的に変数にロードされます。
トップレベルのプレイブックは役割別に分かれています
site.ymlでは、インフラストラクチャ全体を定義するプレイブックをインポートします。 これは、他のいくつかのプレイブックをインポートするだけなので、非常に短い例です:
---
# file: site.yml
- import_playbook: webservers.yml
- import_playbook: dbservers.yml
webservers.ymlのようなファイル(最上位レベル)では、webserversグループの設定を、webserversグループによって実行されるロールにマッピングします。
---
# file: webservers.yml
- hosts: webservers
roles:
- common
- webtier
ここでのアイデアは、site.ymlを「実行」することによってインフラストラクチャ全体を設定することができるということです。あるいはwebservers.ymlを実行してサブセットを実行することもできます。 これは "-limit"パラメータと似ていますが、少しはっきりしています:
ansible-playbook site.yml --limit webservers
ansible-playbook webservers.yml
タスクとハンドラの役割の組織
以下は、役割の仕組みを説明するタスクファイルの例です。 私たちの共通の役割はここではNTPを設定するだけですが、
---
# 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
次に、ハンドラファイルの例を示します。 レビューとして、特定のタスクが変更を報告し、各プレイの最後に実行される場合にのみ、ハンドラが起動されます。
---
# file: roles/common/handlers/main.yml
- name: restart ntpd
service: name=ntpd state=restarted
詳細については、 Rolesを参照してください。
この組織が可能にするもの(例)
私たちは基本的な組織体系を共有しました。
このレイアウトでは、どのような使用例が可能になりましたか? たくさん! インフラストラクチャ全体を再構成したい場合は、それだけです。
ansible-playbook -i production site.yml
すべてのNTPの再設定はどうですか? 簡単:
ansible-playbook -i production site.yml --tags ntp
私のウェブサーバの再構成はどうですか?
ansible-playbook -i production webservers.yml
ボストンの私のウェブサーバーはどうですか?
ansible-playbook -i production webservers.yml --limit boston
最初の10回、次に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'
知っておくべき有用なコマンドがいくつかあります(少なくとも1.1以上で):
# 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
展開と構成の構成
上記のセットアップは、典型的な構成トポロジをモデル化しています。 複数層展開を行う場合、アプリケーションを公開するために層の間を行き来するいくつかのプレイブックが追加されることになります。 この場合、 'site.yml'は 'deploy_exampledotcom.yml'のようなプレイブックで拡張されるかもしれませんが、一般的な概念はまだ適用されます。
スポーツのメタファーとして「プレイブック」を考えてみましょう。あなたのインフラストラクチャに常に使用する1組の演劇だけを持つ必要はありません。異なる時代や異なる目的で使用する状況演劇を持つことができます。
あなたは同じツールを使ってデプロイと設定ができるので、グループを再利用し、OSの設定をアプリのデプロイメントとは別のプレイブックに保存するだけです。
ステージング対プロダクション
上でも言及したように、ステージング(またはテスト)環境と本番環境を別々に保つ良い方法は、ステージングと制作に別々のインベントリファイルを使用することです。 このようにして、あなたが目標としているものを-iで選びます。 それらをすべて1つのファイルに保存すると、驚きにつながる可能性があります。
プロダクションを試す前にステージング環境でテストすることは、常に素晴らしいアイデアです。 環境のサイズが同じである必要はなく、グループ変数を使用してそれらの環境の違いを制御できます。
ローリングアップデート
「シリアル」キーワードを理解する。 Webサーバーファームを更新している場合は、一度に一度に更新するマシンの数を制御するために、実際に使用したいと考えています。
委任、ローリングアップデート、およびローカルアクションを参照してください。
常に国を言及する
'state'パラメータは多くのモジュールにとってオプションです。 'state = present'や 'state = absent'のいずれの場合でも、特に、いくつかのモジュールが追加の状態をサポートしているため、そのパラメータをプレイブックに残すことが常にベストです。
役割別グループ
私たちはこのヒントを少しずつ繰り返していますが、それは繰り返す価値があります。 システムは複数のグループに分けられます。 InventoryとPatterns参照してください。 Webサーバーやdbserversのような名前を付けられたグループは、非常に強力な概念であるため、例で繰り返されています。
これにより、プレイブックはロールに基づいてマシンをターゲットにすることができ、グループ変数システムを使用してロール固有の変数を割り当てることができます。
Roles参照してください。
オペレーティングシステムと配布差異
2つの異なるオペレーティングシステム間で異なるパラメータを扱う場合、これを処理する最も良い方法は、group_byモジュールを使用することです。
これは、そのグループがインベントリファイルで定義されていない場合でも、特定の条件に一致する動的なホストグループを作成します。
---
# 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
これにより、オペレーティングシステム名に基づいてすべてのシステムが動的グループにスローされます。
グループ固有の設定が必要な場合は、これも実行できます。 例えば:
---
# file: group_vars/all
asdf: 10
---
# file: group_vars/os_CentOS
asdf: 42
上記の例では、CentOSマシンはasdfに対して '42'の値を取得しますが、他のマシンは '10'になります。 これは変数の設定だけでなく、特定のシステムに特定の役割を適用するためにも使用できます。
代わりに、変数のみが必要な場合:
- hosts: all
tasks:
- include_vars: "os_{{ ansible_distribution }}.yml"
- debug: var=asdf
これにより、OS名に基づいて変数が取り込まれます。
PlayBookで不可能なモジュールをバンドルする
プレイブックのYAMLファイルを基準にした./library
ディレクトリがある場合、このディレクトリを使用して、自動的に危険なモジュールパスに入る可能性のあるモジュールを追加することができます。 これは、プレイブックを一緒に持っているモジュールを保つ素晴らしい方法です。 これは、このセクションの最初のディレクトリ構造例に示されています。
空白とコメント
物事を壊すために空白を多用し、コメントの使用( '#'で始まる)を奨励します。
常にタスクに名前を付ける
与えられたタスクの「名前」を省略することは可能ですが、代わりに何かが行われている理由についての説明を提供することが推奨されます。 この名前は、プレイブックの実行時に表示されます。
単純にする
あなたが何かを簡単にすることができるときは、単純に何かをしてください。 Ansibleのすべての機能を一度に使い分けることはできません。 あなたのために働くものを使用してください。 たとえば、 vars
、 vars_files
、 vars_prompt
、-- --extra-vars
を一度に必要とせず、外部インベントリファイルを使用することもできます。
何かが複雑であると感じるなら、おそらくそうであり、事を単純化する良い機会かもしれません。
バージョン管理
バージョンコントロールを使用します。 プレイブックとインベントリファイルをgit(または別のバージョン管理システム)に保存し、変更を加えたらコミットします。 このように、インフラストラクチャを自動化するルールをいつ、なぜ変更したのかを説明する監査証跡があります。
変数と格納域
一般的なメンテナンスでは、Grepや同様のツールを使用して、Ansibleセットアップで変数を見つける方が簡単です。 ボールトはこれらの変数を覆い隠しているため、間接的な階層で作業するのが最善です。 Playbookを実行するとき、Ansibleは暗号化されていないファイル内の変数を見つけ、すべての機密変数は暗号化されたファイルから取得します。
このためのベストプラクティスのアプローチは、グループの後に名前が付けられたgroup_vars/
サブディレクトリで開始することgroup_vars/
。 このサブディレクトリの中に、 vars
とvault
という名前の2つのファイルを作成します。 vars
ファイルの中で、必要なすべての変数を定義します。 次に、すべての機密変数をvault
ファイルにコピーし、これらの変数にvault_
接頭辞をvault_
ます。 vars
ファイル内の変数を、jinja2構文を使用して一致するvault_
変数を指すように調整し、 vault
ファイルがボールトで暗号化されていることを確認する必要があります。
このベストプラクティスでは、変数ファイルとボールトファイルまたはその名前の数に制限はありません。
も参照してください