1

I wanted to supply a playbook to ansible-playbook 2.4.2.0 from stdin on RHEL 7.5, I found this post which seemed very promising but it's not working for me:

$ cat  ~/simple-ansible-playbook.yaml | ansible-playbook -i ~/inventory.yaml /dev/stdin
ERROR! Unable to retrieve file contents
Could not find or access '/dev/stdin'
$

I tracked down the message to /usr/lib/python2.7/site-packages/ansible/parsing/dataloader.py:

    if not self.path_exists(b_file_name) or not self.is_file(b_file_name):
        raise AnsibleFileNotFound("Unable to retrieve file contents", file_name=file_name)

os.path.isfile() returns False for /dev/stdin which is a symlink to a character special file:

$ ls -l /dev/stdin
lrwxrwxrwx. 1 root root 15 Nov 11 13:11 /dev/stdin -> /proc/self/fd/0
$ ls -Ll /dev/stdin
crw--w----. 1 stack tty 136, 3 Feb 15 07:45 /dev/stdin

Does anyone have any ideas how to get this to work? I don't understand why it seemed to work for the cited post but it's not working for me.

Update

I think I understand this better. The original post used a here document which the shell apparently returns into a regular file. In my method, the data is in a pipe. I didn't realize the shell behaved differently in this respect: I figured the here document would result in a pipe too. So at least I learned something new about the difference but apparently I can't do what I want unless ansible-playbook changes.

2 Answers 2

0

I figured I'm going to have the bite the bullet and put the playbook in a temporary regular file rather than feeding it through stdin.

2
  • I was thinking about doing a PR to change the behavior but it's already been addressed issue 40383. I must have an older version of ansible but I can't rely on what version is available. I'm going the regular file route.
    – John
    Feb 15, 2019 at 14:41
  • This section of the page is reserved for answers. While this may be your decision, it isn't actually an answer because it doesn't clearly explain either why this is not possible or what the problem was and how to resolve it. Feb 15, 2019 at 19:07
0

The original post used a here document which the shell apparently returns into a regular file

The pipe version works fine on a modern version of ansible (I just used the heredoc to make the answer more succinct):

$ printf -- '- hosts: all\n  tasks:\n    - debug: msg=hello\n' | \
      ansible-playbook -c local -i localhost, /dev/stdin

PLAY [all] *********************************************************************

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

TASK [debug] *******************************************************************
ok: [localhost] =>
  msg: hello

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0

$ ls -l /dev/stdin
lrwxrwxrwx 1 root root 15 Feb 15 16:44 /dev/stdin -> /proc/self/fd/0

$ ansible --version
ansible 2.7.7
  config file = None
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python2.7/dist-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 2.7.15rc1 (default, Nov 12 2018, 14:31:15) [GCC 7.3.0]

So the solution to your problem is to upgrade to a modern version of ansible.

However, I didn't want to be all gloom and doom, so there is a work-around available to you, if you insist on feeding the data into ansible via a pipe: cheat and serialize the pipestream to a file with tee:

$ printf -- '- hosts: all\n  tasks:\n    - debug: msg=hello\n' | \
      tee being-on-old-software-is-dangerous.yml | \
      ansible-playbook -c local -i localhost, being-on-old-software-is-dangerous.yml

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .