Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cat a file located in files directory in Ansible

Tags:

ansible

This is my structure of role:

$ tree my_role
.
├── my_role
│   ├── defaults
│   │   └── main.yml
│   ├── files
│   │   └── foo.conf
│   ├── handlers
│   │   └── main.yml
│   ├── meta
│   │   └── main.yml
│   ├── README.md
│   ├── tasks
│   │   └── main.yml
│   ├── templates
│   ├── tests
│   │   ├── inventory
│   │   └── test.yml
│   └── vars
│       └── main.yml
└── playbook.yml

I would like to cat the file foo.conf located in files folder in tasks/main.yml.

I tried to use directly in tasks.yml by providing relevant path, however, it says the file is not found.

like image 496
smc Avatar asked Oct 31 '25 18:10

smc


2 Answers

I'm almost sure your exact requirement can be rephrased to something like:

How can I get the content of a file situated in my role's files folder on the controller to use it in a task running on any host?

And the answer is to use the file lookup:

- name: file lookup demo
  debug:
    msg: "{{ lookup('file', 'foo.conf') }}"

This has many advantages over cat in a shell task:

  • It provides the content you look for directly without having to run a separate task, register it's result and get the specific .stdout key.
  • It will work regardless of the target host as lookup always run on the controller
  • It will work with any file situated in the file search path without having to specify its exact path, and wherever that task is defined (e.g. in playbook direct tasks if your role was previously used...)
  • It respects ansible good practices: it does not use shell when there is already a module or filter doing the job for you and it is idempotent out of the box.

If my above assumption was wrong and you still badly want to run cat, answer from @Marco Badelli (although a bad practice) will work but only if you run the shell task directly from your role and on localhost as the path will not exist on any other remote target.

A better option in that case is to use the pipe lookup

- name: pipe lookup demo
  debug:
    msg: "{{ lookup('pipe', `cat ' ~ role_path ~ '/files/foo.conf`) }}"

Although this demonstrates how you can easily get the result of any command ran on the controller, it really has no clear advantage over the file lookup in this situation. For example, it will only work if the task is defined inside your role and not from an other role or playbook task (because of the use of the role_path magic variable).

like image 169
Zeitounator Avatar answered Nov 03 '25 00:11

Zeitounator


I guess you could access the file as relative to the role_path, e.g.

$ echo hello > my_role/files/foo.conf

$ cat my_role/tasks/main.yml
---
- command:
     cmd: cat "{{ role_path }}/files/foo.conf"
  register: x
  # This will never change anything on target.
  changed_when: false
  # This is safe to run also in --check mode to still have register available
  check_mode: false

- debug:
    var: x['stdout']

$ cat myplaybook.yml
---
- name: Playbook which includes the role
  hosts: localhost
  roles:
    - my_role

$ ansible-playbook myplaybook.yml

PLAY [Playbook which includes the role] **************************************************************************

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

TASK [my_role : command] *****************************************************************************************
ok: [localhost]

TASK [my_role : debug] *******************************************************************************************
ok: [localhost] => {
    "x['stdout']": "hello"
}

PLAY RECAP *******************************************************************************************************
localhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
like image 41
Marco Baldelli Avatar answered Nov 03 '25 00:11

Marco Baldelli



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!