5

How can I use ansible to ensure that a line is uncommented in an XML file? In /etc/tomcat8/context.xml I want to ensure that the section:

<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->

Is changed to:

<!-- Disable session persistence across Tomcat restarts -->
<Manager pathname="" />
  • The lineinfile module doesn't appear to be able to help because this is a multi-line section

  • The xml module might be able to ensure that the <Manager... is in place, but it doesn't appear to be able to delete the commented out version.

  • I could write a script to do this with sed if I have to, but I find it is better to use ansible modules when possible.

5
  • Suggested tags (I can't create them myself): xml comments line-in-file Commented Jan 12, 2018 at 11:51
  • 2
    There's no reason for those tags (they don't help finding the question better). In my opinion, don't go sed way, don't even go modifying files in place, either manage the whole file or not but changing lines by regex matching is brittle and likely to fail.
    – Tensibai
    Commented Jan 12, 2018 at 14:34
  • 1
    I find that managing entire files that get replaced by the package manager can also be frail. Sometimes stuff gets added to new versions that really needs to be there. Unfortunately, the tomcat configuration doesn't have a conf.d directory to which new files can be added easily. Commented Jan 12, 2018 at 14:39
  • "Sometimes stuff gets added to new versions that really needs to be there" <- and if you let them slip into your production without being aware of them and their reasons you're letting the package maintainer do whatever they wish on your behalf... Better to break in CI on this update and ensure you're in line with the change done by the maintainer.
    – Tensibai
    Commented Jan 12, 2018 at 16:00
  • And anyway, trying to modify from line number or by regex is likely to break without prior information if the file si changed by the maintainer also, so that's up to you, but I really recommend against this practice.
    – Tensibai
    Commented Jan 12, 2018 at 16:02

1 Answer 1

3

As mentioned in the question and the comments on it, this isn't an area in which Ansible excels. The "best" solution depends a bit on the type of file you're dealing with, and the structure of it.

The cleanest way to deal with these sorts of changes in Ansible is to templatize the entire thing; this allows you to see the entire file at once, rather than piecing it together through many places, and is much less fragile than pattern- or line-based approaches. When you need to add configuration in multiple places (for instance, different roles), that's when dynamic-loading directives become very useful, like Apache httpd's Include:

Include /etc/httpd/conf.d/*.conf

This then allows you to write individual configuration files from different places, and let the client software concatenate them. However, as far as I can tell from a quick search, Tomcat doesn't support this, so you would need to operate with a single template file.

lineinfile is a hacky solution that's very fragile, and template is almost always a better option. However, in this case, the node that you're adding is a self-closing one, so as long as it is top-level, it can go anywhere and lineinfile will work (I know you say it won't, but I'll get back to that). xml is a similar option that's a bit less fragile.

Those two you've ruled out because they can't delete the comment you have in the file. However, I'll argue that that's an improper requirement (in most cases, and probably yours).

When using a configuration management tool, the source of truth shifts from the files themselves on servers to the configuration that's checked in to master. If someone wants to edit the file, they'll do so by editing the configuration management scripts, not by editing the file directly on the server. Therefore, there is no need for comments in the resultant file that lives on the server, except perhaps one at the top that says "this is auto-generated, go look at source control instead". The comment should be in your templating code - and as long as the result compiles and works correctly, you shouldn't care at all what it looks like.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.