Solved - Replace three strings in one line

Hello,

Apologies if this was already answered. I haven’t found the answer so far…

I have this templated line in the /etc/fstab file:
NFS_SVM:/p_n_s_REQ_ID_oracle_HOSTNAME_data

Would it be possible to replace NFS_SVM, REQ_ID and HOSTNAME using a single task, considering that I can’t use a template file…? How?
As the /etc/fstab file is not standard across all servers, I’m considering that a template file would not fit as a solution.

Thanks,

Alex

One task might be a convoluted loop, but it certainly easily be done in a few tasks in one playbook.

Check out ansible.builtin.replace, that will probably be the simplest solution.

Hi,

Yes, although I did not mention, I’m assuming the replace module would be the option to go with.
But I could not think/find a way to have it do 3 replacements in a single call/task.

Alex

Welcome to the forum!
You might want to check out and consider using the ansible.posix.mount module. Example:

---
- name: Mount volume.
  hosts: localhost
  gather_facts: false
  vars:
    nfs_svm: example
    req_id: example
    hostname: example
  tasks:

    - name: Mount NFS volume.
      ansible.posix.mount:
        src: "{{ nfs_svm }}:/p_n_s_{{ req_id }}_oracle_{{ hostname }}_data"
        path: /mnt/shared_data
        fstype: nfs
        state: present
      become: true
1 Like

I have successfully used key/value pairs in a loop to do something similar…like this:

- name: SSO - Modify FILENAME
  become: true
  ansible.builtin.replace:
    path: "/tmp/FILENAME"
    regexp: "{{ item.key }}"
    replace: "{{ item.value }}"
  loop:
    - key: "ORIG_VALUE"
      value: "REPLACE_WITH"
    - key: "2ND_ORIG_VALUE"
      value: "2nd_REPLACE_WITH"

Of course this works for me knowing exactly what I need to replace - but with replace you can use wildcards I believe, so you might still be able to use the idea…

1 Like

Hi Jørn,

True, that would work.
But the reason I was not yet considering using it is that I’d like to keep the existing fstab file structure. Unless I did something wrong, the last time I use it it added the new lines to the end of the file… (Although I may ending up not have a choice and use it.)

Thanks a lot…!

Alex

Hi,

That’s looking promising, thanks…! I haven’t seen/used that before.

I’ll later give that a try and post the results.

Alex

Hi,

So, using the replace module in a loop, as many would already know, did solve my “issue” the way I’d prefer it to be solved:

      - name: Replace fstab tags
        ansible.builtin.replace:
            path: "{{ fstab_file }}"
            regexp: "{{ item.key }}"
            replace: "{{ item.value }}"
        loop:
          - key: "NFS_SVM"
            value: "{{ nfs_svm }}"
          - key: "REQ_ID"
            value: "{{ request_id }}"
          - key: "HOSTNAME"
            value: "{{ inventory_hostname }}"

Thank you all for your help,

Alex

1 Like

Hi Alex_Wanderley, welcome to the forum!

Let me share a couple of tips on using the forum to make it easier for people to help out. In this case for tagging @jrglynn2 post as the answer as that one solved your need. We have a feature for that instead of requiring a topic title edit;

Solutions

If you get to a point where you consider a post by someone helped you to solve the issue, please tick :white_check_mark: the check-box below their message:

image

This will mark the message as the solution and show it in the first post for easy access, as well as recognize the person that helped:

image

I’m doing that for you in this case but wanted to mention it for future posts!

For all other replies where someone helped (like @jiholland, which is a very good suggestion) clicking the :heart: is appreciated.

Let us know if you have any questions or doubts!

Yes, the ansible.posix.mount module will add a new line and not replace the line NFS_SVM:/p_n_s_REQ_ID_oracle_HOSTNAME_data in /etc/fstab, but it will ensure idempotency and that entries added to /etc/fstab gets the right structure.

While the ansible.builtin.lineinfile module has its caveats, I think it is better suited in this scenario than ansible.builtin.replaced:

  • ansible.builtin.replace will replace all matched instances.
  • The loop will make the task run multiple times, which takes more time.

Example with lineinfile:

---
- name: Replace line in fstab file.
  hosts: localhost
  gather_facts: false
  vars:
    nfs_svm: example
    req_id: example
    hostname: example
  tasks:
    - name: Replace line in fstab file.
      ansible.builtin.lineinfile:
        path: "/etc/fstab"
        regexp: '^NFS_SVM:/p_n_s_REQ_ID_oracle_HOSTNAME_data$'
        line: "{{ nfs_svm }}:/p_n_s_{{ req_id }}_oracle_{{ hostname }}_data"
      become: true