Ansible

如果在 Ansible 的 host_vars 中設置了 playbook var,我該如何覆蓋它?

  • July 2, 2021

server1 在組it_servers中,但我想使用ansible_connection: local. ansible_connection如果在 playbook 和 host_vars 中定義,如何做到這一點?

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

我的host_vars/server1.yml文件

ansible_connection: local

問:如果在 Ansible 的 host_vars 中設置了 playbook var,如何覆蓋它?

A:看看變數優先級play vars的優先級是 12。還有 10 種以上如何覆蓋play vars的可能性,但它們都不會讓您有選擇地覆蓋單個主機的變數。

ansible_connection: aws_ssm如果要為單個主機更改聲明,則必須從劇本中刪除聲明。連接的組聲明的最佳位置是group_vars(優先級 3-7),而覆蓋單個主機的 group_vars 的最佳位置是host_vars(優先級 8-10)。例如

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

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

有許多host_varsgroup_vars的組合來實現這個場景。但是,如果您在play vars(優先級 12)中設置了一個變數,您將無法再為單個主機覆蓋它。


動態變數

可以動態聲明變數。例如

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

這將適用於任何優先級。但是,由於懶惰的評估,它的效率非常低。每次引用時都會評估該變數。


“實例化”動態變數

如果您確實需要使用動態變數“實例化”它以避免重複評估。這是什麼意思?例如,給定庫存(在 YAML 中以獲得更好的可讀性)

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:

劇本

- 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

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

連接按預期工作,但變數ansible_connection不包含在hostvars中。使用模組set_fact並“實例化”變數,例如

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

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

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

引用自:https://serverfault.com/questions/1068316