1
votes

Without an agent on target host, Ansible is able to perform tasks like for example: adding a user(-m user).

To understand this, I read this article, which says:

"Ansible works by connecting to your nodes and pushing out small programs, called "Ansible modules" to them. These programs are written to be resource models of the desired state of the system."

To understand this point, my interpretation is, user module is python module located in control server and this module is serialized on wire to target host, after running ansible command with -m user option.


Does ansible serialize these programs(user source code) via ssh? to execute on remote host...

Does this serialization involves ssh agent forwarding technique?

1

1 Answers

3
votes

When ansible executes a module in your playbook, it serializes the code it needs to run with the encountered parameters into a local python files named <local user home>/.ansible/tmp/ansible-local-<current-run-hash>/tmp<some-other-hash>.

This file is uploaded to the remote host in <remote_user home dir>/.ansible/tmp/ansible-tmp-<current-run-hashed-id>/AnsiballZ_<module_name>.py using the declared connection for this host (ssh, docker, local...).

The python file is executed on the remote host through that connection, result is fetched back to the local machine and the file is cleaned-up.

You can see exactly how all this is executed using the -vvv option to ansible-playbook (or ansible if you are sending ad-hoc commands). Here is an example of running the stat module against a docker host on my local machine.

The task:

- name: Check if SystemD service is installed
  stat:
    path: /etc/systemd/system/nexus.service
  register: nexus_systemd_service_file

Running with -vvv. The file copy to remote starts at line 7.

    TASK [nexus3-oss : Check if SystemD service is installed] **********************
    task path: /projects/ansible/nexus3-oss/tasks/main.yml:13
    <nexus3-oss-debian-stretch> ESTABLISH DOCKER CONNECTION FOR USER: root
    <nexus3-oss-debian-stretch> EXEC ['/usr/bin/docker', b'exec', b'-i', 'nexus3-oss-debian-stretch', '/bin/sh', '-c', "/bin/sh -c 'echo ~ && sleep 0'"]
    <nexus3-oss-debian-stretch> EXEC ['/usr/bin/docker', b'exec', b'-i', 'nexus3-oss-debian-stretch', '/bin/sh', '-c', '/bin/sh -c \'( umask 77 && mkdir -p "` echo /home/deployuser/.ansible/tmp/ansible-tmp-1555848182.1761565-31974482443721 `" && echo ansible-tmp-1555848182.1761565-31974482443721="` echo /deployuser/.ansible/tmp/ansible-tmp-1555848182.1761565-31974482443721 `" ) && sleep 0\'']
    Using module file /home/localuser/.local/lib/python3.6/site-packages/ansible/modules/files/stat.py
    <nexus3-oss-debian-stretch> PUT /home/localuser/.ansible/tmp/ansible-local-30458wt820190/tmpq2vjarrv TO /home/deployuser/.ansible/tmp/ansible-tmp-1555848182.1761565-31974482443721/AnsiballZ_stat.py
    <nexus3-oss-debian-stretch> EXEC ['/usr/bin/docker', b'exec', b'-i', 'nexus3-oss-debian-stretch', '/bin/sh', '-c', "/bin/sh -c 'chmod u+x /home/deployuser/.ansible/tmp/ansible-tmp-1555848182.1761565-31974482443721/ /home/deployuser/.ansible/tmp/ansible-tmp-1555848182.1761565-31974482443721/AnsiballZ_stat.py && sleep 0'"]
    <nexus3-oss-debian-stretch> EXEC ['/usr/bin/docker', b'exec', b'-i', 'nexus3-oss-debian-stretch', '/bin/sh', '-c', '/bin/sh -c \'http_proxy=\'"\'"\'\'"\'"\' https_proxy=\'"\'"\'\'"\'"\' no_proxy=\'"\'"\'\'"\'"\' /usr/bin/python /home/deployuser/.ansible/tmp/ansible-tmp-1555848182.1761565-31974482443721/AnsiballZ_stat.py && sleep 0\'']
    <nexus3-oss-debian-stretch> EXEC ['/usr/bin/docker', b'exec', b'-i', 'nexus3-oss-debian-stretch', '/bin/sh', '-c', "/bin/sh -c 'rm -f -r /home/deployuser/.ansible/tmp/ansible-tmp-1555848182.1761565-31974482443721/ > /dev/null 2>&1 && sleep 0'"]
    ok: [nexus3-oss-debian-stretch] => {
        "changed": false,
        "invocation": {
            "module_args": {
                "checksum_algorithm": "sha1",
                "follow": false,
                "get_attributes": true,
                "get_checksum": true,
                "get_md5": null,
                "get_mime": true,
                "path": "/etc/systemd/system/nexus.service"
            }
        },
        "stat": {
            "atime": 1555848116.0796735,
            "attr_flags": "",
            "attributes": [],
            "block_size": 4096,
            "blocks": 8,
            "charset": "us-ascii",
            "checksum": "f1de2c2bc91adc019e58f83a29c970d1d79d5cc9",
            "ctime": 1553622777.8884165,
            "dev": 77,
            "device_type": 0,
            "executable": false,
            "exists": true,
            "gid": 0,
            "gr_name": "root",
            "inode": 22997,
            "isblk": false,
            "ischr": false,
            "isdir": false,
            "isfifo": false,
            "isgid": false,
            "islnk": false,
            "isreg": true,
            "issock": false,
            "isuid": false,
            "mimetype": "text/plain",
            "mode": "0644",
            "mtime": 1553622777.3485653,
            "nlink": 1,
            "path": "/etc/systemd/system/nexus.service",
            "pw_name": "root",
            "readable": true,
            "rgrp": true,
            "roth": true,
            "rusr": true,
            "size": 248,
            "uid": 0,
            "version": "687353",
            "wgrp": false,
            "woth": false,
            "writeable": true,
            "wusr": true,
            "xgrp": false,
            "xoth": false,
            "xusr": false
        }
    }