Ansible Module “lineinfile” replace multiple lines

2019-06-09 05:14发布

问题:

our SSL certificate runs out in a couple of days. So I thought Ansible can put the new certs on the server und change the apache2 sites.

Serveral sites are running on this server.

I want to replace the following lines:

  • SSLCertificateChainFile
  • SSLCertificateKeyFile
  • SSLCertificateFile

I use this command to get a list of all sites in /etc/apache2 where the pattern "SSLCertificate" exists.

- name: Apache 2.2 list sites files and store it in register
  command: grep -lR --exclude default-ssl "SSLCertificate" /etc/apache2/
  register: apache22_sites

This is what I use, when only one file has to be changed:

- name: apache2.2.* | configure certs
  lineinfile: dest=/path/to/...  regexp={{ item.regexp }} line={{ item.line}} backrefs=yes
  with_items:
        - { regexp: "SSLCertificateChainFile", line: "    SSLCertificateChainFile = ..." }
        - { regexp: "SSLCertificateKeyFile ", line: "    SSLCertificateKeyFile = ..." }
        - { regexp: "SSLCertificateFile", line: "    SSLCertificateFile = ..."
  notify: reload apache2

How can i tell ansible to use this code with multiple files listed in variable "apache22_sites" and multiples lines?

I found a good hint here, bad sadly only for one line.

I appreciate any tipps, tricks, hints :)

Greetings Dennis

回答1:

As tedder42 pointed out in the comments, and as is generally the case when people are using lineinfile, you'd be much better off templating these files instead.

However, if you want to solve the more general problem of how you loop through multiple lists of things then you should be using the with_nested loop.

So in your case you would have something like:

- name: Apache 2.2 list sites files and store it in register
  command: grep -lR --exclude default-ssl "SSLCertificate" /etc/apache2/
  register: apache22_sites

- name: apache2.2.* | configure certs
  lineinfile: dest={{ item.0 }}  regexp={{ item.1.regexp }} line={{ item.1.line}} backrefs=yes
  with_nested:
        - apache22_sites
        - lines_to_replace
  notify: reload apache2

As long as you define your lines_to_replace somewhere like this:

lines_to_replace:
    - { regexp: "SSLCertificateChainFile", line: "    SSLCertificateChainFile = ..." }
    - { regexp: "SSLCertificateKeyFile ", line: "    SSLCertificateKeyFile = ..." }
    - { regexp: "SSLCertificateFile", line: "    SSLCertificateFile = ..."