The difficulty is this line in the replace module page: "It is up to the user to maintain idempotence by ensuring that the same pattern would never match any replacements made."https://docs.ansible.com/ansible/latest/modules/replace_module.html#id4 It's easy to insert the item but actually quite tricky to make it idempotent, so the target file doesn't grow every time you run the task.
I found a way to do it in one shot with the replace module. You should be able to adapt this. My task checks the GRUB_CMDLINE_LINUX_DEFAULT line for "vt.default_red" and inserts some colour codes if not found.
My method was to copy-and-paste various nearly-there examples into the regex tester website and fiddle until it worked. I still don't grok the result, but it worked in my tests at https://www.regextester.com/ and it works in my playbook.
One problem I had was that Ansible's regex implementation apparently doesn't support conditionals, which gave me odd errors for a while.
- name: colours | configured grub command
replace:
path: /etc/default/grub
regexp: '^GRUB_CMDLINE_LINUX_DEFAULT="((:?(?!vt\.default_red).)*?)"$'
replace: 'GRUB_CMDLINE_LINUX_DEFAULT="\1 vt.default_red=0xee,..."'
The regex matches the literal string ("GRUB_CMDLINE_LINUX_DEFAULT=" and a double quote mark) at the start and the double quote mark at the end. Deconstructing the rest...
( - open capture group #1 (creates backref #1)
(:? - open a non-capturing group (not sure what the question mark is here)
(?! - negative lookahead (ie. don't match if the following string comes next)
vt\.default_red - the string to look for, literal dot is escaped
) - close negative lookahead
.) - match a single char (why?) and close the non-capturing group
* - try to match the non-capturing group zero or more times
? - ... lazily (ie. get the smallest possible match)
) - close capture group #1