Orange的运维学习日记--45.Ansible进阶之文件部署
Orange的运维学习日记–45.Ansible进阶之文件部署
文章目录
- Orange的运维学习日记--45.Ansible进阶之文件部署
- 实验环境
- 文件管理模块概览
- file 模块
- sefcontext 模块
- lineinfile 模块
- replace 模块
- blockinfile 模块
- stat 模块
- copy 模块
- synchronize 模块
- fetch 模块
- Jinja2 模板部署文件
- template 模块
- 示例:部署 Web 服务器首页
- 示例:配置 SSH 服务
- Jinja2 模板语法
- for 循环
- if 条件
- 常用表达式
- 模板注释
- ansible_managed 变量
- 过滤器(filters)
实验环境
在控制节点创建 web
目录并配置 Ansible 基础文件
mkdir web && cd webcat > ansible.cfg <<'EOF'
[defaults]
remote_user = laoma
inventory = ./inventory[privilege_escalation]
become = True
become_user = root
become_method = sudo
become_ask_pass = False
EOFcat > inventory <<'EOF'
controller
node1
node2
node3
node4
EOF
上述配置指定远程用户、主机清单路径和提升权限的方式
文件管理模块概览
Ansible 的 Files 模块库涵盖了大部分与 Linux 文件和目录管理相关的操作,包括创建、复制、修改权限,以及与 SELinux 上下文相关的设置
模块名称 | 功能描述 |
---|---|
file | 创建或删除文件、目录、符号链接和硬链接;设置权限、所有权、SELinux 上下文和时间戳 |
sefcontext | 在 SELinux 策略库中添加或移除持久上下文规则 |
lineinfile | 确保指定行在文件中存在;根据正则表达式插入、替换或删除行 |
replace | 使用正则表达式一次性替换文件中所有匹配行 |
blockinfile | 插入、更新或移除多行文本块;自动添加管理注释 |
stat | 检索文件或目录状态信息;返回权限、校验和等属性 |
copy | 将本地文件或字符串内容复制到受管节点;支持权限和上下文设置 |
synchronize | 基于 rsync 同步文件或目录;支持增量复制和排除规则 |
fetch | 从受管节点拉取文件到控制节点;保持主机子目录结构 |
file 模块
用于在受管节点上创建、删除或修改常规文件、目录、符号链接和硬链接,并设置权限、所有权、SELinux 上下文和时间戳
常用参数
path
:目标文件或目录路径state
:touch
、directory
、absent
、link
等owner
/group
:设置文件所有者和所属组mode
:权限掩码,需带前导零或引号(如'0644'
或01777
)seuser
/setype
:SELinux 用户和类型,仅在启用 SELinux 时使用
示例:创建文件并设置权限
---
- hosts: node1gather_facts: notasks:- name: Touch a file and set permissionsfile:path: /tmp/testfileowner: laomagroup: wheelmode: '0640'state: touch
示例:创建目录
---
- hosts: node1gather_facts: notasks:- name: Create directoryfile:path: /webdevowner: apachegroup: apachemode: '0755'state: directory
示例:删除文件
---
- hosts: node1gather_facts: notasks:- name: Delete filefile:path: /tmp/testfilestate: absent
sefcontext 模块
在 SELinux 策略库中添加或移除持久上下文规则,修改后需执行 relabel 操作才生效
示例:为 Samba 共享目录添加上下文规则
---
- hosts: node1gather_facts: notasks:- name: Add persistent SELinux contextsefcontext:target: '/samba(/.*)?'setype: samba_share_tstate: present
注意
sefcontext
仅修改策略,文件上下文需通过restorecon
或系统重标记后才真正应用file
模块修改文件时会立即生效
lineinfile 模块
确保目标文件包含特定行,或根据正则表达式替换、插入或删除行
示例:在文件中添加一行
---
- hosts: node1gather_facts: notasks:- name: Add line to filelineinfile:path: /tmp/testfileline: 'Add this line to file'state: present
在指定位置插入
insertbefore
:在最后一个匹配前插入insertafter
:在最后一个匹配后插入
---
- hosts: node1gather_facts: notasks:- name: Insert Listen portlineinfile:path: /etc/httpd/conf/httpd.confline: 'Listen 82'insertafter: 'Listen 80'state: present
根据正则替换已有行
---
- hosts: node1gather_facts: notasks:- name: Replace Add with replacelineinfile:path: /tmp/testfileregexp: 'Add'line: 'replace'state: present
插入多行文本
---
- hosts: node1gather_facts: notasks:- name: Insert multi-line blocklineinfile:path: /tmp/testfileline: |line 1line 2regexp: 'replace'state: present
replace 模块
使用正则表达式匹配并替换文件中所有出现的内容
示例:将以 “Hello World” 开头的行替换为单行文本
---
- hosts: node1gather_facts: notasks:- name: Replace Hello World linesreplace:path: /tmp/testfileregexp: '^Hello World.*'replace: 'Hello Laoma'
blockinfile 模块
插入或移除一段多行文本块,并自动添加管理注释
示例:向文件追加一段受 Ansible 管理的文本块
---
- hosts: node1gather_facts: notasks:- name: Add managed block 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 模块
检索文件或目录的状态信息,返回包含权限、属主、大小、校验和等字段的字典
示例:获取文件 MD5 校验和并打印结果
---
- hosts: node1gather_facts: notasks:- stat:path: /tmp/testfilechecksum_algorithm: md5register: result- debug:msg: "/tmp/testfile md5 is {{ result.stat.checksum }}"- debug:var: result
copy 模块
将本地文件或内容复制到受管节点,支持覆盖控制和权限设置
示例:将控制节点 /tmp/testfile
复制到远程节点
---
- hosts: node1gather_facts: notasks:- name: Copy file to remote nodecopy:src: /tmp/testfiledest: /tmp
示例:直接写入字符串到目标文件
---
- hosts: node1gather_facts: notasks:- name: Write string into filecopy:content: "hello world\n"dest: /tmp/testfile
synchronize 模块
基于 rsync
工具提供增量同步功能,简化目录或文件的批量复制
示例:同步单个文件
---
- hosts: node1gather_facts: notasks:- name: Synchronize filesynchronize:src: /tmp/testfiledest: /tmp/
示例:以 root 身份同步系统配置目录
---
- hosts: node1remote_user: rootgather_facts: notasks:- name: Synchronize directorysynchronize:src: /etc/sysconfigdest: /tmp/
fetch 模块
从受管节点拉取文件到控制节点,并保留目录结构,便于后续分发或归档
示例:将远程 /tmp/testfile
拉取到控制节点
---
- hosts: node1gather_facts: notasks:- name: Fetch file from remote nodefetch:src: /tmp/testfiledest: /tmp
拉取结果示例
/tmp/node1/tmp/testfile
Jinja2 模板部署文件
Jinja2 模板能够在部署配置文件时动态渲染变量和表达式,通过 template
模块将本地模板生成的文件复制到受管节点
template 模块
功能与 copy
类似,支持指定模板来源、目标路径、文件属主、权限和 SELinux 上下文
示例:部署 Web 服务器首页
Playbook
---
- name: Enable intranet serviceshosts: node1tasks:- name: Ensure latest version of httpdyum:name: httpdstate: latest- name: Deploy homepagetemplate:src: index.html.j2dest: /var/www/html/index.html- name: Restart httpdservice:name: httpdenabled: truestate: restarted
index.html.j2
Welcome to {{ ansible_fqdn }}
渲染结果示例
Welcome to node1.laoma.cloud
示例:配置 SSH 服务
Playbook 及变量定义
---
- name: Configure sshd servicehosts: node1vars:ssh_port: 1022root_allowed: "yes"groups_allowed: wheelpasswords_allowed: "yes"ansible_managed: "Ansible managed"tasks:- name: Deploy sshd_configtemplate:src: sshd_config.j2dest: /root/sshd_config
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 }}
Jinja2 模板语法
Jinja2 模板语法由三类分隔符组成
{{ EXPR }}
:输出表达式结果,包括变量、运算或比较{% EXPR %}
:控制结构,例如if
、for
等{## 注释 #}
:模板内部注释,不会出现在渲染结果
for 循环
用于遍历列表或其他可迭代对象,可配合条件过滤和循环索引
示例:遍历用户列表
{% for user in users %}
{{ user }}
{% endfor %}
示例:显示循环索引
{% for user in users %}
{{ loop.index }} - {{ user }}
{% endfor %}
示例:内联条件过滤
{% for num in [7,1,5,3,9] if num > 3 %}
{{ num }}
{% endfor %}
if 条件
根据变量或表达式的真假决定是否渲染特定内容,可使用 elif
和 else
{% if PORT is defined %}
bind-address=0.0.0.0:{{ PORT }}
{% else %}
bind-address=0.0.0.0:3306
{% endif %}
常用表达式
比较运算
{{ 1 == 1 }}
{{ 2 != 2 }}
{{ 2 > 1 }}
逻辑运算
{{ (2 > 1) or (1 > 2) }}
{{ not true }}
算术运算
{{ 3 + 2 }}
{{ 7 // 5 }}
{{ 17 % 5 }}
成员测试
{{ 1 in [1,2,3,4] }}
{{ 1 not in [1,2,3,4] }}
模板注释
使用 {## #}
添加注释,注释内容不会出现在最终文件中
{## 这里是注释 #}
ansible_managed 变量
在模板顶部输出 Ansible 管理提示,避免运维人员误改
## {{ ansible_managed }}
默认值可在 ansible.cfg
中 [defaults]
区块修改
过滤器(filters)
对渲染结果进行格式化或转换
数据格式化
| to_json
、| to_yaml
、| to_nice_json
、| to_nice_yaml
| from_json
、| from_yaml
字符串处理
| upper
、| lower
、| capitalize
| reverse
、| first
、| last
| trim
、| center(width=30)
、| length
、| list
列表处理
| min
、| max
、| sort
、| sort(reverse=true)
| sum
、| join(' , ')
、| random
、| unique
数字处理
| int(default)
、| float(default)
、| abs
| round
、| round(5)
、| random(start=5, step=3)
以上示例涵盖了常见的过滤器用法,可根据需求组合使用