Tools/Ansible/Use Cases

De MonPtitSite
Sauter à la navigation Sauter à la recherche
Accueil SysAdmin Hobbies                  


Ansible - Cas d'usages

Include des variables depuis un fichier Ansible Vault

Utilisation de plusieurs "tasks"

Ex, le fichier de variables dépend de l’environnement (prod,dev, qual etc ...)

---
# ./configure_app_servers.yml

- name: configure app servers
  hosts: app_servers
  pre_tasks:
    - name: include env vars
      include_vars: "{{ env }}.yml"
      tags: ["always"]

    - name: include vault for env
      include_vars: "{{ env }}.vault.yml"
      tags: ["always"]
  roles:
    ...

Vous pouvez régler env en passant l'option --extra-vars à ansible-playbook :

$ ansible-playbook configure_app_servers.yml --extra-vars "env=prod"


Exemples de fichier de param :


---
# ./vars/prod.yml

domain: example.com
rails_env: production
https: true

Le fichier prod.vault.yml peut ressembler à ceci (en texte brut) :

$ANSIBLE_VAULT;1.1;AES256
3462353065386462383165626...
...

Mais à ceci si on utilise la commande ansible-vault view ./vars/prod.vault.yml:


---
# ./vars/prod.vault.yml

database_password: "94BqEabtebgzbQItkqPEVMyqjKbp57Gc"
api_key: "xVQKRARKgcwDktPCJjYRFiqmHGsvNFd9"


Utilisation d'une boucle

L'exemple précédent peut être plus clair et concis si on utilise une boucle avec des include_vars plutôt que deux tâches séparées :

---
# ./configure_app_servers.yml

- name: configure app servers
  hosts: app_servers
  pre_tasks:
    - name: include vars and vault for env
      include_vars: "{{ item }}.yml"
      tags: ["always"]
      loop:
        - "{{ env }}"
        - "{{ env }}.vault"
  roles:
    ...

Inclure des "tasks"

gestion de boucles

Cette technique est utile chaque fois que vous devez exécuter plusieurs tâches pour chaque élément d'une boucle.


exemple :

---
# ./greet_tasks.yml

- name: set greeting fact
  set_fact: 
    greeting: "Greeting {{ index }}: Hello, {{ name }}!"

- name: print greeting fact
  debug: var=greeting

Vous pouvez exécuter ces tâches dans une bloucle comme ceci :

# ./greet.yml

- name: greet people
  hosts: "*"
  tasks:
    - include_tasks: greet_tasks.yml
      loop:
        - World
        - Percy
      loop_control:
        loop_var: name
        index_var: index


Ce qui donne à l'exécution du playbook :


TASK [set greeting fact]
ok: [123.123.123.123]

TASK [print greeting fact]
ok: [123.123.123.123] => {
    "greeting": "Greeting 0: Hello, World!"
}

TASK [set greeting fact]
ok: [123.123.123.123]

TASK [print greeting fact]
ok: [123.123.123.123] => {
    "greeting": "Greeting 1: Hello, Percy!"
}

Inclure des "tasks" à partir de fichier dynamiques

L'inclusion de tâches avec un nom de fichier dynamique est le plus souvent utilisée pour faire varier les tâches en fonction du système d'exploitation de l'hôte distant.

Prenons l'exemple suivant :

# ./roles/redis/tasks/main.yml

- name: install redis on Debian based distros 
  apt:
    name: redis-server
    state: present
    update_cache: true
  become: true
  when: ansible_os_family == 'Debian'

- name: ensure epel-release repo is installed on RHEL based distros
  yum:
    name: epel-release
    state: present
    update_cache: true
  become: true
  when: ansible_os_family == 'RedHat'

- name: install redis on RHEL based distros
  yum:
    name: redis
    state: present
    update_cache: true
  become: true
  when: ansible_os_family == 'RedHat'


Il peut être avantageusement factorisé en 3 tâches distinctes de la façon suivante :


---
# ./roles/redis/tasks/setup-Debian.yml

- name: install redis on Debian based distros 
  apt:
    name: redis-server
    state: present
    update_cache: true
  become: true
  when: ansible_os_family == 'Debian'
---
# ./roles/redis/tasks/setup-RedHat.yml

- name: ensure epel-release repo is installed on RHEL based distros
  yum:
    name: epel-release
    state: present
    update_cache: true
  become: true
  when: ansible_os_family == 'RedHat'

- name: install redis on RHEL based distros
  yum:
    name: redis
    state: present
    update_cache: true
  become: true
  when: ansible_os_family == 'RedHat'


# ./roles/redis/tasks/main.yml

- include_tasks: "setup-{{ ansible_os_family }}.yml"


Utilisation de import_playbook & fichiers YAML dynamiques

---
# ./master.yml

- import_playbook: common_roles.yml

- import_playbook: staging_roles.yml
  when: env == 'staging'

- import_playbook: "{{ server_type }}.yml"


On peut les playbooks specifiques aux servers pour qu'ils ne contiennent qu'une tâche chacun :


---
'''# ./web.yml'''

- name: configure web servers
  hosts: "{{ env }}_web"
  roles:
    - nginx
    - my_site
---
'''# ./database.yml'''

- name: configure database servers
  hosts: "{{ env }}_database"
  roles:
    - postgres

A partir de là, il est possible de configurer à la fois les serveurs web et base de données en utilisant seulement le fichier playbook master.yml et en utilisant env et server_type pour specifier quels serveurs on désire configurer :

$ ansible-playbook master.yml --extra-vars "env=staging server_type=web"

$ ansible-playbook master.yml --extra-vars "env=staging server_type=database"


Utilisation de sections pre_tasks et post_tasks

exemple d'utilisation :

Configurez un playbook pour ajouter un message du jour (MOTD, Message Of The Day) sur les serveurs HAProxy lorsqu'une opération de maintenance est en cours. De cette façon, lorsqu'un membre de l'équipe d'assistance se connecte, le système l'informe de la fenêtre de maintenance. Le playbook doit également informer votre les admins à chaque fois qu'Ansible recharge le service haproxy. Un message doit également apparaître dans syslog afin que l'événement doit tracer par le système de corrélation de logs.


- name: Ensure HAProxy is deployed
  hosts: lb_servers
  force_handlers: True
  pre_tasks:
    - name: Setting the maintenance message
      copy:
        dest: /etc/motd.d/maintenance
        content: "Maintenance in progress\n"
  roles:
    # The "haproxy" role has a dependency on the "firewall" role.
    # The "firewall" role requires a "firewall_rules" variable be defined.
    - role: haproxy
  post_tasks:
    - name: Removing the maintenance message
      file:
        path: /etc/motd.d/maintenance
        state: absent

  handlers:
    - name: Sending an email to admins
      mail:
        subject: "HAProxy reloaded on {{ inventory_hostname }}"
        to: admin@supervision.lab.example.com
      delegate_to: localhost
      become: false
      listen: reload haproxy
    - name: Logging a message to syslog
      syslogger:
        msg: "HAProxy reloaded on {{ inventory_hostname }}"
      delegate_to: localhost
      become: false
      listen: reload haproxy

Transformation de données

Types de variables ansible

Principaux types de variables
Type Description
Chaîne de carractères Une chaîne est une séquence de caractères qui est le type de données par défaut dans Ansible. Il n'est pas nécessaire de placer les chaînes entre guillemets ou guillemets doubles.

Ansible supprime les espaces de fin de chaîne des chaînes sans guillemets.

my_string: Those are the contents of the string

Le format YAML permet de définir des chaînes à plusieurs lignes. Utilisez l'opérateur de barre verticale (|) pour conserver les sauts de ligne, ou l'opérateur supérieur à (>) pour les supprimer.

string_with_breaks: |
  This string
  has several
  line breaks
string_without_breaks: >
  This string will not
  contain any line breaks.
  Separated lines are joined
  by a space character.


Nombres Lorsque le contenu de la variable est conforme à un nombre, Ansible (ou YAML, pour être précis) analyse la chaîne et génère une valeur numérique, Integer ou Float.
  • Integers contient des caractères décimaux qui sont éventuellement précédés des signes

+ ou - : answer: 42

  • Si un point décimal (.) est inclus dans une valeur de type entier, il est analysé en tant que Float.

float_answer: 42.0

  • Il est également possible d'utiliser la notation « Scientific » pour écrire des Integers ou Floats importants.

scientific_answer: 0.42e+2

  • Les nombres hexadécimaux commencent par 0x, suivi de caractères hexadécimaux uniquement. La valeur d'exemple suivante est le nombre hexadécimal 2A (42 en décimal) :

hex_answer: 0x2A

  • Si vous placez un nombre entre guillemets, il est traité comme une String.

string_not_number: "20"

Booléens Les valeurs booléennes contiennent les chaînes yes, no, y, n, on, off, true ou false. Les valeurs ne sont pas sensibles à la casse, mais la documentation Jinja2 recommande d'utiliser des minuscules à des fins de cohérence.
Date Si la chaîne est conforme à la norme ISO-8601, Ansible convertit la chaîne en une valeur

typée date.

my_date_time: 2019-05-30T21:15:32.42+02:00
my_simple_date: 2019-05-30
Null La valeur null spéciale déclare une variable comme étant « undefined ». La chaîne null, ou le caractère tilde (~), affecte la valeur null à la variable.

my_undefined: null

Listes ou matrices Une liste, également connue sous le nom de matrice, est une collection triée de valeurs. Les listes sont les structures de base des collections de données et des boucles.

Écrivez des listes sous la forme d'une séquence de valeurs séparées par des virgules, insérées entre crochets, ou d'une série d'éléments, un par ligne, chacun préfixé par un tiret (-). Les exemples suivants sont équivalents :

my_list: ['Douglas', 'Marvin', 'Arthur']
my_list:
  - Douglas
  - Marvin
  - Arthur

À l'instar des matrices de la plupart des langages de programmation, vous pouvez accéder à des éléments spécifiques d'une liste en utilisant un numéro d'index à partir de 0 : <syntaxhighlight lang="yaml"> - name: Confirm that the second list element is "Marvin"

 assert:
   that:
     - my_list[1] == 'Marvin'