/usr/sbin/visudo - : No such file or directory error

**/usr/sbin/visudo - : No such file or directory error **.

  • While execute AWX template, we are getting above error, this template will validate list of sudoers files stored in project files path then move it to server path.

  • kubectl version
    Client Version: v1.29.6+k3s2
    Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
    Server Version: v1.29.6+k3s2
    AWX 24.6.1

  • Logs

{
  "changed": false,
  "stdout": "",
  "stderr": "/bin/sh: line 1: /usr/sbin/visudo: No such file or directory",
  "rc": 127,
  "cmd": "/usr/sbin/visudo -cf \"/runner/project/roles/sudoers/files/sudoers.file1\"",
  "start": "2025-03-10 11:44:14.142522",
  "end": "2025-03-10 11:44:14.146179",
  "delta": "0:00:00.003657",
  "msg": "non-zero return code",
  "invocation": {
    "module_args": {
      "_raw_params": "/usr/sbin/visudo -cf \"/runner/project/roles/sudoers/files/sudoers.file1\"",
      "_uses_shell": true,
      "stdin_add_newline": true,
      "strip_empty_ends": true,
      "argv": null,
      "chdir": null,
      "executable": null,
      "creates": null,
      "removes": null,
      "stdin": null
    }
  },
  "stdout_lines": [],
  "stderr_lines": [
    "/bin/sh: line 1: /usr/sbin/visudo: No such file or directory"
  ],
  "_ansible_no_log": false,
  "item": "sudoers.file1",
  "ansible_loop_var": "item",
  "_ansible_item_label": "sudoers.file1",
  "_ansible_delegated_vars": {
    "ansible_host": "127.0.0.1",
    "ansible_port": null,
    "ansible_user": "user",
    "ansible_connection": "local"
  }
}
  • my code!
- name: Validate sudoers files
  shell: /usr/sbin/visudo -cf "{{ role_path }}/files/{{ item }}"
  with_items:
    - sudoers.file1
    - sudoers.file2
    - sudoers.file3
  run_once: true
  delegate_to: 127.0.0.1
  changed_when: False
  register: result

@kurokobo @NomakCooper

Simple query,
Does your hosts have visudo?

Community.general module has installed in our AWX EE. If this is not covered visudo then how to install or copy it to AWX EE?

You are invoking shell module.
visudo is a file on your host, check if it exists.

Yes @vibhor_agarwalin
File is not available

[root@server1 ~]# podman run -it quay.io/ansible/awx-ee:24.6.1 bash
bash-5.1$ ls -l /usr/sbin/
Display all 126 possibilities? (y or n)
bash-5.1$ ls -l /usr/sbin/visudo
ls: cannot access '/usr/sbin/visudo': No such file or directory
bash-5.1$
````

Hello @vibhor_agarwalin
File is not available

[root@server1 ~]# podman run -it quay.io/ansible/awx-ee:24.6.1 bash
bash-5.1$ ls -l /usr/sbin/
Display all 126 possibilities? (y or n)
bash-5.1$ ls -l /usr/sbin/visudo
ls: cannot access '/usr/sbin/visudo': No such file or directory
bash-5.1$
````

Are you trying to edit something with visudo locally inside your execution environment container or on a remote host? If you’re trying to edit on a remote host, delegating to 127.0.0.1 will just attempt to edit the file there inside the container and not on your target. If you’re trying to edit a file in your container, why not edit the image itself?

1 Like

Hello @mcen1,
We are not editing anything, visudo will check the Sudoers file syntax error.

In case you don’t have a requirement to run it locally, remove below line

1 Like

Yes @vibhor_agarwalin - Just before i tried that option but still failing

{
  "changed": false,
  "stdout": "",
  "stderr": "visudo: unable to open /runner/project/roles/sudoers/files/sudoers.file1 No such file or directory",
  "rc": 1,
  "cmd": "/usr/sbin/visudo -cf \"/runner/project/roles/sudoers/files/sudoers.file1\"",
  "start": "2025-03-11 21:50:03.220202",
  "end": "2025-03-11 21:50:03.224535",
  "delta": "0:00:00.004333",
  "msg": "non-zero return code",
  "invocation": {
    "module_args": {
      "_raw_params": "/usr/sbin/visudo -cf \"/runner/project/roles/sudoers/files/sudoers.file1\"",
      "_uses_shell": true,
      "stdin_add_newline": true,
      "strip_empty_ends": true,
      "argv": null,
      "chdir": null,
      "executable": null,
      "creates": null,
      "removes": null,
      "stdin": null
    }
  },
  "stdout_lines": [],
  "stderr_lines": [
    "visudo: unable to open /runner/project/roles/sudoers/files/sudoers.file1 No such file or directory"
  ],
  "_ansible_no_log": false,
  "item": "sudoers.file1",
  "ansible_loop_var": "item",
  "_ansible_item_label": "sudoers.file1"
}

Run is complaining about these files, where are they?

Hi @vibhor_agarwalin
They are under same project role’s file path

project/roles/sudoers/files/sudoers.file1

image

I think I understand your problem. You’re trying to valiidate a sudoers file thats in your project, which is actually inside the EE at run time. Unless you build a custom EE, you cannot validate in the manner you’re trying to do. Instead of trying to validate first using the shell module, use the copy module instead:

# This will never work from an inside an EE unless you build a custom EE. 
- name: Validate sudoers files
  shell: /usr/sbin/visudo -cf "{{ role_path }}/files/{{ item }}"
  with_items:
    - sudoers.file1
    - sudoers.file2
    - sudoers.file3
  run_once: true
  delegate_to: 127.0.0.1
  changed_when: False
  register: result

# What you should do is:
- name: Copy sudoers file over but validate the file first
  ansible.builtin.copy
      src:  "{{ item }}"
      dest: /etc/sudoers.d/{{ item }}"
      mode: '0440'
      owner: root
      group: root
     validate: /usr/sbin/visudo -csf %s
  loop:
    - sudoers.file1
    - sudoers.file2
    - sudoers.file3


The task wiil fail if the sudoers file is invalid and protects you from pushing a bad sudoers file. Read more here: ansible.builtin.copy module – Copy files to remote locations — Ansible Community Documentation

Thank you @binbashroot for your analysis and suggestion.

i am using community.general module under my project’s collections folder, so i thought sudo will be taken care during execution time.

Regarding the Yml code
our intention is first validate the file locally and then copy to sudoers path based on some when condition and copy few files only , so i will try to refine the code and try again

and second option, i will also try custom EE.