ansible lineinfile regex multiline

2020-07-08 07:47发布

I'm trying to edit apache.conf using Ansible. Here's part of my conf:

# Sets the default security model of the Apache2 HTTPD server. It does
# not allow access to the root filesystem outside of /usr/share and /var/www.
# The former is used by web applications packaged in Debian,
# the latter may be used for local directories served by the web server. If
# your system is serving content from a sub-directory in /srv you must allow
# access here, or in any related virtual host.
<Directory />
        Options FollowSymLinks
        AllowOverride None
        Require all denied
</Directory>

<Directory /usr/share>
        AllowOverride None
        Require all granted
</Directory>

<Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
</Directory>

#<Directory /srv/>
#       Options Indexes FollowSymLinks
        AllowOverride All
#       Require all granted
#</Directory>

I want to change this block

<Directory /var/www/>
            Options Indexes FollowSymLinks
            AllowOverride None
            Require all granted
    </Directory>

into

<Directory /var/www/>
            Options Indexes FollowSymLinks
            AllowOverride All
            Require all granted
    </Directory>

set AllowOverride from None to All. I'm using this ansible task

- name: change htaccess support
  lineinfile:
    dest: /etc/apache2/apache2.conf
    regexp: '\s<Directory /var/www/>\n\sOptions Indexes FollowSymLinks\n\sAllowOverride'
    line: "AllowOverride All"
  tags:
    - test

However, AllowOverride All always added to the end of file. What's the correct regex pattern to do this jobs. I don't use ansible template cuz I only change one line.

3条回答
倾城 Initia
2楼-- · 2020-07-08 07:47

I managed to do exactly this by slightly improving @mattyoung-redhatmatt's answer. As it turns out, the replace module handles multi line regular expressions and backreferences just fine:

- name: AllowOverride all
  replace:
    dest=/etc/apache2/apache2.conf
    regexp='(<[dD]irectory /var/www/>[^<]*)AllowOverride None'
    replace='\1AllowOverride All'
    backup=yes
  sudo: yes
  notify:
    - restart apache
查看更多
The star\"
3楼-- · 2020-07-08 07:47

Ansible's lineinfile module does precisely just that, it deals with single lines in files and has no support for multiple lines.

This leaves you with a couple of options to tackle this problem instead.

As with most tricky things around lineinfile you might be best replacing this with a template instead.

Alternatively you could try using the blockinfile role to first remove (state=absent) the following block:

        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted

after <Directory /var/www/> and then inserting (state=present) the following block:

        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted

after <Directory /var/www/>.

查看更多
我欲成王,谁敢阻挡
4楼-- · 2020-07-08 08:07

I tried and I tried to use blockinfile for this and I did not want to use a full template. I ended up using ansible's replace module and practicing a little regex on regex.com:

- hosts: all
  tasks:
    - name: Update apache2.conf
      replace: dest=/etc/apache2/apache2.conf
        regexp='<Directory /var/www/>\n\tOptions Indexes FollowSymLinks\n\tAllowOverride None'
        replace='<Directory /var/www/>\n\tOptions Indexes FollowSymLinks\n\tAllowOverride All'
        backup=yes
      notify:
        - restart apache2
  handlers:
    - name: restart apache2
      service: name=apache2 state=restarted
查看更多
登录 后发表回答