5

I am configuring a server using Ansible playbook. My playbook works properly at the very first execution but when I run the same playbook again it creates the duplicates lines in the configuration file on the server. I am using lineinfile module. Example following task adds the line each time I run the playbook.

- lineinfile: dest=/etc/pam_ldap.conf line="ssl off"

Is there a way to avoid this, and maintain idempotency.

Mxx
  • 8,979
  • 4
  • 27
  • 37
yogeshagr
  • 819
  • 2
  • 11
  • 20
  • your task should already be idempotent. Is this the exact task? Do you modify this file within the playbook somewere else too? Does the line attribute contains a `\n`? Does your playbook reinstall or reconfigure ldap on the second run? – Sebastian Stigler Feb 12 '15 at 12:36
  • What version of ansible do you use? – Sebastian Stigler Feb 12 '15 at 12:47
  • I am using ansible 1.8.2. – yogeshagr Feb 12 '15 at 17:27
  • There is a separate playbook for installation that I am running once, and there is a separate playbook for configuring the server. And things get added multiple times in multiple run. I am using ansible 1.8.2. Please provide me some suggestion how can I achieve this. – yogeshagr Feb 12 '15 at 17:36
  • I want to add multiple lines to the config files. For that instead of using '\n' I am creating separate task for each line. That essentially means I am modifying files in more than once in a playbook. I do not know if this is good idea or if there is any better way to do. – yogeshagr Feb 12 '15 at 17:38
  • if you **add** (not replace) more then one line in a file, I would work with a template file instead. – Sebastian Stigler Feb 12 '15 at 18:30
  • But i am still confused why it is adding lines everytime only in case when I modify a conf file multiple times in a playbook. Whereas when I am modifying file only once it is maintaining idempotency. – yogeshagr Feb 13 '15 at 08:25
  • `lineinfile` is typically code smell. especially if you are "adding multiple lines". it is basically communicating "I don't care if the rest of the file changes", though you *do*. – tedder42 Feb 13 '15 at 17:32

1 Answers1

1

Theoretically lineinfile should work as you expect it. A line only is added if it is not already present in the file.

Is the file a symlink? I don't see a reason why Ansible shouldn't follow that link, but maybe that might be a reason why it fails to identify the line.

Did you try to add a regexp parameter? It would make sense anyway, to cover cases where a line like ssl on already is present.

- lineinfile: dest=/etc/pam_ldap.conf
              line="ssl off"
              regexp="^ssl\s+"
udondan
  • 57,263
  • 20
  • 190
  • 175
  • It's maintaining idempotency when I am adding single line in a file and modifying the file only once in an Ansible playbook. But it is not working when I am adding multiple lines to a config file, hence modifying the file multiple times in a playbook. – yogeshagr Feb 13 '15 at 06:25
  • I do not understand what symlink has to do here, I am mentioning the file name itself. Config file already exist in the server. – yogeshagr Feb 13 '15 at 06:26
  • And if I use regexp in lineinfile module, then it will only add line if it matches the expression. But in the first run some lines will not be present in the configuration file, and few lines are added newly where regexp won't work, am i right ? – yogeshagr Feb 13 '15 at 06:29
  • 1
    I clearly understand your problem. I just explained how it *should* work. I understand it is not working as expected in your case, for whatever reason. Without the `regexp` attribute basically your `line` becomes the `regexp`. It is searching for the line/regexp. If it finds it, it is updating it - if not it is adding it as a new line. With the `regexp` attribute you can be more specific or unspecific if that line already is contained. Since for some reason the line is not recognized in your case, giving it a try with `regexp` seemed a good idea. – udondan Feb 13 '15 at 06:33
  • 1
    Only if the `regexp`did **not** match the content of the file, the line will be added to the file. Regarding the symlink: It might simply be Ansible is not following a link and therefore can not read the content of the file in the first place. I absolutely do not believe this is a case, but if the file actually was a symlink it would have been something you could check if it was the cause. – udondan Feb 13 '15 at 06:36
  • 1
    It is now working with regexp. If the regexp matches then it will try to replace the line but if the regexp does not match it will add the new line. That's what I wanted thanks for your help. – yogeshagr Feb 13 '15 at 08:51