Leshawn Rice
Leshawn Rice

Reputation: 548

Set constant parameters for a module Ansible

I have a playbook that is using the replace module multiple times to replace multiple lines in a file.

So I have something like:

- name: Replace PROPERTY in NAMED file
  ansible.builtin.replace:
      path: "{{ path_to_file }}"
      after: "{{ AFTER_TEXT}}"
      before: "{{ BEFORE_TEXT }}"
      regexp: "^PROPERTY = [0-9]+$"
      replace: "PROPERTY = {{ PROPERTY }}"

And that basically repeats 5 times with the same first 3 parameters. I looked through the docs but couldn't find a way to do this.

Is there any way that I can somehow store these params in an inventory file so all I would have to write is something like

- name: Replace PROPERTY in NAMED file
  ansible.builtin.replace:
      params: "{{ path, after, before }}"
      regexp: "^PROPERTY = [0-9]+$"
      replace: "PROPERTY = {{ PROPERTY }}"

Upvotes: 1

Views: 581

Answers (1)

Zeitounator
Zeitounator

Reputation: 44615

Turn this the other way around: write the task only once and loop.

- name: Replace whatever has to be
  ansible.builtin.replace:
      path: "{{ path_to_file }}"
      after: "{{ AFTER_TEXT}}"
      before: "{{ BEFORE_TEXT }}"
      regexp: "{{ item.regexp }}"
      replace: "{{ item.replace }}"
  loop:
    - regexp: "^PROPERTY = [0-9]+$"
      replace: "PROPERTY = {{ PROPERTY }}"
    - regexp: "some other regexp"
      replace: "some other replace"
    - regexp: "next regexp"
      replace: "next replace"
    # continue

You can define that list in a var if you wish and reference it in your loop.


Meanwhile, as a direct answer to your question, you can take advantage of yaml anchors and merge key. The only requirement for the next example is that everything takes place in the same yaml file (no includes, imports...).

Here is an example with a pseudo playbook

- name: use anchors and merge operator
  hosts: localhost
  gahter_facts: false
  
  vars:
    # We won't really use that var but the anchor defined on it
    replace_defaults: &rep_def
      path: "{{ path_to_file }}"
      after: "{{ AFTER_TEXT}}"
      before: "{{ BEFORE_TEXT }}"

  tasks:
    - name: task1
      ansible.builtin.replace:
        # Here we load default as options
        # in current mapping
        <<: *rep_def 
        regexp: "^PROPERTY = [0-9]+$"
        replace: "PROPERTY = {{ PROPERTY }}"

    - name: task1
      ansible.builtin.replace:
        <<: *rep_def
        # Note we can still override a default if needed
        path: /some/other/path
        regexp: "^PROPERTY = [0-9]+$"
        replace: "PROPERTY = {{ PROPERTY }}"

In current situation, I would still use the first scenario that is the most DRY.

Upvotes: 3

Related Questions