管理变量和事实
将 playbook 中的某些值使用变量代替,从而简化 playbook 的编写
ansible中的变量可能包含下面这些值:
要创建的用户、
要安装的软件包、
要重启的服务、
要删除的文件、
要从互联网检索的文档
变量命名:
变量名称必须以字母开头,并且只能含有字母、数字和下划线
错误 | 正确 |
---|---|
web server | web_server |
test.file | test_file |
1st file | file1 |
变量定义:
三个范围级别
变量设置范围 | 说明 |
---|---|
全局范围: | 从命令行或 ansible 配置设置的变量 |
play 范围: | 在 play 和相关结构中设置的变量 |
主机范围: | 由清单、事实收集或注册的任务 |
在主机组和个别主机上设置的变量 '如果多个级别上定义了相同名称的变量,优先采用级别最高的变量,窄范围优先于广范围。
由此可见如果三个同时设置了,会生效的就是设置在playbook中的play范围
playbook 中的变量
如何在 playbook 中定义变量
1.常见方式:在 playbook 开头的 vars 块中:
---
- host: all
vars:
user: redhat
home: /home/redhat
2.在外部文件定义 playbook 变量
首先在playbook开头写变量模块,并指定要读取的含有变量的文件名
---
- hosts: all
vars_files:
- vars/users.yml
定义在外部文件后,需要去建立 vars 目录,然后在 vars 目录下编写指定的文件,在文件内写入变量内容
vim users.yml
user: redhat
home: /home/redhat
如何在 playbook 中使用变量
首先在playbook中编写变量模块,我们来测试使用变量创建用户
---
- hosts: all
vars:
user: testuser
tasks:
- name: Create user {{ user }}
user:
name: "{{ user }}"
...
注意: 当变量用作开始一个值的第一元素时,必须使用引号
主机变量和组变量
直接应用于主机的清单变量分为两大类:
1.主机变量:应用于特定主机
2.组变量:应用于一个主机组或一组主机组中的所有主机
主机变量优先于组变量,但是 playbook 中定义的变量比这两者更高
定义主机变量和组变量有两种方法:
方法一:
在清单文件中直接定义
server1.example.com 的 ansible_user 主机变量:
[webservers]
server1.example.com ansible_user=redhat
定义主机组的 user 变量:
[webservers]
server1.example.com
server2.example.com
[websevers:vars]
user=redhat
定义嵌套组 user 变量:
[webservers]
server1.example.com
server2.example.com
[dbsevers]
node1.example.com
node2.example.com
[severs:chllidren]
websevers
dbsevers
[severs:vars]
user=redhat
这种做法使的清单文件难以处理,在同一文件中混合提供主机和变量信息,语法也过时,比较旧,不建议采用
方法二:
使用目录填充主机和组变量
定义主机和主机组变量的首选做法时与清单文件或目录相同的工作目录中,创建 group_vars 和 host_vars 两个目录,这两个目录分别包含用于定义组变量和主机变量的文件
组变量:创建 group_vars 目录,在目录下建立对应组名称的yaml文件
如 vim group_vars/websevers.yml ,在文件里写入变量 user=redhat
主机变量:创建 host_vars ,在目录下建立对应主机名称的yaml文件
如 vim host_vars/node1.example.com.yml 。
所以一个成熟的项目目录中应包含:
ansible.cfg、group_vars、host_vars、inventory、playbook.yml
从命令行覆盖变量
清单变量可以被 playbook 中设置的变量覆盖 两者又可通过命令行参数覆盖
使用数组作为变量
users:
lilei:
first_name: lei
last_name: li
home_dir: /home/lilei
hanmeimei:
first_name: meimei
last_name: han
home_dir: /home/hanmeimei
访问方式:方式一
users.lilei.first_name
users.hanmeimei.home_dir
方式二
users[‘lilei’][‘first_name’]
users[‘hanmeimei’][‘home_dir’]
使用已注册变量捕获命令输出
管理员可以使用 register 语句捕获命令输出
用法操作:
使用playbook去给受管主机安装apache服务
---
- name: Install a packages
hosts: pc1.hehe.com
tasks:
- name: Install
yum:
name: httpd
state: installed
register: install_result
- debug: var=install_result
...
经过register命令输出,使用debug展示出具体执行指令中显示的安装包等
管理机密
目标:使用 ansible vault 加密敏感变量,并运行 vault 加密变量文件的 playbook
ansible vault
ansible 可能需要访问密码或者 api 密钥等敏感数据,以便配置主机。
加密解密工具,命令:ansible-vault ,ansible vault 不实施自有的加密函数,而使用外部 python 工具集。
如何创建加密文件
命令: ansible-vault create fliename
例:ansible-vault create secret.yml,创建一个加密的yuml文件,需要先设置密码,然后进行编辑,保存文件后就无法使用 cat 命令查看
通过指定文件里的密码进行加密,需要加载密码的文件必须是存在的,文件中必须先写入密码
命令: ansible-vault create --vault-password-file=password_list secret.yml
如何查看加密文件
命令:ansible-vault view filename
如何编辑加密文件
原理:将文件解密为一个临时文件,并编辑;保存时,复制内容并删除临时文件
命令: ansible-vault edit filename
edit 命令始终重写文件,因此只有在更改文件时使用,查看尽量使用 view
如何加密存在的文件
命令:ansible-vault encrypt filename (filename可以写入多个)
可以结合文件密码加密命令使用:ansible-vault encrypt --vault-password-file=password_list install.yml
参数:–output=filename ,将加密文件保存为新的名称,但使用此参数时输入文件只能是一个
如何解密加密的文件
命令:ansible-vault decrypt filename
测试:ansible-vault decrypt secret.yml --output=secrypt_test.yml ,解密文件并重命名
如何更改加密文件密码
命令: ansible-vault rekey filename
此命令可以一次更新多个文件密码
测试:ansible-vault rekey secret.yml ,更改密码时先需要输入旧密码
playbook 和 ansible vault
对于加密的playbook文件,运行时,没有密码则报错
对于加密的playbook,交互式提供密码需要使用命令:
ansible-playbook --vault-id @prompt filename.yml
执行命令输入加密的密码就可以进行执行操作
也可以将秘密存在文件中,然后使用命令进行调用文件中的密码,直接执行playbook
ansible-playbook --vault-password-file=password user.yml
管理事实
事实包括:主机名称、内核版本、网络借口、IP 地址等
描述 ansible 事实
查看主机的事实信息
写playbook来进行查看
---
- name: Fact Show
hosts: all
tasks:
- name: Print all facts
debug:
var: ansible_facts #ansible_facts是系统中的变量名,不需要自己定义变量
...
执行后会显示出所有的主机事实信息
使用字典的方式查询事实中动态的值,如主机名、ip地址等信息
---
- name: Fact Show
hosts: all
tasks:
- name: Print all Facts
debug:
var: ansible_facts
- hosts: all
tasks:
- name: Print choose facts
debug:
msg:
This IPv4 address of {{ ansible_facts.fqdn }} is {{ ansible_facts.all_ipv4_addresses }}
...
ansible_facts.fqdn 和 ansible_facts.all_ipv4_addresses 这两个变量就是我们根据ansible_facts查看出
参数 -m setup 可以查看主机的事实信息
提升执行速度,可以关闭playbook执行过程中事实收集
正常执行playbook时会有 Gathering Facts 模块去执行
可以进行参数设置来关闭这个模块的执行:gather_facts: no
创建自定义事实
可以使用 INI 格式或者 JSON 格式
INI 格式:
[packages]
web_package = httpd
db_package = mariadb-server
[users]
user1 = testuser
user2 = redhat
JSON格式:
{
"packages": {
"web_package": "httpd",
"db_package": "mariadb-server"
},
"users": {
"user1": "testuser",
"user2": "redhat"
}
}
因为自定义格式我们不能使用ymal格式,所以使用最接近计算机语言的json为佳。
如何将自定义事实写入配置?
创建目录:mkdir /etc/ansible/facts.d
在该目录下建立文件:vim custom.fact,必须是以 .fact 结尾的文件
然后写入JOSN格式的内容
然后我们执行:ansible localhost -m setup,查看主机事实就可以看到我们写入的自定义事实
调用自定义事实的方式和默认事实的方式相同
使用魔法变量
常用的有四个 | 说明 |
---|---|
hostvars | 包含受管主机的变量,可以用于获取另一台受管主机的变量的值 |
group_names | 列出当前受管主机所属的所有组 |
groups | 列出清单中的所有组和主机 |
inventory_hostname | 包含清单中配置的当前受管主机的主机名称 |
例:可以使用 hostvars 变量去获取其他受管主机的变量
ansible localhost -m debug -a ‘var=hostvars[“pc1.hehe.com”]’