dinko
dinko

Reputation: 19

Ansible change string in multiple files in subfolders

I have a folder containing files as well as other folders.
I have inside those folders, some JSON files, and I would need to change in all those folders, the string "logs" to "LOGINS" in those files.

I am currently able to change this string in files that are in the main folder but was not able to change it in sub-folders.
I was also able to list all the files, even in sub-folders, but I don't know how to change the string in files which are inside a sub-folder.

Here is my current playbook:

- name: Find all files with extension .json under folder and all sub folders
  find:
    paths: /var/log/conf/login/
    patterns: '*.json'
    recurse: yes

- name: Replace string in files
  replace:
    dest: /var/log/conf/login/ # I have try with path instead dest but nothing cannot make is work
    regexp: 'logs'
    replace: 'LOGINS'

Upvotes: 0

Views: 2045

Answers (2)

DinoDD
DinoDD

Reputation: 91

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": [
        {
            "atime": 1569861712.723093,
            "ctime": 1569861712.723093,
            "dev": 104,
            "gid": 0,
            "inode": 5268,
            "isblk": false,
            "ischr": false,
            "isdir": false,
            "isfifo": false,
            "isgid": false,
            "islnk": false,
            "isreg": true,
            "issock": false,
            "isuid": false,
            "mode": "0755",
            "mtime": 1569861712.723093,
            "nlink": 1,
            "path": "/test/configuration/nginx/trials/Zvone/trial-admin-app/app-config.json",
            "rgrp": true,
            "roth": true,
            "rusr": true,
            "size": 12,
            "uid": 0,
            "wgrp": false,
            "woth": false,
            "wusr": true,
            "xgrp": true,
            "xoth": true,
            "xusr": true
        },
        {
            "atime": 1569861712.7270927,
            "ctime": 1569861712.7270927,
            "dev": 104,
            "gid": 0,
            "inode": 5271,
            "isblk": false,
            "ischr": false,
            "isdir": false,
            "isfifo": false,
            "isgid": false,
            "islnk": false,
            "isreg": true,
            "issock": false,
            "isuid": false,
            "mode": "0755",
            "mtime": 1569861712.7270927,
            "nlink": 1,
            "path": "/test/configuration/nginx/trials/Zvone/trial-admin-app/Test1/app-config.json",
            "rgrp": true,
            "roth": true,
            "rusr": true,
            "size": 12,
            "uid": 0,
            "wgrp": false,
            "woth": false,
            "wusr": true,
            "xgrp": true,
            "xoth": true,
            "xusr": true
        },
        {
            "atime": 1569861712.7320926,
            "ctime": 1569861712.7320926,
            "dev": 104,
            "gid": 0,
            "inode": 5274,
            "isblk": false,
            "ischr": false,
            "isdir": false,
            "isfifo": false,
            "isgid": false,
            "islnk": false,
            "isreg": true,
            "issock": false,
            "isuid": false,
            "mode": "0755",
            "mtime": 1569861712.7320926,
            "nlink": 1,
            "path": "/test/configuration/nginx/trials/Zvone/trial-admin-app/Test2/app-config.json",
            "rgrp": true,
            "roth": true,
            "rusr": true,
            "size": 12,
            "uid": 0,
            "wgrp": false,
            "woth": false,
            "wusr": true,
            "xgrp": true,
            "xoth": true,
            "xusr": true
        }
    ]
}

TASK [Replace string inside file] **********************************************
failed: [localhost] (item={u'uid': 0, u'woth': False, u'mtime': 1569861712.723093, u'inode': 5268, u'isgid': False, u'size': 12, u'roth': True, u'isuid': False, u'isreg': True, u'gid': 0, u'ischr': False, u'wusr': True, u'xoth': True, u'rusr': True, u'nlink': 1, u'issock': False, u'rgrp': True, u'path': u'/test/configuration/nginx/trials/Zvone/trial-admin-app/app-config.json', u'xusr': True, u'atime': 1569861712.723093, u'isdir': False, u'ctime': 1569861712.723093, u'isblk': False, u'xgrp': True, u'dev': 104, u'wgrp': False, u'isfifo': False, u'mode': u'0755', u'islnk': False}) => {"failed": true, "item": {"atime": 1569861712.723093, "ctime": 1569861712.723093, "dev": 104, "gid": 0, "inode": 5268, "isblk": false, "ischr": false, "isdir": false, "isfifo": false, "isgid": false, "islnk": false, "isreg": true, "issock": false, "isuid": false, "mode": "0755", "mtime": 1569861712.723093, "nlink": 1, "path": "/test/configuration/nginx/trials/Zvone/trial-admin-app/app-config.json", "rgrp": true, "roth": true, "rusr": true, "size": 12, "uid": 0, "wgrp": false, "woth": false, "wusr": true, "xgrp": true, "xoth": true, "xusr": true}, "msg": "Destination /test/configuration/nginx/trials/Zvone/trial-admin-app/.app-config.json does not exist !", "rc": 257}
failed: [localhost] (item={u'uid': 0, u'woth': False, u'mtime': 1569861712.7270927, u'inode': 5271, u'isgid': False, u'size': 12, u'roth': True, u'isuid': False, u'isreg': True, u'gid': 0, u'ischr': False, u'wusr': True, u'xoth': True, u'rusr': True, u'nlink': 1, u'issock': False, u'rgrp': True, u'path': u'/test/configuration/nginx/trials/Zvone/trial-admin-app/Test1/app-config.json', u'xusr': True, u'atime': 1569861712.7270927, u'isdir': False, u'ctime': 1569861712.7270927, u'isblk': False, u'xgrp': True, u'dev': 104, u'wgrp': False, u'isfifo': False, u'mode': u'0755', u'islnk': False}) => {"failed": true, "item": {"atime": 1569861712.7270927, "ctime": 1569861712.7270927, "dev": 104, "gid": 0, "inode": 5271, "isblk": false, "ischr": false, "isdir": false, "isfifo": false, "isgid": false, "islnk": false, "isreg": true, "issock": false, "isuid": false, "mode": "0755", "mtime": 1569861712.7270927, "nlink": 1, "path": "/test/configuration/nginx/trials/Zvone/trial-admin-app/Test1/app-config.json", "rgrp": true, "roth": true, "rusr": true, "size": 12, "uid": 0, "wgrp": false, "woth": false, "wusr": true, "xgrp": true, "xoth": true, "xusr": true}, "msg": "Destination /test/configuration/nginx/trials/Zvone/trial-admin-app/.app-config.json does not exist !", "rc": 257}
failed: [localhost] (item={u'uid': 0, u'woth': False, u'mtime': 1569861712.7320926, u'inode': 5274, u'isgid': False, u'size': 12, u'roth': True, u'isuid': False, u'isreg': True, u'gid': 0, u'ischr': False, u'wusr': True, u'xoth': True, u'rusr': True, u'nlink': 1, u'issock': False, u'rgrp': True, u'path': u'/test/configuration/nginx/trials/Zvone/trial-admin-app/Test2/app-config.json', u'xusr': True, u'atime': 1569861712.7320926, u'isdir': False, u'ctime': 1569861712.7320926, u'isblk': False, u'xgrp': True, u'dev': 104, u'wgrp': False, u'isfifo': False, u'mode': u'0755', u'islnk': False}) => {"failed": true, "item": {"atime": 1569861712.7320926, "ctime": 1569861712.7320926, "dev": 104, "gid": 0, "inode": 5274, "isblk": false, "ischr": false, "isdir": false, "isfifo": false, "isgid": false, "islnk": false, "isreg": true, "issock": false, "isuid": false, "mode": "0755", "mtime": 1569861712.7320926, "nlink": 1, "path": "/test/configuration/nginx/trials/Zvone/trial-admin-app/Test2/app-config.json", "rgrp": true, "roth": true, "rusr": true, "size": 12, "uid": 0, "wgrp": false, "woth": false, "wusr": true, "xgrp": true, "xoth": true, "xusr": true}, "msg": "Destination /test/configuration/nginx/trials/Zvone/trial-admin-app/.app-config.json does not exist !", "rc": 257}

NO MORE HOSTS LEFT *************************************************************
        to retry, use: --limit @./releases/1.0-SNAPSHOT/ansible/newtest.retry

PLAY RECAP *********************************************************************
localhost                  : ok=16   changed=10   unreachable=0    failed=1

Upvotes: 0

β.εηοιτ.βε
β.εηοιτ.βε

Reputation: 39264

The find module is able to give you the list of files, as you pointed it, based on this result, in order to act on this list, you will need to register the result of the find module.

- name: Find all files with extension .json under folder and all sub folders
  find:
    paths: /var/log/conf/login/
    patterns: '*.json'
    recurse: yes
  register: files_to_change

Then, with this list of files registered, you can create a loop and do the same step multiple times, on all the files resulting from the find module.
This would be done with the with_items loop:

- name: Replace string in files
  replace:
    dest: "{{ item.path }}"
    regexp: 'logs'
    replace: 'LOGINS'
  with_items: "{{ files_to_change.files }}"

A full working playbook illustarting that would be:

---
- hosts: localhost
  connection: local

  tasks:
    ###### 
    # Mind that this step is just there to make this example relevant, 
    # I am creating folders, as your users would do, here
    ######
    - name: Creating folders structure 
      file:
        dest: "{{ item }}"
        state: directory
      with_items:
        - /var/log/conf/login/some
        - /var/log/conf/login/sub
        - /var/log/conf/login/path/to

    ######
    # Mind that this step is just there to make this example relevant, 
    # I am just creating some JSON files, here, as your users would do
    ######
    - name: Creating file with the content to replace 
      copy:
        dest: "{{ item }}"
        content: "The quick brown fox jumps over the lazy logs ;)"
      with_items:
        - /var/log/conf/login/some/test.json
        - /var/log/conf/login/sub/hello.json
        - /var/log/conf/login/path/to/file.json

    - name: Find all files with extension .json under folder and all sub folders
      find:
        paths: /var/log/conf/login/
        patterns: '*.json'
        recurse: yes
      register: files_to_change

    ######
    # Mind that this is looping on the result of the find module,
    # so it is fully dynamic based on the folders that your end-users might create
    ######
    - name: Replace string in files 
      replace:
        dest: "{{ item.path }}"
        regexp: 'logs'
        replace: 'LOGINS'
      loop_control:
        label: "{{ item.path }}"
      with_items: "{{ files_to_change.files }}"

    - name: Display files content
      debug:
        msg: "{{ lookup('file', item.path) }}"
      loop_control:
        label: "{{ item.path }}"
      with_items: "{{ files_to_change.files }}"

This would output:

PLAY [localhost] **************************************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************************************
ok: [localhost]

TASK [Creating folders structure] *********************************************************************************************************************************************************
changed: [localhost] => (item=/var/log/conf/login/some)
changed: [localhost] => (item=/var/log/conf/login/sub)
changed: [localhost] => (item=/var/log/conf/login/path/to)

TASK [Creating file with the content to replace] ******************************************************************************************************************************************
changed: [localhost] => (item=/var/log/conf/login/some/test.json)
changed: [localhost] => (item=/var/log/conf/login/sub/hello.json)
changed: [localhost] => (item=/var/log/conf/login/path/to/file.json)

TASK [Find all files with extension .json under folder and all sub folders] ***************************************************************************************************************
ok: [localhost]

TASK [Replace string in files] ************************************************************************************************************************************************************
changed: [localhost] => (item=/var/log/conf/login/path/to/file.json)
changed: [localhost] => (item=/var/log/conf/login/sub/hello.json)
changed: [localhost] => (item=/var/log/conf/login/some/test.json)

TASK [Display files content] **************************************************************************************************************************************************************
ok: [localhost] => (item=/var/log/conf/login/path/to/file.json) => {
    "msg": "The quick brown fox jumps over the lazy LOGINS ;)"
}
ok: [localhost] => (item=/var/log/conf/login/sub/hello.json) => {
    "msg": "The quick brown fox jumps over the lazy LOGINS ;)"
}
ok: [localhost] => (item=/var/log/conf/login/some/test.json) => {
    "msg": "The quick brown fox jumps over the lazy LOGINS ;)"
}

PLAY RECAP ********************************************************************************************************************************************************************************
localhost                  : ok=6    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Upvotes: 1

Related Questions