ansible系列文章
ansible学习系列之tags的使用
ansible学习系列之顺利启动后台程序
ansible学习系列之make模块的使用
ansible学习系列之become的使用
ansible学习系列之lineinfile模块的使用
场景
最近,在编写ansible脚本的时候,有时候需要对配置文件做修改操作,如新增语句等。而这个操作要求幂等性,不能每次启动脚本的时候,相同的新增语句被重复执行。比如,执行新增操作的时候,每次启动脚本时,只有当配置文件不存在,才新增进去。这个时候就可以使用lineinfile
模块来实现这个功能。
环境
软件 | 版本 |
---|---|
Ansible | 2.9.4 |
Python | 2.7.5 |
Centos | 7 |
正文
简介
该模块确保文件中包含特定行,或使用向后引用的正则表达式替换现有行。 当您只想更改文件中的单行时,那这个模块就可以使用。如果要更改多行相似的行,请参见 replace 模块;如果要在文件中插入/更新/删除一行行,请查看 blockinfile。对于其他情况,请参见 copy 或 template 模块。
参数
参数 | 默认 | 是否必需 | 含义 |
---|---|---|---|
attributes | 否 | 结果文件或目录应具有的属性。 要获取支持的标志,请查看目标系统上chattr 的手册页。 此字符串应包含与lsattr 显示的属性顺序相同的属性。 默认设置为= 运算符,否则需要在字符串中包含+ 或- 运算符。 | |
backrefs | 默认no ,可选:yes /no | 否 | 与state=present 一起使用。如果已设置,则行可以包含在regexp 匹配时将填充的反向引用(位置引用和命名引用)。此参数稍微更改模块的操作;insertbefore 和insertafter 将被忽略,如果regexp 与文件中的任何地方都不匹配,则文件将保持不变。如果regexp 匹配,则最后一个匹配行将被扩展行参数替换。 |
backup | 默认no ,可选:yes /no | 否 | 创建一个包含时间戳信息的备份文件,以便在不正确地删除原始文件时可以将其取回。 |
create | 默认no ,可选:yes /no | 否 | 与state=present 一起使用。如果已指定,则将在文件不存在时创建该文件。默认情况下,如果文件丢失,它将失败。 |
firstmatch | 默认no ,可选:yes /no | 否 | 与insertafter 或insertbefore 一起使用。如果已设置,insertafter 和insertbefore 将处理与给定正则表达式匹配的第一行。 |
group | 否 | 应该拥有文件/目录的组的名称,将被输入chown 。 | |
insertafter | 默认EOF | 否 | 与state=present 一起使用。如果指定,则该行将插入到指定正则表达式的最后一个匹配项之后。如果需要第一个匹配项,请使用(first match=yes )。有一个特殊值可用;EOF 用于在文件末尾插入行。如果指定的正则表达式没有匹配项,则将改用EOF 。如果设置insertbefore ,则将忽略默认值EOF 。如果正则表达式同时传递给regexp 和insertafter ,则只有在找不到regexp的匹配项时才会使用insertafter 。不能与backrefs 或insertbefore 一起使用。 |
insertbefore | 默认 BOF | 否 | 与state=present 一起使用。如果指定,则该行将插入到指定正则表达式的最后一个匹配项之前。如果需要第一个匹配项,请使用first match=yes 。有一个值可用;BOF 用于在文件开头插入行。如果指定的正则表达式没有匹配项,则该行将插入文件末尾。如果正则表达式同时传递给regexp 和insertbefore ,则只有在找不到regexp 的匹配项时才使用insertbefore 。不能与backrefs 或insertafter 一起使用。 |
line | 否 | 要插入/替换到文件中的行。state=present 时必需。如果设置了backrefs ,则可能包含在regexp 匹配时将与regexp 捕获组一起展开的backreferences 。 | |
mode | 否 | 结果文件或目录应具有的权限。对于那些使用/usr/bin/chmod 的模式,请记住模式实际上是八进制数。必须添加前导零,以便Ansible 的YAML 解析器知道它是一个八进制数(如0644 或01777 ),或者引用它(如644 或1777 ),以便Ansible 接收一个字符串并可以自己从字符串转换为数字。给ansibe 一个数字而不遵循这些规则中的任何一条,最后会得到一个十进制数,这将产生意外的结果。从Ansible 1.8 开始,模式可以指定为符号模式(例如,u+rwx 或u=rw ,g=r ,o=r )。从ansibe2.6 开始,模式也可以是特殊的字符串保留。设置为保留文件时,将授予与源文件相同的权限。 | |
others | 否 | 文件模块接受的所有参数也在这里工作。 | |
owner | 否 | 应该拥有该文件/目录的用户的名称,该名称将被馈送给chown 。 | |
path | 是 | 要修改的文件。 在ansibe2.3 之前,这个选项只能用作dest 、destfile 和name 。 | |
regexp | 否 | 要在文件的每一行中查找的正则表达式。对于state=present ,如果找到要替换的模式。只会替换找到的最后一行。对于state=absent ,要删除的行的模式。如果正则表达式不匹配,则该行将按照insertbefore 或insertafter 设置添加到文件中。当修改一行时,regexp 通常应该匹配行的初始状态以及行替换后的状态,以确保等幂性。使用Python 正则表达式。请参见http://docs.python.org/2/library/re.html | |
selevel | 默认 s0 | 否 | SELinux 文件上下文的级别部分。这是MLS/MCS 属性,有时称为范围。当设置为默认值时,它将使用策略的级别部分(如果可用)。 |
serole | 否 | SELinux 文件上下文的角色部分。当设置为默认值时,它将使用策略的角色部分(如果可用)。 | |
setype | 否 | SELinux 文件上下文的类型部分。当设置为默认值时,它将使用策略的类型部分(如果可用)。 | |
seuser | 否 | SELinux 文件上下文的用户部分。默认情况下,它使用系统策略(如果适用)。当设置为默认值时,它将使用策略的用户部分(如果可用)。 | |
state | 否 | 决定line 参数的值是否需要存入或删除 | |
unsafe_writes | 默认no ,可选:yes /no | 否 | 影响何时使用原子操作以防止数据损坏或从目标文件读取不一致。默认情况下,此模块使用原子操作来防止数据损坏或从目标文件中进行不一致的读取,但有时系统的配置或只是以防止这种情况发生的方式中断。一个例子是docker 挂载的文件,它不能从容器内部进行原子更新,只能以不安全的方式写入。此选项允许Ansible 在原子操作失败时返回到更新文件的不安全方法(但是,它不强制Ansible 执行不安全的写入)。重要!不安全的写入会受到竞争条件的影响,并可能导致数据损坏。 |
validate | 否 | 复制之前要运行的验证命令。要验证的文件的路径是通过’%s’传入的,该路径必须如下面的示例中所示。该命令被安全地传递,因此诸如扩展和管道之类的shell 功能将不起作用 |
样例
官方样例
# NOTE: Before 2.3, option 'dest', 'destfile' or 'name' was used instead of 'path'
- name: Ensure SELinux is set to enforcing mode
lineinfile:
path: /etc/selinux/config
regexp: '^SELINUX='
line: SELINUX=enforcing
- name: Make sure group wheel is not in the sudoers configuration
lineinfile:
path: /etc/sudoers
state: absent
regexp: '^%wheel'
- name: Replace a localhost entry with our own
lineinfile:
path: /etc/hosts
regexp: '^127\.0\.0\.1'
line: 127.0.0.1 localhost
owner: root
group: root
mode: '0644'
- name: Ensure the default Apache port is 8080
lineinfile:
path: /etc/httpd/conf/httpd.conf
regexp: '^Listen '
insertafter: '^#Listen '
line: Listen 8080
- name: Ensure we have our own comment added to /etc/services
lineinfile:
path: /etc/services
regexp: '^# port for http'
insertbefore: '^www.*80/tcp'
line: '# port for http by default'
- name: Add a line to a file if the file does not exist, without passing regexp
lineinfile:
path: /tmp/testfile
line: 192.168.1.99 foo.lab.net foo
create: yes
# NOTE: Yaml requires escaping backslashes in double quotes but not in single quotes
- name: Ensure the JBoss memory settings are exactly as needed
lineinfile:
path: /opt/jboss-as/bin/standalone.conf
regexp: '^(.*)Xms(\\d+)m(.*)$'
line: '\1Xms${xms}m\3'
backrefs: yes
# NOTE: Fully quoted because of the ': ' on the line. See the Gotchas in the YAML docs.
- name: Validate the sudoers file before saving
lineinfile:
path: /etc/sudoers
state: present
regexp: '^%ADMIN ALL='
line: '%ADMIN ALL=(ALL) NOPASSWD: ALL'
validate: /usr/sbin/visudo -cf %s
修改配置文件示例
- name: 修改配置文件 /etc/ld.so.conf
lineinfile :
path: /etc/ld.so.conf
regexp: '{{microservice_lboso_install_path}}'
line: '{{microservice_lboso_install_path}}'
become: yes
参考链接
list_of_files_modules
lineinfile_module
总结
工作中遇到问题,即使没办法及时解决,也要放在心里,抽时间去解决,不然就会形成技术债。或许可以告诉自己,问题解决了就好。但是,如果不追求极限,只追求简单地搞定,技术是不会有大的突破的。
随缘求赞
如果我的文章对大家产生了帮忙,可以在文章底部点个赞或者收藏;
如果有好的讨论,可以留言;
如果想继续查看我以后的文章,可以左上角点击关注