Linux Cloud Computing | Daily Practice | Practical Tools | Career Development
π₯ “Manually SSH logging into 100 servers to change configurations, working overtime until dawn and still missing some?”
“Inconsistent environments across different machines, crashing upon deployment?”
“Mistyping commands during late-night deployments and being held accountable?”
These operational “nightmare scenarios” are essentially due to “manual operations” failing to keep up with scaling demands!
As an automation operations “score”, Ansible Playbook allows you to conduct operations on thousands of servers with a single YAML script: batch initializing systems, deploying applications, and enhancing security, completing in 1 hour what used to take 10 people 3 days, with 100% consistent configurations!
This article will guide you step-by-step from environment setup to enterprise-level architecture, from basic scripts to error handling, teaching you how to write practical Playbooks that even beginners can master in 1 day and become proficient in 3 days!
01
Why is Ansible Playbook the “Efficiency Savior” for Operations?

π Using the “Conductor of a Symphony Orchestra” analogy, instantly understand the core value of Playbook
|
Operation Method |
Analogous Scenario |
Time for 100 Servers |
Core Pain Points |
Playbook Solution |
|---|---|---|---|---|
|
Manual SSH Operations |
Each musician looks at the score and plays freely |
10 hours |
Prone to errors, inconsistent environments, no audit logs |
One “score” conducts all servers “synchronously” |
|
Traditional Shell Scripts |
The conductor shouts commands, musicians forget |
2 hours |
Does not support idempotency (issues with repeated executions), poor cross-system compatibility |
Declarative syntax (only states “what state is needed”), idempotency (executing 100 times = 1 time) |
|
Other Automation Tools (e.g., Puppet) |
The conductor must learn complex musical notation |
1.5 hours |
Requires client installation, complex configuration |
No client required (just SSH), YAML syntax is like a “manual”, easy for beginners to understand |
π‘ Three “Operational Magic” Features of Playbook (Easy for Beginners)
1. Declarative Syntax: Only states “what is needed”, not “how to do it”
Traditional scripts: Must write “first apt update, then apt install vim”;
Playbook: Just write “ensure vim is installed (state: present)”, Ansible automatically
determines the current state (skips if installed, installs if not).
π Advantage: No need to worry about “intermediate steps”, focus on “final results”, making scripts simpler and less error-prone.
2. Idempotency: The effect of executing 100 times is exactly the same as executing once
For example, the task of “creating user ops” will create the user on the first execution, and on subsequent executions, it will detect that the user already exists and skip.
π Advantage: No need to worry about “repeated execution causing failures” (e.g., errors when trying to create a user again), can safely
schedule executions or manually retry.
3. No Client Required: Can be used with just SSH, zero deployment cost
No need to install any agents (clients) on target servers, just enable SSH service and configure passwordless
login;
Supports Linux/Windows/macOS, hybrid cloud environments (physical machines + virtual machines + cloud servers)
Unified management.
π Advantage: Can quickly connect to 1000 servers without spending a day installing clients first.


02
Write Your First Playbook in 1 Hour (From 0 to 1 Practical Example)
π οΈTaking “Batch Initialization of 10 Servers” as an example (including system updates, tool installations, user creation, and SSH security configuration) π»Step 1: Environment Preparation (15 minutes, basic configuration) β Install Ansible (Control Machine: 1 Linux server/computer) Ubuntu/Debian:
sudo apt update && sudo apt install ansible -y
CentOS/RHEL/OpenEuler:
sudo yum install epel-release -y # CentOS needs to install EPEL source firstsudo yum install ansible -y
Verify installation:
ansible --version # Output version number (e.g., ansible [core 2.14.2]) indicates success
β‘ Configure the Host Inventory (Tell Ansible which servers to manage) The host inventory is a “server list” that can be grouped by roles (e.g., web servers, DB servers), facilitating subsequent batch operations. Edit Ansible’s default host inventory file:
sudo vim /etc/ansible/hosts
Add server information (replace with your actual IP, supports grouping):
# Group by role: Web server group[web_servers]web1 ansible_host=192.168.1.10 # Server 1: Alias web1, IP 192.168.1.10web2 ansible_host=192.168.1.11 # Server 2# Group by role: DB server group[db_servers]db1 ansible_host=192.168.1.20 # Database server# Parent group: includes all servers (for one-time operations on all machines)[cluster:children]web_serversdb_servers
β’ Configure Passwordless SSH Login (Control Machine β Target Machine)
Ansible communicates via SSH, and passwordless login avoids entering a password every time a script is executed:
Generate SSH keys on the control machine (just press enter, no password needed):
ssh-keygen -t rsa # Generates ~/.ssh/id_rsa (private key) and ~/.ssh/id_rsa.pub (public key)
Push the public key to all target servers (replace with your server IP, first time requires entering a password):
ssh-copy-id [email protected] # Push to web1ssh-copy-id [email protected] # Push to web2ssh-copy-id [email protected] # Push to db1
Verify passwordless login:
ssh [email protected] # Login without entering a password, indicating successful configuration
π»Step 2: Write Your First Playbook (20 minutes, initialize servers)
Create init-server.yml to implement 4 core tasks: update system, install basic tools, create operation user, configure SSH security.
---# Playbook Name: Batch Initialization of Server Cluster- name: Initialize Linux Servers (Web+DB) hosts: all # Applies to all servers in the inventory (cluster group) become: yes # Switch to root privileges when executing tasks (similar to sudo) gather_facts: yes # Collect information about target servers (e.g., system version, IP, etc.) # Task list: executed in order tasks: # Task 1: Update system packages (only for Debian/Ubuntu, CentOS automatically skips) - name: Update package cache and upgrade Debian/Ubuntu system apt: update_cache: yes # Equivalent to apt update upgrade: dist # Equivalent to apt upgrade -y cache_valid_time: 3600 # Do not update cache again within 1 hour (speed optimization) when: ansible_os_family == "Debian" # Condition: only execute on Debian-based systems # Task 2: Install basic tools (common to all systems: vim, curl, wget, etc.) - name: Install basic operation tools package: name: # List of software to install - vim - curl - wget - net-tools # Includes commands like ifconfig - chrony # Time synchronization tool (to avoid inconsistent server times) state: present # Ensure software is installed (skip if already installed, install if not) # Task 3: Create operation user ops (password stored encrypted, avoid plaintext) - name: Create operation user ops user: name: ops # Username groups: sudo # Add to sudo group (has root privileges) shell: /bin/bash # Default shell createhome: yes # Create home directory (/home/ops) password: "{{ 'Ops@2024' | password_hash('sha512') }}" # Password encryption (original password Ops@2024) comment: "Operation-specific account, deletion prohibited" # User comment # Task 4: SSH security hardening (disable root login, disable password login) - name: Configure sshd_config to disable root SSH login lineinfile: path: /etc/ssh/sshd_config # Path to the file to modify regexp: '^#?PermitRootLogin' # Matching line (PermitRootLogin with or without #) line: 'PermitRootLogin no' # Replace with "disable root login" state: present # Ensure this line exists backup: yes # Backup the file before modification (/etc/ssh/sshd_config.bak) - name: Configure sshd_config to disable password login (only allow key login) lineinfile: path: /etc/ssh/sshd_config regexp: '^#?PasswordAuthentication' line: 'PasswordAuthentication no' state: present backup: yes notify: Restart SSH Service # Trigger the "Restart SSH Service" handler (restart needed after modifying configuration) # Handlers: only executed when triggered by tasks (e.g., restart service after modifying sshd_config) handlers: - name: Restart SSH Service service: name: sshd # Service name (both CentOS/Ubuntu are sshd) state: restarted # Status: restart enabled: yes # Ensure service starts on boot
π»Step 3: Execute Playbook (15 minutes, verify results)
Ansible provides a “syntax check β dry run β actual execution” process to avoid failures from direct execution.
β Syntax Check (Check for YAML format errors)
ansible-playbook init-server.yml --syntax-check# Output "playbook: init-server.yml" indicates no syntax errors; errors will prompt specific line numbers
β‘ Dry Run (Simulate execution, no actual changes to servers)
ansible-playbook init-server.yml --check# Output "changed=0" for each task (simulated execution, no actual changes), no errors means can execute formally
β’ Formal Execution (Batch Initialize Servers)
ansible-playbook init-server.yml# Key output interpretation:# - ok=xx: Task executed and status correct (e.g., software installed)# - changed=xx: Task executed and modified status (e.g., first time creating ops user)# - failed=0: No failed tasks (failures will prompt specific reasons, such as SSH connection timeout)
β£ Verify Execution Results (Ensure configuration is effective)
# 1. Check if ops user has been created on all serversansible all -m shell -a "id ops" # Output uid=1001(ops) gid=1001(ops) ... indicates success# 2. Check if root can SSH login (should fail, indicating security hardening is effective)ssh [email protected] # Output "Permission denied" indicates success (must log in with ops user: ssh [email protected])
π»Step 4: Advanced Practice: Role-Based Deployment (Differentiated Configuration for Web+DB Servers)
In actual operations, web servers need to install Nginx, and DB servers need to install MySQL, which can be achieved through “group tasks” for differentiated deployment, creating
<span>deploy-app.yml</span>:
---# First Part: Deploy Web Server (only applies to web_servers group)- name: Deploy Web Server (Install Nginx + Deploy Website Code) hosts: web_servers # Only for Web Server group become: yes vars: # Variable definitions (unified management, easy to modify) nginx_version: "1.24.0" # Nginx version to install web_root: "/var/www/html" # Website root directory index_content: "<h1>Welcome to {{ ansible_host }} (Web Server)</h1>" # Dynamic content (includes server IP) tasks: # Task 1: Install Nginx (CentOS uses yum, Ubuntu uses apt, automatically adapts) - name: Install Nginx package: name: nginx-{{ nginx_version }} # Use variable to define version state: present # Task 2: Create website root directory - name: Create website root directory {{ web_root }} file: path: "{{ web_root }}" state: directory # Ensure directory exists owner: www-data # Owner (Nginx default user) group: www-data mode: 0755 # Permissions: owner read/write/execute, others read/execute # Task 3: Deploy homepage (dynamically generated, includes server IP) - name: Generate homepage index.html copy: content: "{{ index_content }}" # Use variable to dynamically generate content dest: "{{ web_root }}/index.html" owner: www-data group: www-data mode: 0644 # Task 4: Start Nginx and set to start on boot - name: Start Nginx service service: name: nginx state: started enabled: yes# Second Part: Deploy DB Server (only applies to db_servers group)- name: Deploy DB Server (Install MySQL + Initialize Database) hosts: db_servers # Only for DB Server group become: yes vars: mysql_root_pass: "DBroot@2024" # MySQL root password (use Ansible Vault encryption in actual environment) app_db: "app_prod" # Application database name app_user: "app_user" # Application database user tasks: # Task 1: Install MySQL Server (CentOS uses mysql-server, Ubuntu uses mysql-server) - name: Install MySQL Server package: name: mysql-server state: present # Task 2: Start MySQL and set to start on boot - name: Start MySQL service service: name: mysqld # CentOS service name; Ubuntu is mysql state: started enabled: yes # Task 3: Initialize database (create application database and user) - name: Initialize MySQL (create database and user) mysql_db: name: "{{ app_db }}" state: present # Ensure database exists login_user: root login_password: "{{ mysql_root_pass }}" login_unix_socket: /var/lib/mysql/mysql.sock # MySQL local socket path - name: Create application database user {{ app_user }} mysql_user: name: "{{ app_user }}" password: "AppPass@2024" # Application user password priv: "{{ app_db }}.*:ALL" # Permissions: all permissions on all tables of app_db host: "%" # Allow connections from any IP (restrict to web server IP in production) state: present login_user: root login_password: "{{ mysql_root_pass }}" login_unix_socket: /var/lib/mysql/mysql.sock
Execute differentiated deployment:
ansible-playbook deploy-app.yml# Verify Web Server: Access http://192.168.1.10, displays "Welcome to 192.168.1.10 (Web Server)"# Verify DB Server: Log in mysql -u root -pDBroot@2024, execute show databases; can see app_prod database
03
Enterprise-Level Playbook Architecture: From “Single Script” to “Maintainable System”

When managing 1000 servers and 10 applications, a single script becomes bloated and hard to maintain, requiring organization by “roles (Roles) + variables + environment isolation” to achieve“modularity, reusability, and easy expansion”.
1. Role-Based Organization (Roles): Split modules by function
Ansible Roles are a “standardized directory structure” that splits tasks, variables, templates, etc., by role (e.g., common role, nginx role, mysql role), facilitating collaboration and reuse.
β Create Roles Directory Structure
Use <span>ansible-galaxy</span> (Ansible’s built-in tool) to automatically generate the standard structure:
# Create 3 roles: common (general configuration), nginx (web service), mysql (db service)ansible-galaxy init roles/commonansible-galaxy init roles/nginxansible-galaxy init roles/mysql
The generated directory structure is as follows (core directory explanation):
roles/βββ common/ # Common role (needs to be executed on all servers: time synchronization, security hardening)β βββ tasks/ # Task files (main.yml: entry task)β βββ handlers/ # Handlers (main.yml: e.g., restart service)β βββ vars/ # Variables (main.yml: role-specific variables)β βββ templates/ # Template files (e.g., sshd_config.j2, supports variable replacement)βββ nginx/ # Nginx role (specific to web servers)β βββ tasks/β βββ handlers/β βββ vars/β βββ templates/ # e.g., nginx.conf.j2 (Nginx configuration template)βββ mysql/ # MySQL role (specific to db servers) βββ tasks/ βββ handlers/ βββ vars/
β‘ Split Tasks into Roles (using common role as an example)Edit<span>roles/common/tasks/main.yml</span><span> (common task entry):</span>
# common role: common configuration for all servers- name: Install basic tools package: name: [vim, curl, wget, chrony] state: present- name: Configure time synchronization (chrony) template: src: templates/chrony.conf.j2 # Template file (in roles/common/templates/) dest: /etc/chrony.conf notify: Restart chrony service
Edit roles/common/handlers/main.yml (handlers):
- name: Restart chrony service service: name: chronyd state: restarted enabled: yes
β’ Call Roles (Write Main Playbook site.yml)
---# Main Playbook: Call all roles for full cluster deployment- name: Execute common configuration on all servers (common role) hosts: all become: yes roles: - common # Call common role- name: Execute Nginx configuration on web servers (nginx role) hosts: web_servers become: yes roles: - nginx # Call nginx role- name: Execute MySQL configuration on db servers (mysql role) hosts: db_servers become: yes roles: - mysql # Call mysql role
Execute the main Playbook:
ansible-playbook site.yml
2. Environment Isolation: Distinguish between Development/Testing/Production EnvironmentsIn enterprises, it is necessary to distinguish between dev (development), test (testing), and prod (production) environments (e.g., production environment MySQL passwords are more complex), which can be achieved through “inventory environment directories” for isolation.β Create Environment Directory Structure
mkdir -p inventory/{dev,test,prod} # 3 environment directories
β‘ Write Production Environment Host Inventory (inventory/prod/hosts)
[web_servers]prod-web1 ansible_host=10.0.1.10prod-web2 ansible_host=10.0.1.11[db_servers]prod-db1 ansible_host=10.0.2.10
β’ Write Production Environment Variables (inventory/prod/group_vars/all.yml)
# Global variables for production environment (more stringent than development environment)timezone: Asia/Shanghaiport: 2222 # Production environment SSH port is not 22 (security hardening)mysql_root_pass: "ProdDB@2024!" # Production environment password is more complexnginx_access_log: "/var/log/nginx/access.log"
β£ Execute Playbook for Specified Environment
# Execute production environment deployment (use -i to specify environment directory)ansible-playbook -i inventory/prod site.yml# Execute development environment deploymentansible-playbook -i inventory/dev site.yml
3. Best Practices: Make Playbooks More Robust and Efficientβ Tag Execution (Only Execute Part of Tasks, Avoid Full Deployment)Add <span>tags</span>, and use <span>--tags</span> to specify only running certain types of tasks (e.g., only execute security hardening, not software installation):
- name: Security hardening task (tag: security) tags: security tasks: - name: Disable root SSH login lineinfile: path: /etc/ssh/sshd_config regexp: '^#?PermitRootLogin' line: 'PermitRootLogin no'- name: Performance optimization task (tag: performance) tags: performance tasks: - name: Adjust kernel parameters (increase TCP connection count) sysctl: name: net.core.somaxconn value: "65535" state: present
Execute tasks with specified tags:
# Only execute security hardening tasks (suitable for urgent security patches)ansible-playbook site.yml --tags "security"
β‘ Encrypt Sensitive Data (Use Ansible Vault to Avoid Plaintext Passwords)In production environments, sensitive data such as MySQL passwords, SSH keys, etc., should not be written in plaintext in Playbooks, and can be encrypted using <span>ansible-vault</span>:
# 1. Encrypt variable file (e.g., inventory/prod/group_vars/all.yml)ansible-vault encrypt inventory/prod/group_vars/all.yml# Enter encryption password (remember, need to enter for subsequent executions)# 2. View the encrypted file (garbled, cannot be read directly)cat inventory/prod/group_vars/all.yml# 3. Execute Playbook while decrypting (need to enter encryption password)ansible-playbook -i inventory/prod site.yml --ask-vault-pass
β’ Performance Optimization (Manage 1000 Servers Without Lag)Edit <span>/etc/ansible/ansible.cfg</span>, adjust concurrency and SSH connection parameters:
[defaults]forks = 50 # Number of processes for concurrent task execution (default 5, set to 50-100 for 1000 servers)host_key_checking = False # Disable SSH host key checking (avoid pop-up on first connection)gathering = smart # Smartly collect server information (do not re-collect if already collected)[ssh_connection]ssh_args = -o ControlMaster=auto -o ControlPersist=60s # Reuse SSH connections (reduce connection establishment time)pipelining = True # Enable SSH pipelining (reduce data transfer times, improve speed)


04
Common Questions in Operations: Three Core Issues of Ansible Playbook Practice
π Q1: Is Playbook difficult to learn? How long does it take for beginners to get started?
Syntax Difficulty: YAML syntax is simpler than JSON, like “lists + key-value pairs”, can learn basic syntax (e.g., – name: task name, hosts: all) in 1 hour;
Getting Started Time: Can write basic Playbooks for “installing software, creating users” in 1 day, master Roles and environment isolation in 3 days, and handle enterprise-level scenarios in 1 week;
Learning Resources: Ansible official documentation (docs.ansible.com) has detailed module descriptions, and example code can be copied directly.
π Q2: Does it support Windows servers? Can it manage hybrid environments?
Yes! Ansible manages Windows servers via WinRM (Windows Remote Management), just enable WinRM service on Windows;
Hybrid environments (Linux + Windows + macOS) can be managed uniformly, using
when: ansible_os_family == “Windows” to distinguish systems;
Example (Installing IIS service on Windows):
- name: Install IIS on Windows Server hosts: windows_servers tasks: - name: Install IIS win_feature: name: Web-Server state: present
π Q3: What if a task fails? How to troubleshoot?
Failure Prompt: Ansible outputs the specific line number and reason for failed tasks (e.g., “SSH connection timed out” “insufficient permissions”);
Log Troubleshooting: Add -v (detailed log) or -vvv (debug log) when executing to view the complete execution process:
ansible-playbook site.yml -vvv # Outputs detailed logs, including SSH commands, return results
Common Failure Reasons:
SSH Connection Failure: Check if the target server IP is correct, if the SSH port is open, and if passwordless login is configured;
Insufficient Permissions: Ensure become: yes is enabled (use root privileges to execute tasks);
Software Package Does Not Exist: Check if the software name is correct (e.g., mysql-server in CentOS is called mysql-server in Ubuntu).
05
γPractical ChallengeγWrite Your First Playbook

Tasks (Choose Any One)
1. Basic Task:
Write a Playbook to install Docker on 3 servers and take a screenshot of the output of
ansible all -m shell -a “docker –version”;
2. Advanced Task:
Use Roles to split “common role (time synchronization) + nginx role (install Nginx)”, take a screenshot of the Roles directory structure and execution results;
3. High-Level Task:
Create dev and prod environments, achieving “dev environment Nginx port 80, prod environment Nginx port 8080”, take screenshots of the different environment Nginx configuration files.
π Share your results in the comments section
π The first 3 will receive an electronic book of “Ansible Authority Guide” (including enterprise-level Playbook templates and troubleshooting tips)!



γClonezilla Batch CloningγOpenEuler Practical: 50 Servers Done in 1 Hour, Operational Efficiency Soars by 1000%!

γQiskit Quantum ComputingγPractical: Master Quantum Programming in 10 Minutes, Say Goodbye to “Quantum Fear” (One-Click Deployment on Linux)
#linux daily practice#linux cloud computing#LinuxPythonWorkshop#Ansible Playbook#Operational Savior
π The next article will introduce:

γLinux & Python Operation Assistantγis here! Whether it’s writing automation operation scripts, monitoring system resources (CPU / memory / disk), or analyzing logs, executing Linux commands in batches, this will provide you with practical solutions and code examples.
Want to unlock more operational insights? Welcome to experience Tencent Yuanbao Mini Program (Click the mini program above to unlock new skills), and follow the public account to get a wealth of knowledge, easily distilling core content, and enhancing Linux and Python operational skills up up! Come explore together and efficiently solve operational challengesο½
π /Linux Technical Operation Bible, waiting for you to explore/ π οΈ
Hey, tech enthusiasts!π
If you are passionate about Linux technical operations and eager to master core skills, then here is a great opportunity you cannot miss!π
I have created a dedicated IMA knowledge base, which contains a 2500-page Linux technical operation bibleπ. This bible is rich in content, from basic entry to advanced practical skills, covering everything. Whether it’s system management, performance optimization, or troubleshooting, it can be your powerful assistant.πͺ
π By joining us, you will gain:
-
A detailed Linux operation bible to help you quickly enhance your skills.
-
A passionate technical exchange community where everyone learns from each other and progresses together.
-
Opportunities for hands-on practice, applying what you’ve learned to real scenarios, and accumulating valuable experience.
π How to join?
-
Scan the QR code below or click the link to join our IMA knowledge base.
-
Share this content with your technical partners, letting more people join this technical feast.
π Come join us! Let’s explore the unknown in the world of Linux, enhance ourselves, and become tech masters!π
#Linux Operations #Technical Bible #Knowledge Sharing #Technical Community
This article is exclusively published by the Linux Engineer Club, please reprint after obtaining authorization from the account administrator. Planning and Production
Planning: Qingfeng | Supervisor: Mingyue
Editor: Xiaoxiao | Image Source: Gaoding Design and Network, infringement will be deleted