Edit individual configuration lines with Ansible
Use lineinfile for targeted changes, understand match and insertion behavior, and validate sensitive configuration before reloading.
ansible.builtin.lineinfile ensures that a particular line is present or absent while leaving the rest of a file in place. It fits small changes to files shared with the operating system or other tools, such as a configuration setting or a hosts entry. Idempotence depends on how the match and replacement are written, especially when regular expressions or backreferences are involved.
Understand matching and insertion
For the usual state: present operation, a matching regexp causes the last matching line to be replaced. If no match exists, the module inserts the line, normally at the end unless an insertion option changes that. state: absent removes matching lines.
backrefs: true changes this behavior: if the regular expression does not match, the file is left unchanged, and insertbefore and insertafter are ignored. Existing duplicate settings are not automatically consolidated by a normal last-match replacement.
Basic tasks
These task fragments require appropriate privileges:
- name: Set the SSH password authentication option
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?PasswordAuthentication'
line: 'PasswordAuthentication no'
backup: true
validate: '/usr/sbin/sshd -t -f %s'
- name: Add a hosts entry
ansible.builtin.lineinfile:
path: /etc/hosts
line: '192.168.1.50 db.internal'
- name: Remove a legacy setting
ansible.builtin.lineinfile:
path: /etc/app/config.ini
regexp: '^legacy_mode='
state: absent
Before changing SSH authentication, verify that a second key-authenticated session can connect. Retain the current session and an out-of-band recovery or rollback path. Match blocks, included files, and duplicate directives can alter the effective setting. Inspect sshd -T, using the relevant -C connection conditions for Match rules, before reloading the service.
The ^#? expression matches an uncommented line or one with a single leading #; it does not account for arbitrary leading whitespace. Adapt the expression to the file you have actually inspected. Passing syntax validation does not establish that a particular user will still be able to log in.
More precise edits
- Use capture groups with
backrefs: trueto preserve surrounding text while replacing a value. Account for its no-match behavior. insertafterchooses where a new line goes; it does not restrict the search scope ofregexp. For repeated keys in separate INI sections, considercommunity.general.ini_file.validatereceives a temporary file through%s, allowing a tool such assshd -t -f %sto check the candidate before installation. It is not a replacement for an operational check.
Keep the scope clear
Anchor regular expressions to the intended line structure and make them match both the old and desired state when needed. Keep backup: true when a recoverable copy is appropriate. If Ansible owns the entire file, a template is often easier to reason about than many independent edits.
Frequently asked questions
When should I use template instead?
Use template when automation owns the complete configuration and must render it consistently. Use lineinfile when only a targeted part of a shared file belongs to the playbook.
Will repeated runs create duplicate lines?
A correctly designed task should converge, but that is not a guarantee for every expression. Make the regular expression match the desired line as well as the prior setting, and inspect existing duplicates. Replacing the last match does not remove earlier conflicting entries.
What if several settings need changes?
Use a loop over a lineinfile task for a small collection of independent edits. As the changes become interconnected, consider owning the complete file with a template instead of using a fixed number of edits as a hard rule.
References
Related reading
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan