veedub
veedub

Reputation: 1

Ansible Executing Nested Variable Loops on Multiple Files

I want to perform the following command using an Ansible playbook:

sed -i.bak 's/^mirror/#mirror/;s/#baseurl/baseurl/;s/mirror.centos/vault.centos/' /etc/yum.repos.d/CentOS-*.repo

A basic working Ansible playbook looks like this:

---
- name: Resolve any CentOS issues
  hosts: "{{ nodes }}"
  tasks:
  - shell: sed -i.bak 's/^mirror/#mirror/;s/#baseurl/baseurl/;s/mirror.centos/vault.centos/' /opt/yum.repos.d/CentOS-*.repo

However, I would like to create a more advanced playbook, which *might *look something like this:

---
- name: Modify CentOS Reps
  hosts: localhost
  vars:
    filelist: []
    reg:
      - ^mirrorlist
      - ^#baseurl
      - mirror.centos
    rep:
      - #mirror
      - baseurl
      - vault.centos

  tasks:
   - name: Find matching repo files and register to a variable
     find:
       paths: /etc/yum.repos.d
       file_type: file
       recurse: no
       patterns: CentOS-*.repo
     register: output

   - name: Adding filelist to the LIST
     no_log: true
     set_fact:
       filelist: "{{ filelist + [item.path]}}"
     with_items: "{{ output.files }}"

   - debug: var=filelist

   - name: Change the lines
     replace:
       path: "{{ item.0 }}"
       regexp: "{{ item.1.regexp }}"
       replace: "{{ item.1.replace }}"
       backup: true
     with_nested:
       - "{{ filelist }}"
       - '{ regexp: "{{ reg }}", replace: "{{ rep }}" }'

The above gives the following attribute error:

fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'regexp'\n\nThe error appears to be in '/etc/ansible/playbooks/centos-correct-repo301.yml': line 33, column 6, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: Change the lines\n ^ here\n"}

Any thoughts?

Thanks

Upvotes: 0

Views: 255

Answers (1)

Vladimir Botka
Vladimir Botka

Reputation: 68124

There are more options. For example,

  1. Put the regex/replace logic into a dictionary
  reg_rep:
    - {reg: '^mirror', rep: '#mirror'}
    - {reg: '^#baseurl', rep: 'baseurl'}
    - {reg: 'mirror.centos', rep: 'vault.centos'}
  1. Declare the list of the files
  filelist: "{{ output.files|map(attribute='path')|list }}"

and find the files (no changes to your code in this task)

    - name: Find matching repo files and register to a variable
      find:
        paths: /etc/yum.repos.d
        file_type: file
        recurse: no
        patterns: CentOS-*.repo
      register: output
  1. Update the configuration
    - name: Change the lines
      replace:
        path: "{{ item.0 }}"
        regexp: "{{ item.1.reg }}"
        replace: "{{ item.1.rep }}"
        backup: true
      with_nested:
        - "{{ filelist }}"
        - "{{ reg_rep }}"
      loop_control:
        label: "{{ item.0|basename }}"

Example of a complete playbook for testing

shell> cat pb.yml
- hosts: test_24

  vars:

    reg_rep:
      - {reg: '^mirror', rep: '#mirror'}
      - {reg: '^#baseurl', rep: 'baseurl'}
      - {reg: 'mirror.centos', rep: 'vault.centos'}

    filelist: "{{ output.files|map(attribute='path')|list }}"

  tasks:

    - name: Find matching repo files and register to a variable
      find:
        paths: /etc/yum.repos.d
        file_type: file
        recurse: no
        patterns: CentOS-*.repo
      register: output
    - debug:
        var: filelist

    - debug:
        msg: |
          path: "{{ item.0 }}"
          regexp: "{{ item.1.reg }}"
          replace: "{{ item.1.rep }}"
          backup: true
      with_nested:
        - "{{ filelist }}"
        - "{{ reg_rep }}"
      loop_control:
        label: "{{ item.0|basename }}"
      when: debug|d(false)|bool
 
    - name: Change the lines
      replace:
        path: "{{ item.0 }}"
        regexp: "{{ item.1.reg }}"
        replace: "{{ item.1.rep }}"
        backup: true
      with_nested:
        - "{{ filelist }}"
        - "{{ reg_rep }}"
      loop_control:
        label: "{{ item.0|basename }}"

gives abridged, running in --check --diff mode

shell> ansible-playbook pb.yml -CD

PLAY [test_24] *******************************************************************************

TASK [Find matching repo files and register to a variable] ***********************************
ok: [test_24]

TASK [debug] *********************************************************************************
ok: [test_24] => 
  filelist:
  - /etc/yum.repos.d/CentOS-Linux-ContinuousRelease.repo
  - /etc/yum.repos.d/CentOS-Linux-Debuginfo.repo
  - /etc/yum.repos.d/CentOS-Linux-Devel.repo
  - /etc/yum.repos.d/CentOS-Linux-Extras.repo
  - /etc/yum.repos.d/CentOS-Linux-FastTrack.repo
  - /etc/yum.repos.d/CentOS-Linux-HighAvailability.repo
  - /etc/yum.repos.d/CentOS-Linux-Media.repo
  - /etc/yum.repos.d/CentOS-Linux-Plus.repo
  - /etc/yum.repos.d/CentOS-Linux-PowerTools.repo
  - /etc/yum.repos.d/CentOS-Linux-Sources.repo
  - /etc/yum.repos.d/CentOS-Linux-BaseOS.repo
  - /etc/yum.repos.d/CentOS-Linux-AppStream.repo

TASK [debug] *********************************************************************************
skipping: [test_24] => (item=CentOS-Linux-ContinuousRelease.repo) 
skipping: [test_24] => (item=CentOS-Linux-ContinuousRelease.repo) 
...
skipping: [test_24] => (item=CentOS-Linux-AppStream.repo) 
skipping: [test_24]

TASK [Change the lines] **********************************************************************
--- before: /etc/yum.repos.d/CentOS-Linux-ContinuousRelease.repo
+++ after: /etc/yum.repos.d/CentOS-Linux-ContinuousRelease.repo
@@ -17,7 +17,7 @@
 
 [cr]
 name=CentOS Linux $releasever - ContinuousRelease
-mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=cr&infra=$infra
+#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=cr&infra=$infra
 #baseurl=http://mirror.centos.org/$contentdir/$releasever/cr/$basearch/os/
 gpgcheck=1
 enabled=0

changed: [test_24] => (item=CentOS-Linux-ContinuousRelease.repo)
--- before: /etc/yum.repos.d/CentOS-Linux-ContinuousRelease.repo
+++ after: /etc/yum.repos.d/CentOS-Linux-ContinuousRelease.repo
@@ -18,7 +18,7 @@
 [cr]
 name=CentOS Linux $releasever - ContinuousRelease
 mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=cr&infra=$infra
-#baseurl=http://mirror.centos.org/$contentdir/$releasever/cr/$basearch/os/
+baseurl=http://mirror.centos.org/$contentdir/$releasever/cr/$basearch/os/
 gpgcheck=1
 enabled=0
 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial

changed: [test_24] => (item=CentOS-Linux-ContinuousRelease.repo)

...

--- before: /etc/yum.repos.d/CentOS-Linux-AppStream.repo
+++ after: /etc/yum.repos.d/CentOS-Linux-AppStream.repo
@@ -11,7 +11,7 @@
 [appstream]
 name=CentOS Linux $releasever - AppStream
 mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=AppStream&infra=$infra
-#baseurl=http://mirror.centos.org/$contentdir/$releasever/AppStream/$basearch/os/
+#baseurl=http://vault.centos.org/$contentdir/$releasever/AppStream/$basearch/os/
 baseurl=http://vault.centos.org/$contentdir/$releasever/AppStream/$basearch/os/
 gpgcheck=1
 enabled=0

changed: [test_24] => (item=CentOS-Linux-AppStream.repo)

PLAY RECAP ***********************************************************************************
test_24: ok=3    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

Upvotes: 0

Related Questions