ansible-automation

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Ansible Automation

Ansible自动化

Overview

概述

Automate infrastructure provisioning, configuration management, and application deployment across multiple servers using Ansible playbooks, roles, and dynamic inventory management.
使用Ansible剧本、角色和动态清单管理,跨多台服务器实现基础设施置备、配置管理和应用部署的自动化。

When to Use

适用场景

  • Configuration management
  • Application deployment
  • Infrastructure patching and updates
  • Multi-server orchestration
  • Cloud instance provisioning
  • Container management
  • Database administration
  • Security compliance automation
  • 配置管理
  • 应用部署
  • 基础设施补丁与更新
  • 多服务器编排
  • 云实例置备
  • 容器管理
  • 数据库管理
  • 安全合规自动化

Implementation Examples

实现示例

1. Playbook Structure and Best Practices

1. 剧本结构与最佳实践

yaml
undefined
yaml
undefined

site.yml - Main playbook

site.yml - Main playbook


  • name: Deploy application stack hosts: all gather_facts: yes serial: 1 # Rolling deployment
    pre_tasks:
    • name: Display host information debug: var: inventory_hostname tags: [always]
    roles:
    • common
    • docker
    • application
    post_tasks:
    • name: Verify deployment uri: url: "http://{{ inventory_hostname }}:8080/health" status_code: 200 retries: 3 delay: 10 tags: [verify]

  • name: Deploy application stack hosts: all gather_facts: yes serial: 1 # Rolling deployment
    pre_tasks:
    • name: Display host information debug: var: inventory_hostname tags: [always]
    roles:
    • common
    • docker
    • application
    post_tasks:
    • name: Verify deployment uri: url: "http://{{ inventory_hostname }}:8080/health" status_code: 200 retries: 3 delay: 10 tags: [verify]

roles/common/tasks/main.yml

roles/common/tasks/main.yml


  • name: Update system packages apt: update_cache: yes cache_valid_time: 3600 when: ansible_os_family == 'Debian'
  • name: Install required packages package: name: "{{ packages }}" state: present vars: packages: - curl - git - htop - python3-pip
  • name: Configure sysctl settings sysctl: name: "{{ item.name }}" value: "{{ item.value }}" sysctl_set: yes state: present loop:
    • name: net.core.somaxconn value: 65535
    • name: net.ipv4.tcp_max_syn_backlog value: 65535
    • name: fs.file-max value: 2097152
  • name: Create application user user: name: appuser shell: /bin/bash home: /home/appuser createhome: yes state: present

  • name: Update system packages apt: update_cache: yes cache_valid_time: 3600 when: ansible_os_family == 'Debian'
  • name: Install required packages package: name: "{{ packages }}" state: present vars: packages: - curl - git - htop - python3-pip
  • name: Configure sysctl settings sysctl: name: "{{ item.name }}" value: "{{ item.value }}" sysctl_set: yes state: present loop:
    • name: net.core.somaxconn value: 65535
    • name: net.ipv4.tcp_max_syn_backlog value: 65535
    • name: fs.file-max value: 2097152
  • name: Create application user user: name: appuser shell: /bin/bash home: /home/appuser createhome: yes state: present

roles/docker/tasks/main.yml

roles/docker/tasks/main.yml


  • name: Install Docker prerequisites package: name: "{{ docker_packages }}" state: present vars: docker_packages: - apt-transport-https - ca-certificates - curl - gnupg - lsb-release
  • name: Add Docker GPG key apt_key: url: https://download.docker.com/linux/ubuntu/gpg state: present
  • name: Add Docker repository apt_repository: repo: "deb https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable" state: present
  • name: Install Docker package: name: - docker-ce - docker-ce-cli - containerd.io state: present
  • name: Start Docker service systemd: name: docker enabled: yes state: started
  • name: Add user to docker group user: name: appuser groups: docker append: yes

  • name: Install Docker prerequisites package: name: "{{ docker_packages }}" state: present vars: docker_packages: - apt-transport-https - ca-certificates - curl - gnupg - lsb-release
  • name: Add Docker GPG key apt_key: url: https://download.docker.com/linux/ubuntu/gpg state: present
  • name: Add Docker repository apt_repository: repo: "deb https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable" state: present
  • name: Install Docker package: name: - docker-ce - docker-ce-cli - containerd.io state: present
  • name: Start Docker service systemd: name: docker enabled: yes state: started
  • name: Add user to docker group user: name: appuser groups: docker append: yes

roles/application/tasks/main.yml

roles/application/tasks/main.yml


  • name: Clone application repository git: repo: "{{ app_repo_url }}" dest: "/home/appuser/app" version: "{{ app_version }}" force: yes become: yes become_user: appuser
  • name: Copy environment configuration template: src: .env.j2 dest: "/home/appuser/app/.env" owner: appuser group: appuser mode: '0600' notify: restart application
  • name: Build Docker image docker_image: name: "myapp:{{ app_version }}" build: path: "/home/appuser/app" pull: yes source: build state: present become: yes
  • name: Start application container docker_container: name: myapp image: "myapp:{{ app_version }}" state: started restart_policy: always ports: - "8080:8080" volumes: - /home/appuser/app:/app:ro env: NODE_ENV: "{{ environment }}" LOG_LEVEL: "{{ log_level }}" healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 30s timeout: 10s retries: 3
handlers:
  • name: restart application docker_container: name: myapp state: restarted
undefined

  • name: Clone application repository git: repo: "{{ app_repo_url }}" dest: "/home/appuser/app" version: "{{ app_version }}" force: yes become: yes become_user: appuser
  • name: Copy environment configuration template: src: .env.j2 dest: "/home/appuser/app/.env" owner: appuser group: appuser mode: '0600' notify: restart application
  • name: Build Docker image docker_image: name: "myapp:{{ app_version }}" build: path: "/home/appuser/app" pull: yes source: build state: present become: yes
  • name: Start application container docker_container: name: myapp image: "myapp:{{ app_version }}" state: started restart_policy: always ports: - "8080:8080" volumes: - /home/appuser/app:/app:ro env: NODE_ENV: "{{ environment }}" LOG_LEVEL: "{{ log_level }}" healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 30s timeout: 10s retries: 3
handlers:
  • name: restart application docker_container: name: myapp state: restarted
undefined

2. Inventory and Variables

2. 清单与变量

yaml
undefined
yaml
undefined

inventory/hosts.ini

inventory/hosts.ini

[webservers] web1 ansible_host=10.0.1.10 web2 ansible_host=10.0.1.11 web3 ansible_host=10.0.1.12
[databases] db1 ansible_host=10.0.2.10 db_role=primary db2 ansible_host=10.0.2.11 db_role=replica
[all:vars] ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_rsa ansible_python_interpreter=/usr/bin/python3
[webservers] web1 ansible_host=10.0.1.10 web2 ansible_host=10.0.1.11 web3 ansible_host=10.0.1.12
[databases] db1 ansible_host=10.0.2.10 db_role=primary db2 ansible_host=10.0.2.11 db_role=replica
[all:vars] ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_rsa ansible_python_interpreter=/usr/bin/python3

inventory/group_vars/webservers.yml

inventory/group_vars/webservers.yml


app_version: "1.2.3" app_repo_url: "https://github.com/myorg/myapp.git" environment: production log_level: INFO

app_version: "1.2.3" app_repo_url: "https://github.com/myorg/myapp.git" environment: production log_level: INFO

inventory/host_vars/web1.yml

inventory/host_vars/web1.yml


server_role: primary max_connections: 500
undefined

server_role: primary max_connections: 500
undefined

3. Ansible Deployment Script

3. Ansible部署脚本

bash
#!/bin/bash
bash
#!/bin/bash

ansible-deploy.sh - Deploy using Ansible

ansible-deploy.sh - Deploy using Ansible

set -euo pipefail
ENVIRONMENT="${1:-dev}" PLAYBOOK="${2:-site.yml}" INVENTORY="inventory/hosts.ini" LIMIT="${3:-all}"
echo "Deploying with Ansible: $PLAYBOOK" echo "Environment: $ENVIRONMENT" echo "Limit: $LIMIT"
set -euo pipefail
ENVIRONMENT="${1:-dev}" PLAYBOOK="${2:-site.yml}" INVENTORY="inventory/hosts.ini" LIMIT="${3:-all}"
echo "Deploying with Ansible: $PLAYBOOK" echo "Environment: $ENVIRONMENT" echo "Limit: $LIMIT"

Syntax check

Syntax check

echo "Checking Ansible syntax..." ansible-playbook --syntax-check
-i "$INVENTORY"
-e "environment=$ENVIRONMENT"
"$PLAYBOOK"
echo "Checking Ansible syntax..." ansible-playbook --syntax-check
-i "$INVENTORY"
-e "environment=$ENVIRONMENT"
"$PLAYBOOK"

Dry run

Dry run

echo "Running dry-run..." ansible-playbook
-i "$INVENTORY"
-e "environment=$ENVIRONMENT"
-l "$LIMIT"
--check
"$PLAYBOOK"
echo "Running dry-run..." ansible-playbook
-i "$INVENTORY"
-e "environment=$ENVIRONMENT"
-l "$LIMIT"
--check
"$PLAYBOOK"

Ask for confirmation

Ask for confirmation

read -p "Continue with deployment? (y/n): " -r if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo "Deployment cancelled" exit 1 fi
read -p "Continue with deployment? (y/n): " -r if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo "Deployment cancelled" exit 1 fi

Execute playbook

Execute playbook

echo "Executing playbook..." ansible-playbook
-i "$INVENTORY"
-e "environment=$ENVIRONMENT"
-l "$LIMIT"
-v
"$PLAYBOOK"
echo "Deployment complete!"
echo "Executing playbook..." ansible-playbook
-i "$INVENTORY"
-e "environment=$ENVIRONMENT"
-l "$LIMIT"
-v
"$PLAYBOOK"
echo "Deployment complete!"

Run verification

Run verification

echo "Running post-deployment verification..." ansible-playbook
-i "$INVENTORY"
-e "environment=$ENVIRONMENT"
-l "$LIMIT"
verify.yml
undefined
echo "Running post-deployment verification..." ansible-playbook
-i "$INVENTORY"
-e "environment=$ENVIRONMENT"
-l "$LIMIT"
verify.yml
undefined

4. Configuration Template

4. 配置模板

jinja2
undefined
jinja2
undefined

roles/application/templates/.env.j2

roles/application/templates/.env.j2

Environment Configuration

Environment Configuration

NODE_ENV={{ environment }} LOG_LEVEL={{ log_level }} PORT=8080
NODE_ENV={{ environment }} LOG_LEVEL={{ log_level }} PORT=8080

Database Configuration

Database Configuration

DATABASE_URL=postgresql://{{ db_user }}:{{ db_password }}@{{ db_host }}:5432/{{ db_name }} DATABASE_POOL_SIZE=20 DATABASE_TIMEOUT=30000
DATABASE_URL=postgresql://{{ db_user }}:{{ db_password }}@{{ db_host }}:5432/{{ db_name }} DATABASE_POOL_SIZE=20 DATABASE_TIMEOUT=30000

Cache Configuration

Cache Configuration

REDIS_URL=redis://{{ redis_host }}:6379 CACHE_TTL=3600
REDIS_URL=redis://{{ redis_host }}:6379 CACHE_TTL=3600

Application Configuration

Application Configuration

APP_NAME=MyApp APP_VERSION={{ app_version }} WORKERS={{ ansible_processor_vcpus }}
APP_NAME=MyApp APP_VERSION={{ app_version }} WORKERS={{ ansible_processor_vcpus }}

API Configuration

API Configuration

API_TIMEOUT=30000 API_RATE_LIMIT=1000
API_TIMEOUT=30000 API_RATE_LIMIT=1000

Monitoring

Monitoring

SENTRY_DSN={{ sentry_dsn | default('') }} DATADOG_API_KEY={{ datadog_api_key | default('') }}
undefined
SENTRY_DSN={{ sentry_dsn | default('') }} DATADOG_API_KEY={{ datadog_api_key | default('') }}
undefined

Ansible Commands

Ansible命令

bash
undefined
bash
undefined

List all hosts in inventory

列出清单中的所有主机

ansible all -i inventory/hosts.ini --list-hosts
ansible all -i inventory/hosts.ini --list-hosts

Run ad-hoc command

运行临时命令

ansible webservers -i inventory/hosts.ini -m ping
ansible webservers -i inventory/hosts.ini -m ping

Execute playbook

执行剧本

ansible-playbook -i inventory/hosts.ini site.yml
ansible-playbook -i inventory/hosts.ini site.yml

Syntax check

语法检查

ansible-playbook --syntax-check site.yml
ansible-playbook --syntax-check site.yml

Dry-run

试运行

ansible-playbook -i inventory/hosts.ini site.yml --check
ansible-playbook -i inventory/hosts.ini site.yml --check

Run with specific tags

使用指定标签运行

ansible-playbook -i inventory/hosts.ini site.yml -t deploy
undefined
ansible-playbook -i inventory/hosts.ini site.yml -t deploy
undefined

Best Practices

最佳实践

✅ DO

✅ 建议

  • Use roles for modularity
  • Implement proper error handling
  • Use templates for configuration
  • Leverage handlers for idempotency
  • Use serial deployment for rolling updates
  • Implement health checks
  • Store inventory in version control
  • Use vault for sensitive data
  • 使用角色实现模块化
  • 实施适当的错误处理
  • 使用模板管理配置
  • 利用处理器实现幂等性
  • 使用串行部署进行滚动更新
  • 实施健康检查
  • 将清单存储在版本控制系统中
  • 使用Vault存储敏感数据

❌ DON'T

❌ 不建议

  • Use command/shell without conditionals
  • Copy files without templates
  • Run without check mode first
  • Mix environments in inventory
  • Hardcode values
  • Ignore error handling
  • Use shell for simple tasks
  • 无判断条件地使用command/shell模块
  • 直接复制文件而不使用模板
  • 不先进行试运行就执行部署
  • 在清单中混合不同环境
  • 硬编码数值
  • 忽略错误处理
  • 对简单任务使用shell模块

Resources

资源