Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
641 views
in Technique[技术] by (71.8m points)

ansible behavior to specific sudo commands on managed nodes

Here to discuss the ansible behavior when user at managed nodes is given sudo privileges to specific commands.

I have sudo privileges on remote managed host [rm-host.company.com] to specific commands. Two of them are:

   /bin/mkdir /opt/somedir/unit*
   /bin/chmod 2775 /opt/somedir/unit*

PS: /opt/somedir at remote nodes exists already.

My ansible control machine version:

ansible 2.7.10
python version = 2.7.5 (default, Mar 26 2019, 22:13:06) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]

YAML code fails when I use ansbile "file" module even though I have sudo privileges to chmod and mkdir as listed above.

   - name:  7|Ensure Directory - "/opt/somedir/{{ ENV_CHOSEN }}" Permissions are 2775

     become: yes
     become_method: sudo
     file: path="/opt/somedir/{{ ENV_CHOSEN }}" state=directory mode=2775

     when:
       - ansible_facts['os_family'] == "CentOS" or ansible_facts['os_family'] == "RedHat"
       - ansible_distribution_version | int >= 6
       - http_dir_path.stat.exists == true
       - http_dir_path.stat.isdir == true
       - CreateWebAgentEnvDir is defined
       - CreateWebAgentEnvDir is succeeded

     register: ChangeDirPermission

   - debug:
       var: ChangeDirPermission

Runtime error:

TASK [7|Ensure Directory - "/opt/somedir/unitc" Permissions are 2775] **************************************************************************************************************************************************************************************
fatal: [rm-host.company.com]: FAILED! => {"changed": false, "module_stderr": "FIPS mode initialized
Shared connection to rm-host.company.com closed.
", "module_stdout": "sudo: a password is required
", "msg": "MODULE FAILURE
See stdout/stderr for the exact error", "rc": 1}
        to retry, use: --limit @/u/joker/scripts/Ansible/playbooks/agent/plays/agent_Install.retry

PLAY RECAP ***************************************************************************************************************************************************************************************************************************************************
rm-host.company.com     : ok=9    changed=2    unreachable=0    failed=1

But succeeds when I use command module, like so:

  - name:  7|Ensure Directory - "/opt/somedir/{{ ENV_CHOSEN }}" Permissions are 2775

     command: sudo /bin/chmod 2775 "/opt/somedir/{{ ENV_CHOSEN }}"

     when:
       - ansible_facts['os_family'] == "CentOS" or ansible_facts['os_family'] == "RedHat"
       - ansible_distribution_version | int >= 6
       - http_dir_path.stat.exists == true
       - http_dir_path.stat.isdir == true
       - CreateagentEnvDir is defined
       - CreateagentEnvDir is succeeded

     register: ChangeDirPermission

   - debug:
       var: ChangeDirPermission

Success Runtime debug output captured:

TASK [7|Ensure Directory - "/opt/somedir/unitc" Permissions are 2775] **************************************************************************************************************************************************************************************
 [WARNING]: Consider using 'become', 'become_method', and 'become_user' rather than running sudo

changed: [rm-host.company.com]

TASK [debug] *************************************************************************************************************************************************************************************************************************************************
ok: [rm-host.company.com] => {
    "ChangeDirPermission": {
        "changed": true,
        "cmd": [
            "sudo",
            "/bin/chmod",
            "2775",
            "/opt/somedir/unitc"
        ],
        "delta": "0:00:00.301570",
        "end": "2019-06-22 13:20:17.300266",
        "failed": false,
        "rc": 0,
        "start": "2019-06-22 13:20:16.998696",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "",
        "stdout_lines": [],
        "warnings": [
            "Consider using 'become', 'become_method', and 'become_user' rather than running sudo"
        ]
    }
}

Question:

How can I make this work without using command module? I want to stick to ansible core modules using 'become', 'become_method' rather than running sudo in command module.

Note:

It works when sudo is enabled for ALL commands. But [ user ALL=(ALL) NOPASSWD: ALL ] cannot be given on remote host. Not allowed by company policy for the group I am in.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The short answer is you can't. The way ansible works is by executing python scripts in the remote host (except for the raw, command and shell modules). See the docs.

The file module executes this script with a long line of parameters. But ansible will first become the required user, in this case root by running sudo -H -S -n -u root /bin/sh in the remote ssh session (please bear in mind that this command might be slightly different in your case).

Once the user logged remotely has become the root user, Ansible will upload and execute the file.py script.

It looks like in your case, you'll need to revert to use the raw, command or shell in the cases you need to run the privileged commands.

To understand this a bit better and see the detail and order of the commands being executed, run ansible-playbook with the parameter -vvvv.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...