不废话,让我们直接开始!
什么需求?
- 操作对象是1台服务器SRV01,都有Python环境
- 需要在每台服务器上跑一些收集服务信息的命令
- 要把每个命令的输出分门别类保存在用户文件夹
本例中涉及到的知识点
- group_vars的使用
- 循环的使用
- 字典、列表的使用
开始整活
1. 创建工作目录
带“!”的目录,目录名请与下述保持一致。Ansible会自动从中读取所需内容。
pj/ (主目录)
|- site.yml
|- group_vars (!)/
|- all.yml
|- inventory (!)/
|- servers.ini
|- roles (!)
|- run_commands
|- tasks (!)/
|- main.yml
2. 编辑inventory
参考《简单的例子》,保留SRV01。这里不再赘述。
3. 编辑site.yml
说明见《简单的例子》,这里不再赘述。
---
- name: ANSIBLE TEST
hosts: my_servers
gather_facts: no
tasks:
roles:
- role: run_commands
4. 编辑group_vars
将以下内容写入pj/group_vars/all.yml
。
cmd_list:
uname: "uname -a"
date: "date"
其中字典键值uname
和date
将作为命令的索引。
5. 编辑Role
将以下内容写入pj/roles/run_commands/tasks/main.yml
。
- name: 执行命令
command: "{{ cmd_list[item] }}"
with_items: "{{ cmd_list.keys() }}"
register: cmd_return
- name: 保存文件
connection: local
# 不写connection的话文件会被存储到远程主机上
copy:
content: "{{ item.stdout }}"
dest: "{{ lookup('env', 'HOME') }}/{{ item.item }}.txt"
loop:
"{{ cmd_return.results }}"
这里说明几件事:
- 推荐用
loop
,它和with_items
功能相同。而且据说后者快要被淘汰了。。 - 你可能看不懂
loop
循环的语法,但你应该看得懂Python。下面的Python语句和Playbook是一个意思:
# Python
for item in ['A', 'B', 'C']:
print(item)
# Playbook
debug:
msg: {{ item }}
loop:
- "A"
- "B"
- "C"
- 字典索引可以用
dict.key
形式,也可以用Python的dict[key]
形式。 - 如果你用
msg
打印了命令执行结果cmd_return
就会明白,cmd_return
是一个类似于下面这个结构的字典。这也就是使用cmd_return.results
作为循环项目的原因。
{
"changed": true,
"msg": "All items completed",
"results": [{...}, {...}, ...]
// 其中{...}保存着每个命令的执行结果以及相关信息
}
6. 执行脚本🎉
至此,实现需求所需要的条件都已具备。现在切回主目录pj/
中,执行以下命令执行Ansible Playbook。
ansible-playbook -i ./inventory/servers.ini ./site.yml
你会看到在~/
中创建了date.txt
和uname.txt
两个文件,内容为date
和uname -a
在远程主机上的执行结果。