From Zero to Expert: A Comprehensive Guide to Ansible Configuration Automation (Includes Complete Project Case)
1. Introduction
In the modern IT operations environment, configuration management automation has become a key technology for improving efficiency, ensuring consistency, and reducing human errors. Ansible, as an open-source configuration management tool, has become one of the preferred tools for operations engineers due to its ease of use and agentless architecture. This article will comprehensively introduce various aspects of Ansible configuration automation, from basic concepts to advanced applications, helping operations engineers master this powerful automation tool.
2. Basic Concepts of Ansible
2.1 What is Ansible
Ansible is an open-source automation platform used for configuration management, application deployment, task automation, and IT orchestration. It adopts an agentless architecture, executing tasks remotely via SSH protocol, and uses YAML language to write playbooks, characterized by low learning costs and simple deployment.
2.2 Core Components
Control Node
- • The machine where Ansible is installed
- • Executes playbooks and ad-hoc commands
- • Manages inventory files
Managed Node
- • The target machine managed by Ansible
- • Requires SSH service to be enabled
- • Typically requires a Python environment
Inventory
- • Defines the list of managed nodes
- • Supports static and dynamic inventory
- • Can set host variables and group variables
Playbook
- • Configuration files written in YAML
- • Describes the execution process of automation tasks
- • Contains one or more plays
Module
- • The execution unit of Ansible
- • Completes specific task operations
- • Built-in thousands of modules
Plugin
- • Components that extend Ansible’s functionality
- • Includes connection plugins, filter plugins, etc.
3. Installation and Configuration
3.1 Installing Ansible
CentOS/RHEL Systems
# Use EPEL repository
yum install epel-release -y
yum install ansible -y
# Or install using pip
pip install ansible
Ubuntu/Debian Systems
# Add PPA repository
sudo apt-add-repository ppa:ansible/ansible
sudo apt update
sudo apt install ansible -y
# Or install using pip
pip install ansible
Verify Installation
ansible --version
3.2 Configuration File Structure
The search order for Ansible configuration files is as follows:
- 1.
<span>$ANSIBLE_CONFIG</span>specified by the environment variable - 2. The
<span>ansible.cfg</span>in the current directory - 3. The
<span>.ansible.cfg</span>in the user’s home directory - 4. The system configuration file
<span>/etc/ansible/ansible.cfg</span>
Main Configuration Items
[defaults]
# Default inventory file path
inventory = /etc/ansible/hosts
# Remote user
remote_user = root
# SSH private key file path
private_key_file = ~/.ssh/id_rsa
# Host key checking
host_key_checking = False
# Number of forks
forks = 20
# Timeout
timeout = 30
# Log file
log_path = /var/log/ansible.log
[ssh_connection]
# SSH parameters
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
# Enable pipelining
pipelining = True
4. Inventory Management
4.1 Static Inventory
Basic Format
# Single host
web1.example.com
# Host group
[webservers]
web1.example.com
web2.example.com
web3.example.com
[databases]
db1.example.com
db2.example.com
# Host variables
[webservers]
web1.example.com http_port=80 maxRequestsPerChild=808
web2.example.com http_port=8080 maxRequestsPerChild=909
# Group variables
[webservers:vars]
ntp_server=ntp.example.com
proxy=proxy.example.com
Host Range
# Numeric range
[webservers]
web[01:50].example.com
# Alphabetic range
[databases]
db[a:f].example.com
# Multiple ranges
[servers]
server[01:20].example[1:3].com
4.2 Dynamic Inventory
AWS EC2 Dynamic Inventory
#!/usr/bin/env python3
import boto3
import json
def get_ec2_instances():
ec2 = boto3.client('ec2')
response = ec2.describe_instances()
inventory = {
'_meta': {'hostvars': {}},
'all': {'hosts': []},
'webservers': {'hosts': []},
'databases': {'hosts': []}
}
for reservation in response['Reservations']:
for instance in reservation['Instances']:
if instance['State']['Name'] == 'running':
public_ip = instance.get('PublicIpAddress')
if public_ip:
inventory['all']['hosts'].append(public_ip)
# Grouping by tags
for tag in instance.get('Tags', []):
if tag['Key'] == 'Role':
role = tag['Value']
if role not in inventory:
inventory[role] = {'hosts': []}
inventory[role]['hosts'].append(public_ip)
return inventory
if __name__ == '__main__':
print(json.dumps(get_ec2_instances(), indent=2))
4.3 Host Variables and Group Variables
Directory Structure
inventory/
├── hosts
├── group_vars/
│ ├── all.yml
│ ├── webservers.yml
│ └── databases.yml
└── host_vars/
├── web1.example.com.yml
└── db1.example.com.yml
group_vars/all.yml
---
# Global variables
timezone: Asia/Shanghai
dns_servers:
- 8.8.8.8
- 8.8.4.4
group_vars/webservers.yml
---
# Web server group variables
http_port: 80
max_clients: 200
document_root: /var/www/html
5. Ad-hoc Commands
5.1 Basic Syntax
ansible <pattern> -m <module> -a <arguments>
5.2 Common Ad-hoc Commands
Execute Shell Commands
# Execute command on all hosts
ansible all -m shell -a "uptime"
# Execute command on specific group
ansible webservers -m shell -a "systemctl status nginx"
# Use sudo privileges
ansible all -m shell -a "systemctl restart nginx" --become
File Operations
# Copy files
ansible all -m copy -a "src=/tmp/test.txt dest=/tmp/test.txt"
# Create directory
ansible all -m file -a "path=/tmp/testdir state=directory"
# Change file permissions
ansible all -m file -a "path=/tmp/test.txt mode=0644"
Package Management
# Install package
ansible all -m yum -a "name=nginx state=present"
# Uninstall package
ansible all -m yum -a "name=nginx state=absent"
# Update all packages
ansible all -m yum -a "name=* state=latest"
Service Management
# Start service
ansible all -m service -a "name=nginx state=started"
# Stop service
ansible all -m service -a "name=nginx state=stopped"
# Restart service
ansible all -m service -a "name=nginx state=restarted"
6. Writing Playbooks
6.1 Basic Structure
---
- name: Configure Web Server
hosts: webservers
become: yes
vars:
http_port: 80
max_clients: 200
tasks:
- name: Install Nginx
yum:
name: nginx
state: present
- name: Start Nginx Service
service:
name: nginx
state: started
enabled: yes
6.2 Variable Usage
Defining Variables
---
- name: Variable Example
hosts: all
vars:
packages:
- nginx
- mysql
- php
user_info:
name: webapp
group: webapp
shell: /bin/bash
tasks:
- name: Install Packages
yum:
name: "{{ packages }}"
state: present
- name: Create User
user:
name: "{{ user_info.name }}"
group: "{{ user_info.group }}"
shell: "{{ user_info.shell }}"
Variable Files
# vars/main.yml
---
database_name: myapp
database_user: myapp_user
database_password: "{{ vault_database_password }}"
Referencing in Playbook
---
- name: Database Configuration
hosts: databases
vars_files:
- vars/main.yml
tasks:
- name: Create Database
mysql_db:
name: "{{ database_name }}"
state: present
6.3 Conditional Statements
---
- name: Conditional Example
hosts: all
tasks:
- name: Install Apache (RedHat)
yum:
name: httpd
state: present
when: ansible_os_family == "RedHat"
- name: Install Apache (Debian)
apt:
name: apache2
state: present
when: ansible_os_family == "Debian"
- name: Check Disk Space
shell: df -h /
register: disk_usage
- name: Warn Disk Space Insufficient
debug:
msg: "Disk space is insufficient, please clean up promptly"
when: "'90%' in disk_usage.stdout"
6.4 Loops
---
- name: Loop Example
hosts: all
tasks:
- name: Install Multiple Packages
yum:
name: "{{ item }}"
state: present
loop:
- nginx
- mysql
- php
- redis
- name: Create Multiple Users
user:
name: "{{ item.name }}"
group: "{{ item.group }}"
state: present
loop:
- { name: 'user1', group: 'web' }
- { name: 'user2', group: 'db' }
- { name: 'user3', group: 'app' }
- name: Process Dictionary Loop
debug:
msg: "{{ item.key }}: {{ item.value }}"
loop: "{{ lookup('dict', {'a': 1, 'b': 2, 'c': 3}) }}"
6.5 Error Handling
---
- name: Error Handling Example
hosts: all
tasks:
- name: Attempt to Start Service
service:
name: nginx
state: started
ignore_errors: yes
- name: Capture Error Information
shell: /bin/false
register: result
failed_when: result.rc != 0
ignore_errors: yes
- name: Execute Different Operations Based on Result
debug:
msg: "Command execution failed"
when: result.failed
- name: Rescue Operation
block:
- name: Potentially Failing Task
shell: /bin/false
rescue:
- name: Rescue Task
debug:
msg: "Executing rescue operation"
always:
- name: Task Always Executed
debug:
msg: "Executed regardless of success or failure"
7. Module Details
7.1 System Modules
User Module
- name: Create User
user:
name: webapp
group: webapp
shell: /bin/bash
home: /home/webapp
create_home: yes
password: "{{ 'password' | password_hash('sha512') }}"
Group Module
- name: Create Group
group:
name: webapp
gid: 1001
state: present
Cron Module
- name: Add Cron Job
cron:
name: "backup database"
minute: "0"
hour: "2"
job: "/usr/local/bin/backup.sh"
user: root
7.2 File Modules
File Module
- name: Create Directory
file:
path: /var/www/html
state: directory
owner: nginx
group: nginx
mode: '0755'
- name: Create Symbolic Link
file:
src: /var/www/html
dest: /var/www/site
state: link
Copy Module
- name: Copy File
copy:
src: /tmp/source.txt
dest: /tmp/dest.txt
owner: root
group: root
mode: '0644'
backup: yes
Template Module
- name: Generate Configuration File
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
notify: restart nginx
7.3 Package Modules
Yum Module
- name: Install Package
yum:
name:
- nginx
- mysql-server
- php
state: present
update_cache: yes
- name: Install Specific Version
yum:
name: nginx-1.18.0
state: present
Apt Module
- name: Update Package Cache
apt:
update_cache: yes
cache_valid_time: 3600
- name: Install Package
apt:
name: "{{ packages }}"
state: present
vars:
packages:
- nginx
- mysql-server
- php
7.4 Service Modules
Service Module
- name: Start and Enable Service
service:
name: nginx
state: started
enabled: yes
- name: Restart Service
service:
name: nginx
state: restarted
Systemd Module
- name: Reload Systemd
systemd:
daemon_reload: yes
- name: Start Service
systemd:
name: nginx
state: started
enabled: yes
8. Templates and Filters
8.1 Jinja2 Templates
Basic Syntax
# nginx.conf.j2
user {{ nginx_user }};
worker_processes {{ ansible_processor_cores }};
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections {{ nginx_worker_connections }};
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
{% for upstream in nginx_upstreams %}
upstream {{ upstream.name }} {
{% for server in upstream.servers %}
server {{ server }};
{% endfor %}
}
{% endfor %}
server {
listen {{ http_port }};
server_name {{ server_name }};
location / {
root {{ document_root }};
index index.html index.htm;
}
}
}
8.2 Common Filters
---
- name: Filter Example
hosts: all
vars:
items: [1, 2, 3, 4, 5]
text: "Hello World"
tasks:
- name: Number Filter
debug:
msg: "{{ items | max }}" # Maximum value
- name: String Filter
debug:
msg: "{{ text | lower }}" # Convert to lowercase
- name: Default Value Filter
debug:
msg: "{{ undefined_var | default('default_value') }}"
- name: Password Hash
debug:
msg: "{{ 'password' | password_hash('sha512') }}"
- name: Time Filter
debug:
msg: "{{ ansible_date_time.iso8601 | to_datetime }}"
9. Handlers and Notifications
9.1 Basic Usage of Handlers
---
- name: Web Server Configuration
hosts: webservers
tasks:
- name: Install Nginx
yum:
name: nginx
state: present
- name: Configure Nginx
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify:
- restart nginx
- reload nginx
- name: Ensure Nginx is Running
service:
name: nginx
state: started
enabled: yes
handlers:
- name: restart nginx
service:
name: nginx
state: restarted
- name: reload nginx
service:
name: nginx
state: reloaded
9.2 Conditional Handlers
---
- name: Conditional Handler Example
hosts: all
tasks:
- name: Check Configuration File
stat:
path: /etc/nginx/nginx.conf
register: nginx_config
- name: Update Configuration
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
when: nginx_config.stat.exists
notify: restart nginx
handlers:
- name: restart nginx
service:
name: nginx
state: restarted
when: nginx_config.stat.exists
10. Roles
10.1 Role Structure
roles/
└── nginx/
├── tasks/
│ └── main.yml
├── handlers/
│ └── main.yml
├── templates/
│ └── nginx.conf.j2
├── files/
│ └── index.html
├── vars/
│ └── main.yml
├── defaults/
│ └── main.yml
├── meta/
│ └── main.yml
└── README.md
10.2 Creating a Role
tasks/main.yml
---
- name: Install Nginx
yum:
name: nginx
state: present
- name: Create Configuration File
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: restart nginx
- name: Start Nginx Service
service:
name: nginx
state: started
enabled: yes
handlers/main.yml
---
- name: restart nginx
service:
name: nginx
state: restarted
defaults/main.yml
---
nginx_user: nginx
nginx_worker_connections: 1024
http_port: 80
document_root: /usr/share/nginx/html
meta/main.yml
---
galaxy_info:
author: your-name
description: Nginx web server role
company: your-company
license: MIT
min_ansible_version: 2.9
platforms:
- name: EL
versions:
- 7
- 8
- name: Ubuntu
versions:
- 18.04
- 20.04
dependencies: []
10.3 Using Roles
---
- name: Deploy Web Server
hosts: webservers
roles:
- nginx
- mysql
- php
# Passing Variables to Role
- name: Deploy Web Server
hosts: webservers
roles:
- role: nginx
nginx_user: www-data
http_port: 8080
11. Vault Encryption
11.1 Creating Encrypted Files
# Create encrypted file
ansible-vault create secret.yml
# Edit encrypted file
ansible-vault edit secret.yml
# View encrypted file
ansible-vault view secret.yml
# Encrypt existing file
ansible-vault encrypt existing_file.yml
# Decrypt file
ansible-vault decrypt secret.yml
11.2 Using Encrypted Variables
Encrypted Variable File
# vault.yml
---
vault_database_password: secretpassword123
vault_api_key: abc123def456
Using in Playbook
---
- name: Use Encrypted Variables
hosts: databases
vars_files:
- vault.yml
tasks:
- name: Create Database User
mysql_user:
name: myapp
password: "{{ vault_database_password }}"
priv: "myapp.*:ALL"
state: present
Running Playbook
ansible-playbook -i inventory site.yml --ask-vault-pass
# Or use password file
ansible-playbook -i inventory site.yml --vault-password-file ~/.vault_pass
12. Advanced Features
12.1 Strategy Control
---
- name: Strategy Control Example
hosts: all
strategy: free # Free strategy, each host executes independently
tasks:
- name: Long Running Task
shell: sleep 30
- name: Quick Task
debug:
msg: "This task will complete quickly"
12.2 Delegation and Proxy
---
- name: Delegation Execution Example
hosts: webservers
tasks:
- name: Check Service Status on Monitoring Server
uri:
url: "http://{{ inventory_hostname }}/health"
method: GET
delegate_to: monitor.example.com
- name: Execute Command Locally
shell: echo "Executed on Control Node"
delegate_to: localhost
run_once: true
12.3 Rolling Updates
---
- name: Rolling Update Example
hosts: webservers
serial: 2 # Process 2 servers at a time
tasks:
- name: Remove from Load Balancer
uri:
url: "http://lb.example.com/remove/{{ inventory_hostname }}"
method: POST
delegate_to: localhost
- name: Update Application
yum:
name: myapp
state: latest
notify: restart myapp
- name: Wait for Service to Start
wait_for:
port: 8080
delay: 10
- name: Add to Load Balancer
uri:
url: "http://lb.example.com/add/{{ inventory_hostname }}"
method: POST
delegate_to: localhost
handlers:
- name: restart myapp
service:
name: myapp
state: restarted
12.4 Asynchronous Tasks
---
- name: Asynchronous Task Example
hosts: all
tasks:
- name: Long Running Task
shell: /opt/long_running_script.sh
async: 3600 # Maximum running time (seconds)
poll: 0 # Do not wait for result
register: long_task
- name: Execute Other Tasks
debug:
msg: "Continue executing other tasks"
- name: Check Asynchronous Task Status
async_status:
jid: "{{ long_task.ansible_job_id }}"
register: job_result
until: job_result.finished
retries: 30
delay: 10
13. Best Practices
13.1 Directory Structure
ansible-project/
├── inventories/
│ ├── production/
│ │ ├── hosts
│ │ └── group_vars/
│ └── staging/
│ ├── hosts
│ └── group_vars/
├── roles/
│ ├── common/
│ ├── nginx/
│ └── mysql/
├── playbooks/
│ ├── site.yml
│ ├── webservers.yml
│ └── databases.yml
├── group_vars/
│ └── all.yml
├── host_vars/
├── vault/
│ └── secrets.yml
├── files/
├── templates/
├── library/
├── filter_plugins/
└── ansible.cfg
13.2 Naming Conventions
---
# Use descriptive names
- name: Install and Configure Nginx Web Server
hosts: webservers
tasks:
- name: Install Nginx Package
yum:
name: nginx
state: present
- name: Create Nginx Configuration File
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart Nginx Service
- name: Start and Enable Nginx Service
service:
name: nginx
state: started
enabled: yes
handlers:
- name: Restart Nginx Service
service:
name: nginx
state: restarted
13.3 Variable Management
# Use clear variable hierarchy
nginx_config:
user: nginx
worker_processes: auto
worker_connections: 1024
keepalive_timeout: 65
server:
listen: 80
server_name: example.com
root: /var/www/html
index: index.html
upstream:
name: backend
servers:
- 192.168.1.10:8080
- 192.168.1.11:8080
13.4 Error Handling
---
- name: Robust Error Handling
hosts: all
tasks:
- name: Check System Requirements
assert:
that:
- ansible_distribution_major_version | int >= 7
- ansible_memtotal_mb >= 1024
fail_msg: "System does not meet minimum requirements"
- name: Backup Configuration File
copy:
src: /etc/nginx/nginx.conf
dest: /etc/nginx/nginx.conf.bak
remote_src: yes
ignore_errors: yes
- name: Update Configuration
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
validate: nginx -t -c %s
notify: restart nginx
14. Monitoring and Logging
14.1 Log Configuration
# ansible.cfg
[defaults]
log_path = /var/log/ansible.log
display_skipped_hosts = False
display_ok_hosts = False
14.2 Callback Plugins
# callback_plugins/timer.py
from ansible.plugins.callback import CallbackBase
from datetime import datetime
class CallbackModule(CallbackBase):
def __init__(self):
super(CallbackModule, self).__init__()
self.start_time = datetime.now()
def v2_playbook_on_task_start(self, task, is_conditional):
self.task_start_time = datetime.now()
def v2_runner_on_ok(self, result):
duration = datetime.now() - self.task_start_time
self._display.display(f"Task completed in {duration.total_seconds():.2f}s")
14.3 Performance Monitoring
---
- name: Performance Monitoring Example
hosts: all
tasks:
- name: Collect System Information
setup:
gather_subset:
- hardware
- network
- virtual
- name: Record Performance Metrics
debug:
msg: |
CPU Cores: {{ ansible_processor_cores }}
Memory Size: {{ ansible_memtotal_mb }}MB
Disk Usage: {{ ansible_mounts | selectattr('mount', 'equalto', '/') | map(attribute='size_available') | first }}
15. CI/CD Integration
15.1 GitLab CI Integration
# .gitlab-ci.yml
stages:
- test
- deploy
ansible-lint:
stage: test
script:
- ansible-lint playbooks/site.yml
only:
- merge_requests
deploy-staging:
stage: deploy
script:
- ansible-playbook -i inventories/staging/hosts playbooks/site.yml --vault-password-file $VAULT_PASSWORD_FILE
environment:
name: staging
url: https://staging.example.com
only:
- develop
deploy-production:
stage: deploy
script:
- ansible-playbook -i inventories/production/hosts playbooks/site.yml --vault-password-file $VAULT_PASSWORD_FILE
environment:
name: production
url: https://production.example.com
when: manual
only:
- master
15.2 Jenkins Integration
// Jenkinsfile
pipeline {
agent any
environment {
ANSIBLE_HOST_KEY_CHECKING = 'False'
VAULT_PASSWORD_FILE = credentials('ansible-vault-password')
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Syntax Check') {
steps {
sh 'ansible-playbook --syntax-check playbooks/site.yml'
}
}
stage('Lint') {
steps {
sh 'ansible-lint playbooks/site.yml'
}
}
stage('Deploy to Staging') {
steps {
sh '''
ansible-playbook -i inventories/staging/hosts \
playbooks/site.yml \
--vault-password-file $VAULT_PASSWORD_FILE
'''
}
}
stage('Deploy to Production') {
when {
branch 'master'
}
steps {
input message: 'Deploy to Production?'
sh '''
ansible-playbook -i inventories/production/hosts \
playbooks/site.yml \
--vault-password-file $VAULT_PASSWORD_FILE
'''
}
}
}
post {
always {
archiveArtifacts artifacts: 'logs/*.log', allowEmptyArchive: true
}
failure {
emailext (
subject: "Ansible Deployment Failed: ${env.JOB_NAME} - ${env.BUILD_NUMBER}",
body: "Build failed. Check console output at ${env.BUILD_URL}",
to: "${env.CHANGE_AUTHOR_EMAIL}"
)
}
}
}
15.3 GitHub Actions Integration
# .github/workflows/deploy.yml
name: Deploy with Ansible
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install dependencies
run: |
pip install ansible ansible-lint
- name: Run ansible-lint
run: ansible-lint playbooks/site.yml
- name: Syntax check
run: ansible-playbook --syntax-check playbooks/site.yml
deploy-staging:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/develop'
steps:
- uses: actions/checkout@v2
- name: Deploy to staging
env:
ANSIBLE_HOST_KEY_CHECKING: False
VAULT_PASSWORD: ${{ secrets.VAULT_PASSWORD }}
run: |
echo "$VAULT_PASSWORD" > .vault_pass
ansible-playbook -i inventories/staging/hosts playbooks/site.yml --vault-password-file .vault_pass
rm .vault_pass
deploy-production:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
environment: production
steps:
- uses: actions/checkout@v2
- name: Deploy to production
env:
ANSIBLE_HOST_KEY_CHECKING: False
VAULT_PASSWORD: ${{ secrets.VAULT_PASSWORD }}
run: |
echo "$VAULT_PASSWORD" > .vault_pass
ansible-playbook -i inventories/production/hosts playbooks/site.yml --vault-password-file .vault_pass
rm .vault_pass
16. Troubleshooting
16.1 Common Issues and Solutions
SSH Connection Issues
# Check SSH connection
ansible all -m ping
# Use verbose output
ansible all -m ping -vvv
# Skip host key checking
export ANSIBLE_HOST_KEY_CHECKING=False
Permission Issues
# Use sudo privileges
ansible all -m shell -a "systemctl status nginx" --become
# Specify sudo user
ansible all -m shell -a "systemctl status nginx" --become-user=root
Module Not Found
# Check module path
ansible-doc -l | grep module_name
# Install missing Python modules
pip install required_module
16.2 Debugging Techniques
---
- name: Debug Example
hosts: all
tasks:
- name: Collect Facts
setup:
register: facts
- name: Display Variable Content
debug:
var: facts
verbosity: 2
- name: Conditional Debug
debug:
msg: "Disk space is insufficient"
when:
- ansible_mounts | selectattr('mount', 'equalto', '/') | map(attribute='size_available') | first < 1000000000
- name: Pause Execution
pause:
prompt: "Please check system status and press enter to continue"
when: debug_mode | default(false)
16.3 Performance Optimization
# ansible.cfg optimization configuration
[defaults]
# Increase number of forks
forks = 50
# Enable fact caching
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts_cache
fact_caching_timeout = 3600
[ssh_connection]
# Enable SSH pipelining
pipelining = True
# Control connection reuse
ssh_args = -o ControlMaster=auto -o ControlPersist=300s
# Reduce SSH connection time
control_path = /tmp/ansible-ssh-%%h-%%p-%%r
17. Security Considerations
17.1 Permission Control
---
- name: Security Configuration Example
hosts: all
become: yes
become_method: sudo
tasks:
- name: Create Dedicated User
user:
name: ansible
groups: wheel
shell: /bin/bash
create_home: yes
- name: Configure Sudo Permissions
lineinfile:
path: /etc/sudoers.d/ansible
line: 'ansible ALL=(ALL) NOPASSWD: ALL'
create: yes
validate: 'visudo -cf %s'
- name: Configure SSH Key
authorized_key:
user: ansible
key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
state: present
17.2 Sensitive Information Protection
---
- name: Sensitive Information Handling
hosts: all
vars:
sensitive_data: "{{ vault_sensitive_data }}"
tasks:
- name: Use Sensitive Data
shell: echo "{{ sensitive_data }}"
no_log: true # Prevent sensitive information from being logged
- name: Handle Password
user:
name: dbuser
password: "{{ vault_db_password | password_hash('sha512') }}"
no_log: true
17.3 Network Security
---
- name: Network Security Configuration
hosts: all
tasks:
- name: Configure Firewall
firewalld:
service: "{{ item }}"
permanent: yes
state: enabled
immediate: yes
loop:
- ssh
- http
- https
- name: Restrict SSH Access
lineinfile:
path: /etc/ssh/sshd_config
regexp: "^#?PasswordAuthentication"
line: "PasswordAuthentication no"
notify: restart sshd
- name: Configure SELinux
selinux:
policy: targeted
state: enforcing
handlers:
- name: restart sshd
service:
name: sshd
state: restarted
18. Enterprise Deployment Cases
18.1 Automated Deployment of LAMP Architecture
---
- name: Deploy LAMP Architecture
hosts: webservers
become: yes
vars:
mysql_root_password: "{{ vault_mysql_root_password }}"
app_user: webapp
app_group: webapp
roles:
- common
- apache
- mysql
- php
- application
post_tasks:
- name: Validate Deployment
uri:
url: "http://{{ inventory_hostname }}/health"
method: GET
status_code: 200
delegate_to: localhost
18.2 Docker Containerization Deployment
---
- name: Docker Containerization Deployment
hosts: docker_hosts
become: yes
tasks:
- name: Install Docker
yum:
name: docker
state: present
- name: Start Docker Service
service:
name: docker
state: started
enabled: yes
- name: Pull Application Image
docker_image:
name: "{{ app_image }}"
tag: "{{ app_version }}"
source: pull
- name: Deploy Application Container
docker_container:
name: "{{ app_name }}"
image: "{{ app_image }}:{{ app_version }}"
state: started
restart_policy: always
ports:
- "80:8080"
env:
DB_HOST: "{{ db_host }}"
DB_PASSWORD: "{{ vault_db_password }}"
- name: Wait for Application to Start
wait_for:
port: 80
delay: 10
timeout: 60
18.3 Kubernetes Cluster Deployment
---
- name: Kubernetes Cluster Deployment
hosts: k8s_masters
become: yes
tasks:
- name: Initialize Cluster
shell: |
kubeadm init --pod-network-cidr=10.244.0.0/16
register: kubeadm_init
run_once: true
- name: Save Join Command
set_fact:
join_command: "{{ kubeadm_init.stdout_lines | select('match', 'kubeadm join.*') | first }}"
run_once: true
- name: Configure kubectl
shell: |
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
run_once: true
- name: Deploy Network Plugin
shell: kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
run_once: true
- name: Join Worker Nodes
hosts: k8s_workers
become: yes
tasks:
- name: Join Cluster
shell: "{{ hostvars[groups['k8s_masters'][0]]['join_command'] }}"
19. Conclusion
Ansible, as an important tool for modern IT infrastructure automation, provides operations engineers with powerful and flexible configuration management capabilities. Through this comprehensive introduction, we can see Ansible’s advantages in the following aspects:
Easy to Use: Using YAML syntax, it has a low learning curve and can be used without complex programming knowledge.
Agentless Architecture: There is no need to install clients on target hosts, reducing deployment and maintenance complexity.
Powerful Module System: Built-in thousands of modules covering various aspects of system management, while supporting custom module extensions.
Good Scalability: Supports infrastructure management from small to large scale, meeting the needs of enterprises of different sizes.
Integration with DevOps Toolchain: Can integrate well with CI/CD tools, monitoring systems, container platforms, etc., to build a complete automation workflow.
In practical applications, it is recommended that operations engineers gradually master Ansible from the following aspects:
- 1. Basic Learning: Master core concepts, module usage, and playbook writing
- 2. Practical Application: Start with simple system configurations and gradually apply to complex multi-layer architecture deployments
- 3. Best Practices: Follow naming conventions, directory structures, security configurations, and other best practices
- 4. Advanced Features: Learn advanced functionalities such as Roles, Vault, and strategy control
- 5. Integration Optimization: Integrate Ansible into existing DevOps workflows for end-to-end automation
With the continuous development of cloud computing, containerization, and microservices architecture, the importance of configuration management automation is increasingly prominent. Ansible, with its simplicity, power, and flexibility, will play an even more important role in future IT operations automation. Mastering Ansible not only improves operational efficiency but also lays a solid foundation for the career development of operations engineers.
I hope this article can help readers comprehensively understand and master Ansible configuration automation technology, flexibly apply it in practical work, and enhance the level of operational automation.
End of Article Benefits
