Installation #

Adopting Ansible as your infrastructure automation tool pays off from the very first step: the ease of installation. Unlike traditional configuration management systems like Chef, Puppet, or SaltStack that require installing a dedicated agent (daemon) on every target server, Ansible uses a master-only architecture. You only need to install Ansible on one controlling machine called the control node. The target infrastructure, or managed nodes, requires no additional application installation at all. This article guides you through pre-installation preparation, installation methods on various operating systems, system verification, secure Secure Shell (SSH) authentication configuration, and managing additional collections.

Before Installing #

Before starting the installation process, you must make sure the machine you’ll use as the control node and the managed nodes meet the required minimum specifications. Failing to meet these requirements often causes module execution failures or cryptographic library compilation errors during setup.

Control Node Requirements #

The control node is the machine where you run Ansible commands, store playbooks, and manage the server inventory. Its system requirements include:

  1. Operating System: A POSIX-based operating system is required. You can use Linux (such as Ubuntu, Debian, RHEL, CentOS, Rocky Linux, AlmaLinux, Fedora), macOS, or Windows Subsystem for Linux (WSL) on Windows. Ansible Core can’t run natively on the Windows operating system because Ansible heavily depends on POSIX functions like fork() and file descriptor handling that Windows doesn’t support natively.
  2. Python: Python version 3.9 or newer must be installed. Python is a core component because Ansible is written in this language and extracts its modules as Python scripts before shipping them to target machines.
  3. Cryptography Libraries: System packages like OpenSSL and Python development libraries (such as python3-dev or python3-devel) are needed if you want to install Ansible using the Python package manager (pip) because some cryptographic modules require native C compilation.

Managed Node Requirements #

The target machine, or managed node, is a server, network device, or container that you’ll manage. Its requirements are very minimal:

  1. Python: Linux/Unix-based target servers need Python 2.7 or Python 3.5+. Using Python 3.8+ is highly recommended for security and long-term compatibility.
  2. SSH Connectivity: An SSH server (like OpenSSH) must be running on the default port (22) or a defined custom port, and the control node must have network access permission to that port.
  3. Windows Systems (Alternative): If the target server is Windows, you don’t need Python — instead you need Windows Remote Management (WinRM) or OpenSSH for Windows configuration.

You can check the existence and version of Python on your control node with the following commands:

# Check the system's default Python version
python3 --version
# Example output: Python 3.10.12

# Check the pip version (Python Package Installer)
pip3 --version
# Example output: pip 22.0.2 from /usr/lib/python3/dist-packages/pip (python 3.10)

Ansible Connection Architecture #

To give you a clear picture of how this installation process fits into Ansible’s lifecycle, the diagram below illustrates the execution flow from the control node to managed nodes after installation completes.

flowchart TD
    subgraph "Control Node (Controlling Machine)"
        A["Playbook / CLI Command"] --> B["Ansible Core Engine"]
        B --> C["Compile Module into Python Script"]
    end
    subgraph "Transmission Path"
        C -->|"SSH Connection (Port 22)"| D["Copy Script via SFTP/SCP or Stream via Pipelining"]
    end
    subgraph "Managed Node (Target Server)"
        D --> E["Python Interpreter (Target Server)"]
        E --> F["Execute Module Script Locally"]
        F --> G["Send Back Execution Results (JSON Output)"]
    end
    G -->|"SSH Channel"| B

Simply put, installing Ansible only focuses on providing the Control Node Engine (the left side of the diagram). As long as the Managed Node has a Python interpreter and proper SSH access, the system is ready to run without any additional installation on the target side.


Installing via pip and pipx #

Installing Ansible with the Python package manager (pip or pipx) is the community-recommended method. The main advantage of this method is portability and the freedom to choose a specific Ansible version, regardless of the package version provided by the official OS repositories, which are often outdated.

The Difference Between ansible and ansible-core Packages #

Before installing, you need to understand the difference between the two packages available on PyPI:

  • ansible-core: This package only contains the main execution engine, playbook runtime, configuration engine, and a number of basic builtin modules. It’s very lightweight and suits CI/CD environments or production servers with minimal needs.
  • ansible: This package includes ansible-core plus thousands of the most popular community modules and plugins grouped into various collections (such as modules for AWS, Docker, Kubernetes, and MySQL).

Using a Python Virtual Environment (venv) #

It’s highly recommended to install Ansible inside a virtual environment to avoid dependency conflicts with the OS’s built-in Python libraries, which could destabilize the system.

Here are the complete steps for creating a virtual environment and installing Ansible inside it:

# 1. Update the package list and install virtual environment libraries
sudo apt update
sudo apt install -y python3-venv python3-dev build-essential

# 2. Create a dedicated directory for our automation project
mkdir -p ~/ansible-project
cd ~/ansible-project

# 3. Create a virtual environment named 'ansible-env'
python3 -m venv ansible-env

# 4. Activate the virtual environment
source ansible-env/bin/activate
# After activation, the shell prompt will change to show (ansible-env) at the front

# 5. Upgrade pip to the latest version inside the virtual environment
pip install --upgrade pip

# 6. Install the full Ansible version (including community collections)
pip install ansible

# 7. Or if you only need the minimal core engine:
# pip install ansible-core

Using pipx for Application Isolation #

If you want to use Ansible globally without worrying about breaking system Python libraries, you can use pipx. This tool automatically isolates Python CLI applications into their own virtual environment while exposing their executable commands to your system’s global PATH.

# Install pipx using the system package manager
sudo apt install -y pipx
pipx ensurepath

# Close and reopen your terminal, or reload the shell
source ~/.bashrc

# Install Ansible via pipx
pipx install ansible

# Verify the global command is now available
ansible --version

Operating System Installation #

If you prefer managing application lifecycles with the OS’s built-in package manager (for easy integration with automatic security update systems), Ansible provides official packages for various Linux platforms and macOS.

Installing on Ubuntu and Debian #

Ubuntu provides an Ansible package in its official repositories, but if you want the latest stable version released by the Ansible development team, you need to add their official Personal Package Archive (PPA).

# Make sure your system supports adding PPAs
sudo apt update
sudo apt install -y software-properties-common

# Add the official Ansible PPA repository
sudo add-apt-repository --yes --update ppa:ansible/ansible

# Install Ansible
sudo apt install -y ansible

For Debian, the official Ubuntu PPA isn’t supported directly. You can use the Debian Backports repository or the pip method discussed earlier. If you want to use apt on Debian, follow these steps:

# Add the Ansible repository signature key
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367

# Add the repository source line to sources.list
echo "deb http://ppa.launchpad.net/ansible/ansible/ubuntu jammy main" | sudo tee /etc/apt/sources.list.d/ansible.list

# Update the package index and install
sudo apt update
sudo apt install -y ansible

Installing on RHEL, CentOS, Rocky Linux, and AlmaLinux #

On the Enterprise Linux family (RHEL and its derivatives), the Ansible package is available through the EPEL (Extra Packages for Enterprise Linux) repository. You must enable EPEL first before you can download Ansible.

# RHEL 8 / 9, Rocky Linux, AlmaLinux
# 1. Enable the EPEL repository
sudo dnf install -y epel-release

# 2. Install Ansible
sudo dnf install -y ansible

# For older RHEL (CentOS 7)
sudo yum install -y epel-release
sudo yum install -y ansible

Installing on macOS #

For macOS users, the easiest and most efficient method is using Homebrew. Homebrew handles the entire dependency chain, including a Homebrew-specific isolated Python that doesn’t disturb macOS’s internal Python interpreter.

# Make sure Homebrew is installed, or run its installation script:
# /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Install Ansible via Homebrew
brew install ansible

# Verify your macOS installation
ansible --version

Verifying the Installation #

After one of the installation methods above completes, you must verify that Ansible is properly installed and ready to manage target servers.

The first step is running the version review command:

ansible --version

The command above displays very detailed diagnostic information. Let’s break down the meaning of that output in depth so you understand your Ansible runtime structure:

ansible [core 2.16.2]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/user/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]
  jinja version = 3.0.3
  libyaml = True

Detailed Explanation of the Diagnostic Output: #

  1. ansible [core 2.16.2]: Shows the main Ansible engine version (Ansible Core). This number is crucial when you want to match module compatibility with official documentation.
  2. config file: The location of the active configuration file Ansible is reading. If it says None, Ansible is using factory defaults because it didn’t detect an ansible.cfg file in your project directory.
  3. executable location: The location of the main executable binary file. Useful for tracking down overlapping Ansible installations on the system.
  4. python version: The Python interpreter used to execute Ansible on the control node.
  5. libyaml = True: Indicates whether the C-bindings YAML parser extension is active. If True, YAML playbook parsing performance is much faster than the pure-Python parser (False).

First Ping Test (Localhost) #

To make sure the Python interpreter on the control node can process Ansible scripts correctly, you can run an ad-hoc command test using the built-in ping module against the local target (localhost). This test doesn’t require an external SSH connection.

ansible localhost -m ping

If successful, you’ll get a green/yellow formatted JSON output like this:

localhost | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

[!NOTE] The ping module in Ansible is not the network ICMP ping protocol. It’s a Python module that tests whether the control node can connect to the target server, transfer the test script, execute it with the target’s Python interpreter, and receive the JSON output successfully.


SSH Key Setup for Managed Nodes #

Ansible is designed to operate securely over the standard SSH protocol. Although Ansible supports using passwords to log into target servers, it’s strongly discouraged because it forces you to store passwords in plain text, slows down automation, and invites brute force security risks.

The safe best practice is key-based authentication (SSH Key-Based Authentication).

Step 1: Generating a New SSH Key #

Use the Ed25519 algorithm when creating SSH keys. Ed25519 is far more secure, has a compact key size (saves storage space), and offers faster cryptographic performance than the traditional RSA algorithm.

# Generate a new Ed25519 key on our control node
ssh-keygen -t ed25519 -a 100 -C "ansible-deploy-key"

Parameter Explanation:

  • -t ed25519: Specifies the public key algorithm type.
  • -a 100: Sets the number of key derivation function (KDF) rounds to increase the private key file’s encryption resistance against offline brute force if that key file is stolen.
  • -C "ansible-deploy-key": Adds an identifying comment at the end of the public key file.

Press Enter on all prompts to accept the default storage location (~/.ssh/id_ed25519) and leave the passphrase empty if you need automated execution without human intervention (or use a passphrase and configure ssh-agent).

Step 2: Distributing the Public Key to Managed Nodes #

You need to copy the newly created public key (id_ed25519.pub) to all target machines so they recognize the SSH authorization from your control node. Use the built-in ssh-copy-id utility:

# Copy the public key to the target managed node
ssh-copy-id -i ~/.ssh/id_ed25519.pub [email protected]

You’ll be asked to enter the target user’s password once. After the copying process finishes, your public key will be automatically added to the target’s ~/.ssh/authorized_keys file.

Step 3: Verifying Passwordless SSH Connection #

To make sure key authentication works, make a direct SSH connection:

ssh -i ~/.ssh/id_ed25519 [email protected]
# You should land directly in the target server's terminal with no password prompt

Step 4: Setting Up Passwordless Sudoers #

Most automation tasks (like installing packages or modifying system configuration files in /etc/) require admin (root) privileges. To prevent Ansible execution from stopping at a sudo password input prompt during privilege escalation, you need to configure the target machine so the deployer user (in this example ubuntu) can run sudo commands without a password.

Log into the target machine, run the sudo visudo command, then add the following lines at the end of the file:

# ANTI-PATTERN: Using a global sudo rule that asks for interactive password input
# ubuntu ALL=(ALL:ALL) ALL

# CORRECT: Allow passwordless privilege escalation only for our automation user
ubuntu ALL=(ALL) NOPASSWD:ALL

Step 5: Distributed Testing via Ansible #

Now, let’s test our automation connection using Ansible against the prepared target server. We’ll create a temporary inventory file and test the SSH ping module:

# 1. Create a temporary inventory file containing the target IP address
echo "192.168.56.10" > ~/ansible-project/hosts

# 2. Run the ad-hoc ping command with the target user 'ubuntu' and our private key
ansible -i ~/ansible-project/hosts all -m ping -u ubuntu --private-key=~/.ssh/id_ed25519

If the integration succeeds, the verification output will show a success status:

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

Installing Additional Ansible Collections #

As we touched on in the package differences, Ansible Core only ships with basic modules. If you want to automate infrastructure for a specific cloud provider, databases, or network hardware, you need to use third-party collections available on Ansible Galaxy (the community module sharing hub).

To install external collections, use the ansible-galaxy CLI utility:

# Install the AWS collection to manage EC2 instances, S3, and VPC
ansible-galaxy collection install amazon.aws

# Install the common community collection containing hundreds of extra utility modules
ansible-galaxy collection install community.general

# Check the list of collections installed on our system
ansible-galaxy collection list

By default, ansible-galaxy installs collection files into your home directory at ~/.ansible/collections/ansible_collections/. If you want to isolate them per-project so the libraries can be distributed together with your playbook code in Git, you can install them into a local project folder:

# Install the collection into the local project subdirectory 'collections'
ansible-galaxy collection install community.docker -p ./collections

Summary #

  • Control Node Only — Ansible only needs to be installed on one controlling machine (control node); no software agent needs to be installed on target servers (managed nodes).
  • pip & Virtual Environment Method — Installing via pip inside a Python virtual environment (venv) is the best method because it isolates Ansible dependencies from the OS’s built-in packages.
  • Platform Support — The control node must use a POSIX-based OS (Linux, macOS, WSL); Windows can only be a managed node.
  • Detailed Verification — The ansible --version command diagnoses important components like the configuration file location and active Python interpreter, and confirms the libyaml C-extension parser reports True.
  • Ed25519 Authentication — SSH Key-based authentication using the Ed25519 algorithm is the best security standard because it’s faster and more secure than RSA.
  • NOPASSWD Privilege Escalation — Setting up the NOPASSWD:ALL rule in the target server’s visudo file prevents playbook execution failures caused by interactive sudo password prompts.
  • Ansible Galaxy — Use the ansible-galaxy command to extend automation functionality by installing external collections (such as AWS or Docker modules).

← Previous: Module Next: Configuration →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact