>
>
>
>
When working with Ansible to compile software from source, the command and shell modules behave differently in how they handle command arguments. In this case, we're seeing failures specifically during the ./configure step of building curl from source.
>
>
>
>
- name: Build CURL with openssl
>
> command: 'chdir={{ curl_dir }} "{{ item }}"'
>
> with_items:
>
> - ./buildconf
>
> - ./configure --with-gssapi --with-libidn --with-libssh2 --prefix=/usr --without-nss
>
> - make
>
> - make install
>
> - ldconfig
>
>
The error occurs because Ansible's command module doesn't handle shell-style command parsing. It tries to execute the entire configure string as a single command name rather than parsing the switches.
>
>
>
>
The proper way to handle complex configure commands is to use the shell module with proper quoting:
>
>
- name: Configure and build CURL
>
> shell: |
>
> cd {{ curl_dir }} && \
>
> ./buildconf && \
>
> ./configure --with-gssapi --with-libidn --with-libssh2 --prefix=/usr --without-nss && \
>
> make && \
>
> make install && \
>
> ldconfig
>
> args:
>
> executable: /bin/bash
>
>
>
>
For better error handling and idempotency, consider breaking this into separate tasks:
>
>
- name: Run buildconf
>
> command: ./buildconf
>
> args:
>
> chdir: "{{ curl_dir }}"
>
>- name: Run configure
>
> command: ./configure --with-gssapi --with-libidn --with-libssh2 --prefix=/usr --without-nss
>
> args:
>
> chdir: "{{ curl_dir }}"
>
> register: configure_result
>
> changed_when: "'config.status' not in lookup('file', '{{ curl_dir }}/config.status')"
>
>- name: Run make
>
> make:
>
> chdir: "{{ curl_dir }}"
>
> target: all
>
>- name: Install curl
>
> make:
>
> chdir: "{{ curl_dir }}"
>
> target: install
>
>
>
>
Ensure all build dependencies are installed. For CentOS/RHEL systems, this includes:
>
>
- name: Install build dependencies
>
> yum:
>
> name:
>
> - make
>
> - gcc
>
> - libtool
>
> - automake
>
> - autoconf
>
> - libidn-devel
>
> - libssh2-devel
>
> - krb5-devel
>
> - openssl-devel
>
> state: present
>
>
>
>
Add debug tasks to verify the build environment:
>
>
- name: Check directory structure
>
> command: ls -la {{ curl_dir }}
>
> register: dir_listing
>
> changed_when: false
>
>- debug:
>
> var: dir_listing.stdout_lines
>
>
>
>
-
>
- Always clean the source directory between runs if recompiling
- Consider using
createsparameter to make tasks idempotent - Capture build output in log files for debugging
- Test the playbook in a clean environment
>
>
>
>
>
>
>
>
>
>
>
The root issue stems from how Ansible's command module handles complex command strings differently than direct shell execution. In your playbook, the configure command fails because:
The command module treats the entire string as a single executable path rather than parsing it as a shell would. The error occurs because:
"./configure --with-gssapi --with-libidn --with-libssh2 --prefix=/usr --without-nss"
is interpreted as looking for a single file with that complete name rather than executing ./configure with parameters.
There are several better approaches to execute build commands in Ansible:
- name: Build CURL with openssl (Recommended approach)
shell: |
cd {{ curl_dir }} &&
./buildconf &&
./configure --with-gssapi --with-libidn --with-libssh2 --prefix=/usr --without-nss &&
make &&
make install &&
ldconfig
args:
chdir: "{{ curl_dir }}"
Or using separate tasks with proper module selection:
- name: Run buildconf
command: ./buildconf
args:
chdir: "{{ curl_dir }}"
- name: Run configure
command: ./configure
args:
chdir: "{{ curl_dir }}"
argv:
- "--with-gssapi"
- "--with-libidn"
- "--with-libssh2"
- "--prefix=/usr"
- "--without-nss"
- Using
shellfor complex command sequences with proper chdir handling - Proper argument splitting when using
commandmodule - Maintaining idempotence through proper creates/removes parameters
- Better error handling through sequential execution with &&
Here's the corrected version of your playbook section:
- name: Build and install CURL
block:
- name: Run build steps
shell: |
./buildconf &&
./configure {{ configure_flags }} &&
make &&
make install &&
ldconfig
args:
chdir: "{{ curl_dir }}"
vars:
configure_flags: >
--with-gssapi
--with-libidn
--with-libssh2
--prefix=/usr
--without-nss
environment:
PATH: "{{ ansible_env.PATH }}:/usr/local/bin"