变量的命名必须以字母开头,中间不能有空格,且只能含有字母、数字和下划线
ansible可以在多个位置定义变量
ansible配置文件中定义的变量
环境变量
ansible或ansible-playbook命令行中传递的变量
play中vars关键字下定义的变量
模块include_vars中定义的变量
role在default/main.yml和vars/main.yml中定义的变量
主机清单中的变量
主机的系统变量
注册变量
Ansible变量的优先级(由低到高) |
role defaults |
dynamic inventory variables |
inventory variables |
inventory group_vars |
inventory host_vars |
playbook group_vars |
plsybook host_vars |
host facts |
registered variables |
set_facts |
play variables |
play vars_prompt |
play vars_files |
role variables and include variables |
block variables |
task variables |
extrd variables |
总结:除了role default变量外,其余变量的作用域越小,优先级越高。
1. role defaults
role x的默认变量放在文件roles/x/default/main.yml中
2. inventory vars
在inventory文件中定义的变量
#file: /etc/ansible/hosts
host1 ansible_ssh_port=22 ntp_server=inventory.ntp.com
3. inventory group_vars
有两个地方可以定义group_vars:一个是在inventory中直接定义;二是在inventory文件同级的文件夹groups_vars下定义,放在group同名的文件中。
所有group中都生效的变量放在文件/etc/ansible/group_vars/all中。
#file: /etc/asnible/hosts
[group1:vars]
ntp_server=inventory_group_vars.example.com
#file: /etc/ansible/group_vars/all
ntp_server: default-time.example.com
4. inventory hos_vars
有两个地方可以定义host_vars:一个是在inventory中直接定义;二是在inventory文件同级的文件夹host_vars下,与host用吗的文件中定义。
#file: /etc/asnible/hosts
host1 ntp_server=inventory_host_vars.example.com
#file: /etc/ansible/host_vars/hosts1
ntp_server: default-time.example.com
5. Playbook group_vars
和playbook文件同级的子目录下定义的变量。例如:当前的playbook放在~/playbooks目录下,那么Group "group1"的变量放在下面的文件中:
#~/playbooks/group_vars/group1
ntp_server: default-time.example.com
6. Playbook host_vars
Playbook文件同级的子目录Host-vars下定义的变量。例如:当前的playbook放在~/playbooks目录下,那么对应的Host "host1"的变量放在下面的文件中:
#~/playbooks/host_vars/host1
ntp_server: default-time.example.com
7. Host facts
Ansible在执行playbook时,会自动搜索远程直接的信息。关于这些主机的系统变量都可以在playbook中直接使用。
8. Play vars
- hosts: web
vars:
http_port: 80
defined_name: "Hello, my name is Yuki"
9. play vars_prompt
vars_prompt是需要用户在执行playbook的时候输入变量值的变量。
---
- hosts: all
remote_user: root
gether_facts: no
vars:
test: "camelot"
vars_prompt:
- name: "name"
prompt: "what is your name? "
- name: "favcolor"
prompt: "what is you favorite color?"
tasks:
- debug: msg="Hello {{name}}, your favorite color is {{favcolor}}"
10. Play vars_files
把一个变量单独放在一个文件中,通过关键字vars_file从文件加载进来的变量就是play vars_file.
- host: web
vars_file:
- apache_vars.yml
11. registered vars
把执行结果注册到一个动态值的变量中,这个变量就是registered vars。
register关键字可用于在变量中捕获命令的输出
tasks:
- shell: ls
register: result ##result变量记录了ls的返回值
ignore_errors: True
- debug:
msg: "{{ result.stdout }}"
12. set_facts
set_facts 是一个模块的名字,在任务中通过set_facts加入以下Facts变量。
- set_facts:
one_fact: "something"
other_fact: "{{local_var}}"
13. role and include vars
role vars
---
# file: roles/x/vars/main.yml
http_port:80
14. role include vars
在role/x/tasks/main.yml include 中, 通过关键字include 加载进来的变量
---
# file: roles/x/vars/apache.yml
http_port:80
---
# file: roles/x/tasks/main.yml
- name: Add apache variables
include_vars: "apache.yml"
15. block vars
只能在playbook的任务中的某个block里定义和使用的变量。
tasks:
- block:
- yum: name={{ service }} state=installed
- service: name={{ status }} state=started enabled=True
vars:
service: httpd
status: started
16. tasks vars
只能在该任务里使用的变量
tasks:
- debug: msg="{{ service }} is {{ status }}"
vars:
service=httpd
status=started
17. extrd vars
通过命令行传递进来的变量
ansible-playbook test.yml --extra-vars "hosts=web user=root"
当变量作用于开始一个值的第一元素时必须使用引号。
#错误示范
yum:
name: {{ service }}
#正确写法
yum:
name: "{{ service }}"
或
yum:
name: '{{ service }}'
ansible-vault可以加密和解密任何由ansible使用的结构化数据文件。在命令行中使用ansible-vault创建、编辑、加密、解密和查看文件
[root@wzy ansible]#ansible-vault create secret.yml
New Vault password:
Confirm New Vault password:
[root@wzy ansible]#ls
ansible.cfg inventory roles secret.yml
也可以使用vault密码文件来存储密码,从而使用该密码文件给目标文件加密。
#创建存储密码的文件
echo '112233' > pwd.txt
#创建加密文件
ansible-vault create secret.yml --vault-id=pwd.txt
ansible-vault view secret.yml
ansible-vault edit secret.yml
ansible-vault decrypt secret.yml
ansible-vault rekey secret.yml
指定密码文件
ansible-playbook site.yml --vault-id=pwd.txt
交互式
ansible-playbook site.yml --ask-vault-pass
ansible事实指ansible在受控主机上自动检测到的变量。通常,每个play在执行第一个任务之前都会自动运行setup模块来收集事实。
事实 | 变量 | 另一种写法 | 旧事实变量形式 |
短主机名 | ansible_facts['hostname'] | ansible_facts.hostname | ansible_hostname |
完全限定域名 | ansible_facts['fqdn'] | ansible_facts.fqdn | ansible_fqdn |
主要的IPV4地址 | ansible_facts['default_ipv4']['address'] | ansible_facts.defaults_ipv4.address | ansible_default_ipv4['address'] |
所有网络接口的名称 | ansible_facts['interfaces'] | ansible_facts.interfaces | ansible_interfaces |
/dev/vda1磁盘分区的大小 | ansible_facts['devices']['vda']['partitions']['vda1']['size'] | ansible_facts.devices.vda.partitions.vda1.size | ansible_devices['vda']['partitions']['vda1']['size'] |
DNS服务器列表 | ansible_facts['dns']['nameservers'] | ansible_facts.dns.nameservers | ansible_dns['nameservers'] |
当前运行的内核版本 | ansible_facts['kernel'] | ansible_facts.kernel | ansible_kenel |
示例
[root@wzy ansible]#vim playbook.yml
---
- name:
hosts: all
tasks:
- name:
debug:
msg: >
The default IPV4 address of {{ ansible_facts['fqdn'] }}
is {{ ansible_facts.default_ipv4.address }},
and kernel is {{ ansible_kernel }}
[root@wzy ansible]#ansible-playbook --syntax-check playbook.yml
playbook: playbook.yml
[root@wzy ansible]#ansible-playbook playbook.yml
PLAY [all] ******************************************************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************************************
ok: [192.168.29.143]
ok: [192.168.29.144]
ok: [192.168.29.142]
TASK [debug] ****************************************************************************************************************************************************************************
ok: [192.168.29.144] => {
"msg": "The default IPV4 address of centos8-04.localdomain is 192.168.29.144, and kernel is 4.18.0-193.el8.x86_64\n"
}
ok: [192.168.29.142] => {
"msg": "The default IPV4 address of centos8-02.localdomain is 192.168.29.142, and kernel is 4.18.0-193.el8.x86_64\n"
}
ok: [192.168.29.143] => {
"msg": "The default IPV4 address of centos8-03.localdomain is 192.168.29.143, and kernel is 4.18.0-193.el8.x86_64\n"
}
PLAY RECAP ******************************************************************************************************************************************************************************
192.168.29.142 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.29.143 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.29.144 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
管理员可以创建自定义事实,将其本地存储在每个受控主机上。这些事实整合到setup模块在受控主机运行时收集的标准事实列表中。
自定义事实在静态文件中体现为INI格式或JSON格式;也可以是生成JSON输出的可执行脚本。
默认情况下,setup模块从各个受控主机的/etc/ansible/facts.d目录下的文件和脚本中加载自定义事实。各个文件或脚本的名称必须以.fact结尾。
自定义事实由setup模块存储在ansible_facts.ansible_local变量中
示例
#INI格式
[packages]
web_package = httpd
db_package = mariadb
[users]
user1 = zs
user2 = ls
#JSON格式
{
"packages": {
"web_package": "httpd",
"db_package": "mariadb"
},
"users": {
"user1": "zs",
"user2": "ls"
}
}
常用的魔法变量
hostvars | 包含受控主机的变量,可用于获取另一台受控主机的变量的值。如果还没有为受控主机收集事实,则它不会包含该主机的事实 |
group_names | 列出当前受控主机所属的所有组 |
groups | 列出清单中的所有组和主机 |
inventory_hostname | 包含清单中配置的当前受控主机的主机名称。 |
通过debug模块查看特定主机的hostvars变量的内容
[root@wzy ansible]#ansible 192.168.29.142 -m debug -a 'var=hostvars["192.168.29.142"]'
192.168.29.142 | SUCCESS => {
"hostvars[\"192.168.29.142\"]": {
"ansible_check_mode": false,
"ansible_diff_mode": false,
"ansible_facts": {},
"ansible_forks": 5,
"ansible_inventory_sources": [
"/root/ansible/inventory"
],
"ansible_playbook_python": "/usr/libexec/platform-python",
"ansible_verbosity": 0,
"ansible_version": {
"full": "2.9.27",
"major": 2,
"minor": 9,
"revision": 27,
"string": "2.9.27"
},
"group_names": [
"AA",
"AB"
],
"groups": {
"AA": [
"192.168.29.142"
],
"AB": [
"192.168.29.142",
"192.168.29.143"
],
"BB": [
"192.168.29.143"
],
"CC": [
"192.168.29.144"
],
"all": [
"192.168.29.144",
"192.168.29.142",
"192.168.29.143"
],
"ungrouped": []
},
"inventory_dir": "/root/ansible",
"inventory_file": "/root/ansible/inventory",
"inventory_hostname": "192.168.29.142",
"inventory_hostname_short": "192",
"omit": "__omit_place_holder__c26076107b5c658ac4dd5197fd828c5384423b1b",
"playbook_dir": "/root/ansible"
}
}
示例
生成主机文件
将一个初始模板文件从 http://content.example.com/hosts.j2 下载到 /home/student/ansible
完成该模板,以便用它生成以下文件:针对每个清单主机包含一行内容,其格式与 /etc/hosts 相同
创建名为 /home/student/ansible/hosts.yml 的 playbook ,它将使用此模板在 dev 主机组中的主机上生成文件 /etc/myhosts 。
该 playbook 运行后, dev 主机组中主机上的文件 /etc/myhosts 应针对每个受管主机包含一行内容:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.250.9 workstation.lab.example.com workstation
172.25.250.10 servera.lab.example.com servera
172.25.250.11 serverb.lab.example.com serverb
172.25.250.12 serverc.lab.example.com serverc
172.25.250.13 serverd.lab.example.com serverd
注:清单主机名称的显示顺序不重要。
#下载模板文件
wget http://content.example.com/hosts.j2 -P /home/student/ansible
#编辑hosts.j2
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
{% for i in groups.all %}
{{ hostvars[i].ansible_default_ipv4.address }} {{ hostvars[i].ansible_fqdn }} {{ hostvars[i].ansible_hostname }}
{% endfor %}
#编写playbook
vim /home/student/ansible/hosts.yml
---
- name: get facts
hosts: all
- name: cp files
hosts: dev
tasks:
- name: cp hosts
template:
src: /home/student/ansible/hosts.j2
dest: /etc/hosts