Ceci est une ancienne révision du document !
Table des matières
Notes Ansible
Voir :
- http://www.ageekslab.com/ansible/ansible3/ (boucles imbriquées)
Voir mode pull :
Voir aussi :
Exemples cool :
A lire
Install et config
Install avec PIP
- https://raw.githubusercontent.com/mrlesmithjr/ansible-samba/master/provision.sh
#!/bin/bash sudo apt-get update sudo apt-get install -y git python-pip python-dev sudo pip install jinja2 sudo pip install ansible sudo ansible-galaxy install -r /vagrant/requirements.yml -f ansible-playbook -i "localhost," -c local /vagrant/playbook.yml
Inventaire
Voir :
“inline content” inventory
ansible -m ping all -i 'node1,node2,'
lister toutes les nœuds
ansible-inventory --list -y
config
cp /etc/ansible/ansible.cfg ~/.ansible.cfg mkdir ~/.ansible cp /etc/ansible/hosts ~/.ansible/hosts.ini sed -i -e 's%/etc/ansible/hosts%$HOME/.ansible/hosts.ini%' ~/.ansible.cfg sed -i -e 's%#\(.*$HOME/\.ansible/hosts.ini\)%\1%' ~/.ansible.cfg sed -i -e 's/^remote_port/#remote_port/' ~/.ansible.cfg echo "localhost ansible_connection=local" >> ~/.ansible/hosts.ini
Ou
- /etc/ansible/ansible.cfg
[defaults] host_key_checking = False timeout = 60 vault_password_file = /var/lib/plop/ansible/vault/vault_pass.txt ansible_managed = Ansible managed file, do not edit directly filter_plugins = /var/lib/plop/ansible/filter_plugins/ lookup_plugins = /var/lib/plop/ansible/lookup_plugins/ library = /var/lib/plop/ansible/library/ remote_tmp = /tmp/.ansible local_tmp = /tmp/.ansible #allow_world_readable_tmpfiles = true [ssh_connection] pipelining = True ssh_args = -o ControlMaster=auto -o ControlPersist=30m -o UserKnownHostsFile=/dev/null
export ANSIBLE_CONFIG=$HOME/.ansible.cfg ansible -i ~/.ansible/hosts.ini test -m ping
La connexion via SSH doit être configurée via ~/.ssh/config et via ssh-agent. Si besion :
ssh-agent -k eval $(ssh-agent -s) ssh-add
Usage
Sudo / become
ansible-playbook -u user -kKb playbook.yml
Sur les serveurs distants
apt-get install python-minimal libpython-stdlib sudo
Traitements parallèles
Connexions
[arista] eos ansible_host=192.168.2.10 ansible_connection=network_cli ansible_network_os=eos [juniper] junos ansible_host=192.168.2.20 ansible_connection=netconf ansible_network_os=junos
Autres
Lancer une commande
ansible all -a "free -m"
Lancer une commande bash (utilisation Pipe vars etc…)
ansible all -m shell -a "ifconfig |grep inet"
Connaître toutes les variables et les valeurs associées (Nom machine, mémoire, Version noyaux …)
ansible all -m setup
Lancer une commande simultanément sur plusieurs serveurs par lots de 2 machines -s pour sudo
ansible webservers -m service -a "name=nginx state=restarted" --forks=2 -s
Mode “noop” / “dry-run”
--check \ ou --check--diff --limit foo.example.com
always_run: True sinon --check n’exécute pas les instructions du module shell,
lineinfile
A la place de lineinfile il existe aussi replace
Dépendance de rôles
Quand un rôle dépend d'un autre.
Ici foo dépend de bar
- roles/foo/meta/main.yml
--- allow_duplicates: no dependencies: - { role: bar }
Exemple
Exemple
- Découpage “role” un plusieurs morceaux (split role)
- “when when”
- Include dans un role
- Action si fichier n'existe pas
- Si
/etc/systemd/system/multi-user.target.wants/rpcbind.servicen'existe pas faire :systemctl add-wants multi-user.target rpcbind.service
- /roles/nis_client/tasks/main.yml
--- - include: "{{ ansible_os_family|lower }}.yml"
- /roles/nis_client/tasks/debian.yml
--- - name: Ubuntu lancer rpcbind avant NIS stat: path='/etc/systemd/system/multi-user.target.wants/rpcbind.service' register: systemdwants - name: DEBUG debug: msg="systemdwants = {{ systemdwants }}" - name: Ubuntu lancer rpcbind avant NIS 2 command: systemctl add-wants multi-user.target rpcbind.service when: systemdwants.stat.exists == False notify: - restart nis
Vérifier si un paquet deb est déjà installé
Source : http://chaosmail.github.io/programming/2015/03/04/install-deb-packages-in-ansible/
--- - name: Check if my_package is installed command: dpkg-query -W my_package register: my_package_check_deb failed_when: my_package_check_deb.rc > 1 changed_when: my_package_check_deb.rc == 1 check_mode: false - name: copie du paquet my_package copy: src=my_package_linux.ubuntu14.04_x86-64.deb dest=/root/my_package_linux.ubuntu14.04_x86-64.deb changed_when: my_package_check_deb.rc == 1 - name: installation des dépendances apt: name=libacl1 state=present changed_when: my_package_check_deb.rc == 1 - name: install du paquet apt: deb=/root/my_package_linux.ubuntu14.04_x86-64.deb changed_when: my_package_check_deb.rc == 1
Exemple de find shell
- name: /var/log/* readable by user process - find shell: 'find /var/log/ -not \( -perm /o=r -o -user process \) -a -not \( -wholename "/var/log/btmp*" \)' changed_when: False always_run: True register: list_files_var_log_notreadable - name: /var/log/* readable by user process - set file: mode="o+rX" dest={{ item }} #file: mode="0755" dest={{ item }} with_items: - "{{ list_files_var_log_notreadable.stdout.split('\n') }}" when: list_files_var_log_notreadable.stdout != ""
Exemples include role conditionnel
Exemple 1
- hosts: webservers roles: - { role: debian_stock_config, when: ansible_os_family == 'Debian' }
Exemple 2
- name: Enable local cache DNS include_role: name: acme.dns.enable_local_cache_dns vars: EVAR_BACKUP_NAME: postinstall host_func_excluded: - FOO # trigramme_appli: "{{ inventory_hostname[5:8] }}" trigramme_appli: "{{ ansible_hostname[5:8] }}" when: not trigramme_appli | lower in host_func_excluded | lower
Notes Ansible
Lancer l'action même si Check Mode (Dry Run) ''--check''
always_run is deprecated. Use check_mode = no instead
#always_run: true check_mode: false
Parfois il est préférable de trouver une solution plus élégante. Par exemple :
- name: mkdir /san/label file: dest='/san/{{ item }}' state=directory with_items: #- '{{ list_label_ext4devs.stdout_lines }}' #- '{{ list_label_xfsdevs.stdout_lines }}' - '{{ list_label_ext4devs.stdout_lines |default() }}' - '{{ list_label_xfsdevs.stdout_lines |default() }}'
Ici nous utilisons default() pour éviter une erreur à cause d'un champ vide
fatal: [plop1]: FAILED! => {"failed": true, "msg": "'dict object' has no attribute 'stdout_lines'"}
Ignorer si mode check (ne pas tester)
when: not ansible_check_mode
- name: activation service sysstat 1 lineinfile: dest=/etc/default/sysstat line='ENABLED="false"' state=absent when: not ansible_check_mode
Exemple module command ne lancer qu'une seule fois une commande.
- name: newer autolock screen - do conf command: dbus-launch gsettings set org.gnome.desktop.lockdown disable-lock-screen true become: '{{ autologin_user }}' args: creates: /root/.ansible-jalon-disable-lock-screen - name: newer autolock screen - jalon exist ? stat: path=/root/.ansible-jalon-disable-lock-screen register: p - name: newer autolock screen - jalon touch file: path=/root/.ansible-jalon-disable-lock-screen state=touch when: p.stat.exists == False
Gather_fact partiel
Grâce à gather_subset
- play.yml
- name: Test hosts: all gather_subset: os_family
Pb
becoming-an-unprivileged-user Err Failed to set permissions on the temporary...Not owner\nchown
Lors de l’exécution d’un playbook Ansible avec un sudo (become) faisant appel à un utilisateur non privilégié (ici « oracle »)
ansible -m ping -u user01 -i srv1, all --become-user=oracle -b
Nous avons l’erreur suivante :
srv1 | FAILED! => {
"msg": "Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user (rc: 1, err: chown: /var/tmp/ansible-tmp-1685976784.0795348-3077033-272077328342364/: Not owner\nchown: /var/tmp/ansible-tmp-1685976784.0795348-3077033-272077328342364/AnsiballZ_ping.py: Not owner\n}). For information on working around this, see https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user"
}
Apparemment cela concernerait que AIX.
Solution
La solution de contournement la plus simple à mettre en place est de définir à True la variable ansible_shell_allow_world_readable_temp
- play1.yml
#!/usr/bin/ansible-playbook # # ./play1.yml -u user01 -i srv1, --- - name: test sudo oracle hosts: all gather_facts: false become: true become_user: oracle vars: ansible_shell_allow_world_readable_temp: true tasks: - name: command id command: id changed_when: false register: cmd_id - name: echo id debug: var: cmd_id
Remote copy does not support recursive copy of directory
Le module copy ne supporte pas les copies de répertoire (mode récursif).
Le module synchronize est plus approprié. Dans notre exemple nous voulons copier srv1:/mnt/plop/ sur srv1:/tmp/
Note : peut-être que cela marche avec 'directory_mode'
- name: push omniplanar installer copy: src: /mnt/plop/ dest: /tmp remote_src: True #directory_mode: True
Solution
- name: push plop synchronize: src: /mnt/plop/plop.run dest: /usr/local/bin/ rsync_opts: - "--chmod=F755" - "--chown=root:staff" #delegate_to: "{{ inventory_hostname }}" use_ssh_args: true
Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user
Erreur
fatal: [aws-zbx1]: FAILED! => {"msg": "Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user (rc: 1, err: chown: changing ownership of '/var/tmp/ansible-tmp-1559124598.47-172527571991348/': Operation not permitted\nchown: changing ownership of '/var/tmp/ansible-tmp-1559124598.47-172527571991348/AnsiballZ_postgresql_db.py': Operation not permitted\n}). For information on working around this, see https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user"
Solution
- ~/.ansible.cfg
[defaults] allow_world_readable_tmpfiles = true
ou
vars: ansible_shell_allow_world_readable_temp: true
Voir https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user
sudo: no tty present and no askpass program specified
Solution de contournement (workaround) Source: https://github.com/ansible/ansible/issues/15297
lineinfile: path: /etc/sudoers state: present insertafter: EOF line: '{{ ansible_user }} ALL=NOPASSWD:/usr/bin/rsync'
Solution 2 Source : https://github.com/ansible/ansible/issues/20769
Applique la perte de l'élévation de privilèges
Ajouter rsync_path: /usr/bin/rsync
tasks: - name: Synchronization of src on the control machine to dest on the remote hosts synchronize: src: /etc/hostname dest: /home/user rsync_path: /usr/bin/rsync
Pb No module named 'ansible'
$ ansible --version
Traceback (most recent call last):
File "/usr/bin/ansible", line 34, in <module>
from ansible import context
ModuleNotFoundError: No module named 'ansible'
Solution
Test
env PYTHONPATH=/usr/lib/python3/dist-packages ansible --version
Solution si test OK
- ~/.bashrc
# Fix bug Ansible : No module named 'ansible' export PYTHONPATH=$PYTHONPATH:/usr/lib/python3/dist-packages
Err template error while templating string: Could not load \"search\": 'search'.
TASK [dns_update_resolv_conf : Remove immutable attribute] **************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "The conditional check 'stat_resolv_conf.stat.attr_flags | search(\"i\")' failed. The error was: template error while templating string: Could not load \"search\": 'search'. String: {% if stat_resolv_conf.stat.attr_flags | search(\"i\") %} True {% else %} False {% endif %}. Could not load \"search\": 'search'\n\nThe error appears to be in '/home/jean/code/dns_update_resolv_conf/roles/dns_update_resolv_conf/tasks/main.yml': line 147, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Remove immutable attribute\n ^ here\n"}
Solution
Change
when: - result | failed
By
when: - result is failed
Example :
- name: Remove immutable attribute become: true ansible.builtin.file: path: "{{ resolv_filepath }}" attributes: "-i" # when: stat_resolv_conf.stat.attr_flags | search("i") when: stat_resolv_conf.stat.attr_flags is search("i")
Pb passer un boolean ou des listes en extravars à Ansible
Solution
Passer par du JSON
--extra-vars '{"abc": false}'
--extra-vars '{"abc": ["elm",] }'
Test
Voir :
- ansible-test
- Molecule
- bats
ansible-test sanity --list-tests ansible-test sanity --docker
Molecule
Debug
env ANSIBLE_NOCOLOR=1 ansible-playbook -vvvvv
Voir le module debug
env ANSIBLE_DEBUG=1 ansible-playbook
Ansible-lint
Voir :
.ansible-lint
- yaml
--- profile: null exclude_paths: - test/playbook.yml
--- # Offline mode disables installation of requirements.yml and schema refreshing offline: true profile: production exclude_paths: - .git/ - .github/ - .gitlab/ - .cache/ warn_list: - var_naming - idiom skip_list: - var-naming[no-role-prefix]
- .ansible-lint-ignore
roles/agent/defaults/main.yml var-naming[no-role-prefix]
Syntax
Voir :
ansible-playbook --syntax-check- Ansible-lint
Callback plugin
Autres
ansible_python_interpreter=/home/user/network-automation/venv/bin/python
