1

When editing configuration files, such as /etc/sysctl.conf for example, it is often useful to do the update in an idempotent way, meaning that if the script is executed multiple times, you don't end up with multiple entries for the configuration change you made.

As a real-world instance where I encountered this, I need to edit the above file in multi-stage ansible playbook. But the problem is that if the later stage fails, the playbook will need to be run again, which means that the update command may run multiple times, causing duplication if the update is not idempotent.

So the question is how can you update such configuration files in an idempotent way?

An example of a non-idempotent update would be:

echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf

or in ansible:

  - name: Set swappiness setting
    shell: echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf

Ideally if the value of the variable is initially set, it should be replaced with new value.

1
  • 1
    This is precisely why more and more systems move from monolithic configuration files to configuration directories with configuration file fragments. E.g., /etc/paths.d/, /etc/network/interfaces.d/, /etc/apt/sources.list.d/, /etc/netplan/, and so on. Unfortunately, this realization is still not universal. Commented Jan 19, 2024 at 11:57

2 Answers 2

5

Instead of running shell commands, use the sysctl module.

If possible, avoid using shell.

- ansible.posix.sysctl:
    name: vm.swappiness
    value: '10'
    state: present
2
  • 1
    Great for the specific example, this seems to work perfectly! Thanks! But is the only option to try to find an ansible module for the specific file you are trying to configure? I would be also interested in knowing if a general solution exists, if anybody knows one. Commented Jan 18, 2024 at 9:40
  • 3
    @user000001 the general solution is to use drop-in files (files in some <software>.d directory), like /etc/sysctl.d/xx-foobar.conf for sysctl, or /etc/sudoers.d/foobar for sudo and so on. Those are not supported by everything, but support is increasing these days precisely because such files allow configuration to be transactionally updated. Commented Jan 18, 2024 at 9:53
2

I just found another SO answer, https://stackoverflow.com/a/31632883/376258, pointing to http://augeas.net/ thanks to a bit of curious googling prompted by your question. Here's how i made it work in ubuntu 20.04:

sudo apt install libaugeas-dev
virtualenv -p /usr/bin/python3.10 venv; . venv/bin/activate.fish
pip install git+https://github.com/hercules-team/python-augeas
sudo venv/bin/python3 -c """
import augeas
aug = augeas.Augeas()
aug.set('/files/etc/sysctl.conf/fs.inotify.max_inotify_watches', '44194306')
aug.set('/files/etc/sysctl.conf/fs.inotify.max_user_watches', '44194306')
aug.save()
"""

and verify:

cat /etc/sysctl.conf | grep inotify
1
  • This looks like a good solution, especially if you are already using python, but I went the ansible module since I was already using ansible. Thanks though! Commented Jan 18, 2024 at 10:01

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.