'Add word to end of line in Ansible

I've been trying a lot of lineinfile and replace examples but i can't get it to work.

I have the following lines:

deb-src http://httpredir.debian.org/debian buster main
deb http://security.debian.org/debian-security buster/updates main
deb-src http://security.debian.org/debian-security buster/updates main 

And i want them to look like this:

deb-src http://httpredir.debian.org/debian buster main contrib
deb http://security.debian.org/debian-security buster/updates main contrib
deb-src http://security.debian.org/debian-security buster/updates main contrib

I tried to do so with Ansible;

- name: Add contrib repository
  lineinfile:
    dest: /etc/apt/sources.list
    backup: yes
    state: present
    regexp: '^(deb (.*)$)'
    backrefs: yes
    line: '\1 contrib'
  check_mode: no

Which kinda works, but after the 2nd run it shows like, e.g.

deb http://security.debian.org/debian-security buster/updates main contrib contrib

So it keeps adding the word with every run.

Obviously the lines are not as-is on every system, but they do start with deb or deb-src

Thanks!



Solution 1:[1]

- name: Add contrib repository
  replace:
    dest: /etc/apt/sources.list
    regexp: '^(deb.+)(?<! contrib)$'
    replace: '\1 contrib'

Solution 2:[2]

lineinfile only replaces 1 single line. replace changes all lines that match.

- name: Add contrib repository
  replace:
    dest: /etc/apt/sources.list
    regexp: '^(deb(?!.* contrib).*)'
    replace: '\1 contrib'

Note that a negative lookahead regular expression like (?!bar) means: "assert that 'bar' does not immediately follow as the next word" and not: "assert that 'bar' is not somewhere in the rest of the line". Note also the greediness of .*.

This Ansible code snippet can be used to add any option / string to all lines that does not yet have that option / string.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Tommy
Solution 2 β.εηοιτ.βε