Ansible Playbook编写详解

Ansible Playbook是Ansible的核心组件,它是一种基于YAML语言的配置管理工具,用于自动化部署、配置管理和应用编排。本教程将详细介绍Ansible Playbook的编写方法,包含结构、语法、常用模块和最佳实践。

1. Playbook基本结构

Playbook是由一个或多个"play"组成的YAML文件,每个play定义一组在特定主机上执行的任务。基本结构如下:

---
- name: 安装和配置Nginx
  hosts: webservers
  become: yes
  vars:
    http_port: 80
    max_clients: 200

  tasks:
    - name: 安装Nginx
      ansible.builtin.apt:
        name: nginx
        state: present

    - name: 启动Nginx服务
      ansible.builtin.service:
        name: nginx
        state: started
        enabled: yes

结构解析:

  • `---`:YAML文档开始标记
  • `- name`:play名称,描述此play的目的
  • `hosts`:指定目标主机或主机组
  • `become`:是否使用特权执行(默认为sudo)
  • `vars`:定义变量
  • `tasks`:任务列表,每个任务使用模块执行特定操作
  • 2. 常用核心模块

    2.1 包管理模块

    ---
    - name: 包管理示例
      hosts: all
      become: yes
    
      tasks:
        - name: 安装最新版Apache (Ubuntu)
          ansible.builtin.apt:
            name: apache2
            state: latest
          when: ansible_os_family == "Debian"
    
        - name: 安装最新版Apache (CentOS)
          ansible.builtin.yum:
            name: httpd
            state: latest
          when: ansible_os_family == "RedHat"

    2.2 服务管理模块

    ---
    - name: 服务管理示例
      hosts: webservers
      become: yes
    
      tasks:
        - name: 确保Nginx服务运行
          ansible.builtin.service:
            name: nginx
            state: started
            enabled: yes
    
        - name: 重启Nginx服务
          ansible.builtin.service:
            name: nginx
            state: restarted

    2.3 文件操作模块

    ---
    - name: 文件操作示例
      hosts: all
    
      tasks:
        - name: 创建目录
          ansible.builtin.file:
            path: /opt/myapp
            state: directory
            mode: '0755'
    
        - name: 复制配置文件
          ansible.builtin.copy:
            src: files/myapp.conf
            dest: /etc/myapp.conf
            owner: root
            group: root
            mode: '0644'
            backup: yes

    2.4 命令执行模块

    ---
    - name: 命令执行示例
      hosts: all
    
      tasks:
        - name: 安全执行命令
          ansible.builtin.command:
            cmd: echo "Hello World" > /tmp/hello.txt
            creates: /tmp/hello.txt
    
        - name: 执行带条件的shell命令
          ansible.builtin.shell:
            cmd: |
              if [ ! -f /tmp/lockfile ]; then
                touch /tmp/lockfile
                echo "Lock file created"
              fi

    3. 变量使用

    3.1 定义变量

    ---
    - name: 变量使用示例
      hosts: all
      vars:
        package_name: nginx
        config_file: /etc/nginx/nginx.conf
    
      tasks:
        - name: 安装软件包
          ansible.builtin.apt:
            name: "{{ package_name }}"
            state: present
    
        - name: 备份配置文件
          ansible.builtin.copy:
            src: "{{ config_file }}"
            dest: "{{ config_file }}.bak"
            remote_src: yes

    3.2 变量文件

创建`vars/main.yml`:

---
nginx_port: 80
nginx_worker_processes: auto
nginx_keepalive_timeout: 65

在Playbook中使用:

---
- name: 使用变量文件
  hosts: webservers
  vars_files:
    - vars/main.yml

  tasks:
    - name: 配置Nginx
      ansible.builtin.template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/nginx.conf
      notify: Restart Nginx

  handlers:
    - name: Restart Nginx
      ansible.builtin.service:
        name: nginx
        state: restarted

4. 条件判断和循环

4.1 条件判断

---
- name: 条件判断示例
  hosts: all

  tasks:
    - name: 安装特定版本的Python
      ansible.builtin.apt:
        name: python3.9
        state: present
      when:
        - ansible_os_family == "Debian"
        - ansible_distribution_version == "20.04"

4.2 循环结构

---
- name: 循环示例
  hosts: all

  tasks:
    - name: 创建多个用户
      ansible.builtin.user:
        name: "{{ item }}"
        state: present
      loop:
        - user1
        - user2
        - user3

    - name: 安装多个软件包
      ansible.builtin.apt:
        name: "{{ item.name }}"
        state: "{{ item.state }}"
      loop:
        - { name: 'nginx', state: 'present' }
        - { name: 'mysql-server', state: 'present' }
        - { name: 'php-fpm', state: 'absent' }

5. 模板和配置管理

创建模板文件`templates/nginx.conf.j2`:

user www-data;
worker_processes {{ nginx_worker_processes }};
pid /run/nginx.pid;

events {
    worker_connections 768;
}

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout {{ nginx_keepalive_timeout }};
    types_hash_max_size 2048;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    server {
        listen {{ nginx_port }};
        root /var/www/html;
        index index.html;

        location / {
            try_files $uri $uri/ =404;
        }
    }
}

在Playbook中使用模板:

---
- name: 配置Nginx
  hosts: webservers
  become: yes

  tasks:
    - name: 部署Nginx配置
      ansible.builtin.template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/nginx.conf
        owner: root
        group: root
        mode: '0644'
        validate: 'nginx -t -c %s'
      notify: Restart Nginx

  handlers:
    - name: Restart Nginx
      ansible.builtin.service:
        name: nginx
        state: restarted

6. 错误处理和调试

6.1 忽略错误

---
- name: 忽略错误示例
  hosts: all

  tasks:
    - name: 尝试删除可能不存在的文件
      ansible.builtin.file:
        path: /tmp/nonexistent_file
        state: absent
      ignore_errors: yes

6.2 调试任务

---
- name: 调试示例
  hosts: all

  tasks:
    - name: 显示系统信息
      ansible.builtin.debug:
        msg: |
          主机名: {{ ansible_hostname }}
          操作系统: {{ ansible_distribution }}
          内核版本: {{ ansible_kernel }}

    - name: 显示变量内容
      ansible.builtin.debug:
        var: ansible_facts

7. 角色组织

创建角色结构:

site.yml
webservers.yml
roles/
   common/
     tasks/
     handlers/
     files/
     templates/
     vars/
     defaults/
     meta/
   nginx/
     tasks/
     handlers/
     files/
     templates/
     vars/
     defaults/
     meta/

示例角色任务`roles/nginx/tasks/main.yml`:

---
- name: 安装Nginx
  ansible.builtin.apt:
    name: nginx
    state: present

- name: 部署配置文件
  ansible.builtin.template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
  notify: Restart Nginx

- name: 确保Nginx运行
  ansible.builtin.service:
    name: nginx
    state: started
    enabled: yes

在Playbook中使用角色:

---
- name: 配置Web服务器
  hosts: webservers
  become: yes

  roles:
    - common
    - nginx
    - { role: php, when: ansible_os_family == "Debian" }

8. 高级技巧

8.1 块和错误处理

---
- name: 块和错误处理示例
  hosts: all

  tasks:
    - name: 尝试安装并配置服务
      block:
        - name: 安装软件包
          ansible.builtin.apt:
            name: "{{ package_name }}"
            state: present

        - name: 启动服务
          ansible.builtin.service:
            name: "{{ service_name }}"
            state: started

      rescue:
        - name: 回滚操作
          ansible.builtin.debug:
            msg: "安装失败,执行回滚操作"

        - name: 卸载软件包
          ansible.builtin.apt:
            name: "{{ package_name }}"
            state: absent

      always:
        - name: 记录日志
          ansible.builtin.debug:
            msg: "操作执行完成"

8.2 动态包含

---
- name: 动态包含任务
  hosts: all

  tasks:
    - name: 包含基于变量的任务
      include_tasks: "tasks/{{ ansible_os_family }}.yml"

8.3 标签使用

---
- name: 标签示例
  hosts: all

  tasks:
    - name: 安装基础包
      ansible.builtin.apt:
        name: "{{ item }}"
      loop:
        - curl
        - wget
        - git
      tags: ['packages', 'base']

    - name: 配置防火墙
      ansible.builtin.ufw:
        state: enabled
      tags: ['security', 'firewall']

运行特定标签的任务:

ansible-playbook site.yml --tags "packages"
ansible-playbook site.yml --skip-tags "firewall"

9. 最佳实践

1. 保持幂等性:确保任务多次执行结果一致

2. 使用角色:组织复杂配置为可重用组件

3. 版本控制:将所有Playbook和配置文件纳入Git

4. 测试驱动开发:使用Molecule测试角色

5. 模块化设计:小而专一的任务优于大而复杂的任务

6. 变量外部化:敏感信息使用Vault加密

7. 文档化:为每个角色和Playbook添加README

8. 命名规范:使用一致的命名约定

总结

Ansible Playbook是一种强大而灵活的自动化工具,通过YAML语法定义系统配置和部署流程。本教程详细介绍了Playbook的基本结构、常用模块、变量使用、条件判断、循环结构、模板管理、错误处理和角色组织等核心概念。

关键要点:

1. Playbook使用YAML语法,基于主机、变量和任务构建

2. 模块是执行实际工作的原子单元,如apt、service、copy等

3. 变量使配置更灵活,可通过多种方式定义

4. 条件和循环提供执行流程控制

5. 模板实现动态配置文件生成

6. 角色是组织复杂配置的最佳实践

7. 错误处理和调试机制确保可靠性

8. 标签和动态包含提供执行灵活性

掌握这些技术后,您可以构建高效、可维护的自动化配置管理解决方案。随着经验的积累,可以进一步探索Ansible的高级特性如异步任务、策略文件和动态清单等,以应对更复杂的自动化场景。

发表回复

后才能评论