>
>
>
>
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
creates
parameter 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
shell
for complex command sequences with proper chdir handling - Proper argument splitting when using
command
module - 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"