How to execute Ad-Hoc commands on remote node using ansible

How to execute Ad-Hoc commands on remote node using ansible

ansible_adhoc.jpg

Here in this article we will see how we can install ansible and manage a remote node by gathering information related to the remote node from the controller node. We will look at some the Ad-hoc modules which we can execute using the ansible tool.

Test Environment

Ansible Controller
Ansible Node

If you are interested in watching the video. Here is the YouTube video on the same step by step procedure outlined below.

Procedure

Step1: Install Ansible from RPM repository

Let’s install ansible on the Ansible controller node.

sudo dnf install ansible

Step2: Validate Ansible Installation

Verify the ansible installation by checking the version information.

ansible --version

Output:

ansible 2.9.18
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/admin/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.8/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.8.2 (default, Feb 28 2020, 00:00:00) [GCC 10.0.1 20200216 (Red Hat 10.0.1-0.8)]

Step3: Create an Inventory file with the nodes to manage

Let’s define the inventory file with the hostname or ip address of the remote which we would like to manage.

File: /etc/ansible/hosts

Output:

[stack]
192.168.47.130

Step4: Generate SSH key pairs and copy to remote node

Generate ssh private and public for user admin.

ssh-keygen -t rsa -C admin
ls -ltr ~/.ssh/

Output:

-rw-r--r--. 1 admin admin  176 Mar 29 15:53 known_hosts
-rw-r--r--. 1 admin admin  559 Mar 29 15:56 id_rsa.pub
-rw-------. 1 admin admin 2590 Mar 29 15:56 id_rsa

Once the key pair are generated we can copy the public key to the remote node as shown below.

ssh-copy-id -i ~/.ssh/id_rsa.pub admin@192.168.47.130

Output:

/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/admin/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
admin@192.168.47.130's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'admin@192.168.47.130'"
and check to make sure that only the key(s) you wanted were added.

Step5: Validate SSH connection

We can validate the remote ssh login using the user admin once the ssh public key has been copied to the remote host. You should be able to login without asking for the password.

ssh admin@192.168.47.130

Output:

Web console: https://ansinode.stack.com:9090/ or https://192.168.47.130:9090/

Last login: Mon Mar 29 15:54:35 2021 from 192.168.47.129

Now that we are able to remote ssh to our node using user admin. Lets try to run some Ad-hoc command using ansible. Ad-hoc commands can be used to manage the files, packages, users, groups, services and facts about the remote node. The default module for the ansible command-line utility is the ansible.builtin.command module.

Step6: Ping the remote node

As a first step, lets try to use the ping module to ping the remote and check what is the response we get from the remote node.

ansible stack -m ping

Output:

192.168.47.130 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"

Step7: Check the kernel version and hostname of the remote host

In this step we will run the ad-hoc command ‘uname -a’ to get the hostname and kernal version details as shown below.

ansible stack -a "uname -a"

Output:

192.168.47.130 | CHANGED | rc=0 >>
Linux ansinode.stack.com 5.6.6-300.fc32.x86_64 #1 SMP Tue Apr 21 13:44:19 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

Step8: Check the free memory

Verify the free memory that is available on the remote node as shown below.

ansible stack -a "free -m"

Output:

192.168.47.130 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:           1951         257        1220           1         472        1542
Swap:          2047           0        2047

Step9: Check the IP address

Verify the IP address of the remote node as shown below.

ansible stack -a "ip addr"

Output:

192.168.47.130 | CHANGED | rc=0 >>
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:63:e4:47 brd ff:ff:ff:ff:ff:ff
    altname enp2s1
    inet 192.168.47.130/24 brd 192.168.47.255 scope global dynamic noprefixroute ens33
       valid_lft 1093sec preferred_lft 1093sec
    inet6 fe80::c8da:2d7b:8a00:668a/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

Until now we have looked at how we can use the default command module. If we want to use a different module we need to pass the -m module name. For using the shell module we need to pass the module name ‘ansible.builtin.shell’. Lets see some of the examples below.

Step10: Run the shell module to retrieve the hostname of the node

Please note we need to make sure on the shell quoting rules so the local shell retains the variables and passes it to Ansible. For example, using double rather than single quotes in the above example would evaluate the variable on the box you were on.

ansible stack -m shell -a 'echo $HOSTNAME'

Output:

192.168.47.130 | CHANGED | rc=0
ansinode.stack.com

Step11: Copy files using the copy module

Here, lets create and txt file and use the copy module to copy the file from controller node to the remote node destination location.

ansible stack -m copy -a 'src=/tmp/helloansible.txt dest=/tmp/helloansible.txt'

Output:

192.168.47.130 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "checksum": "97b63eb592e525b043cf4a8d50fa88ad5fd1f031",
    "dest": "/tmp/helloansible.txt",
    "gid": 1000,
    "group": "admin",
    "md5sum": "a26463d9ebdd339c8ece493267ae5ee5",
    "mode": "0664",
    "owner": "admin",
    "secontext": "unconfined_u:object_r:user_home_t:s0",
    "size": 14,
    "src": "/home/admin/.ansible/tmp/ansible-tmp-1617016144.584841-1823-233756633783429/source",
    "state": "file",
    "uid": 1000

Validate on ansinode server.

ls -ltr /tmp/helloansible.txt

Output:

-rw-rw-r--. 1 admin admin 14 Mar 29 16:39 /tmp/helloansible.txt

Step12: Changing file ownership and permissions using the file module and Managing files

We can also change the ownership and permissions of the files using the file module as shown below. First lets try to change the permissions on the file.

ansible stack -m file -a "dest=/tmp/helloansible.txt mode=600"

Output:

192.168.47.130 | CHANGED
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "gid": 1000,
    "group": "admin",
    "mode": "0600",
    "owner": "admin",
    "path": "/tmp/helloansible.txt",
    "secontext": "unconfined_u:object_r:user_home_t:s0",
    "size": 14,
    "state": "file",
    "uid": 1000

Validate on ansinode server.

Output:

-rw-------. 1 admin admin 14 Mar 29 16:39 /tmp/helloansible.txt

Now lets try to change ownership of the file to root:root and see what happens.

ansible stack -m file -a "dest=/tmp/helloansible.txt owner=root group=root"

Output:

192.168.47.130 | FAILED! {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "gid": 1000,
    "group": "admin",
    "mode": "0600",
    "msg": "chown failed: [Errno 1] Operation not permitted: b'/tmp/helloansible.txt'",
    "owner": "admin",
    "path": "/tmp/helloansible.txt",
    "secontext": "unconfined_u:object_r:user_home_t:s0",
    "size": 14,
    "state": "file",
    "uid": 1000
}

As you can see the user admin does not have the privilege to change the ownership of the file. Lets try to elevate the privilege to root user to change the ownership.

ansible stack -m file -a "dest=/tmp/helloansible.txt owner=root group=root" --become --ask-become-pass

Output:

192.168.47.130 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "gid": 0,
    "group": "root",
    "mode": "0600",
    "owner": "root",
    "path": "/tmp/helloansible.txt",
    "secontext": "unconfined_u:object_r:user_home_t:s0",
    "size": 14,
    "state": "file",
    "uid": 0
}

Validate on ansinode server.

Output:

-rw-------. 1 root root 14 Mar 29 16:39 /tmp/helloansible.txt

We can also manage the directories on the remote node as shown below.

ansible stack -m file -a "dest=/tmp/stack state=directory"

Validate on ansinode server its presence.

ls -ltr /tmp/stack/
ansible stack -m file -a "dest=/tmp/stack state=absent"

Validate on ansinode server its absense.

ls -ltr /tmp/stack/

Output:

ls: cannot access '/tmp/stack/': No such file or directory

Step13: Managing the packages on the remote node using yum module

Here we can install, update, remove the packages on the remote machine using the yum module as shown.

We can also manage users and groups using the ‘user’ module and services using the service module. Also one of the most important thing is about capturing the information about the remote node using the setup module as shown below.

ansible stack -m yum -a 'name=sscg state=present' --become --ask-become-pass

Output:

192.168.47.130 | CHANGED {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "msg": "",
    "rc": 0,
    "results": [
        "Installed: sscg-2.6.2-1.fc32.x86_64"
    ]
}
ansible stack -m yum -a 'name=sscg state=latest' --become --ask-become-pass

Output:

192.168.47.130 | SUCCESS {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "msg": "Nothing to do",
    "rc": 0,
    "results": []
}
ansible stack -m yum -a 'name=sscg state=absent' --become --ask-become-pass

Output:

192.168.47.130 | CHANGED {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "msg": "",
    "rc": 0,
    "results": [
        "Removed: sscg-2.6.2-1.fc32.x86_64"
    ]
}

We can also manage users and groups using the ‘user’ module and services using the service module. Also one of the most important thing is about capturing the information about the remote node using the setup module as shown below.

ansible stack -m setup

Output:

192.168.47.130 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.47.130"
        ],
        "ansible_all_ipv6_addresses": [
            "fe80::c8da:2d7b:8a00:668a"
        ],
        "ansible_apparmor": {
            "status": "disabled"
        },
...

Hope you enjoyed reading this article. Thank you..