Skip to main content

⚙️ Configuration Management & Orchestration

🌐 Environment Setup

Initiating a Docker container named "nginx-container" using the latest NGINX image, and starts a Bash shell inside the container for interactive usage.


docker run -it --name nginx-container nginx:latest /bin/bash

Making sure everything is correctly configured


root@23c06c085cbe:/# ansible all -i 'localhost,' -c local -m ping

localhost | SUCCESS => {

"changed": false,

"ping": "pong"

}

Generating key pairs, if never used we need to have openssh installed and the .ssh folder is created automatically

root@23c06c085cbe:/# ssh-keygen -t rsa

Generating public/private rsa key pair.

Enter file in which to save the key (/root/.ssh/id_rsa):

Created directory '/root/.ssh'.

Enter passphrase (empty for no passphrase):

Enter same passphrase again:

Your identification has been saved in /root/.ssh/id_rsa.

🛠️ Installation

sudo dnf install -y epel-release &&  # Install EPEL repository for Ansible
sudo dnf install -y ansible && # Install Ansible
ansible all -m ping # Ping all hosts to test connectivity

🔧 Foundation

🗂️ Inventory

Viewing the Inventory

  • List all hosts in your inventory: ansible all --list-hosts
  • Display detailed information about all hosts in your inventory: ansible-inventory --list --yaml
  • Check the syntax of your inventory file: ansible-inventory --inventory-file=your_inventory_file --syntax-check

🖥️ Host

Basic Commands

  • Ping all hosts in the inventory: ansible all -m ping
  • Ping a specific host group: ansible webservers -m ping
  • Execute a command on all hosts: ansible all -a "uptime"
  • Gather facts from all hosts: ansible all -m setup
  • Check if a specific service is running: ansible all -m service -a "name=nginx state=started"

Ad-hoc Commands

  • Install a package on all hosts: ansible all -m apt -a "name=htop state=present" --become
  • Copy a file to all hosts: ansible all -m copy -a "src=/local/path dest=/remote/path"
  • Run a command with a non-default user: ansible all -a "df -h" -u username

📋 Tasks

Playbooks and Tasks

  • Run a playbook: ansible-playbook playbook.yml
  • Check the syntax of a playbook: ansible-playbook playbook.yml --syntax-check
  • List all tasks that will be executed in a playbook: ansible-playbook playbook.yml --list-tasks
  • Execute specific tasks in a playbook using tags: ansible-playbook playbook.yml --tags "tag1,tag2"
  • Skip specific tasks in a playbook using tags: ansible-playbook playbook.yml --skip-tags "tag1,tag2"
  • Run a playbook in check mode (dry run): ansible-playbook playbook.yml --check

Task Examples

  • Install a package: - name: Install htop apt: name: htop state: present
  • Start and enable a service: - name: Ensure nginx is started and enabled service: name: nginx state: started enabled: true
  • Copy a file to a remote host: - name: Copy nginx configuration file copy: src: /local/path/nginx.conf dest: /etc/nginx/nginx.conf
  • Create a user: - name: Create a user user: name: john state: present groups: "sudo"
  • Add a cron job:
  • - name: Add a cron job cron: name: "backup" minute: "0" hour: "2" job: "/usr/local/bin/backup.sh"

📜 PlayBooks

  • Basic Playbook Structure:

     - hosts: webservers
    tasks:
    - name: Ensure Nginx is installed
    apt:
    name: nginx
    state: present

    For playbook inventory Visit Github > Luminalink-AI/Playbooks

**WARNING: This repository contains sensitive data, DO NOT SHARE**

A list of reusable playbooks will be inplemented in this section

1. Ad Hoc Commands

  • Ping all hosts: ansible all -m ping

  • Run a command on all hosts: ansible all -a "uptime"

  • Gather facts from all hosts: ansible all -m setup

  • Check if a specific service is running: ansible all -m service -a "name=nginx state=started" `

  • Install a package on all hosts: ansible all -m apt -a "name=htop state=present" --become

  • Copy a file to all hosts: ansible all -m copy -a "src=/local/path dest=/remote/path"

  • Run a command with a non-default user: ansible all -a "df -h" -u username

2. Introduction

Ansible Basics:

  • Inventory File: Define your inventory in a file (e.g., hosts):

    [webservers]
    web1.example.com
    web2.example.com

    [dbservers]
    db1.example.com
    db2.example.com
  • Running Ansible Commands:

    • Ping all hosts in the inventory: ansible all -m ping -i hosts

    • Execute a command on all hosts: ansible all -a "uptime" -i hosts

3. Packages (apt, become, with_items)

Install Packages with apt:

  • Single Package:


    - name: Install htop
    apt:
    name: htop
    state: present
  • Multiple Packages using with_items:

    - name: Install multiple packages
    apt:
    name: "{{ item }}"
    state: present
    with_items:
    - htop
    - git
    - curl

Using become for Privileged Tasks:

  • Ensure Nginx is installed and started:

    - name: Ensure Nginx is installed and started
    apt:
    name: nginx
    state: present
    become: yes

    - name: Ensure Nginx is running
    service:
    name: nginx
    state: started
    become: yes
  • Create a User with sudo Privileges:

    - name: Create a user with sudo privileges
    user:
    name: john
    state: present
    groups: sudo
    become: yes

🛎️ Services

1. Roles

Roles in Ansible are a way to organize playbooks into reusable units. Roles can include tasks, handlers, variables, templates, and files.

Creating a Role:

  1. Create a Role Directory Structure:
ansible-galaxy init <role_name>

This creates the following structure:

<role_name>/
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
  1. Using a Role in a Playbook:
---
- hosts: webservers
roles:
- role: <role_name>

2. Overview

Roles provide a structured way to group tasks, handlers, variables, and other Ansible components. They help in reusing and organizing code.

Benefits of Using Roles:

  • Modular and reusable code
  • Simplifies playbook management
  • Easy to share and maintain

3. Converting to Roles: Tasks, Handlers

To convert existing tasks and handlers into a role, follow these steps:

  1. Create the Role:
ansible-galaxy init my_role
  1. Move Tasks to the Role:

Copy tasks from your playbook to my_role/tasks/main.yml.

  1. Move Handlers to the Role:

Copy handlers from your playbook to my_role/handlers/main.yml.

Advanced Concepts

1. Advanced Execution Introduction

Advanced execution in Ansible involves optimizing and customizing playbook runs using features like limits, tags, and conditions.

2. Limiting Execution by Hosts: limit

The limit option restricts playbook execution to specific hosts.

Example:

ansible-playbook site.yml --limit webservers

3. Removing Unnecessary Steps: gather_facts

The gather_facts option controls whether Ansible collects facts about the hosts.

Example:

---
- hosts: all
gather_facts: no
tasks:
- name: Simple task
debug:
msg: "No facts gathered"

4. Extracting Repetitive Tasks: cache_valid_time

The cache_valid_time option caches facts to avoid gathering them multiple times.

Example:

---
- hosts: all
gather_facts: yes
facts:
cache_valid_time: 3600
tasks:
- name: Use cached facts
debug:
var: ansible_facts

5. Limiting Execution by Tasks: tags

Tags allow you to run specific tasks within a playbook.

Example:

---
- hosts: all
tasks:
- name: Install package
apt:
name: vim
state: present
tags: install

- name: Configure file
copy:
src: /src/file
dest: /dest/file
tags: config

Run only the tasks with the install tag:

ansible-playbook site.yml --tags install

6. Idempotence: changed_when, failed_when

Idempotence ensures that running a playbook multiple times results in the same state.

Using changed_when:

---
- name: Check if file exists
stat:
path: /path/to/file
register: file_stat

- name: Create file if not exists
file:
path: /path/to/file
state: touch
changed_when: not file_stat.stat.exists

Using failed_when:

---
- name: Check if directory exists
stat:
path: /path/to/dir
register: dir_stat

- name: Fail if directory does not exist
fail:
msg: "Directory does not exist"
failed_when: not dir_stat.stat.exists

Troubleshooting, Testing & Validation

Troubleshooting Ansible Playbooks:

  • Verbose Mode:

Run playbooks with increased verbosity to get more detailed output.

ansible-playbook site.yml -vvv
  • Check Mode:

Run playbooks in check mode to see what changes would be made without actually applying them.

ansible-playbook site.yml --check
  • Dry Run:

Combine check mode with verbosity for a detailed dry run.

ansible-playbook site.yml --check -vvv

Testing & Validation:

  • YAML Syntax:

Use yamllint to check the syntax of your YAML files.

yamllint playbook.yml
  • Playbook Syntax:

Use ansible-playbook --syntax-check to check the syntax of your playbooks.

ansible-playbook site.yml --syntax-check
  • Role Testing:

Use Molecule to test Ansible roles.

pip install molecule
molecule init role my_role
molecule test