Ansible Playbook Practical Guide: From Basics to Large-Scale Cluster Automation Deployment

Ansible Playbook Practical Guide: From Basics to Large-Scale Cluster Automation Deployment

Introduction: Why Choose Ansible?

In the cloud-native era, manual operations have become the biggest bottleneck restricting team efficiency. When faced with hundreds of servers needing batch deployment, traditional SSH operations on each machine are not only inefficient but also prone to errors. The emergence of Ansible has completely changed this situation —it allows for large-scale automated operations without the need to install any agents on the target machines, using only SSH.

This article will take you from the basic concepts of Ansible to practical large-scale cluster deployment in production environments, enabling you to master the core skills of modern operations.

Chapter 1: Quick Overview of Ansible Core Concepts

1.1 Architecture Analysis: Control Node + Managed Node

# Typical Ansible Architecture
Control Node (控制节点)
├── ansible.cfg         # Global configuration
├── inventory/          # Host inventory
│   ├── hosts.ini
│   └── group_vars/
├── playbooks/          # Playbook directory
└── roles/             # Roles directory

Key Advantages:

  • • No need to install agents on target machines
  • • Secure and reliable based on SSH connections
  • • Declarative syntax, easy to read and maintain
  • • Idempotency guarantee, safe for repeated execution

1.2 In-Depth Understanding of Core Components

Inventory (Host Inventory)

[webservers]
web01 ansible_host=192.168.1.10
web02 ansible_host=192.168.1.11

[databases]
db01 ansible_host=192.168.1.20
db02 ansible_host=192.168.1.21

[all:vars]
ansible_user=deploy
ansible_ssh_private_key_file=~/.ssh/id_rsa

Playbook (剧本)

---
-name: Deploy Web Application
hosts: webservers
become: yes
vars:
    app_name: "myapp"
    app_version: "v1.2.0"

tasks:
    -name: Install Nginx
      yum:
        name: nginx
        state: present
    
    -name: Start and enable Nginx
      systemd:
        name: nginx
        state: started
        enabled: yes

Chapter 2: Advanced Practice – Production-Level Playbook Design

2.1 Best Practices for Variable Management

In production environments, variable management is key to success. Adopt a layered variable management strategy:

# group_vars/webservers.yml
nginx_version: "1.20.2"
app_port: 8080
ssl_enabled: true

# host_vars/web01.yml
server_id: 1
local_storage_path: "/data/web01"

# Using in playbook
-name: Configure application port
lineinfile:
    path: /etc/nginx/nginx.conf
    regexp: '^listen'
    line: "listen {{ app_port }};"

2.2 Role Architecture Design

Modularize complex deployment tasks:

roles/
├── common/              # Basic environment configuration
│   ├── tasks/main.yml
│   ├── handlers/main.yml
│   └── vars/main.yml
├── nginx/               # Nginx specific role
└── mysql/               # MySQL specific role

Example of common/tasks/main.yml:

---
-name: Update system packages
yum:
    name: "*"
    state: latest
when: ansible_os_family == "RedHat"

-name: Install basic tools
package:
    name: "{{ item }}"
    state: present
loop:
    - htop
    - vim
    - curl
    - wget

-name: Configure timezone
timezone:
    name: Asia/Shanghai

2.3 Error Handling and Rollback Mechanism

- name: Main application deployment process
block:
    -name: Backup current version
      archive:
        path: /opt/app
        dest: "/backup/app_{{ ansible_date_time.epoch }}.tar.gz"
    
    -name: Deploy new version
      git:
        repo: "{{ app_repo_url }}"
        dest: /opt/app
        version: "{{ app_version }}"
      
    -name: Restart application service
      systemd:
        name: "{{ app_service_name }}"
        state: restarted

rescue:
    -name: Rollback to backup version
      unarchive:
        src: "/backup/app_{{ ansible_date_time.epoch }}.tar.gz"
        dest: /opt/
        remote_src: yes
    
    -name: Restore service
      systemd:
        name: "{{ app_service_name }}"
        state: restarted

Chapter 3: Large-Scale Cluster Deployment Case Study

3.1 Scenario: Deploying a Microservices Cluster with 100+ Nodes

Challenges:

  • • Batch server initialization
  • • Multi-environment configuration management
  • • Phased rolling deployment
  • • Service health checks

Solution Architecture:

# site.yml - Main entry file
---
- import_playbook: playbooks/01-system-init.yml
- import_playbook: playbooks/02-docker-deploy.yml  
- import_playbook: playbooks/03-app-deploy.yml
- import_playbook: playbooks/04-monitoring.yml

3.2 System Initialization Playbook

# playbooks/01-system-init.yml
---
-name: Large-scale cluster system initialization
hosts: all
serial: 20 # Process 20 machines in parallel
gather_facts: yes
become: yes

pre_tasks:
    -name: Check system compatibility
      fail:
        msg: "Unsupported operating system version"
      when:
        - ansible_distribution != "CentOS"
        - ansible_distribution_major_version | int < 7

roles:
    - common
    - security
    - monitoring-agent

post_tasks:
    -name: Validate basic service status
      service_facts:
    
    -name: Confirm critical services are running
      assert:
        that:
          - ansible_facts.services["sshd.service"].state == "running"
          - ansible_facts.services["chronyd.service"].state == "running"

3.3 Docker Container Deployment

# playbooks/02-docker-deploy.yml
---
-name: Docker environment deployment
hosts: app_servers
serial: "30%" # Process 30% of nodes in parallel
become: yes

vars:
    docker_version: "20.10.17"
    docker_compose_version: "2.6.0"

tasks:
    -name: Install Docker CE
      yum:
        name:
          - docker-ce-{{ docker_version }}
          - docker-ce-cli-{{ docker_version }}
          - containerd.io
        state: present

    -name: Configure Docker daemon
      template:
        src: docker-daemon.json.j2
        dest: /etc/docker/daemon.json
      notify: restart docker

    -name: Start Docker service
      systemd:
        name: docker
        state: started
        enabled: yes

handlers:
    -name: restart docker
      systemd:
        name: docker
        state: restarted

3.4 Phased Rolling Deployment Strategy

# playbooks/03-app-deploy.yml  
---
-name: Microservices application phased deployment
hosts: app_servers
serial: 5 # Process 5 servers per batch
max_fail_percentage: 10 # Allow 10% failure rate

vars:
    deployment_strategy: "rolling"
    health_check_retries: 3
    health_check_delay: 10

tasks:
    -name: Remove node from load balancer
      uri:
        url: "http://{{ load_balancer_host }}/api/remove/{{ inventory_hostname }}"
        method: POST
      delegate_to: localhost
    
    -name: Wait for connections to drain
      wait_for:
        timeout: 30
    
    -name: Stop old version application
      docker_compose:
        project_src: /opt/app
        state: absent
    
    -name: Deploy new version application
      docker_compose:
        project_src: /opt/app
        files:
          - docker-compose.yml
          - docker-compose.prod.yml
        state: present
        pull: yes
    
    -name: Application health check
      uri:
        url: "http://{{ inventory_hostname }}:8080/health"
        status_code: 200
      retries: "{{ health_check_retries }}"
      delay: "{{ health_check_delay }}"
    
    -name: Re-add node to load balancer
      uri:
        url: "http://{{ load_balancer_host }}/api/add/{{ inventory_hostname }}"
        method: POST
      delegate_to: localhost

Chapter 4: Performance Optimization and Troubleshooting

4.1 Ansible Performance Tuning Tips

Concurrency Control Optimization:

# ansible.cfg
[defaults]
host_key_checking = False
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts_cache
fact_caching_timeout = 3600
forks = 50  # Number of concurrent processes
callback_whitelist = timer, profile_tasks

[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
pipelining = True
control_path_dir = /tmp/.ansible-cp

Facts Collection Optimization:

- name: Optimized task execution
hosts: all
gather_facts: no # Skip facts collection

tasks:
    -name: Collect only necessary facts
      setup:
        gather_subset:
          - "!all"
          - "!min"
          - network
          - virtual

4.2 Common Issue Diagnosis

Connection Timeout Issues:

- name: Diagnose network connection
wait_for:
    host: "{{ inventory_hostname }}"
    port: 22
    timeout: 5
delegate_to: localhost
ignore_errors: yes
register: connection_test

-name: Report connection status
debug:
    msg: "{{ inventory_hostname }} connection status: {{ 'SUCCESS' if connection_test.failed == false else 'FAILED' }}"

Chapter 5: Enterprise-Level Practices and Security Hardening

5.1 Sensitive Information Management – Ansible Vault

# Create encrypted file
ansible-vault create secrets.yml

# Encrypt existing file  
ansible-vault encrypt vars/database.yml

# Use in playbook
ansible-playbook -i inventory site.yml --ask-vault-pass

Example of secrets.yml:

database_password: !vault |
    $ANSIBLE_VAULT;1.1;AES256
    66386439653138363739653730636365396464333661643138656234323837653462613431613938
    3730623234643863666466303435346138666330363834660a653864373765623965383535633166

5.2 RBAC Permission Control

# playbooks/security-hardening.yml
---
-name: System security hardening
hosts: all
become: yes

tasks:
    -name: Create operations user group
      group:
        name: ops
        state: present
    
    -name: Configure sudo permissions
      lineinfile:
        path: /etc/sudoers.d/ops
        line: "%ops ALL=(ALL) NOPASSWD: /usr/bin/systemctl, /usr/bin/docker"
        create: yes
        mode: '0440'
    
    -name: Disable root SSH login
      lineinfile:
        path: /etc/ssh/sshd_config
        regexp: '^PermitRootLogin'
        line: 'PermitRootLogin no'
      notify: restart sshd

5.3 CI/CD Integration Best Practices

GitLab CI Integration Example:

# .gitlab-ci.yml
deploy:
stage: deploy
script:
    - ansible-playbook -i inventory/prod site.yml --vault-password-file .vault_pass
only:
    - main
when: manual
environment:
    name: production

Chapter 6: Monitoring and Logging Integration

6.1 Deploying Monitoring Stack

- name: Deploy Prometheus + Grafana Monitoring
hosts: monitoring
become: yes

tasks:
    -name: Create monitoring directory
      file:
        path: /opt/monitoring
        state: directory
    
    -name: Deploy monitoring service
      docker_compose:
        project_src: /opt/monitoring
        definition:
          version: '3.8'
          services:
            prometheus:
              image: prom/prometheus:latest
              ports:
                - "9090:9090"
              volumes:
                - ./prometheus.yml:/etc/prometheus/prometheus.yml
            
            grafana:
              image: grafana/grafana:latest
              ports:
                - "3000:3000"
              environment:
                - GF_SECURITY_ADMIN_PASSWORD=admin123

6.2 Automated Operations Report

- name: Generate deployment report
hosts: localhost
gather_facts: no

tasks:
    -name: Collect deployment statistics
      set_fact:
        deployment_stats:
          total_hosts: "{{ groups['all'] | length }}"
          successful_hosts: "{{ groups['all'] | length - ansible_failed_hosts | default([]) | length }}"
          failed_hosts: "{{ ansible_failed_hosts | default([]) | length }}"
          deployment_time: "{{ ansible_date_time.iso8601 }}"
    
    -name: Send deployment notification
      uri:
        url: "{{ slack_webhook_url }}"
        method: POST
        body_format: json
        body:
          text: |
            🚀 Deployment Completion Report
            ✅ Success: {{ deployment_stats.successful_hosts }}/{{ deployment_stats.total_hosts }}
            ❌ Failure: {{ deployment_stats.failed_hosts }}
            🕐 Time: {{ deployment_stats.deployment_time }}

Conclusion: The Core Value of Ansible Operations Automation

Through the in-depth practice in this article, we have completed the full process of learning from the basic concepts of Ansible to large-scale production environment deployment.Key takeaways include:

Technical Aspects:

  • • Mastered the core architecture and working principles of Ansible
  • • Learned the design patterns of production-level Playbooks
  • • Implemented automated deployment strategies for large-scale clusters
  • • Established a complete error handling and rollback mechanism

Operational Philosophy:

  • • Infrastructure as Code
  • • Declarative configuration management
  • • Idempotent operations guarantee
  • • Layered variable management strategy

Enterprise Value:

  • • Deployment efficiency improvement of over 90%
  • • Reduction of human errors by 95%
  • • Environment consistency achieved at 99.9%
  • • Significant reduction in operational costs

Next Steps Learning Path

  1. 1. Deepen Container Orchestration: Combine with Kubernetes for cloud-native deployment
  2. 2. Monitoring System Construction: Build a full-link monitoring and alerting system
  3. 3. Security Operations Practices: Zero Trust Network and automated security scanning
  4. 4. Multi-Cloud Management: Unified operational practices across cloud platforms

Recommended Practical Resources

  • Official Documentation: docs.ansible.com
  • Best Practices: ansible-best-practices
  • Community Modules: galaxy.ansible.com

If this article has been helpful to you, please like, bookmark, and follow me. I will continue to share more practical experiences in operations automation!

What challenges have you encountered while using Ansible? Feel free to share your experiences and questions in the comments section.

Leave a Comment