环境版本说明
- RedHat9 [Red Hat Enterprise Linux release 9.0]
- Ansible [core 2.13.3]
- Python [3.9.10]
- jinja [3.1.2]
1. 修改文件并将其复制到主机
文件模块介绍
- 在受管主机上创建文件和目录
- 复制文件或内容到受管主机
- 从受管主机复制文件到管理主机
- 修改文件内容、查看文件状态、修改文件属性、文件同步
ansible.builtin的常用文件模块
模块名 | 说明 | 类似Linux中命令 |
---|---|---|
blockinfile | 插入、更新、删除、自定义标记的多行文本块,可以同时插入多行文本 | |
file | 设置权限、所有者、SElinux上下文及常规文件、符号连接、硬链接等 | touch、mkdir、chown、chmod、rm |
copy | 远程copy,类似file模块,可以设置文件属性、SELinux上下文 | cp、echo重定向到文件 |
fetch | 和copy类似,相反的工作方式,从远端拷贝到控制主机 | |
lineinfile | 更改文件中特定一行内容 | sed、grep |
stat | 检测文件状态,类似Linux中的stat命令 | stat |
synchronize | 围绕rsync一个打包程序,备份 | rsync |
EXAMPLE-创建目录
在node1上创建一个目录,目录路径为/tmp/dir1,所有者和所属组分别为greg和wheel。
[Step1]:
编写playbook,文件内容如下:
vim newdir.yml
# 写入以下内容
---
- name: play1
hosts: node1
tasks:
- name: Change file ownership, group and permissions
ansible.builtin.file:
path: /tmp/dir1
owner: greg
group: wheel
state: directory
mode: '0644'
[Step2]:
验证playbook语法格式
ansible-navigator run newdir.yml -m stdout --syntax-check
[Step3]:
运行playbook
ansible-navigator run newdir.yml -m stdout
[Step4]:
验证:查看node1主机上创建的目录
ansible node1 -m shell -a 'ls -l /tmp | grep dir1'
EXAMPLE-删除目录
在node1上创建一个目录,目录路径为/tmp/dir1,所有者和所属组分别为greg和wheel。
[Step1]:
编写playbook,文件内容如下:
vim rmdir.yml
# 文件内容如下
---
- name: play1
hosts: node1
tasks:
- name: Recursively remove directory
ansible.builtin.file:
path: /tmp/dir1
state: absent
[Step2]:
验证playbook语法格式
ansible-navigator run rmdir.yml -m stdout --syntax-check
[Step3]:
运行playbook
ansible-navigator run rmdir.yml -m stdout
[Step4]:
验证:查看node1主机上创建的目录
ansible node1 -m shell -a "ls /tmp"
EXAMPLE-针对文本的中特定行
修改node1的SELinux模式,永久修改为disabled
[Step1]:
编写playbook,文件内容如下:
vim selinux.yml
# 文件内容如下
---
- name: play1
hosts: node1
tasks:
- name: Ensure SELinux is set to disabled mode
ansible.builtin.lineinfile:
path: /etc/selinux/config # 文件路径
regexp: '^SELINUX=' # 匹配表达式
line: SELINUX=disabled # 修改的后的文件内容
[Step2]:
验证playbook语法格式
ansible-navigator run selinux.yml -m stdout --syntax-check
[Step3]:
运行playbook
ansible-navigator run selinux.yml -m stdout
##
EXAMPLE-网络下载文件
在node1上下载文件
[Step1]:
编写playbook,文件内容如下:
vim download.yml
# 文件内容如下
---
- name: play1
hosts: node1
tasks:
- name: Download foo.conf
ansible.builtin.get_url:
url: http://content/rhel9.0/x86_64/dvd/BaseOS/Packages/zstd-1.5.1-2.el9.x86_64.rpm # 下载的URL
dest: /tmp/zstd-1.5.1-2.el9.x86_64.rpm # 保存路径和文件名
mode: '0440' # 下载文件后设置的权限
[Step2]:
验证playbook语法格式
ansible-navigator run download.yml -m stdout --syntax-check
[Step3]:
运行playbook
ansible-navigator run download.yml -m stdout
[Step4]:
验证:查看node1主机上下载的文件
ansible node1 -m shell -a 'ls -l /tmp | grep zstd*'
2. 使用jinja2模板部署自定义文件
Ansible的jinja2模板,也就是template模块。template模块和copy模块作用基本一样,都是将某个文件复制到受管主机上,但是区别在于template模块可以获取变量的值和使用循环,而copy则是原封不动的将文件内容复制。
- 管理文件一般使用的模块:copy、file、blockinfile、lineinfile
- 进阶的文件管理方式是使用 jinja2 语法制作模板文件来生成最终使用的配置文件
- jinja2 模板文件内,可以通过多种方式组成,如:魔法变量、事实变量、普通字符、控制语句等
- 使用 jinja2 模板的方法是,先构建 jinja2 模板,再通过 template 模块将jinja2 模板同步至受管主机
- 构建的模板文件通常名称自定义,后缀为
.j2
EXAMPLE-普通jinja模板
在node1上生成文件,文件内容类似hosts文件
[Step1]:
编写jinja2文件,文件内容如下:
vim hosts.j2
# 文件内容如下
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
{# 注释信息 #} # 注释语句
192.168.10.1 {{ ansible_hostname }} # 事实变量
192.168.11.1 {{ ansible_nodename }} # 事实变量
[Step2]:
编写playbook文件,文件内容如下:
vim hosts.yml
# 文件内容如下
---
- name: play1
hosts: node1
tasks:
- name: Template a file to /tmp/hosts
ansible.builtin.template:
src: hosts.j2 # jinja2 模板文件路径
dest: /tmp/hosts # 上传路径以及文件名
[Step3]:
验证playbook语法格式
ansible-navigator run hosts.yml -m stdout --syntax-check
[Step4]:
运行playbook
ansible-navigator run hosts.yml -m stdout
[Step5]:
验证:查看node1文件内容
ansible node1 -m shell -a "cat /tmp/hosts"
控制结构-使用循环
shell语法下实现简单循环
for user in list;do
cmd
done
使用jinja2模板
{% for user in list %}
{{ user }}
{% endfor %}
EXAMPLE:循环输出清单文件中的所有主机至文件中
[Step1]:
测试变量输出
ansible node1 -m debug -a var=groups.all
[Step2]:
编写jinja2文件,文件内容如下:
vim fors.j2
# 文件内容如下
{% for host in groups.all %}
{{ host }}
{% endfor %}
[Step3]:
编写playbook文件,文件内容如下:
vim fors.yml
# 文件内容如下
---
- name: play1
hosts: node1
tasks:
- name: Template a file to /tmp/host
ansible.builtin.template:
src: fors.j2
dest: /tmp/host
[Step4]:
验证playbook语法
ansible-navigator run fors.yml -m stdout --syntax-check
[Step5]:
运行playbook
ansible-navigator run fors.yml -m stdout
[Step6]:
验证:查看node1主机上的host文件内容
ansible node1 -m shell -a "cat /tmp/host"
控制结构-复杂引用
制作真实的hosts文件
[Step1]:
调用魔法变量hostvars,重定向到文本文件中,方便查询
vim demo.yml
# 写入下列内容
---
- name: play1
hosts: node1
tasks:
- ansible.builtin.debug:
var: hostvars
# 运行playbook
ansible-navigator run demo.yml -m stdout > demo.txt
[Step2]:
查询IP地址、IQN完全合格域名、主机名
[Step3]:
编写jinja2文件,文件内容如下:
vim host.j2
# 文件内容如下
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
{% for host in groups.all %}
{{ hostvars[host].ansible_default_ipv4.address }} {{ hostvars[host].ansible_fqdn }} {{ hostvars[host].ansible_hostname }}
{% endfor %}
[Step3]:
编写Playbook文件,文件内容如下:
vim host.yml
# 文件内容如下
---
- name: play1
hosts: all
tasks:
- name: Template a file to /tmp/host
ansible.builtin.template:
src: host.j2
dest: /tmp/host
when: inventory_hostname == 'node1'
[Step4]:
验证playbook语法
ansible-navigator run host.yml -m stdout --syntax-check
[Step5]:
运行playbook
ansible-navigator run host.yml -m stdout
[Step6]:
验证:查看node1主机上的host文件内容
ansible node1 -m shell -a "cat /tmp/host"
控制结构-条件语句
EXAMPLE:当finished的值为True时,才将result变量导入到playbook中
{% if finished %}
{{ result }}
{% endif %}
更改输出格式
EXAMPLE1:指定输出格式为json
{{ out_var | to_json }}
EXAMPLE2:指定输出格式为yaml
{{ out_var | to_yaml }}
EXAMPLE3:指定输出格式为利于人类阅读的json格式
{{ out_var | to_nice_json }
EXAMPLE4:指定输出格式为利于人类阅读的yaml格式
{{ out_var | to_nice_yaml }}