<p>I added a step in the additional_build_steps section of my <code>execution-environment.yml</code> (for ansible-builder to make the Docker image) to set the capabilities:</p>
<pre><code>  additional_build_steps:
    prepend_base:
      - RUN setcap cap_net_raw+ep /usr/bin/ping
</code></pre>
<p>This command gives the ping command the <strong>CAP_NET_RAW</strong> capability, which it needs to create raw network sockets.
I made sure to install the <code>iptuils</code> packages and set the capability during the build process of the Execution Environment.</p>
<p>The CAP_NET_RAW capability allows the ping command to run without root privileges while still being able to send and receive ICMP packets, which is necessary for its operation.
This solution addressed the core issue: in containerized environments, the ping command often doesn't work by default due to security restrictions. By explicitly granting it the necessary capability, I enabled it to function correctly within the constraints of the container environment.</p>
<p>My final <code>execution-environment.yml</code> is:</p>
<pre><code>  ---
  version: 3

  images:
    base_image:
      name: quay.io/centos/centos:stream9

  dependencies:
    ansible_core:
      package_pip: ansible-core&gt;=2.15.0rc2,&lt;2.16
    ansible_runner:
      package_pip: ansible-runner
    galaxy:
      collections:
        - name: awx.awx
        - name: community.vmware
        - name: cisco.nxos
        - name: cisco.aci
        - name: kubernetes.core
        - name: ansible.posix
        - name: ansible.windows
        - name: redhatinsights.insights
    python:
      - paramiko
      - pymssql
      - git+https://github.com/vmware/vsphere-automation-sdk-python.git
    system:
      - dnf-plugins-core
      - git
      - python3-devel
      - gcc
      - iputils
      - iproute
      - libcap
      - net-tools

  additional_build_steps:
    prepend_base:
      - RUN curl -LO &quot;https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl&quot;
      - RUN install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
      - RUN rm kubectl
      - RUN dnf install -y iputils iproute
      - RUN setcap cap_net_raw+ep /usr/bin/ping
    append_final:
      - RUN pip install --upgrade pip

  options:
    package_manager_path: /usr/bin/dnf
</code></pre>

CC BY-SA 4.0
2024-07-26T17:48:44.387Z
2024-07-26T17:48:44.387Z
KidACrimson
<p>I built a Docker image from CentOS 9 Stream via Ansible-Builder. When I spin up the Docker container I can ping VMs in my network. Also when I run a Playbook to manually create a K8s Pod from the Docker image ping works fine. However, when I use the EE for my Template, ping fails inside the Job. Even when I test pinging 127.0.0.1 or localhost it still fails.</p>
<p>I have used this exact same Docker image in a work lab and ping works fine, so I know the issue is related to my home K8s and/or AWX environment.</p>
<p>When I <code>kubectl exec -it</code> into the running EE pod, I see no output from ping:</p>
<pre><code>root@ansible-ubuntu-1:~# kubectl exec -it automation-job-239-5dft4 -- /bin/bash
bash-5.1$ ping 127.0.0.1
bash-5.1$
bash-5.1$ ping 192.168.1.1
bash-5.1$
bash-5.1$ ping 192.168.3.1
</code></pre>
<p>Perhaps this is a Kubernetes issue? If so I would also expect the pings from inside the EE pod I spin up to fail, however.</p>
<p>Here is my Playbook:</p>
<pre><code>---
- name: Ping Localhost and 127.0.0.1
  hosts: localhost
  gather_facts: false

  tasks:
    - name: Show the location of the ping command using 'command -v'
      ansible.builtin.command:
        cmd: command -v ping
      register: command_v_ping_result

    - name: Display the location of the ping command using 'command -v'
      ansible.builtin.debug:
        var: command_v_ping_result.stdout

    - name: Show the location of the ping command using 'type'
      ansible.builtin.shell:
        cmd: type ping
      register: type_ping_result

    - name: Display the location of the ping command using 'type'
      ansible.builtin.debug:
        var: type_ping_result.stdout

    - name: Wait for 30 minutes
      ansible.builtin.pause:
        minutes: 30
        prompt: &quot;Pausing for 30 minutes. You can kubectl exec -it into the pod during this time.&quot;

    - name: Ping localhost
      ansible.builtin.ping:
      delegate_to: localhost

    - name: Ping 127.0.0.1
      ansible.builtin.command:
        cmd: ping -c 2 127.0.0.1
      register: ping_result

    - name: Display ping result
      ansible.builtin.debug:
        var: ping_result.stdout
</code></pre>
<p>Here is the job output:</p>
<pre><code>[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'

PLAY [Ping Localhost and 127.0.0.1] ********************************************

TASK [Show the location of the ping command using 'command -v'] ****************
changed: [localhost]

TASK [Display the location of the ping command using 'command -v'] *************
ok: [localhost] =&gt; {
    &quot;command_v_ping_result.stdout&quot;: &quot;/usr/sbin/ping&quot;
}

TASK [Show the location of the ping command using 'type'] **********************
changed: [localhost]

TASK [Display the location of the ping command using 'type'] *******************
ok: [localhost] =&gt; {
    &quot;type_ping_result.stdout&quot;: &quot;ping is /usr/sbin/ping&quot;
}

TASK [Ping localhost] **********************************************************
ok: [localhost]

TASK [Ping 127.0.0.1] **********************************************************
fatal: [localhost]: FAILED! =&gt; {&quot;changed&quot;: true, &quot;cmd&quot;: [&quot;ping&quot;, &quot;-c&quot;, &quot;2&quot;, &quot;127.0.0.1&quot;], &quot;delta&quot;: &quot;0:00:00.009202&quot;, &quot;end&quot;: &quot;2024-07-24 15:19:28.971365&quot;, &quot;msg&quot;: &quot;non-zero return code&quot;, &quot;rc&quot;: 2, &quot;start&quot;: &quot;2024-07-24 15:19:28.962163&quot;, &quot;stderr&quot;: &quot;&quot;, &quot;stderr_lines&quot;: [], &quot;stdout&quot;: &quot;&quot;, &quot;stdout_lines&quot;: []}

PLAY RECAP *********************************************************************
localhost                  : ok=5    changed=2    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
</code></pre>
<p>Here is my execution-environment.yml file I'm using to build the Docker image via ansible-builder:</p>
<pre><code>version: 3
images:
  base_image:
    name: quay.io/centos/centos:stream9
dependencies:
  system: |
    git
    python3-devel
    gcc
    iputils  # Added to include the ping command
  ansible_core:
    # Require minimum of 2.15 to get ansible-inventory --limit option
    package_pip: ansible-core&gt;=2.15.0rc2,&lt;2.16
  ansible_runner:
    package_pip: ansible-runner
  galaxy: |
    ---
    collections:
      - name: awx.awx
      - name: community.vmware
      - name: cisco.nxos
      - name: cisco.aci
      - name: kubernetes.core
      - name: ansible.posix
      - name: ansible.windows
      - name: redhatinsights.insights
  python: |
    paramiko
    pymssql
</code></pre>

<kubernetes><ansible><awx>
Ansible AWX issue - Ping module fails in my custom Execution Environment pod when running Jobs, but not when I start the Pod manually
KidACrimson
# Ansible AWX issue - Ping module fails in my custom Execution Environment pod when running Jobs, but not when I start the Pod manually

(Asked by: username_0 on 2024-07-25)

I built a Docker image from CentOS 9 Stream via Ansible-Builder. When I spin up the Docker container I can ping VMs in my network. Also when I run a Playbook to manually create a K8s Pod from the Docker image ping works fine. However, when I use the EE for my Template, ping fails inside the Job. Even when I test pinging 127.0.0.1 or localhost it still fails.
I have used this exact same Docker image in a work lab and ping works fine, so I know the issue is related to my home K8s and/or AWX environment.
When I kubectl exec -it into the running EE pod, I see no output from ping:
root@ansible-ubuntu-1:~# kubectl exec -it automation-job-239-5dft4 -- /bin/bash
bash-5.1$ ping 127.0.0.1
bash-5.1$
bash-5.1$ ping 192.168.1.1
bash-5.1$
bash-5.1$ ping 192.168.3.1

Perhaps this is a Kubernetes issue? If so I would also expect the pings from inside the EE pod I spin up to fail, however.
Here is my Playbook:
---
- name: Ping Localhost and 127.0.0.1
  hosts: localhost
  gather_facts: false

  tasks:
    - name: Show the location of the ping command using 'command -v'
      ansible.builtin.command:
        cmd: command -v ping
      register: command_v_ping_result

    - name: Display the location of the ping command using 'command -v'
      ansible.builtin.debug:
        var: command_v_ping_result.stdout

    - name: Show the location of the ping command using 'type'
      ansible.builtin.shell:
        cmd: type ping
      register: type_ping_result

    - name: Display the location of the ping command using 'type'
      ansible.builtin.debug:
        var: type_ping_result.stdout

    - name: Wait for 30 minutes
      ansible.builtin.pause:
        minutes: 30
        prompt: "Pausing for 30 minutes. You can kubectl exec -it into the pod during this time."

    - name: Ping localhost
      ansible.builtin.ping:
      delegate_to: localhost

    - name: Ping 127.0.0.1
      ansible.builtin.command:
        cmd: ping -c 2 127.0.0.1
      register: ping_result

    - name: Display ping result
      ansible.builtin.debug:
        var: ping_result.stdout

Here is the job output:
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'

PLAY [Ping Localhost and 127.0.0.1] ********************************************

TASK [Show the location of the ping command using 'command -v'] ****************
changed: [localhost]

TASK [Display the location of the ping command using 'command -v'] *************
ok: [localhost] => {
    "command_v_ping_result.stdout": "/usr/sbin/ping"
}

TASK [Show the location of the ping command using 'type'] **********************
changed: [localhost]

TASK [Display the location of the ping command using 'type'] *******************
ok: [localhost] => {
    "type_ping_result.stdout": "ping is /usr/sbin/ping"
}

TASK [Ping localhost] **********************************************************
ok: [localhost]

TASK [Ping 127.0.0.1] **********************************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": ["ping", "-c", "2", "127.0.0.1"], "delta": "0:00:00.009202", "end": "2024-07-24 15:19:28.971365", "msg": "non-zero return code", "rc": 2, "start": "2024-07-24 15:19:28.962163", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}

PLAY RECAP *********************************************************************
localhost                  : ok=5    changed=2    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

Here is my execution-environment.yml file I'm using to build the Docker image via ansible-builder:
version: 3
images:
  base_image:
    name: quay.io/centos/centos:stream9
dependencies:
  system: |
    git
    python3-devel
    gcc
    iputils  # Added to include the ping command
  ansible_core:
    # Require minimum of 2.15 to get ansible-inventory --limit option
    package_pip: ansible-core>=2.15.0rc2,<2.16
  ansible_runner:
    package_pip: ansible-runner
  galaxy: |
    ---
    collections:
      - name: awx.awx
      - name: community.vmware
      - name: cisco.nxos
      - name: cisco.aci
      - name: kubernetes.core
      - name: ansible.posix
      - name: ansible.windows
      - name: redhatinsights.insights
  python: |
    paramiko
    pymssql

**Tags:** kubernetes, ansible, awx


---

## 1 answers

### Answer by username_0 on 2024-07-26. Score: 0 | Accepted answer

I added a step in the additional_build_steps section of my execution-environment.yml (for ansible-builder to make the Docker image) to set the capabilities:
  additional_build_steps:
    prepend_base:
      - RUN setcap cap_net_raw+ep /usr/bin/ping

This command gives the ping command the CAP_NET_RAW capability, which it needs to create raw network sockets.
I made sure to install the iptuils packages and set the capability during the build process of the Execution Environment.
The CAP_NET_RAW capability allows the ping command to run without root privileges while still being able to send and receive ICMP packets, which is necessary for its operation.
This solution addressed the core issue: in containerized environments, the ping command often doesn't work by default due to security restrictions. By explicitly granting it the necessary capability, I enabled it to function correctly within the constraints of the container environment.
My final execution-environment.yml is:
  ---
  version: 3

  images:
    base_image:
      name: quay.io/centos/centos:stream9

  dependencies:
    ansible_core:
      package_pip: ansible-core>=2.15.0rc2,<2.16
    ansible_runner:
      package_pip: ansible-runner
    galaxy:
      collections:
        - name: awx.awx
        - name: community.vmware
        - name: cisco.nxos
        - name: cisco.aci
        - name: kubernetes.core
        - name: ansible.posix
        - name: ansible.windows
        - name: redhatinsights.insights
    python:
      - paramiko
      - pymssql
      - git+https://github.com/vmware/vsphere-automation-sdk-python.git
    system:
      - dnf-plugins-core
      - git
      - python3-devel
      - gcc
      - iputils
      - iproute
      - libcap
      - net-tools

  additional_build_steps:
    prepend_base:
      - RUN curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
      - RUN install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
      - RUN rm kubectl
      - RUN dnf install -y iputils iproute
      - RUN setcap cap_net_raw+ep /usr/bin/ping
    append_final:
      - RUN pip install --upgrade pip

  options:
    package_manager_path: /usr/bin/dnf


---

