当前位置: 首页 > news >正文

【网络运维】Playbook部署文件:Files模块库&JINJA2模板

部署文件到受管主机

实验环境

[furongwang@controller ~]$ mkdir web && cd web[furongwang@controller web]$ cat > ansible.cfg <<'EOF'
[defaults]
remote_user = furongwang
inventory = ./inventory[privilege_escalation]
become = True
become_user = root
become_method = sudo
become_ask_pass = False
EOF[furongwang@controller web]$ cat > inventory <<'EOF'
controller
node1
node2
node3
node4
EOF

Files模块库

红帽Ansible引擎本身内置附带了大型模块集合(模块库),为了便于整理、记录和管理这些模块,已根据文档中的功能以及在系统上安装的时间将它们分成多个组。

Files 模块库包含的模块允许您完成与Linux文件管理相关的大多数任务,如创建、复制、编辑和修改文件的权限和其他属性,下表列出了常用的Files模块库中使用的模块。

  • file:设置权限、所有权、SELinux上下文以及常规文件、符号链接、硬链接和目录的时间戳等属性。此模块还可以创建或删除常规文件、符号链接、硬链接和目录。
  • sefcontext,设置持久selinux上下文。
  • lineinfile:确保特定行位于某个文件中,或使用反向引用正则表达式来替换现有行。
  • replace:查找文件中行,一次性替换成对应内容。
  • blockinfile:插入、更新或删除多行文本块。
  • stat:检索文件的状态信息,类似于Linux stat命令。
  • copy:将文件从本地或远程计算机复制到受管节点上的某个位置。
  • synchronize:围绕rsync命令的一个程序,可加快和简化常见任务。
  • fetch:用于从远程计算机获取文件到控制节点。
file 模块

示例1: 创建文件或修改文件属性

---
- hosts: node1gather_facts: notasks:- name: Touch a file and set permissionsfile:path: /tmp/testfileowner: furongwanggroup: wheelmode: "640"state: touch

mode选项: 必须使用前导0 (‘0644’ or ‘01777’) 或者引起来 (‘‘644’’ or ‘‘1777’’) 。如果直接写640,则会640当做10进制,并转换成二进制1 010 000 000,最终文件权限是-w- — --T。

示例2: 创建目录

---
- hosts: node1gather_facts: notasks:- name: create directoryfile:path: /webdevowner: apachegroup: apachemode: 0755state: directory                 

示例3: 删除文件

---
- hosts: node1gather_facts: notasks:- name: delete file file:path: /tmp/testfilestate: absent
sefcontext 模块

selinux库中添加默认规则。

示例:

---
- hosts: node1gather_facts: notasks:- sefcontext:target: '/samba(/.*)?'setype: samba_share_tstate: present

注意:

  • sefcontext模块是修改selinux 库规则,并不会立刻应用于文件,relabel时候才会生效。
  • file模块会立刻应用于文件。
lineinfile 模块

示例1:确保文件中存在特定行,没有对应文本时在最后一行加入

---
- hosts: node1gather_facts: notasks:- name: add linelineinfile:path: /tmp/testfileline: 'Add this line to file'state: present

在这里插入图片描述
还可以在特定位置插入:

  • insertbefore,最后一个匹配到前插入

    ---
    - hosts: node1gather_facts: notasks:- name: add linelineinfile:path: /etc/httpd/conf/httpd.confline: 'Listen 82'insertbefore: 'Listen 80'state: present
    
  • insertafter,最后一个匹配到后插入

    ---
    - hosts: node1gather_facts: notasks:- name: add linelineinfile:path: /etc/httpd/conf/httpd.confline: 'Listen 82'insertafter: 'Listen 80'state: present
    

示例2:替换文本行


---                   
- hosts: node1        gather_facts: no    tasks:              - name: replace linelineinfile:     path: /tmp/testfileregexp: 'Add' line: 'replace'state: present

在这里插入图片描述
原包含Add的行“Add this line to file” 被替换。

---
- hosts: node1gather_facts: notasks:- name: add linelineinfile:path: /etc/httpd/conf/httpd.confline: '#Listen 80'regexp: '^Listen 80'state: present
  • 有相同行时,优先替换靠后的行。

示例3:替换成多行文本

---
- hosts: node1gather_facts: notasks:- name: add linelineinfile:path: /tmp/testfileline: |line 1line 2regexp: 'replace'state: present 
replace 模块

该模块使用正则表达式匹配内容,将匹配的内容替换成指定的内容。匹配的多个地方都会被替换掉。

示例:

---
- hosts: node1gather_facts: notasks:- name: replace multi linereplace:path: /tmp/testfileregexp: '^Hello World.*'replace: 'Hello furongwang'
blockinfile 模块

示例:将文本块添加到现有文件

---
- hosts: node1gather_facts: notasks:- name: add block lines to fileblockinfile:path: /tmp/testfileblock: |line 1 in fileline 2 in fileaaline 3 in file sssstate:  present

添加的内容如下,会在第一行和最后一行额外添加注释。

# BEGIN ANSIBLE MANAGED BLOCK
line 1 in file
line 2 in fileaa
line 3 in file sss
# END ANSIBLE MANAGED BLOCK
stat 模块

stat 模块检索文件的信息,类似于Linux stat命令。 参数提供检索文件属性、确定文件校验和等功能。

stat 模块返回一个包含文件状态数据的值的散列字典,允许您使用单独的变量引用各条信息。

示例:

---
- hosts: node1gather_facts: notasks:- stat:path: /tmp/testfilechecksum_algorithm: md5register: result- debug:msg: "/tmp/testfile md5 is {{ result.stat.checksum }}"- debug:var: result
copy 模块

示例1:将控制节点上文件拷贝到受管理节点,类似于Linux中scp命令。

---
- hosts: node1gather_facts: notasks:- name: copy /tmp/testfile to remote nodecopy:src: /tmp/testfiledest: /tmp

说明:此模块假定设置了force: yes,强制覆盖远程文件,类似scp命令。如果设置force: no, 则不会出现覆盖。

示例2:写入字符串到文件

---
- hosts: node1gather_facts: notasks:- name: write string into /tmp/testfilecopy:content: "hello world\n"dest: /tmp/testfile
synchronize 模块

synchronize 模块是一个围绕 rsync 工具的打包程序,它简化了playbook中的常见文件管理任务。

rsync工具必须同时安装在本地和远程主机上。默认情况下,在使用synchronize模块时, “本地主机”是同步任务的源主机, 而 “目标主机”是synchronize连接到的主机。

示例1:同步文件

---
- hosts: node1gather_facts: notasks:- name: synchronize filesynchronize:src: /tmp/testfiledest: /tmp/

示例2:同步目录

---
- hosts: node1gather_facts: noremote_user: roottasks:- name: synchronize directorysynchronize:src: /etc/sysconfigdest: /tmp/
fetch 模块

从受管节点检索文件,例如将被管理节点文件先取到控制节点,然后用于分发到其他节点。诸如SSH公钥之类的文件。

示例:

---
- hosts: node1gather_facts: notasks:- name: fetch file from remote nodefetch:src: /tmp/testfiledest: /tmp

文件保存在:/tmp/node1/tmp/testfile。

[furongwang@controller web]$ tree /tmp/node1
/tmp/node1
└── tmp└── testfile1 directory, 1 file

使用JINJA2模板部署文件

JINJA2 模板介绍

Jinja2 模板是功能强大的工具,可用于自定义要在受管节点上部署的配置文件。 创建Jinja2 模板后,可以通过template模块部署到受管节点上, 该模块支持将控制节点中的本地文件转移到受管节点。

示例1:部署web服务器,主页内容显示为Welcome to HOSTNAME。HOSTNAME为受管主机完全主机名。

playbook内容如下:

---
- name: Enable intranet serviceshosts: node1tasks:- name: ensure latest version of httpd yum:name: httpdstate: latest- name: test html page is installedtemplate:   # template模块: 复制文件到受管主机时,根据jinja2语法替换src: index.html.j2   # 指定 Jinja2 模板来源dest: /var/www/html/index.html   # 指定要在目标主机上创建的文件- name: httpd enabled and runningservice:name: httpdenabled: truestate: restarted
...

在文件目录下创建 index.html.j2 ,内容如下:

Welcome to {{ ansible_fqdn }}

剧本执行完成后,index.html内容如下:

Welcome to node1.furongwang.cloud

template模块,与copy模块类似,允许指定已部署文件的所有者(拥有该文件的用户) 、组、权限和 SELinux上下文 。

示例2:推送 ssh 服务配置文件。 sshd_config.j2内容如下:

# {{ ansible_managed }}
# DO NOT MAKE LOCAL MODIFICATIONS TO THIS FILE AS THEY WILL BE LOST
Port {{ ssh_port }}
ListenAddress {{ ansible_facts['default_ipv4']['address'] }}HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
SyslogFacility AUTHPRIV
PermitRootLogin  {{ root_allowed }}
AllowGroups {{ groups_allowed }}AuthorizedKeysFile      /etc/.rht_authorized_keys .ssh/authorized_keys
PasswordAuthentication {{ passwords_allowed }}

playbook 参考

---
- name: config sshd servicehosts: node1vars:ssh_port: 1022root_allowed: "yes"groups_allowed: wheelpasswords_allowed: "yes"ansible_managed: "Ansible managed"tasks:- name: config sshd servicetemplate:src: sshd_config.j2dest: /root/sshd_config
Jinja2 模板语法

Jinja2 模板由多个元素组成:数据、变量和表达式。在呈现Jinja2模板时, 这些变量和表达式被替换为对应的值。模板中使用的变量可以在playbook的vars部分中指定,也可以使用受管主机FACTS。

变量和逻辑表达式置于分隔符之间:

  • {{ EXPR }},用于装载表达式,比如变量,运算表达式,比较表达式。
  • {% EXPR %},用于装载控制语句,比如iffor等。
  • {# #},用于装载注释,模板文件中的注释不会包含在最终生成文件中。
for 语句

Jinja2使用for语句来提供循环功能。

示例1:

---
- name: test templatehosts: node1vars:users:- tom- jack- Snoopy- lucytasks:- name: test templatetemplate:src: testfile.j2dest: /tmp/testfile
...

testfile.j2内容如下:

{% for user in users %}
{{ user }}
{% endfor %}

for用于声明循环,{% endfor %} 表示结束。user变量会遍历users变量中所有值。

生成的/tmp/testfile内容如下:

tom
jack
Snoopy
lucy

示例2: testfile.j2内容如下

{# for statement #}
{% for user in users %}
{{ loop.index }} - {{ user }}
{% endfor %} 

loop.index代表当前循环的索引号,从1开始到最后循环体的数量。例如循环体有12个,那么loop.index代表1,2,3,…,12。

生成的/tmp/testfile内容如下:

1 - tom
2 - jack
3 - Snoopy
4 - lucy

示例3: 部署myhosts

创建 playbook:

  • 使用模板文件hosts.j2在dev主机组中的主机上生成文件/etc/myhosts。

  • hosts.j2内容如下:

    127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 
    ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
    
  • 针对每个受管节点包含一行内容:

    127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 
    ::1 localhost localhost.localdomain localhost6 localhost6.localdomain610.1.8.10 controller.furongwang.cloud controller
    10.1.8.11 node1.furongwang.cloud node1 
    10.1.8.12 node2.furongwang.cloud node2 
    10.1.8.13 node3.furongwang.cloud node3 
    10.1.8.14 node4.furongwang.cloud node4
    

    注:清单主机名称的显示顺序不重要。

inventory 内容如下:

[controllers]
controller[dev]
node1[test]
node2[prod]
node3
node4

答案如下:

---
- name: /etc/myhosts is up to datehosts: alltasks:- name: Deploy /etc/myhoststemplate:src: hosts.j2dest: /etc/myhostswhen: inventory_hostname in groups.dev

文件目录下创建 hosts.j2,内容如下:

127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6{% for server in groups.all %}
{{ hostvars[server].ansible_default_ipv4.address }} {{ hostvars[server].ansible_fqdn }} {{ hostvars[server].ansible_hostname }}
{% endfor %}

说明:

  • hostvars是magic 变量,通过该变量引用其他受管主机facts。
  • [server]不能使用单引号,因为server作为变量处理,替换为all中主机。
  • play 必须针对所有主机执行,收集所有主机facts,因为模版需要引用所有主机的facts。
  • 只部署到dev主机组,使用when语句。groups.dev是magic变量,该变量获取dev主机组中主机清单。

示例4: num 变量引用方括号中列表

{% for num in [3,1,7,8,2] %}
{{ num }}
{% endfor %}

生成的文件内容如下:

3
1
7
8
2

示例5: range(3)代表 0 1 2,循环三次。

{% for num in range(3) %}
{{ num }}
{% endfor %}

生成的文件内容如下:

0
1
2

示例6: range(1,4,2),从1开始,到4结束,步长2。

{% for num in range(1,4,2) %}
{{ num }}
{% endfor %}

生成的文件内容如下:

1
3
if 语句

Jinja2使用if语句来提供条件控制。如果满足某些条件, 则在部署文件中放置一行。if语句判断条件同ansible中when语句。

示例1: 只要变量finished不是假值,那么输出finished变量值。

{% if finished %}
{{ finished }}
{% endif %}

示例2: 如果PORT定义了端口,那么使用该值,否则使用默认3306。

{% if PORT is defined %}
bind-address=0.0.0.0:{{ PORT }}
{% else %}
bind-address=0.0.0.0:3306
{% endif %}

示例3:

{% if 条件1 %}
...
{% elif 条件2 %}
...
{% elif 条件n %}
...
{% else %}
...
{% endif %}

{% elif 条件N %}可以多次使用。

示例4: for和if配合使用

{% for num in [7,1,5,3,9] if num>3 %}
{{ num }}
{% endfor %}

等同于:

{% for num in [7,1,5,3,9] %}
{% if num>3 %}
{{ num }}
{% endif %}
{% endfor %}

生成的文件内容如下:

7
5
9
表达式

示例1:

{{ 1 == 1 }}
{{ 2 != 2 }}
{{ 2 > 1 }}
{{ 2 >= 1 }}
{{ 2 < 1 }}
{{ 2 <= 1 }}

生成的文件内容如下:

True
False
True
True
False
False

示例2:

jinja2 test
{{ (2 > 1) or (1 > 2) }}
{{ (2 > 1) and (1 > 2) }}
{{ not true }}
{{ not True }}
{{ not false }}
{{ not False }}

生成的文件内容如下:

jinja2 test
True
False
False
False
True
True

示例3:

{{ 3 + 2 }}
{{ 3 - 4 }}
{{ 3 * 5 }}
{{ 2 ** 3 }}
{{ 7 / 5 }}
{{ 7 // 5 }}
{{ 17 % 5 }}

生成的文件内容如下:

5
-1
15
8
1.4
1
2

示例4:

jinja2 test
{{ 1 in [1,2,3,4] }}
{{ 1 not in [1,2,3,4] }}

生成的文件内容如下:

jinja2 test
True
False
模版注释

{# #},用于装载注释,模板文件中的注释不会包含在最终生成文件中。

示例:

{# 此处是注释 #}
{% for num in [7,1,5,3,9] %}
{% if num>3 %}
{{ num }}
{% endif %}
{% endfor %}

生成的文件内容如下:

7
5
9
ansible_managed 变量

为避免系统管理员修改Ansible部署的文件,最好在模板顶部包含注释,指示不应手动编辑该文件。

在/etc/ansible/ansible.cfg配置文件[defaults]块中有如下默认配置:

[defaults]
ansible_managed = Ansible managed

可使用ansible_managed变量来引用“Ansible managed” 字符串。

要想在jinja2 模板内,使用ansible_managed变量代表的字符串,使用下列语法:

{{ ansible_managed }}
http://www.lryc.cn/news/625793.html

相关文章:

  • 18650锂电池自动化生产线:智能集成提升制造效能
  • Qt猜数字游戏项目开发教程 - 从零开始构建趣味小游戏
  • 厚板数控矫平机的“第三堂课”——把视角拉远,看看它如何重塑整条制造链
  • AUTOSAR进阶图解==>AUTOSAR_SWS_FlashEEPROMEmulation
  • 星链之供应链:SpaceX供应链韧性密码,70%内部制造+模块化设计,传统航天企业如何追赶?
  • 数字孪生 :提高制造生产力的智能方法
  • 写代码的方式部署glm-4-9b-chat模型:gradio和api两种模式
  • python学习DAY46打卡
  • Apache ECharts 6.0.0 版本-探究自定义动态注册机制(二)
  • npm下的scratch(少儿编程篇)
  • 使用segment-anything将目标检测label转换为语义分割label
  • 零售行业新店网络零接触部署场景下,如何选择SDWAN
  • 【Proteus仿真】【51单片机】基于51单片机自动售货机12864屏幕
  • ICCV 2025 | 首个3D动作游戏专用VLA模型,打黑神话只狼超越人类玩家
  • 如何免费给视频加字幕
  • AndroidR车机系统Settings数据库增加非持久化存储键值方案-续
  • 国产!全志T113-i 双核Cortex-A7@1.2GHz 工业开发板—ARM + FPGA通信案例
  • 深入解析Spring MVC运行流程:从请求到响应的完整旅程
  • React学习(六)
  • Spring Cache 整合 Redis 实现高效缓存
  • Android音频学习(十三)——音量配置文件分析
  • proDAD VitaScene:专业视频转场特效滤镜软件
  • spring声明式事务,finally 中return对事务回滚的影响
  • 第12章 React生态工具链
  • 第14章 现代React特性
  • 在VSCode中进行Vue前端开发推荐的插件
  • Web3.0 时代的电商系统:区块链如何解决信任与溯源问题?
  • [Git] 如何拉取 GitHub 仓库的特定子目录
  • 神经网络训练过程详解
  • 20.2 QLoRA微调全局参数实战:高点击率配置模板+显存节省50%技巧