Ansible playbook not working trying to run patch

I'm trying to use Ansible to provision a Vagrant VM. The VM is running CentOS 6.4. I'm using the following (abbreviated) ansible playbook:

- hosts: default
  vars:
    home: '/home/vagrant'
    curl_version: '7_19_7'
    curl_url: 'https://github.com/bagder/curl/archive/curl-{{ curl_version }}.tar.gz'
    curl_dir: '{{ home }}/curl-curl-{{ curl_version }}'

  # user: vagrant
  remote_user: vagrant
  sudo: yes

  tasks:

  - name: Ensure required packages and installed and up to date - pt1
    yum: pkg={{ item }} state=present
    with_items:
      - make
      - gcc
      - etc...

  # Lots more yum tasks in here

  - name: Ensure CURL source downloaded
    get_url: url={{ curl_url }} dest=/home/vagrant/curl-{{ curl_version }}.tar

  - name: Extract CURL source
    command: tar -zxf {{ home }}/curl-{{ curl_version }}.tar creates={{ curl_dir }}

  - name: Copy ssh patch over
    copy: src=./files/ssh.c.patch dest={{ home }}/ssh.c.patch

  - name: Patch CURL with openssl
    command: '"{{ item }}" chdir={{ curl_dir }}/lib'
    with_items:
      - patch {{ curl_dir }}/lib/ssh.c {{ home }}/ssh.c.patch

Vagrangt is working fine and the Ansible playbook runs successfully up to the last task 'Patch CURL with openssl' - which fails, like so:

TASK: [Patch CURL with openssl] *********************************************** 
failed: [default] => (item=patch < /home/vagrant/ssh.c.patch) => {"cmd": ["patch < /home/vagrant/ssh.c.patch"], "failed": true, "item": "patch < /home/vagrant/ssh.c.patch", "rc": 2}
msg: [Errno 2] No such file or directory

FATAL: all hosts have already failed -- aborting

I've verified that all the tasks up to that point work, and the files are downloaded and extracted to the expected places.

After the task fails, if you SSH into the VM that's being configured, and run the same thing yourself - using the exact values from the playbook variables, it works:

cd /home/vagrant/curl-curl-7_19_7
sudo patch /home/vagrant/curl-curl-7_19_7/lib/ssh.c /home/vagrant/ssh.c.patch

I'm new to Ansible and I'm not sure why this isn't working - it looks like it should be? What am I doing wrong?


Solution 1:

It looks like you are using a shell redirect less-than sign in your "command" call (but it got eaten by the ServerFault parser). Try using "shell" instead of "command" there. Command doesn't go through the shell, so shell stuff like redirects and pipes won't work. Shell should work.

Solution 2:

The answer from @Tybstar pointed me in the right direction - using shell instead of command. The actual fix was to change the patch task from this:

- name: Patch CURL with openssl
  command: '"{{ item }}" chdir={{ curl_dir }}/lib'
  with_items:
    - patch {{ curl_dir }}/lib/ssh.c {{ home }}/ssh.c.patch

to this:

- name: Patch CURL with openssl
  shell: patch {{ curl_dir }}/lib/ssh.c {{ home }}/ssh.c.patch chdir={{ curl_dir }}/lib