J'utilise ansible pour gérer la configuration comme pour la production, ainsi que pour la boite vagabonde. J'ai un fichier avec des valeurs par défaut: 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"
Dans Host_vars/vagrantbox je veux avoir quelque chose comme:
db:
root_pwd: super_easy_password
Mais celui-ci remplace complètement dbtrionary db, alors que je veux remplacer une seule clé. Comment y parvenir?
MISE À JOUR 1 Juste vérifié avec ansible.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
J'obtiens l'erreur suivante:
One or more undefined variables: 'dict object' has no attribute 'name'
Ce que je fais mal?
Par défaut, Ansible remplace les variables au premier niveau. Si vous voulez pouvoir fusionner des dictionnaires, vous devez changer votre ansible.cfg
fichier et ensemble:
hash_behaviour=merge
(la valeur par défaut étant replace
).
Notez que l'équipe Ansible ne le recommande pas (mais n'explique pas pourquoi). Je suppose que c'est un véritable paramètre de division entre les utilisateurs. Une sorte de décision qui se fait une fois pour toutes: lorsque vous commencez à utiliser cette fonctionnalité, vous ne pouvez pas revenir en arrière et vous ne pouvez probablement pas partager votre playbook avec des personnes de type replace
-.
Cependant, vous pouvez toujours bénéficier des playbooks (je ne pense pas que les playbooks utilisent le comportement replace
comme "fonctionnalité"). C'est comme avoir un groupe sanguin AB, être un récepteur universel ... mais comme la magie se produit généralement à résolution variable, pas à l'intérieur de tâches ou de modèles, je pense qu'il est souvent possible de partager vos rôles sans aucun changement.
Si vous devez remplacer une seule clé de, disons, les paramètres de rôle, vous devrez passer les paramètres d'une manière compliquée.
Par exemple, pour remplacer post_max_size
et upload_max_size
touches dans un php5
dictionnaire pour un rôle spécifique, vous devrez le faire de cette façon:
- { role: php5-fpm, php5: { post_max_size: 40M,
upload_max_filesize: 20M }}
Cela étant dit, j'utilise le comportement merge
depuis le début, et j'en suis assez content. Il est très pratique de garder les variables organisées.
À partir d'Ansible 2.0, vous pouvez utiliser le filtre Jinja2 combine
pour fusionner les hachages/dictionnaires YAML sans avoir à définir hash_behavior=merge
au niveau mondial dans votre ansible.cfg
fichier.
Documents pertinents: http://docs.ansible.com/ansible/playbooks_filters.html#combining-hashes-dictionaries
La meilleure façon que j'ai trouvée est d'utiliser des variables comme valeur de l'élément de dictionnaire et de les remplacer. Je trouve que cela permet une priorité de variable simple et puissante en ce qui concerne l'ordre de variable de ansible
---
root_pw_value: ParentPassword
parent_dict:
- root_pw: "{{ root_pw_value }}"
Remarque: role/child/meta/main.yml
contient dependencies: - { role: parent }
---
root_pw_value: ChildPassword
---
- hosts: all
roles:
- child
- debug: var=parent_dict
Courir ansible -i localhost, --connection="local" play-me.yml
et vous obtenez la sortie suivante:
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
Et ce sont des valeurs par défaut. Si vous spécifiez root_pw_value
à des niveaux de priorité plus spécifiques, tels que les variables de groupe d'inventaire/hôte, les variables de rôle, les extra_vars sur la ligne de commande, ou quoi que ce soit de l'ordre de priorité [0], vous les obtiendrez.
Je viens d'essayer avec ansible 1.9.3 et cela fonctionne très bien. Pas sûr, mais il semble que vous ayez juste une faute de frappe dans le nom de group_vars
répertoire (pas groups_vars
).