J'ai rencontré ce problème dans une configuration où j'avais besoin de créer plusieurs environnements de déploiement (en direct, démo, bac à sable) sur le même serveur physique (pas de machines virtuelles autorisées ici), puis un script pour déployer des dépôts svn arbitraires
Cela nécessitait une arborescence de répertoires de fichiers variable.yml (facultatifs), qui fusionneraient les uns sur les autres et ne lèveraient pas d'exception le cas échéant
Commencez par activer la fusion de variables dans ansible - notez que cela fait une fusion de hachage peu profonde (1 niveau de profondeur) et une fusion profonde non récursive
ansible.cfg
[defaults]
hash_behaviour=merge ;; merge rather than replace dictionaries http://docs.ansible.com/ansible/intro_configuration.html###hash-behaviour
Disposition de répertoire possible
/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
rôles / déployer / tâches / inclut.yml
Il s'agit de la logique principale d'une arborescence de répertoires de fichiers variables facultatifs.
;; 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"
group_vars / all.yml
Configurer 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
rôles / deploy / vars / main.yml
valeurs par défaut du projet
ansible_project:
node_env: development
node_port: 4200
nginx_port: 4400
rôles / deploy / vars / project_1.yml
valeurs par défaut pour project_1
ansible_project:
node_port: 4201
nginx_port: 4401
rôles / deploy / vars / live / main.yml
par défaut pour l'environnement en direct, remplace les valeurs par défaut du projet
ansible_project:
node_env: production
rôles / deploy / vars / live / project_1.yml
substitutions finales pour project_1 dans l'environnement en direct
ansible_project:
nginx_port: 80
playbooks / demo.yml
Configurer des 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 Ansible tentera de manière irrégulière d'exécuter tous les scripts en tant que premier utilisateur de connexion ssh et n'utilisera que les variables pour le premier utilisateur. Si vous devez exécuter tous les scripts séquentiellement, utilisez xargs pour les exécuter chacun en tant que commandes distinctes.
find ./playbooks/*.yml | xargs -L1 time ansible-playbook