私はansibleを使用して、プロダクションとバガントボックスの構成を管理しています。デフォルト値のファイルがあります:group_vars/all。
---
env: prod
wwwuser: www-data
db:
root_pwd: root_pwd
pdo_driver: pdo_mysql
Host: localhost
name: test
user: test
pwd: test
charset: utf8
domain: somedomain
projectdir: /var/www/application
webrootdir: "{{ projectdir }}/web"
Host_vars/vagrantboxのようにしたい:
db:
root_pwd: super_easy_password
しかし、これは完全にdb dictrionaryをオーバーライドしていますが、単一のキーをオーバーライドしたいのです。それを達成する方法は?
UPDATE 1ansible.cfgでチェックしたところ:
[defaults]
Host_key_checking=false
hash_behaviour=merge
groups_vars/all
db:
root_pwd: some_strong_pwd
pdo_driver: pdo_mysql
Host: localhost
name: dbname
user: dbuser
pwd: some password
charset: utf8
Host_vars/vagrantbox
db:
root_pwd: root
次のエラーが発生します。
One or more undefined variables: 'dict object' has no attribute 'name'
私は何を間違っていますか?
デフォルトでは、Ansibleは最初のレベルで変数をオーバーライドします。辞書をマージできるようにするには、ansible.cfg
ファイルを変更して次のように設定する必要があります。
hash_behaviour=merge
(デフォルト値はreplace
です)。
Ansibleチーム これはお勧めしません に注意してください(ただし、理由は説明しません)。これは、ユーザー間の実際の分割設定だと思います。一度に行われる一種の決定:この機能の使用を開始すると、戻ることはできず、おそらくreplace
タイプの人とプレイブックを共有することはできません。
しかし、あなたはまだそこにあるプレイブックから利益を得ることができます(私は、プレイブックがreplace
動作を「機能」として使用しているとは思いません)。それは、AB血液型を持っている、ユニバーサルレシーバーのようなものですが、魔法は通常、タスクやテンプレートの内部ではなく、変数の解決で発生するため、変更なしで役割を共有できることが多いと思います。
たとえば、ロールパラメータから単一のキーをオーバーライドする必要がある場合は、複雑な方法でパラメータを渡す必要があります。
たとえば、特定の役割のpost_max_size
辞書のupload_max_size
キーとphp5
キーをオーバーライドするには、次のようにする必要があります。
- { role: php5-fpm, php5: { post_max_size: 40M,
upload_max_filesize: 20M }}
そうは言っても、私は最初からmerge
動作を使用しており、私はそれに非常に満足しています。変数を整理しておくと非常に便利です。
Ansible 2.0以降では、Jinja2 combine
フィルターを使用して、hash_behavior=merge
をグローバルレベルでansible.cfg
ファイルに設定する必要なく、YAMLハッシュ/辞書をマージできます。
関連ドキュメント: http://docs.ansible.com/ansible/playbooks_filters.html#combining-hashes-dictionaries
私が見つけた最良の方法は、変数を辞書項目の値として使用し、それをオーバーライドすることです。これにより、Ansibleの変数の順序に関して、シンプルで強力な変数の優先順位が可能になります。
---
root_pw_value: ParentPassword
parent_dict:
- root_pw: "{{ root_pw_value }}"
注:role/child/meta/main.yml
にはdependencies: - { role: parent }
が含まれています
---
root_pw_value: ChildPassword
---
- hosts: all
roles:
- child
- debug: var=parent_dict
ansible -i localhost, --connection="local" play-me.yml
を実行すると、次の出力が得られます。
PLAY [all] ********************************************************************
GATHERING FACTS ***************************************************************
ok: [localhost]
TASK: [parent | debug var=parent_dict] ****************************************
ok: [localhost] => {
"var": {
"parent_dict": [
{
"root_pw": "ParentPassword"
}
]
}
}
TASK: [child | debug var=parent_dict] *****************************************
ok: [localhost] => {
"var": {
"parent_dict": [
{
"root_pw": "ChildPassword"
}
]
}
}
PLAY RECAP ********************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0
そして、これらはデフォルトです。インベントリグループ/ホスト変数、ロール変数、コマンドラインのextra_vars、または優先順位[0]からの優先順位など、より具体的な優先レベルでroot_pw_value
を指定すると、それらを取得できます。
Ansible 1.9.3で試したところ、問題なく動作しました。確かではありませんが、group_vars
ディレクトリの名前にタイプミスがあるようです(groups_vars
ではありません)。