Ansible replace code in multiple files in a directory

10,352

Solution 1

This question seems to have trailed off without fully completing... at least not with using find. Here is an example of the 2-step process that was sought after. The case for using raw for the first case has been answered. But I find this solution more appealing, even if harder:

tasks:
- name: Find all of the files inside this directory
  find:
    paths: "/etc/yum.repos.d/"
    patterns: "*.repo"
  register: repos

- name: Replace foo with bar in the files
  replace:
    path: "{{ item.path }}"
    regexp: 'foo'
    replace: 'bar'
  with_items: "{{ repos.files }}"

This required some research on the output structure of the find command.

Solution 2

It is "trying them all at once", because you are providing the whole output of the previous task as an argument for the dest:

dest={{repos}}

Instead, you should be feeding the items you iterate over:

dest={{item}}

You also don't quote the variable in the with_items.

Second task should look like this:

- name: disable all repos
  replace: dest={{item}} regexp="enabled=1" replace="enabled=0"
  with_items: "{{ repos.stdout_lines }}"

Besides, you can use find module instead of raw command.

Share:
10,352
completenewb
Author by

completenewb

Updated on June 13, 2022

Comments

  • completenewb
    completenewb almost 2 years

    I'm trying to disable all repos on my server using ansible, so I'm trying to do a replace on multiple files within one directory but can't seem to get it to work any idea appreciated!

    tasks:
    
      - name: get repo names
        raw: find /etc/yum.repos.d/ -type f -name "*.repo"
        register: repos
    
      - name: disable all repos
        replace: dest={{repos}} regexp="enabled=1" replace="enabled=0"
        with_items: repos.stdout_lines
    

    When I run this I just get an error like it's trying to do them all at once? How would I split them up if that was the case?

    /etc/yum.repos.d/CentOS-Debuginfo.repo\r\n/etc/yum.repos.d/epel.repo\r\n/etc/yum.repos.d/CentOS-Base.repo\r\n'} does not exist !",

    update:

      - find:
          paths: "/etc/yum.repos.d/"
          patterns: "*.repo"
        register: repos
    
      - name: disable all repos
        replace: dest={{items}} regexp="enabled=1" replace="enabled=0"
        with_items: repos
    

    The new error is following: "msg": "the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'items' is undefined

    Okay Getting closer! getting this error at the disable repo now:

    FAILED! => {
        "failed": true,
        "msg": "'dict object' has no attribute 'stdout_lines'"
    }
    
  • completenewb
    completenewb about 7 years
    Hi Updated above sorry didnt realise it wouldn't show okay on a comment!
  • completenewb
    completenewb about 7 years
    Thanks for that, I don't think the find is correctly storing the information for the disable read from possibly? added new error, thanks again!
  • Vikram
    Vikram almost 7 years
    Trying something similar - name: Find files with yaml find: path: "$HOME/kube_objs/" pattern: "*.yaml" register: kubespecs - name: Replace docker repository replace: dest={{ item }} regexp="11.168.25.68" replace='x' with_items: "{{ kubespecs.stdout_lines }}" But getting the same error as mentuioned above "'dict object' has no attribute 'stdout_lines'"} Tried with {{ kubespecs }} instead of {{item}} as well Please help.
  • bviktor
    bviktor about 6 years
    You explain she should use {{item}}, then you go on and use {{repos}} anyway. That's not really helpful.
  • techraf
    techraf about 6 years
    @bviktor Thank you for spotting the typo and kindly letting me know.
  • bviktor
    bviktor about 6 years
    Thanks, upped the answer!
  • amphetamachine
    amphetamachine about 2 years
    This worked for me. The Ansible docs say you should use ansible.builtin.replace instead of replace in your YAML.