对受管节点上的特定 sudo 命令的 ansible 行为

ansible behavior to specific sudo commands on managed nodes

此处讨论当受管节点上的用户被授予特定命令的 sudo 权限时的 ansible 行为。

我在远程托管主机 [rm-host.company.com] 上拥有特定命令的 sudo 权限。其中两个是:

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

PS: /opt/somedir 在远程节点已经存在。

我的ansible控制机版本:

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)]

当我使用 ansbile "file" 模块时,YAML 代码失败,即使我拥有上面列出的 chmod 和 mkdir 的 sudo 权限。

   - 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

运行时错误:

TASK [7|Ensure Directory - "/opt/somedir/unitc" Permissions are 2775] **************************************************************************************************************************************************************************************
fatal: [rm-host.company.com]: FAILED! => {"changed": false, "module_stderr": "FIPS mode initialized\r\nShared connection to rm-host.company.com closed.\r\n", "module_stdout": "sudo: a password is required\r\n", "msg": "MODULE FAILURE\nSee 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

但是当我使用命令模块时成功了,像这样:

  - 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

成功捕获运行时调试输出:

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"
        ]
    }
}

问题:

如何在不使用命令模块的情况下完成这项工作?我想在命令模块中使用 'become'、'become_method' 而不是 运行 sudo 坚持使用 ansible 核心模块。

:

当为所有命令启用 sudo 时它会起作用。但是 [ user ALL=(ALL) NOPASSWD: ALL ] 不能在远程主机上给出。公司政策不允许我所在的组。

简短的回答是你不能。 ansible 的工作方式是在远程主机中执行 python 脚本(原始、命令和 shell 模块除外)。参见 the docs

file 模块执行this script 带有一长串参数。但是 ansible 将首先成为必需的用户,在这种情况下 root by 运行ning sudo -H -S -n -u root /bin/sh 在远程 ssh 会话中(请记住,此命令在您的情况下可能略有不同) .

一旦远程登录的用户成为 root 用户,Ansible 将上传并执行 file.py 脚本。

在你的情况下,你需要恢复使用原始命令或 shell 在你需要 运行 特权命令的情况下。

为了更好地理解这一点并查看正在执行的命令的详细信息和顺序,运行 ansible-playbook 带有参数 -vvvv

我通过从剧本中删除 become_methodbecome_user 解决了这个问题。

首先,我使用 ansible_user=your_user 在清单文件中指定了用户。然后,我从剧本中删除了 become_methodbecome_user,只留下 become=yes

有关此答案的更多详细信息,请查看其他