8 votes

Comment puis-je remplacer une variable de playbook si elle est définie dans host_vars dans Ansible ?

Server1 est dans le groupe it_servers mais j'aimerais utiliser ansible_connection: local . Comment cela peut-il être fait si ansible_connection est défini dans le playbook et les host_vars ?

--
- hosts: it_servers
  vars:
    ansible_connection: aws_ssm
  roles:
    - nginx
    - mysql

Mon host_vars/server1.yml fichier

ansible_connection: local

10voto

Vladimir Botka Points 3372

Q : " Comment remplacer la variable du playbook si elle est définie dans host_vars dans Ansible ? "

R : Jetez un coup d'œil à Priorité des variables . La préséance de jouer les vars est de 12. Il y a 10 autres possibilités de contournement. jouer les vars mais aucun d'entre eux ne vous permet de remplacer de manière sélective une variable pour un seul hôte.

Vous devrez supprimer la déclaration de ansible_connection: aws_ssm du playbook si vous voulez le modifier pour un seul hôte. Le meilleur endroit pour le groupe la déclaration de la connexion est paramètres du groupe (précédence 3-7) et le meilleur endroit pour remplacer les group_vars pour un seul hôte est paramètres de l'hôte (précédence 8-10). Par exemple

shell> cat hosts
[aws1]
server1 ansible_connection=local      # precedence 8.
server2
server3

[aws1:vars]
ansible_connection=aws_ssm            # precedence 3.

Il existe de nombreuses combinaisons de paramètres de l'hôte y paramètres du groupe pour réaliser ce scénario. Mais, si vous définissez une variable à jouer les vars (précédence 12), vous ne pouvez plus l'ignorer pour un seul hôte.


Variable dynamique

Il est possible de déclarer la variable de façon dynamique. Par exemple

ansible_connection: "{{ 'local'
                        if inventory_hostname == 'server1'
                        else
                        'aws_ssm' }}"

Cela fonctionnerait à n'importe quel niveau de préséance. Mais, à cause de l'évaluation paresseuse, c'est très inefficace. La variable sera évaluée à chaque fois qu'elle sera référencée.


Instanciation de la variable dynamique

Si vous avez vraiment besoin d'utiliser la variable dynamique, "instanciez-la" pour éviter une évaluation répétée. Qu'est-ce que cela signifie ? Par exemple, étant donné l'inventaire (en YAML pour une meilleure lisibilité)

shell> cat hosts
all:
  hosts:
    server1:
      ansible_host: localhost
      ansible_python_interpreter: /usr/bin/python3.8
    server2:
      ansible_host: 10.1.0.62
      ansible_user: admin
      ansible_python_interpreter: /usr/local/bin/python3.8
    server3:
      ansible_host: 10.1.0.63
      ansible_user: admin
      ansible_python_interpreter: /usr/local/bin/python3.8
  children:
    servers:
      hosts:
        server1:
        server2:
        server3:

Le livre de jeu

- hosts: servers
  vars:
    ansible_connection: "{{ 'local'
                            if inventory_hostname == 'server1'
                            else
                            'ssh' }}"
  tasks:
    - debug:
        msg: "{{ ansible_play_hosts|
                 map('extract', hostvars, 'ansible_connection') }}"
      run_once: true
    - debug:
        var: ansible_connection

donne

PLAY [servers] *****************************************************

TASK [Gathering Facts] *********************************************
ok: [server1]
ok: [server2]
ok: [server3]

TASK [debug] *******************************************************
ok: [server1] => 
  msg: '[AnsibleUndefined, AnsibleUndefined, AnsibleUndefined]'

TASK [debug] *******************************************************
ok: [server1] => 
  ansible_connection: local
ok: [server2] => 
  ansible_connection: ssh
ok: [server3] => 
  ansible_connection: ssh

Les connexions fonctionnent comme prévu, mais la variable ansible_connection n'est pas inclus dans le hostvars . Utilisez le module Faits et chiffres et "instanciez" la variable, par ex.

    - set_fact:
        ansible_connection: "{{ ansible_connection }}"
    - debug:
        msg: "{{ ansible_play_hosts|
                 map('extract', hostvars, 'ansible_connection') }}"
      run_once: true

donne

TASK [set_fact] ****************************************************
ok: [server1]
ok: [server2]
ok: [server3]

TASK [debug] *******************************************************
ok: [server1] => 
  msg:
  - local
  - ssh
  - ssh

0voto

Gerald Schneider Points 17588

Vous pouvez utiliser delegate_to: localhost pour la tâche.

0voto

Max Points 11

Ansible applique une préséance variable, et vous pourriez en avoir l'utilité. Voici l'ordre de préséance du plus petit au plus grand (les dernières variables listées remplacent toutes les autres variables) :

les valeurs de la ligne de commande (par exemple, -u mon_utilisateur, ce ne sont pas des variables)

rôles par défaut (définis dans role/defaults/main.yml) 1

fichier d'inventaire ou script groupe vars 2

inventaire groupe_vars/all 3

playbook groupe_vars/all 3

inventaire groupe_vars/* 3

playbook groupe_vars/* 3

fichier d'inventaire ou script vars hôte 2

inventaire host_vars/* 3

playbook host_vars/* 3

host facts / cached set_facts 4

jouer les vars

jouer vars_prompt

jouer vars_files

paramètres du rôle (définis dans role/vars/main.yml)

vars du bloc (seulement pour les tâches du bloc)

vars de la tâche (uniquement pour la tâche)

inclure_vars

set_facts / vars enregistrés

paramètres de rôle (et include_role)

inclure les paramètres

les variables supplémentaires (par exemple, -e "user=my_user") (toujours prioritaires)

Ceci est mieux expliqué ici : https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X