trying to understand expect functionality using below piece of code... I know I can do using becom_user, but I would like to check expect module... since there is requirement where I need to use expect module for automating client app CLI
tasks:
- name: testing expect
expect:
command: sudo su
responses:
<?i>password<?i>: "password\n"
<?i>: ls
timeout: 30
echo: yes
register: exp
- debug: var=exp
fatal: [192.168.153.31]: FAILED! => {"changed": true, "cmd": "sudo su", "delta": "0:00:30.133859", "end": "2021-09-30 00:51:45.538114", "msg": "non-zero return code", "rc": 1, "start": "2021-09-30 00:51:15.404255", "stdout": "[sudo] password for XXXXXX: ", "stdout_lines": ["[sudo] password for XXXXX: "]}
Issue is that <?i>password<?i> regex does not match sudo's prompt. Ansible uses python regex and angle brackets have no special meaning there. If you want case insensetive match use (?i)password instead.
Few sidenotes:
Newline at the end of password string is superfluous. Code works without it.
command: sudo su will hang execution on success as it runs shell. It is more convenient to run something that exits, command: sudo id for example.
Related
Ansible4 builtin shell rewrites trust list command to trust list-modules:
- block:
- name: Check if Certs installed - Linux RHEL8 - step 1
ansible.builtin.shell:
cmd: "trust list"
register: isCertInstalled
some additional formatting is piped to whittle this down to a number (omitted for privacy purposes), then:
TASK [Check if Certs installed - Linux RHEL8 - step 1] ********************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": ["trust", "list"], "delta": "0:00:00.007482", "end": "2022-06-21 18:20:43.759496", "msg": "non-zero return code", "rc": 2, "start": "2022-06-21 18:20:43.752014", "stderr": "p11-kit: 'list-modules' is not a valid command. See 'trust --help'", "stderr_lines": ["p11-kit: 'list-modules' is not a valid command. See 'trust --help'"], "stdout": "", "stdout_lines": []}
Any idea how to force it to literally just run "trust list" instead of "trust list-modules"?
RHEL 8.5, Ansible 4.1, Python 3.9
Use the full path for the trust command and enclose trust list in single quotes. Ansible is only seeing LIST, tying that in as list module.
ie. "'trust list' | grep Internal-Cert | wc -l | tr -d '\n'"
I have an ansible task:
- name: Get vault's binary path
shell: type -p vault
register: vault_binary_path
returns
TASK [update_vault : Get vault's binary path] **********************************************************************************************************************************************************************
fatal: [xxxxx]: FAILED! => {"changed": true, "cmd": "type -p vault", "delta": "0:00:00.003303", "end": "2020-04-08 11:37:19.636528", "msg": "non-zero return code", "rc": 1, "start": "2020-04-08 11:37:19.633225", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
but when I run it in shell it returns just fine
[root#ip-xxxxx]# type -p vault
/usr/local/bin/vault
I run ansible as root with become: true. All previous steps are fine up until this one. Any advice appreciated.
Define an update to your PATH in your playbook:
environment:
PATH: "{{ ansible_env.PATH }}:/usr/local/bin"
...so that /usr/local/bin is guaranteed to be included.
(Also, while when writing bash-specific code type is almost always preferable to which, this isn't such a case, as your shell may be /bin/sh, which isn't guaranteed to support any features that aren't given in the POSIX sh specification. Consider changing to shell: command -v vault, which is guaranteed to work as-intended on all POSIX-compliant shells).
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\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
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.
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.
I solved this issue by removing the become_method and become_user off my playbook.
First, I specified the user in the inventory file using ansible_user=your_user. Then, I removed the become_method and become_user off my playbook leaving just become=yes
For more details about this answer, look on this other answer.
I have configured a fully distributed hadoop cluster using ansible, but I want to configure ansible to execute the next command too.
I use the next to execute zookeeper, but I have the next error.
- name: ejecutar zkServer.sh
become_user: vagrant
shell: sh /opt/zookeeper-3.4.7/bin/zkServer.sh
TASK: [ejecutar | ejecutar zkServer.sh] ***************************************
failed: [172.16.8.211] => {"changed": true, "cmd": "sh /opt/zookeeper-3.4.7/bin/zkServer.sh", "delta": "0:00:00.006246", "end": "2016-01-18 14:28:44.181146", "rc": 2, "start": "2016-01-18 14:28:44.174900", "warnings": []}
stderr: /opt/zookeeper-3.4.7/bin/zkServer.sh: 81: /opt/zookeeper-3.4.7/bin/zkEnv.sh: Syntax error: "(" unexpected (expecting "fi")
FATAL: all hosts have already failed -- aborting
Thanks.
It is working like with the next command:
- name: ejecutar zkServer.sh
become_user: vagrant
command: "/opt/zookeeper-3.4.7/bin/zkServer.sh restart"
I have an ansible script I created that backs up a Databases, Destroys, Creates, and Points the back up to the newly created DB:
- name: Backing up database
command: pg_dump --schema-only --file=image.dump.20100217 image
- name: Destroying Current Database
command: time dropdb image
- name: Creating Database
postgresql_db: name=image
owner='ryan'
- name: Pointing newly created DB to Backed up DB
command: psql image < image.dump.20100217
Everything runs fine until it tries to point to the backed up DB. Ansible doesn't process the < symbol and ultimately crashes:
failed: [192.168.x.x] => {"changed": true, "cmd": ["psql", "image", "<", "image.dump.20100217"], "delta": "0:00:00.003229", "end": "2015-08-19 11:26:21.796224", "rc": 2, "start": "2015-08-19 11:26:21.792995", "warnings": []}
stderr: psql: warning: extra command-line argument "image.dump.20100217" ignored
psql: FATAL: role "<" does not exist
FATAL: all hosts have already failed -- aborting
Does anyone have any suggestions on how to work around this?
Have not tested it but the ultimate trick with problematic characters is to put it into a Jinja expression:
command: psql image {{ "<" }} image.dump.20100217
I can't reproduce this in Ansible 1.9.2. Here is what I tested:
- command: echo psql image < image.dump.20100217
register: x
- debug: var=x
Use the module 'shell' instead of 'command'
---
name: Pointing newly created DB to Backed up DB
shell: psql image < image.dump.20100217