C'est la partie:
vars_files:
- vars/vars.default.yml
- vars/vars.yml
Si un fichier vars/vars.yml
n'existe pas - voici une erreur.
ERROR: file could not read: /.../vars/vars.yml
Comment puis-je charger des variables supplémentaires à partir de ce fichier que s'il existe? (sans erreurs)
C'est vraiment simple vraiment. Vous pouvez écraser vos différents éléments vars_files dans un seul tuple et une autre manière à parcourir automatiquement chacun d'entre eux jusqu'à ce qu'il trouve un fichier qui existe et chargez-le. Ex.:
vars_files:
- [ "vars/foo.yml", "vars/bar.yml", "vars/default.yml" ]
Selon - Développeurs ansibles , le correct moyen de résoudre ce problème est d'utiliser quelque chose comme:
vars_files_locs: ['../path/to/file1', '../path/to/file2', ...]
- include_vars: "{{ item }}"
with_first_found: vars_files_locs
En outre, dit-on :
Ce qui précède ne chargera que le premier fichier trouvé et est plus flexible que d'essayer de le faire via le
vars_files
Mot-clé de langue.
J'ai rencontré ce problème dans une configuration où je devais créer plusieurs environnements de déploiement (Live, Demo, Sandbox) sur le même serveur physique (pas autorisé les machines virtuelles ici), puis un script pour déployer des repos svn arbitraires
Cela nécessitait une arborescence de répertoires de fichiers variables (facultatif), qui fusionneraient à l'autre et ne jettent pas une exception si elle manque
Commencez par la mise en place de la fusion variable dans une ondulation - Notez que cela fait la fusion de hachage peu profonde (1 niveau de profondeur) et non une fusion profonde entièrement récursive
[defaults]
hash_behaviour=merge ;; merge rather than replace dictionaries http://docs.ansible.com/ansible/intro_configuration.html###hash-behaviour
/group_vars
└── all.yml
/playbooks
├── boostrap.yml
├── demo.yml
├── live.yml
└── sandbox.yml
/roles/deploy/
├── files
├── tasks
│ ├── includes.yml
│ ├── main.yml
└── vars
├── main.yml
├── project_1.yml
├── project_2.yml
├── demo
│ ├── project_1.yml
│ ├── project_2.yml
│ └── main.yml
├── live
│ ├── project_1.yml
│ ├── project_2.yml
│ └── main.yml
└── sandbox
├── project_1.yml
├── project_2.yml
└── main.yml
Ceci est la principale logique pour un arborescence de répertoires de fichiers variables optionnels.
;; imports in this order:
;; - /roles/deploy/vars/main.yml
;; - /roles/deploy/vars/{{ project_name }}.yml
;; - /roles/deploy/vars/{{ project_name }}/main.yml
;; - /roles/deploy/vars/{{ project_name }}/{{ project_env }}.yml
- include_vars:
dir: 'vars'
files_matching: "{{ item }}"
depth: 1
with_items:
- "main.yml"
- "{{ project_name }}.yml"
- include_vars:
dir: 'vars/{{ env_name }}'
files_matching: "{{ item }}"
depth: 1
with_items:
- "main.yml"
- "{{ project_name }}.yml"
Configurez les variables par défaut pour le projet et divers utilisateurs et environnements
project_users:
bootstrap:
env: bootstrap
user: ansible
group: ansible
mode: 755
root: /cs/ansible/
home: /cs/ansible/home/ansible/
directories:
- /cs/ansible/
- /cs/ansible/home/
live:
env: live
user: ansible-live
group: ansible
mode: 755
root: /cs/ansible/live/
home: /cs/ansible/home/ansible-live/
demo:
env: demo
user: ansible-demo
group: ansible
mode: 755
root: /cs/ansible/demo/
home: /cs/ansible/home/ansible-demo/
sandbox:
env: sandbox
user: ansible-sandbox
group: ansible
mode: 755
root: /cs/ansible/sandbox/
home: /cs/ansible/home/ansible-sandbox/
project_env: bootstrap
project_user: "{{ ansible_users[project_env] }}" ;; this will be retroactively updated if project_env is redefined later
par défaut du projet
ansible_project:
node_env: development
node_port: 4200
nginx_port: 4400
par défaut pour Project_1
ansible_project:
node_port: 4201
nginx_port: 4401
les valeurs par défaut pour l'environnement en direct, remplacent les valeurs par défaut du projet
ansible_project:
node_env: production
nursons finaux pour le projet_1 dans l'environnement en direct
ansible_project:
nginx_port: 80
Configurez les playbooks séparés pour chaque environnement
- hosts: shared_server
remote_user: ansible-demo
vars:
project_env: demo
pre_tasks:
- debug: "msg='{{ facter_gid }}@{{ facter_fqdn }} ({{ server_pseudonym }})'"
- debug: var=project_ssh_user
roles:
- { role: deploy, project_name: project_1 }
AVERTISSEMENT: Étant donné que tous les environnements vivent sur un seul hôte, tous les playbooks doivent être exécutés individuellement, sinon une tentative ansite tentent d'exécuter tous les scripts en tant que premier utilisateur de connexion SSH et n'utilisez que les variables pour le premier utilisateur. Si vous devez exécuter tous les scripts séquentiellement, utilisez Xargs pour les exécuter chacun comme des commandes distinctes.
find ./playbooks/*.yml | xargs -L1 time ansible-playbook
- hosts: all
vars_files: vars/vars.default.yml
vars:
optional_vars_file: "{{ lookup('first_found', 'vars/vars.yml', errors='ignore') }}"
tasks:
- when: optional_vars_file is file
include_vars: "{{ optional_vars_file }}"
Remarque: Les tests de cheminement (fichier sont-ils existent, ...) ne fonctionnent qu'avec des chemins ou des chemins absolus par rapport au répertoire de travail actuel lors de l'exécution de la commande Ansible-Playbook. C'est la raison pour laquelle nous avons utilisé la recherche. La recherche accepte les chemins par rapport au répertoire de lecture et renvoie la voie absolue lorsque le fichier existe.
Assembler diverses pièces ensemble ... Inclure_vars avec une clause WHERE qui est vrai lorsque le fichier existe. c'est à dire.
vars:
file_to_include: /path/to/file
tasks:
- include_vars: "{{ file_to_include }}"
when: file_to_include is exists
Nouvelle réponse basée sur les dernières versions ansibles - essentiellement, vous devez utiliser with_first_found
, de même que skip: true
Pour ignorer la tâche si aucun fichier n'est trouvé.
- name: Include vars file if one exists meeting our condition.
include_vars: "{{ item }}"
with_first_found:
- files:
- vars/{{ variable_here }}.yml
skip: true
Cela le rend afin que vous n'ayez pas besoin d'avoir un fichier varys de Fallback dans cette liste.
Voir Connexes: https://stackoverflow.com/a/395444405/100134