我开始研究使用 ansible 来维护一组服务器。我在使用 lineinfile 时遇到了困难。我正在设置 rsyslog,并希望确保 /etc/rsyslog.conf 中有几行:
- name: set up rsyslog
lineinfile:
dest: /etc/rsyslog.conf
line: '{{ item }}'
with_items:
- "*.* @@rsysserver.example.com:514"
- "*.info;mail.none;authpriv.none;cron.none;user.none /var/log/messages"
- "user.* -/var/log/user_messages"
这在新机器上运行良好,但我的问题是一些服务器已经手动维护了一段时间,这意味着行中的空格量可能有所不同,所以如果应该有一行像user.* -/var/log/user_messages
ansible 会添加到上面规则的最后一项。
我可以制定三条不同的规则,例如
lineinfile:
dest: /etc/rsyslog.conf
line: user.* -/var/log/user_messages
regexp: 'user.\*\s+-/var/log/user_messages'
state: present
应该可以工作,但是我需要编写三条不同的规则来将三行添加到 /etc/syslog.conf。
有什么方法可以设置一条规则来维护文件,但对我想要添加的每一行使用不同的正则表达式?
答案1
系统化、更健壮且幂等的方式是分别声明选择器和操作,并在正则表达式和行中使用它。例如
- name: set up rsyslog
lineinfile:
dest: rsyslog.conf
regexp: '^\s*{{ item.selector|regex_escape() }}\s+{{ item.action|regex_escape() }}\s*$'
line: '{{ item.selector }} {{ item.action }}'
loop:
- selector: '*.*'
action: '@@rsysserver.example.com:514'
- selector: '*.info;mail.none;authpriv.none;cron.none;user.none'
action: '/var/log/messages'
- selector: 'user.*'
action: '-/var/log/user_messages'
给出
shell> cat rsyslog.conf
*.* @@rsysserver.example.com:514
*.info;mail.none;authpriv.none;cron.none;user.none /var/log/messages
user.* -/var/log/user_messages
使用反向引用如果您想保持选择器和操作之间的间距。例如,下面的任务
- name: set up rsyslog
lineinfile:
dest: rsyslog.conf
backrefs: true
regexp: '^\s*{{ item.selector|regex_escape() }} (\s*){{ item.action|regex_escape() }}\s*$'
line: '{{ item.selector }} \1{{ item.action }}'
loop:
- selector: '*.*'
action: '@@rsysserver.example.com:514'
- selector: '*.info;mail.none;authpriv.none;cron.none;user.none'
action: '/var/log/messages'
- selector: 'user.*'
action: '-/var/log/user_messages'
将保持此文件不变
shell> cat rsyslog.conf
*.* @@rsysserver.example.com:514
*.info;mail.none;authpriv.none;cron.none;user.none /var/log/messages
user.* -/var/log/user_messages
不幸的是,不会添加新行。引用自反向引用
如果正则表达式在文件中任何地方都不匹配,则文件将保持不变
看格式尝试更复杂的格式。
答案2
首先编写一个删除行的规则或脚本,然后使用“设置 rsyslog”任务将其重新添加。一旦所有文件都修复并保持一致,您就可以删除删除该行的规则或脚本。
或者,您是否考虑过使用 Ansible 管理整个/etc/rsyslog.conf
文件,而不是尝试添加/删除/更新文件中的个别行?如果可能的话,我会这样做。