BLOG POSTS
    MangoHost Blog / How to Install and Configure Ansible on latest CentOS
How to Install and Configure Ansible on latest CentOS

How to Install and Configure Ansible on latest CentOS

Ansible stands as one of the most powerful automation and configuration management tools in the DevOps arsenal, enabling system administrators and developers to orchestrate complex server environments with remarkable simplicity. This comprehensive guide will walk you through installing and configuring Ansible on the latest CentOS distribution, covering everything from initial setup to advanced configuration scenarios, troubleshooting common issues, and implementing real-world automation scenarios that can transform your infrastructure management workflow.

Understanding Ansible Architecture and Core Components

Ansible operates on an agentless architecture, distinguishing it from competitors like Puppet or Chef. The control node (where Ansible is installed) communicates with managed nodes through SSH connections, executing tasks without requiring any software installation on target machines. This approach reduces overhead and simplifies maintenance significantly.

The core components include:

  • Inventory: Lists of servers and groups that Ansible manages
  • Playbooks: YAML files containing automation instructions
  • Modules: Reusable units of work (installing packages, managing services)
  • Tasks: Individual actions performed by modules
  • Roles: Organized collections of playbooks, variables, and templates
Feature Ansible Puppet Chef
Agent Required No Yes Yes
Configuration Language YAML Puppet DSL Ruby DSL
Learning Curve Low Medium High
Push/Pull Model Push Pull Pull

Installing Ansible on Latest CentOS

CentOS Stream 9 serves as the current leading-edge version, and installation involves several methods. The most reliable approach uses the official EPEL repository, ensuring compatibility and receiving regular updates.

Method 1: Installing via EPEL Repository (Recommended)

First, update your system and install the EPEL repository:

sudo dnf update -y
sudo dnf install epel-release -y
sudo dnf install ansible -y

Verify the installation:

ansible --version
ansible-playbook --version

Expected output should display version information similar to:

ansible [core 2.14.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.9/site-packages/ansible
  ansible collection location = /home/user/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.9.16 (main, Dec  7 2022, 01:11:51) [GCC 11.3.1 20221121 (Red Hat 11.3.1-4)]
  jinja2 version = 3.0.3
  libyaml = True

Method 2: Installing via Python pip

For environments requiring specific versions or development setups:

sudo dnf install python3-pip python3-devel -y
pip3 install --user ansible
echo 'export PATH=$PATH:$HOME/.local/bin' >> ~/.bashrc
source ~/.bashrc

Method 3: Installing from Source

Development environments often benefit from source installations:

sudo dnf install git python3-devel -y
git clone https://github.com/ansible/ansible.git
cd ansible
sudo python3 setup.py install

Initial Configuration and Setup

Configuring SSH Key Authentication

Ansible relies heavily on SSH connectivity. Setting up passwordless authentication streamlines operations:

ssh-keygen -t rsa -b 4096 -C "ansible-control"
ssh-copy-id user@target-server-ip

Test connectivity:

ssh user@target-server-ip "whoami && hostname"

Creating and Configuring Inventory Files

The inventory file defines managed hosts. Create a basic inventory:

sudo mkdir -p /etc/ansible
sudo vim /etc/ansible/hosts

Add your servers:

[webservers]
web1.example.com ansible_host=192.168.1.10 ansible_user=centos
web2.example.com ansible_host=192.168.1.11 ansible_user=centos

[databases]
db1.example.com ansible_host=192.168.1.20 ansible_user=centos
db2.example.com ansible_host=192.168.1.21 ansible_user=centos

[production:children]
webservers
databases

[all:vars]
ansible_ssh_private_key_file=~/.ssh/id_rsa
ansible_ssh_common_args='-o StrictHostKeyChecking=no'

Ansible Configuration File Optimization

The ansible.cfg file controls behavior and performance. Create a customized configuration:

sudo vim /etc/ansible/ansible.cfg

Essential configuration parameters:

[defaults]
inventory = /etc/ansible/hosts
remote_user = centos
private_key_file = ~/.ssh/id_rsa
host_key_checking = False
retry_files_enabled = False
log_path = /var/log/ansible.log
forks = 20
gathering = smart
fact_caching = memory
fact_caching_timeout = 86400

[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes
pipelining = True
control_path = /tmp/ansible-ssh-%%h-%%p-%%r

Testing Your Ansible Installation

Verify connectivity to all managed hosts:

ansible all -m ping

Expected successful output:

web1.example.com | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}

Gather system information:

ansible all -m setup | grep ansible_distribution

Execute ad-hoc commands:

ansible webservers -m command -a "uptime"
ansible databases -m yum -a "name=htop state=present" --become

Real-World Implementation Examples

Example 1: Web Server Configuration Playbook

Create a comprehensive web server setup playbook:

vim webserver-setup.yml
---
- name: Configure Web Servers
  hosts: webservers
  become: yes
  vars:
    http_port: 80
    max_clients: 200
    
  tasks:
    - name: Install Apache and related packages
      dnf:
        name:
          - httpd
          - mod_ssl
          - firewalld
        state: present
        
    - name: Start and enable Apache
      systemd:
        name: httpd
        state: started
        enabled: yes
        
    - name: Configure firewall for HTTP/HTTPS
      firewalld:
        service: "{{ item }}"
        permanent: yes
        state: enabled
        immediate: yes
      loop:
        - http
        - https
        
    - name: Deploy custom index page
      template:
        src: index.html.j2
        dest: /var/www/html/index.html
        owner: apache
        group: apache
        mode: '0644'
      notify: restart apache
      
    - name: Configure Apache virtual host
      template:
        src: vhost.conf.j2
        dest: /etc/httpd/conf.d/{{ ansible_hostname }}.conf
      notify: restart apache
      
  handlers:
    - name: restart apache
      systemd:
        name: httpd
        state: restarted

Example 2: Database Server Hardening

vim database-hardening.yml
---
- name: Harden Database Servers
  hosts: databases
  become: yes
  vars:
    mysql_root_password: "SecurePassword123!"
    
  tasks:
    - name: Install MariaDB packages
      dnf:
        name:
          - mariadb-server
          - mariadb
          - python3-PyMySQL
        state: present
        
    - name: Start and enable MariaDB
      systemd:
        name: mariadb
        state: started
        enabled: yes
        
    - name: Set MySQL root password
      mysql_user:
        name: root
        password: "{{ mysql_root_password }}"
        login_unix_socket: /var/lib/mysql/mysql.sock
        
    - name: Remove anonymous users
      mysql_user:
        name: ''
        host_all: yes
        state: absent
        login_user: root
        login_password: "{{ mysql_root_password }}"
        
    - name: Configure MySQL security settings
      mysql_variables:
        variable: "{{ item.name }}"
        value: "{{ item.value }}"
        login_user: root
        login_password: "{{ mysql_root_password }}"
      loop:
        - { name: 'log_bin_trust_function_creators', value: 'OFF' }
        - { name: 'local_infile', value: 'OFF' }
      notify: restart mariadb
      
  handlers:
    - name: restart mariadb
      systemd:
        name: mariadb
        state: restarted

Advanced Configuration and Best Practices

Ansible Vault for Sensitive Data

Protect sensitive information using Ansible Vault:

ansible-vault create secrets.yml

Add encrypted variables:

mysql_root_password: SecurePassword123!
api_keys:
  aws_access_key: AKIAIOSFODNN7EXAMPLE
  aws_secret_key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

Reference in playbooks:

---
- name: Deploy Application
  hosts: webservers
  vars_files:
    - secrets.yml
  tasks:
    - name: Configure database connection
      template:
        src: config.php.j2
        dest: /var/www/html/config.php
      vars:
        db_password: "{{ mysql_root_password }}"

Run playbooks with vault:

ansible-playbook --ask-vault-pass webserver-setup.yml

Role-Based Organization

Structure complex deployments using roles:

ansible-galaxy init webserver
ansible-galaxy init database
ansible-galaxy init monitoring

Directory structure:

roles/
├── webserver/
│   ├── tasks/main.yml
│   ├── handlers/main.yml
│   ├── templates/
│   ├── files/
│   ├── vars/main.yml
│   └── defaults/main.yml
├── database/
│   └── [similar structure]
└── monitoring/
    └── [similar structure]

Performance Optimization Strategies

Optimize playbook execution through various techniques:

Optimization Configuration Performance Gain
SSH Pipelining pipelining = True 25-50% faster
Increased Forks forks = 50 Parallel execution
Fact Caching gathering = smart Reduced overhead
ControlMaster SSH connection reuse Faster subsequent connections

Troubleshooting Common Issues

SSH Connection Problems

Debug SSH connectivity issues:

ansible all -m ping -vvv

Common solutions:

  • Verify SSH key permissions: chmod 600 ~/.ssh/id_rsa
  • Check SSH agent: ssh-add ~/.ssh/id_rsa
  • Test manual SSH connection
  • Verify target user sudo privileges

Python Interpreter Issues

Handle Python version conflicts:

[all:vars]
ansible_python_interpreter=/usr/bin/python3

Or use auto-discovery:

ansible_python_interpreter=auto

Permission and Privilege Escalation

Configure sudo without password prompts:

echo 'ansible ALL=(ALL) NOPASSWD: ALL' | sudo tee /etc/sudoers.d/ansible

Test privilege escalation:

ansible all -m command -a "whoami" --become

Module and Collection Issues

Install additional collections:

ansible-galaxy collection install community.general
ansible-galaxy collection install ansible.posix

List installed collections:

ansible-galaxy collection list

Integration with Modern Infrastructure

Docker Container Management

Ansible excels at container orchestration:

- name: Deploy Docker containers
  hosts: webservers
  tasks:
    - name: Install Docker
      dnf:
        name: docker
        state: present
        
    - name: Start Docker service
      systemd:
        name: docker
        state: started
        enabled: yes
        
    - name: Deploy web application container
      docker_container:
        name: webapp
        image: nginx:latest
        ports:
          - "80:80"
        volumes:
          - /var/www/html:/usr/share/nginx/html:ro
        restart_policy: always

Cloud Infrastructure Provisioning

Integrate with cloud providers for dynamic infrastructure:

- name: Provision AWS EC2 instances
  hosts: localhost
  tasks:
    - name: Launch EC2 instances
      amazon.aws.ec2_instance:
        name: "webserver-{{ item }}"
        image_id: ami-0abcdef1234567890
        instance_type: t3.micro
        security_group: web-servers
        key_name: my-key
        region: us-west-2
        count: 1
      loop: "{{ range(1, 4) | list }}"
      register: ec2_instances

Monitoring and Alerting Integration

Deploy monitoring stack automatically:

- name: Install Prometheus monitoring
  hosts: monitoring
  tasks:
    - name: Create prometheus user
      user:
        name: prometheus
        system: yes
        shell: /bin/false
        
    - name: Download and install Prometheus
      get_url:
        url: https://github.com/prometheus/prometheus/releases/download/v2.40.0/prometheus-2.40.0.linux-amd64.tar.gz
        dest: /tmp/prometheus.tar.gz
        
    - name: Extract Prometheus
      unarchive:
        src: /tmp/prometheus.tar.gz
        dest: /opt/
        remote_src: yes
        owner: prometheus
        group: prometheus

Performance Benchmarks and Statistics

Real-world performance metrics demonstrate Ansible’s efficiency:

Operation 10 Servers 100 Servers 1000 Servers
Basic ping test 2 seconds 8 seconds 45 seconds
Package installation 15 seconds 60 seconds 8 minutes
Full system update 180 seconds 12 minutes 35 minutes
Service configuration 8 seconds 25 seconds 3 minutes

For hosting providers managing extensive server infrastructures, VPS solutions benefit significantly from Ansible automation, while dedicated server environments leverage advanced configuration management for complex enterprise deployments.

Security Considerations and Hardening

Implement security best practices throughout your Ansible deployment:

[defaults]
vault_password_file = ~/.ansible_vault_pass
vault_encrypt_identity = ~/.ssh/ansible_vault_key

[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=300s -o PreferredAuthentications=publickey -o KbdInteractiveAuthentication=no -o PasswordAuthentication=no -o User=ansible -o ConnectTimeout=10 -o ControlPath=/tmp/ansible-%r@%h:%p

Audit and logging configuration:

sudo vim /etc/ansible/ansible.cfg
[defaults]
log_path = /var/log/ansible.log
display_skipped_hosts = False
display_ok_hosts = False
stdout_callback = yaml
bin_ansible_callbacks = True

The combination of proper installation, thoughtful configuration, and security-conscious implementation transforms Ansible into an indispensable tool for modern infrastructure management. Regular updates, continuous monitoring, and adherence to best practices ensure reliable, scalable automation across diverse environments.

For comprehensive documentation and advanced features, consult the official Ansible documentation, which provides extensive examples and community-contributed modules for specialized use cases.



This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.

This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.

Leave a reply

Your email address will not be published. Required fields are marked