Home > Enterprise >  Read every line from a text file through ansible
Read every line from a text file through ansible

Time:04-20

I have to read every line from a text file and add that in yaml. Here is my play book

- hosts: localhost
  tasks:
    - name: Register a file content as a variable
      ansible.builtin.shell: cat /home/packages.txt
      register: result

    - name: Print the transformed variable
      ansible.builtin.debug:
        msg: '{{ item }}'
      loop: '{{ result.stdout | list }}'

    - name: install
      shell: yum install '{{ item }}'
      loop: '{{ result.stdout | list }}'

packages.txt contains

nginx
vim
grafana

When I run this, the packages are not getting installed. This is the console output,

TASK [Register a file content as a variable] **********************************************************************************
changed: [localhost]

TASK [Print the transformed variable] *****************************************************************************************

TASK [install] ****************************************************************************************************************

PLAY RECAP ********************************************************************************************************************
localhost : ok=2    changed=1    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0

Requirement is to install those packages from the text file through this ansible playbook

CodePudding user response:

Given the file

shell> cat packages.txt 
nginx
vim
grafana

On localhost, simply iterate the list, e.g. the playbook below

shell> cat test.yml
- hosts: localhost
  tasks:
    - name: install
      package: "{{ item }}"
      loop: "{{ lookup('file', 'packages.txt').split('\n') }}"

gives

shell> ansible-playbook test.yml --check

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

TASK [install] *******************************************************
ok: [localhost] => (item=nginx)
ok: [localhost] => (item=vim)
ok: [localhost] => (item=grafana)

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

On a remote host (lookup works on the localhost only), iterate stdout_lines, e.g.

    - name: Register a file content as a variable
      command: cat packages.txt
      register: result

    - name: install
      package: "{{ item }}"
      loop: "{{ result.stdout_lines }}"

Optionally, if you want to avoid the command or shell module use fetch. For example, in the playbook below

shell> cat test.yml
- hosts: test_11
  tasks:
    - name: Create directory files
      file:
        state: directory
        path: files

    - name: Get file
      fetch:
        src: packages.txt
        dest: files

    - name: install
      package:
        name: "{{ item }}"
      loop: "{{ lookup('file', path).split('\n') }}"
      vars:
        path: 'files/{{ inventory_hostname }}/packages.txt'

create the directory files and fetch the file from the remote host(s) first. This will create the file

shell> cat files/test_11/packages.txt 
nginx
vim
grafana

Then iterate the lines from the file

TASK [install] ***************************************************
changed: [test_11] => (item=nginx)
changed: [test_11] => (item=vim)
changed: [test_11] => (item=grafana)
  • Related