# How to use Ansible over Meshnet

## Introduction

[Ansible](https://www.redhat.com/en/technologies/management/ansible/what-is-ansible) is free, open-source software available on macOS and Linux that is used for cross-platform automation. It allows you to control numerous host devices at the same time. You can automate virtual machine creation, operating system installation, software configuration, and much more.

While you can use Ansible with remote devices, you must ensure that the host device’s network allows outside connections by opening ports in the firewall. This configuration may leave the host device vulnerable to malicious intrusion.

By using [Meshnet](https://nordvpn.com/meshnet/) in your Ansible configuration, you can connect devices to virtual private networks. All commands and [playbooks ](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_intro.html)are executed via an encrypted tunnel using the [NordLynx technology](https://nordvpn.com/blog/nordlynx-protocol-wireguard/). This results in a fast and secure data exchange between the devices.

In this article, you will find instructions on how to prepare an Ansible control node on macOS and Linux for remote connections over Meshnet.

## Before you begin <a href="#before-you-begin" id="before-you-begin"></a>

{% hint style="info" %}
**Note**

For the purpose of this article, Ansible host devices will be Linux machines.
{% endhint %}

Ansible uses a [secure shell](https://en.wikipedia.org/wiki/Secure_Shell) (SSH) connection between devices. While username and password authentication can be used, SSH keys are preferred. SSH key-based authentication is more secure due to its asymmetric encryption. Additionally, no user input is required for authentication, which makes it easier to set up and execute automated workflows.

### Enable host SSH access <a href="#enable-host-ssh-access" id="enable-host-ssh-access"></a>

Ensure that your Ansible host devices accept SSH connections by following instructions from the [Enable SSH access](https://meshnet.nordvpn.com/~/changes/5hiVtBuK6qwLGxb0SjCm/how-to/access-remote-systems-over-ssh#enable-ssh-access) section of the "How to access remote systems over Meshnet using SSH" article.

### Prepare SSH key authentication <a href="#prepare-ssh-key-authentication" id="prepare-ssh-key-authentication"></a>

For this configuration, you need to generate an SSH key on your control node device and copy it to your Ansible host devices. For instructions on setting up SSH keys, see the [Configuring SSH keys](https://meshnet.nordvpn.com/~/changes/5hiVtBuK6qwLGxb0SjCm/how-to/access-remote-systems-over-ssh#configuring-ssh-keys) section of the "How to access remote systems over Meshnet using SSH" article.

## Install Ansible <a href="#install-ansible" id="install-ansible"></a>

With the prerequisites taken care of, you can proceed with installing the Ansible software.

{% tabs %}
{% tab title="Linux" %}

1. Open **Terminal**.
2. Execute this command to update your repositories and install Ansible:

   ```bash
   sudo apt update && sudo apt install ansible -y
   ```

Ansible and its required packages are now installed on your system and ready for use.
{% endtab %}

{% tab title="macOS" %}
To install Ansible on macOS, you need to use the [Homebrew](https://brew.sh/) package manager.

1. Open **Terminal**.
2. Enter the following command to install Homebrew:<br>

   <pre class="language-bash" data-overflow="wrap"><code class="lang-bash">/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
   </code></pre>

   &#x20;

   For additional information about the installation process, refer to [Homebrew documentation](https://docs.brew.sh/Installation).
3. Follow the on-screen instructions to finish the installation.
4. Install Ansible by running the following command:<br>

   ```bash
   brew install ansible
   ```

Ansible and its required packages are now installed on your system and ready for use.
{% endtab %}
{% endtabs %}

## Add Meshnet host devices <a href="#add-meshnet-host-devices" id="add-meshnet-host-devices"></a>

After installing, you need to point Ansible to the host devices in Ansible’s `hosts` file.

{% tabs %}
{% tab title="Linux" %}

1. Open the `hosts` file in the Nano text editor using this command:<br>

   ```bash
   sudo nano /etc/ansible/hosts
   ```

   &#x20;

   If the `hosts` file or the `ansible` directory are not present on your system, you can create them using the following command:<br>

   ```bash
   sudo mkdir /etc/ansible && sudo nano /etc/ansible/hosts
   ```

   &#x20;
2. Append a line for your Meshnet device as shown:<br>

   ```bash
   <alias> ansible_host=<NordName> ansible_user=<username>
   ```

   \
   Where:\
   • `<alias>` is a custom alias for the host device.\
   • `<NordName>` is the host device's Nord name or Meshnet IP address.\
   • `<username>` is the username of the host device's account used for SSH.\
   \
   This line creates an alias for a specified IP address or hostname. The alias can then be used in Ansible commands or playbooks for controlling the specified device.\
   \
   **Example**

   ```bash
   meshUbuntu ansible_host=secret.meerkat-altai.nord ansible_user=ubuntu
   ```

   &#x20;
3. Press **Ctrl** + **X**, **Y**, and **Enter** to save changes and exit.

For each additional host device, you need to append a new line in the `hosts` file.

You can also assign host devices into groups. This allows you to control all devices in a group with a single command by addressing them via the group name. The group name must be written inside square brackets before any of the host devices in that group.

For example, to create a group called `meshDevices`, you need to append a `[meshDevices]` line above all device lines.

<figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FcpfTeFvTx87wnc9ypjou%2Fansible_linux_host_group.png?alt=media&#x26;token=7c3ab4e6-1b4d-4f76-960e-427b210de5b0" alt="Ansible hosts file"><figcaption></figcaption></figure>
{% endtab %}

{% tab title="macOS (Intel)" %}

1. Create and open the `hosts` file using the Nano text editor by running this command in the terminal:<br>

   ```bash
   mkdir /usr/local/etc/ansible && nano /usr/local/etc/ansible/hosts
   ```

   &#x20;
2. Append a line for your Meshnet device as shown:<br>

   ```bash
   <alias> ansible_host=<NordName> ansible_user=<username>
   ```

   &#x20;

   Where:\
   • `<alias>` is a custom name for the host device.\
   • `<NordName>` is the host device's Nord name or Meshnet IP address.\
   • `<username>` is the username of the host device's account used for SSH.\
   \
   This line creates an alias for a specified IP address or hostname. The alias can then be used in Ansible commands or playbooks for controlling the specified device.\ <br>

   **Example**

   ```bash
   meshUbuntu ansible_host=secret.meerkat-altai.nord ansible_user=ubuntu
   ```

   &#x20;
3. Press **Control** + **X**, **Y**, and **Return** to save changes and exit.
4. Create an Ansible configuration file and point it to the `hosts` file using this command:<br>

   <pre class="language-bash" data-overflow="wrap"><code class="lang-bash">echo "[defaults]\ninventory = /usr/local/etc/ansible/hosts" >> /usr/local/etc/ansible/ansible.cfg
   </code></pre>

   &#x20;
5. Check if the `ansible.cfg` file has been created with the correct `hosts` file path by running this command:<br>

   ```bash
   cat /usr/local/etc/ansible/ansible.cfg
   ```

   <div align="left"><figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FqrMWt4aElOYlXcalikhg%2Fansible_mac_cat.png?alt=media&#x26;token=710d8ceb-ae7b-4159-8d6b-36f02dbe9f5b" alt="Ansible configuration file"><figcaption></figcaption></figure></div>

For each additional host device, you need to append a new line in the `hosts` file.

You can also assign host devices into groups. This allows you to control all devices in a group with a single command by addressing them via the group name. The group name must be written inside square brackets before any of the host devices in that group.

For example, to create a group called `meshDevices`, you need to append a `[meshDevices]` line above all device lines.

<div align="left"><figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2Frly0Mh6Z0L39k3yqJtwE%2Fansible_mac_group.png?alt=media&#x26;token=1b1bc985-0a2a-4fa0-9934-fe7ea05143b0" alt="Ansible hosts file"><figcaption></figcaption></figure></div>
{% endtab %}

{% tab title="macOS (Apple silicon)" %}

1. Create and open the `hosts` file using Nano by running this command in the terminal:<br>

   <pre class="language-bash" data-overflow="wrap"><code class="lang-bash">mkdir /opt/homebrew/etc/ansible &#x26;&#x26; nano /opt/homebrew/etc/ansible/hosts
   </code></pre>

   &#x20;
2. Append a line for your Meshnet device as shown:<br>

   <pre class="language-bash" data-overflow="wrap"><code class="lang-bash">&#x3C;alias> ansible_host=&#x3C;NordName> ansible_user=&#x3C;username>
   </code></pre>

   &#x20;

   Where:\
   • `<alias>` is a custom name for the host device.\
   • `<NordName>` is the host device's Nord name or Meshnet IP address.\
   • `<username>` is the username of the host device's account used for SSH.\
   \
   This line creates an alias for a specified IP address or hostname. The alias can then be used in Ansible commands or playbooks for controlling the specified device.<br>

   **Example**

   <pre class="language-bash" data-overflow="wrap"><code class="lang-bash">meshUbuntu ansible_host=secret.meerkat-altai.nord ansible_user=ubuntu
   </code></pre>

   &#x20;
3. Press **Control** + **X**, **Y**, and **Return** to save changes and exit.
4. Create an Ansible configuration file and point it to the `hosts` file via this command:<br>

   <pre class="language-bash" data-overflow="wrap"><code class="lang-bash">echo "[defaults]\ninventory = /opt/homebrew/etc/ansible/hosts" >> /opt/homebrew/etc/ansible/ansible.cfg
   </code></pre>

   &#x20;
5. Check if the `ansible.cfg` file has been created with the correct `hosts` file path by running this command:<br>

   ```bash
   cat /opt/homebrew/etc/ansible/ansible.cfg 
   ```

   <div align="left"><figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FqhFtD1l60zdyeq9zU2vP%2Fansible_mac_cat_as.png?alt=media&#x26;token=5c5dc759-b93d-41aa-8ced-cbf8dd11d626" alt="Ansible configuration file"><figcaption></figcaption></figure></div>

For each additional host device, you need to append a new line in the `hosts` file.

You can also assign host devices into groups. This allows you to control all devices in a group with a single command by addressing them via the group name. The group name must be written inside square brackets before any of the host devices in that group.

For example, to create a group called `meshDevices`, you need to append a `[meshDevices]` line above all device lines.

<div align="left"><figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2F4Mtm8AeQfCxkesYAuzBB%2Fansible_mac_group_as.png?alt=media&#x26;token=5230cb63-472a-467b-b2e1-f666570fa9c7" alt="Ansible hosts file"><figcaption></figcaption></figure></div>
{% endtab %}
{% endtabs %}

## Enable passwordless sudo access <a href="#enable-passwordless-sudo-access" id="enable-passwordless-sudo-access"></a>

To make Ansible more efficient, you want to minimize the number of times you need user input. By default, you are prompted to enter the root password to perform many tasks, for example, installing software or performing updates.

To avoid this, you can disable the sudo password prompt for a specific user on your Ansible host devices.

1. Open **Terminal**.

2. Run the following command to safely edit the `sudoers` file:<br>

   ```bash
   sudo visudo
   ```

   &#x20;

3. At the end of the file, append a line, replacing `<username>` with the account’s username:<br>

   ```bash
   <username> ALL=(ALL) NOPASSWD:ALL
   ```

   \
   This command will disable the root password requirement for the specified user.\
   \
   **Example**

   <div align="left"><figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FHwB2wT1aKNj3i5EbYKpa%2Flinux_visudo.png?alt=media&#x26;token=99111e72-d12b-40d1-9f9b-4991d56b68c6" alt="sudoers file being edited"><figcaption></figcaption></figure></div>

4. Press **Ctrl** + **X**, **Y**, and **Return** to save changes and exit.

## Test connection to Meshnet hosts <a href="#test-connection-to-meshnet-hosts" id="test-connection-to-meshnet-hosts"></a>

Check if a connection between the control node and host devices can be established by using the following command:

```bash
ansible -m ping all
```

The response you receive should be `SUCCESS`.

<div align="left"><figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FvqYSHVicF8foaLRMvw6e%2Fansible_linux_ping.png?alt=media&#x26;token=374e2f9e-90ec-4bc3-9f7f-098f1182b1ea" alt="Ansible ping success"><figcaption></figcaption></figure></div>

## Execute an Ansible command <a href="#execute-an-ansible-command" id="execute-an-ansible-command"></a>

With the Ansible `hosts` file configured for your Meshnet devices and the connection verified, you can use standard Ansible commands or playbooks. For detailed instructions, refer to the [Ansible documentation](https://docs.ansible.com/ansible/latest/index.html).

Consider the following example:

```bash
ansible meshUbuntu -bm apt -a "name=cowsay state=latest"
```

In this example, the [cowsay](https://github.com/cowsay-org/cowsay) application is installed on a remote Ubuntu server, which is specified under the `meshUbuntu` alias in the `hosts` file.

Once the process finishes, `cowsay` commands can be used on the remote server.

<div align="left"><figure><img src="https://3559400189-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0cTezbT2vN0lurEio8Z5%2Fuploads%2FCY4KnpluaszVZPx1HIy1%2Fcowsay.png?alt=media&#x26;token=ebdc6bc1-310b-4639-9a61-4d8c72fa7ee8" alt="Cowsay application output"><figcaption></figcaption></figure></div>

{% hint style="info" %}
**Note**

If you choose not to configure SSH keys, you will need to use the `--ask-pass` or the `-k` option with your Ansible commands and enter the SSH password.
{% endhint %}
