Skip to content
Snippets Groups Projects

ansible

ansible

ansible

  • outil de

    • provisioning
    • gestion de config
    • déploiemenet d'application
  • racheté par RedHat en octobre 2015

  • outils équivalents

    • puppet, chief, salt ...

ansible Φ

  • idempotence
  • héritage
  • réutilisabilité
  • parallélisation
  • automatisation

toute intervention manuelle sur un système est une faute ...

... GRAVE!

ansible

  • écrit en python

    • python 2 par défaut
    • marche bien en python 3 <3
      • virtualenv
  • ansible

ansible

  • prérequis
    • sur la machine pilote (mgmt node)
      • ansible (donc python)
    • sur le(s) noeud(s)
      • une connextion ssh ou PowerShell
      • python

ansible

gestion ansible

terminologie

  • mgmt node (machine pilote)
    • machine sur laquelle ansible est installé
    • pilote la configuration de toutes les machines de l'inventaire
  • inventory (inventaire)
    • fichier contenant les ip ou les noms de domaine de toutes les machines à configurer
  • playbook
    • gère la configuration à déployer sur chaque machine

terminologie

  • task
    • fichier où sont définies les actions réalisées par le playbook
  • module
    • actions plus ou moins complexes, utilisables à partir des tasks
    • ansible possède de nombreux modules natifs
    • il est possible d'écrire ses propres modules.
  • role
    • permet d'organiser les playbooks en parties claires et réutilisables

terminologie

  • play
    • est l'exécution d'un playbook sur une machine
  • facts
    • information collectée par ansible sur le système d'une machine à configurer
  • handlers
    • similaire aux tasks mais appelable à partir d'une task
      • redémarrage de service par exemple

inventory

  • fichier texte au format ini
  • organiser par groupes
  • fixer des configurations
    • pour tous / par groupe / par machine
  • déclarer des variables
    • pour tous / par groupe / par machine

inventory

[criprod]
pvecriprod2.isima.fr
py.criprod.isima.fr
gitlab-runner1.criprod.isima.fr

[all:vars]
environment                = production
ansible_python_interpreter = /usr/bin/python3
ansible_user               = limosadm

tips ssh

  • utilisez ~/.ssh/config
Host pvecriprod2.isima.fr
  User limosadm
  IdentityFile ~/.ssh/keys/limosadm

Host py.criprod.isima.fr
  User limosadm
  IdentityFile ~/.ssh/keys/limosadm
  ProxyCommand ssh pvecriprod2.isima.fr -W %h:%p

ad-hoc command

$ ansible all --inventory-file=inventory.ini --module-name ping

pvecriprod2.isima.fr | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
py.criprod.isima.fr | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
gitlab-runner1.criprod.isima.fr | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

ad-hoc command

$ ansible criprod -a "/usr/bin/uptime"

pvecriprod2.isima.fr | CHANGED | rc=0 >>
 16:18:08 up 41 days, 23:11,  3 users,  load average: 0.63, 0.18, 0.10

py.criprod.isima.fr | CHANGED | rc=0 >>
 15:18:15 up 1 day, 21:51,  1 user,  load average: 0.13, 0.03, 0.01

gitlab-runner1.criprod.isima.fr | CHANGED | rc=0 >>
 15:18:15 up 1 day, 22:14,  1 user,  load average: 0.00, 0.00, 0.00

ad-hoc command

playbook

playbooks

my-playbook.yml

- name: my-playbook # ce que vous voulez
  hosts: criprod # ou all
                 # ou n'importe quel nom de machine
                 # ou n'importe quel nom de groupe
  remote_user: limosadm # prioritaire sur ansible_user de l'inventaire

  roles:

    - role: debug # le rôle debug sera exécuté par le playbook
      tags: debug # le tag debug sera ajouté à toutes les tâches du role debug
      my-variable: "pipo" # il ya d'autres endroit où mettre les variables
                          # à suivre ...
    - role: vault-cli # le rôle vault-cli sera exécuté par le playbook
      tags: vault # le tag vault sera ajouté à toutes les tâches du role vault-cli

playbook

$ ansible-playbook my-playbook.yml

exécute le playbook sur toutes les machines de l'inventaire

playbook

$ ansible-playbook my-playbook.yml --check --diff

--check

simule les tâches à effectuer sans les effectuer (dry-run)

--diff

indique ce qui change

playbook

$ ansible-playbook my-playbook.yml -vvv

-v, -vv, -vvv, -vvvv

pour la verbosité

playbook

$ ansible-playbook my-playbook.yml --list-tags

liste tous les tags disponibles dans le playbook

$ ansible-playbook my-playbook.yml --tags debug

n'exécute que les tâches du playbook ayant un tag debug

$ ansible-playbook my-playbook.yml --skip-tags debug

exécute toutes les tâches du playbook sauf celles ayant un tag debug

playbook

$ ansible-playbook my-playbook.yml --limit=py.isima.fr

exécute toutes les tâches du playbook sur py.isima.fr uniquement

variables

  • nommage
    • pas de - pas de .
    • pas de numérique pure

variables

précédence des variables

jinja

templating

group_vars/all.yml

my-role: my-awesome-role

playbook.yml

roles:

  - role: "{{ my-role }}"

utilisable partout (playbook, role, tasks, template)

filters

filters

"{{ item.path[:4] | replace('/', '-') }}"
  • renvoie un path
    • sans les 4 derniers caractères
    • avec les / remplacés par des -

lookup

lookup

vars:
  file_contents: "{{lookup('file', 'path/to/file.txt')}}"

lookup list

callback

variable & secret

- debug:
  msg: "{{ lookup('env','PVE_NODE') }}"

lit une valeur à partir d'une variable d'environement

- debug:
  msg: "{{ lookup('hashi_vault', 'secret=secret/hi:value token=xxx url=http://myvault')}}"

lit une valeur à partir Vault (ansible-vault)

vars_prompt:
  - name: "name"
    prompt: "what is your name?"

les var_prompts permettent de lire les variables à partir de l'entrée standard.

task

debug

- debug:
    msg: "System {{ inventory_hostname }} has uuid {{ ansible_product_uuid }}"
  • raw
    • n'utilise que ssh et pas python
      • permet d'installer python
  • command
  • shell
    • comme command mais au travers d'un shell

task

- shell: somescript.sh >> somelog.txt
  args:
    chdir: somedir/
    creates: somelog.txt

register

shell: /usr/bin/foo
register: foo_result
ignore_errors: True

register dans une liste

task

loop

- user:
    name: "{{ item }}"
    state: present
  loop:
     - testuser1
     - testuser2
  • marche avec
    • n'importe quelle variable itérable
    • fileglob - list files matching a pattern
    • filetree - recursively match all files in a directory tree
    • ...

task

when

conditions

- shell: echo "only on Red Hat 6, derivatives, and later"
  when: ansible_facts['os_family'] == "RedHat" and ansible_facts['lsb']['major_release']|int >= 6

set_fact & pre_task

criprod:
  pvecriprod1:
    api_users:
      - proxmoxapi
      - vimazeno
- name: provisionner l'environnement du noeud (pour y accéder plus facilement dans les roles)
  set_fact:
    _pve: "{ 'cluster': '{{ lookup('env','PVE_CLUSTER') }}', 'node': '{{ lookup('env','PVE_NODE') }}', 'host': '{{ lookup('env','PVE_HOST') }}'}"

- name: provisionner les utilisateurs d'api pve uniquement du noeud (pour y accéder plus facilement dans les roles)
  set_fact:
    api_users: "{ 'api_users': {{ hostvars[inventory_hostname][_pve.cluster][_pve.node]['api_users'] }}}"

- name: fusionner l'environnement du noeud (pour y accéder plus facilement dans les roles)
  set_fact:
    pve: "{{ _pve | combine(api_users) }}"

exemple permettant de réorganiser les variables

tags

tags au niveau tâches

- name: s'assurer que le fichier user.cfg existe
  file:
    dest: /etc/pve/user.cfg
    state: touch
  tags: [pve-users]

tags au niveau roles à l'inclusion dans le playbook

roles:

  - role: debug
    tags: debug

always tag spécial exécuté à tous les coups

modules

modules

roles

debops

skeleton

ansible-galaxy init --role-skeleton /path/to/stack/ansible/roles/skeletons/role-with-vagrant gitlab

ansible/roles/skeletons/role-with-vagrant

remote roles

requirements.yml

- name: vault-server
  src: git+ssh://git@gitlab.isima.fr/cri/ansible-playbook-vault.git
  path: ./ansible/roles/remotes
$ ansible-galaxy install -f -r requirements.yml

ansible.cfg

[defaults]
roles_path = ./ansible/roles/remotes:./ansible/roles/apps:./ansible/roles/commons:./ansible/roles/services
inventory = ./ansible/inventory.ini
filter_plugins = ./ansible/plugins/filter:
lookup_plugins = ./ansible/plugins/lookup:
callback_plugins = ./ansible/plugins/callback:
module_utils = ./ansible/module_utils:
stdout_callback = anstomlog
deprecation_warnings = False

[privilege_escalation]
become: yes
become_user: root
become_method: sudo

extend

developing plugins

developing modules