Ansible支持利用变量来存储值,并在Ansible项目的所有文件中重复使用这些值。这可以简化项目的创建和维护,并减少错误的数量。
通过变量,可以轻松地在Ansible项目中管理给定环境的动态值。例如,变量可能包含下面这些值:
要创建的用户
要安装的软件包
要重新启动的服务
要删除的文件
要从互联网检索的存档
可以在Ansible项目中的多个位置定义变量。不过,这些变量大致可简化为三个范围级别:
全局范围:从命令行或Ansible配置设置的变量
Play范围:在play和相关结构中设置的变量
主机范围:由清单、事实收集或注册的任务,在主机组和个别主机上设置的变量
如果在多个xeklh定义了相同名称的变量,则采用优先级别最高的变量。窄范围优先于更广泛的范围:由清单定义的变量将被playbook定义的变量覆盖,后者将被命令行中定义的变量覆盖。
变量在Ansible Playbook中发挥着重要作用,因为它们可以简化playbook中变量数据的管理。
编写playbook时,可以定义自己的变量,然后在任务中调用这些值。例如,名为web_package的变量可以使用值httpd来定义。然后,任务可以使用yum模块调用该变量来安装httpd软件包。
Playbook变量可以通过多种方式定义。一种常见的方式是将变量放在playbook开头的vars块中:
清单文件
[root@server ansible]# cat inventory
[man]
192.168.58.20
[pro]
192.168.58.30
[web]
192.168.58.40
命令行中定义,通过 -e EXTRA_VARS, --extra-vars=EXTRA_VARS 定义
在 playbook 的 yml 文件中定义
在 inventory 清单中定义
变量名可以有下划线,但不能有中横线。
优先级:命令行定义变量 > playbook定义变量 > inventory 定义变量
如下内容也是按照优先级从低到高写的,如果是为了测试优先级那么你可以直接按照如下步骤测验。
有三种定义方式:
直接在 inventory 清单文件中定义变量「了解即可,不推荐使用」
通过 group_vars 定义变量
通过 host_vars 定义变量
自身内部的优先级:host_vars/主机名【或别名】 定义变量 > group_vars/清单组名 定义变量 > group_vars/all 定义变量> inventory 文件中直接定义变量
[root@server ansible]# cat inventory
[man]
192.168.58.20
[pro]
192.168.58.30
[web]
192.168.58.40
[bi:children]
man
pro
web
[bi:vars]
user:pp
写一个创建用户的 yml
[root@server ansible]# cat playbook/cuser.yml
---
- hosts: bi
tasks:
- name: create user
user:
name: "{{ user }}"
state: present
[root@server ansible]#
执行
[root@server ansible]# ansible-playbook playbook/cuser.yml
PLAY [bi] *******************************************************************************
TASK [Gathering Facts] ******************************************************************
ok: [192.168.58.30]
ok: [192.168.58.20]
ok: [192.168.58.40]
TASK [create user] **********************************************************************
changed: [192.168.58.20]
changed: [192.168.58.30]
changed: [192.168.58.40]
PLAY RECAP ******************************************************************************
192.168.58.20 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.58.30 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.58.40 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
注意事项:
要创建的 group_vars 目录要与 inventory 清单文件在同一个目录,或者与要执行的 playbook 的 yml 文件在同一个目录。
group_vars 目录下的文件名是 inventory 清单文件中的组名。或者文件名为 all「特殊组」,表示对所有机器主机生效。
在 group_vars/all 定义变量
[root@server ansible]# cat host_vars/192.168.58.20
package: wget
[root@server ansible]# cat playbook/wget.yml
---
- hosts: 192.168.58.20
tasks:
- name: install package
yum:
name: "{{package}}"
state: present
[root@server ansible]#
执行
[root@server ansible]# ansible-playbook playbook/wget.yml
PLAY [192.168.58.20] ********************************************************************
TASK [Gathering Facts] ******************************************************************
ok: [192.168.58.20]
TASK [install package] ******************************************************************
ok: [192.168.58.20]
PLAY RECAP ******************************************************************************
192.168.58.20 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
被控主机查看
[root@httpd ~]# rpm -qa | grep wget
wget-1.19.5-8.el8_1.1.x86_64
[root@httpd ~]#
在group_vars目录里创建一个mysql的文件指定变量
[root@server ansible]# ls group_vars/
paa
[root@server ansible]# ls group_vars/paa
group_vars/paa
[root@server ansible]# cat playbook/autofs.yml
---
- hosts: man
tasks:
- name: install package
yum:
name: "{{package}}"
state: present
[root@server ansible]#
执行
[root@server ansible]# ansible-playbook playbook/autofs.yml
PLAY [man] ******************************************************************************
TASK [Gathering Facts] ******************************************************************
ok: [192.168.58.20]
TASK [install package] ******************************************************************
ok: [192.168.58.20]
PLAY RECAP ******************************************************************************
192.168.58.20 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
被控主机查看
[root@httpd ~]# rpm -qa |grep autofs
libsss_autofs-2.2.3-20.el8.x86_64
[root@httpd ~]#
[root@server ansible]# cat playbook/testing.yml
---
- hosts: pro
vars:
ip: 192.168.58.30
name: httpd
tasks:
- name:
lineinfile:
path: /etc/hosts
line: "{{ip}} {{name}}"
state: present
执行
[root@server ansible]# ansible-playbook playbook/testing.yml
PLAY [pro] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.58.20]
TASK [lineinfile] **************************************************************
changed: [192.168.58.20]
PLAY RECAP *********************************************************************
192.168.58.20 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
在被控主机上查看
[root@mysql ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.58.30 httpd
编写vars_files来定义变量
[root@server playbook]# cat vars.yml
ip: 192.168.58.111
name: kjl
[root@server playbook]# cat testing.yml
---
- hosts: pro
vars_files:
- vars.yml
tasks:
- name:
lineinfile:
path: /etc/hosts
line: "{{ip}} {{name}}"
state: present
执行
[root@server playbook]# ansible-playbook testing.yml
[WARNING]: Found variable using reserved name: name
PLAY [pro] ******************************************************************************
TASK [Gathering Facts] ******************************************************************
ok: [192.168.58.30]
TASK [lineinfile] ***********************************************************************
changed: [192.168.58.30]
PLAY RECAP ******************************************************************************
192.168.58.30 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
在被控主机上查看
[root@mysql ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.58.30 httpd
192.168.58.111 kjl
[root@mysql ~]#
//清单变量可被playbook中设置的变量覆盖,这两种变量又可通过在命令行中传递参数到ansible或ansible-playbook命令来覆盖。在命令行上设置的变量称为额外变量。
当需要覆盖一次性运行的playbook的变量的已定义值时,额外变量非常有用
ansible-playbook main.yml -e "package=apache2"
//编写一个
---
- hosts: httpd
tasks:
- name:
command: "echo biuding"
register: result
- name:
shell: "echo {{ result['stdout']}} > /root/xun"
[root@lserver ansible]# ansible-playbook playbook/tesingt.yml
PLAY [httpd] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.58.30]
TASK [command] *****************************************************************
changed: [192.168.58.30]
TASK [shell] *******************************************************************
changed: [192.168.58.30]
PLAY RECAP *********************************************************************
192.168.58.30 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
被控主机查看
[root@mysql ~]# cat xun
biuding
Ansible可能需要访问密码或API密钥等敏感数据,以便能配置受管主机。通常,此信息可能以纯文本形式存储在清单变量或其他Ansible文件中。但若如此,任何有权访问Ansible文件的用户或存储这些Ansible文件的版本控制系统都能够访问此敏感数据。这显示存在安全风险。
Ansible提供的Ansible Vault可以加密和解密任何由Ansible使用的结构化数据文件。若要使用Ansible Vault,可通过一个名为ansible-vault的命令行工具创建、编辑、加密、解密和查看文件。Ansible Vault可以加密任何由Ansible使用的结构化数据文件。这可能包括清单变量、playbook中含有的变量文件、在执行playbook时作为参数传递的变量文件,或者Ansible角色中定义的变量。
[root@server ansible]# ansible-vault create secret.yml
New Vault password: #输入密码
Confirm New Vault password: #再次输入密码
[root@server ansible]# cat secret.yml #查看内容
$ANSIBLE_VAULT;1.1;AES256
3424242373037613563393732646565356361633665646638653061636364326635323931366637
38643336353832373861689898989735344234242342343242432466665613230643930
30646433333661f2456464i63866663338396430313961323335373433656661653664
3865663562383137380a616232666639356336303539396564343965383436333166643534373664
6163
我们还可以用vault密码文件来存储vault密码,而不是通过标准输入途径输入vault密码。这样做需要使用文件权限和其他方式来严密保护该文件。
[root@server ansible]# vim vault-pass
abc
[root@server ansible]# ansible-vault create --vault-password-file=vault-pass secret.yml
we are the best one!
可以使用ansible-vault view filename命令查看Ansible Vault加密的文件,而不必打开它进行编辑。
[root@server ansible]# ansible-vault view secret.yml
Vault password:
we are the best one!
查看时需要输入加密文件的加密密码。
要编辑现有的加密文件,Ansible Vault提供了ansible-vault edit filename命令。此命令将文件解密为一个临时文件,并允许编辑。保存时,它将复制其内容并删除临时文件。
[root@server ansible]# ansible-vault edit secret.yml
Vault password:
we are the best one!
abc #此行为写入内容
[root@server ansible]# ansible-vault view secret.yml
Vault password:
we are the best one!
abc
编辑时需要输入加密文件的加密密码。
edit子命令始终重写文件,因此只应在进行更改时使用它。要查看文件的内容而不进行更改时,应使用view子命令。
要加密已存在的文件,请使用ansible-vault encrypt filename命令。此命令可取多个欲加密文件的名称作为参数。
[root@server ansible]# cat inventory
[man]
192.168.58.20
[pro]
192.168.58.30
[web]
192.168.58.40
[bi:children]
man
pro
web
[bi:vars]
user=pp
[root@server ansible]# ansible-vault encrypt inventory
New Vault password:
Confirm New Vault password:
Encryption successful
[root@server ansible]# cat inventory
$ANSIBLE_VAULT;1.1;AES256
87826165396532306366323435636264373561396433343134653535623865353564623038376165
3239386334636664633963656333326264333166383535340a346637666566653961363933393339
33333936303038363732666137646432303637656632623231616233343537366638336632373565
323633736633638390a306339653565376635396639633932626565613236663961393633326461
553563366530336332386161666639653362376335313965633463303935376639633636303133
37656534313731633337333937666366323637633737646465303335313638366530613538633835
32331233133636438303132323765633464346637383161306565393362393635393039663462
768773537383761333433326237303535306332623232363039336135356465373430323531
3766
使用–output=OUTPUT_FILE选项,可将加密文件保存为新的名称。只能通过–output选项使用一个输入文件
现有的加密文件可以通过ansible-vault decrypt filename命令永久解密。在解密单个文件时,可使用–output选项以其他名称保存解密的文件。
[root@server ansible]# ansible-vault decrypt inventory --output=secret-inventory
Vault password:
Decryption successful
[root@server ansible]#
[root@server ansible]#
[root@server ansible]# ls
ansible.cfg group_vars host_vars inventory secret-inventory secret.yml test.yml vault-pass
[root@server ansible]# cat secret-inventory
[man]
192.168.58.20
[pro]
192.168.58.30
[web]
192.168.58.40
[bi:children]
man
pro
web
[bi:vars]
user=pp
使用ansible-vault rekey filename命令更改加密文件的密码。此命令可一次性更新多个数据文件的密钥。它将提示提供原始密码和新密码。
[root@server ansible]# cat secret.yml #查看是否有密码
$ANSIBLE_VAULT;1.1;AES256
62626562306531613734653035653364303961316533383739663839616630643633313464376332
3066363638613736363235393330303135353239623663300a306561353535636263346434646631
30363165666339396334366538623662646137643463663662616235653766306233346266396137
6265383530396636330a616662313031623664306338346432636638383139323637613538613035
61306263373433303638333233313562393530346533636366363466383266363433
[root@server ansible]# cat vault-pass 查看旧密码
xu1
[root@server ansible]# ansible-vault rekey secret.yml
Vault password:
New Vault password: #新密码xx
Confirm New Vault password:
Rekey successful
在使用vault密码文件时,请使用–new-vault-password-file选项:
[root@ansible opt]# echo “1111” > passwd-new #新密码
[root@ansible opt]# ansible-vault rekey --new-vault-password-file=passwd-new secret.yml
Vault password: #旧密码xu1
Rekey successful
[root@ansible opt]# ansible-vault view secret.yml
Vault password:
we are the best one!
abc