server1 在组中它服务器,但我想使用。如果在剧本和 host_vars 中定义了,ansible_connection: local
该如何做?ansible_connection
--
- hosts: it_servers
vars:
ansible_connection: aws_ssm
roles:
- nginx
- mysql
我的主机变量/server1.yml文件
ansible_connection: local
答案1
问:“如果在 Ansible 中的 host_vars 中设置了 playbook var,如何覆盖它?“
答:看一下变量优先级. 优先级玩变量是 12。还有 10 种方法可以覆盖玩变量,但它们都不能让您有选择地覆盖单个主机的变量。
ansible_connection: aws_ssm
如果要为单个主机更改它,则必须从剧本中删除声明。团体连接声明是组变量(优先级 3-7)并且覆盖单个主机的 group_vars 的最佳位置是主机变量(优先级 8-10)。例如
shell> cat hosts
[aws1]
server1 ansible_connection=local # precedence 8.
server2
server3
[aws1:vars]
ansible_connection=aws_ssm # precedence 3.
有很多组合主机变量和组变量来实现此场景。但是,如果你在玩变量(优先级 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不包括在内主机变量. 使用模块设置事实并“实例化”变量,例如
- 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
答案2
您可以将其delegate_to: localhost
用于该任务。
答案3
Ansible 确实应用了变量优先级,您可能会用到它。以下是从最低到最高的优先级顺序(最后列出的变量覆盖所有其他变量):
命令行值(例如,-u my_user,这些不是变量)
角色默认值(在 role/defaults/main.yml 中定义) 1
库存文件或脚本组变量 2
库存 group_vars/all 3
剧本 group_vars/all 3
库存组变量/* 3
剧本 group_vars/* 3
库存文件或脚本主机变量 2
库存主机变量/* 3
剧本 host_vars/* 3
主机事实/缓存的 set_facts 4
玩变量
播放 vars_prompt
播放 vars_files
角色变量(在 role/vars/main.yml 中定义)
块变量(仅适用于块中的任务)
任务变量(仅适用于任务)
包含变量
set_facts / 注册变量
role(和 include_role)参数
包括参数
额外变量(例如,-e“user=my_user”)(始终优先)