使用 Ansible 自动化部署 Web 服务并验证访问

一、场景背景

在日常的运维工作中,Web 服务的部署、配置及可用性验证是高频操作。手动完成这些步骤不仅效率低下,还容易出现人为失误。本文将基于 Ansible 工具,重点围绕Jinja2 模板部署Block-Rescue 异常处理Playbook 整合(import) 三大核心知识点,实现 Web 服务器的自动化部署、配置,以及访问结果的验证与异常记录。

二、核心 Playbook 编写

1. Web 服务器部署(dev_deploy.yml)

该 Playbook 核心实现 httpd 服务全生命周期管理,重点通过Jinja2 模板部署实现配置文件的动态生成,结合 Handler 机制保证配置变更后的服务一致性。

---
- name: Install and configure web servers
  hosts: webservers
  become: true

  tasks:
    # 安装httpd软件包
    - name: Install httpd package
      ansible.builtin.dnf:
        name: httpd
        state: present

    # 启动httpd服务
    - name: Start httpd service
      ansible.builtin.service:
        name: httpd
        state: started
        enabled: yes  # 设置开机自启,增强服务稳定性

    # 核心:基于Jinja2模板部署虚拟主机配置(动态生成配置文件)
    - name: Deploy Jinja2-based vhost configuration template
      ansible.builtin.template:
        src: templates/vhost.conf.j2  # 本地Jinja2模板文件路径
        dest: /etc/httpd/conf.d/vhost.conf  # 目标主机配置文件路径
        owner: root
        group: root
        mode: '0644'
      notify: Restart httpd  # 配置变更时触发handler重启服务

    # 拷贝网页文件到目标主机(按主机名动态指定目录)
    - name: Copy index.html to host-specific directory
      ansible.builtin.copy:
        src: files/
        dest: "/var/www/vhosts/{{ ansible_facts['hostname'] }}/"  # 引用主机事实变量
        owner: root
        group: root
        mode: '0644'

    # 开放防火墙http端口
    - name: Ensure web server port is open
      ansible.posix.firewalld:
        state: enabled
        permanent: true
        immediate: true
        service: http

  # 定义handler,用于配置变更后重启httpd服务
  handlers:
    - name: Restart httpd
      ansible.builtin.service:
        name: httpd
        state: restarted
关键知识点:Jinja2 模板部署(vhost.conf.j2 示例)

Jinja2 模板支持变量、条件判断、循环等语法,可动态生成适配不同主机的配置文件,示例如下:

# templates/vhost.conf.j2
<VirtualHost *:80>
    ServerName {{ ansible_facts['fqdn'] }}  # 引用主机完全限定域名变量
    DocumentRoot "/var/www/vhosts/{{ ansible_facts['hostname'] }}"  # 引用主机名变量
    
    # 条件判断:仅对特定主机开启日志
    {% if ansible_facts['hostname'] == 'servera' %}
    ErrorLog "/var/log/httpd/servera-error.log"
    CustomLog "/var/log/httpd/servera-access.log" combined
    {% endif %}

    <Directory "/var/www/vhosts/{{ ansible_facts['hostname'] }}">
        AllowOverride None
        Require all granted
    </Directory>
</VirtualHost>

注:Jinja2 模板中可直接引用 Ansible Facts 变量、Playbook 自定义变量,实现配置文件的动态化、个性化。

2. Web 访问验证(get_web_content.yml)

该 Playbook 核心通过Block-Rescue 异常处理块实现 Web 服务访问结果的校验,访问失败时自动记录错误日志,保障运维可追溯性。

yaml

---
- name: Test web content with error handling
  hosts: workstation
  become: true

  tasks:
    # 核心:Block-Rescue结构实现异常捕获与处理
    - name: Retrieve web content and write to error log on failure
      block:
        # 正常执行块:发送HTTP请求验证Web服务
        - name: Retrieve web content from servera
          ansible.builtin.uri:
            url: http://servera.lab.example.com
            return_content: yes  # 返回网页内容
            status_code: 200     # 预期返回状态码,非200则判定失败
          register: web_content  # 注册访问结果到变量

        # 可选:打印正常访问的网页内容(调试用)
        - name: Show successful web content
          ansible.builtin.debug:
            var: web_content.content
            verbosity: 1
      rescue:
        # 异常处理块:block中任务失败时执行
        - name: Write access error to log file
          ansible.builtin.lineinfile:
            path: /home/student/review-cr2/error.log
            line: "[$(date)] Web访问失败 - 目标地址:http://servera.lab.example.com - 错误信息:{{ web_content | default('未知错误') }}"
            create: true  # 日志文件不存在则自动创建
            mode: '0644'

注:block包含正常业务逻辑,rescue仅在block中任务失败时触发,可有效隔离正常流程与异常处理,提升 Playbook 健壮性。

3. 整合 Playbook(site.yml)

通过import_playbook指令将多个功能独立的 Playbook 整合,实现 “部署 + 验证” 一键执行,是 Ansible 规模化自动化的核心方式。

---
# 核心:import_playbook整合多个Playbook,按顺序执行
- import_playbook: dev_deploy.yml  # 第一步:部署Web服务器
- import_playbook: get_web_content.yml  # 第二步:验证Web访问

注:import_playbook为静态导入(执行前加载),适合固定流程的 Playbook 整合;若需动态导入(基于条件判断),可使用include_playbook

三、执行 Playbook

完成上述文件编写后,执行以下命令启动自动化流程,-m stdout参数用于以标准输出形式展示执行结果,便于查看每一步执行状态:

# 执行整合后的Playbook,开启特权升级
ansible-navigator run -m stdout site.yml --become
# 可选:开启基础调试,查看更详细的执行日志
ansible-navigator run -m stdout site.yml --become -v

四、关键知识点深度解析

1. Jinja2 模板部署

  • 核心价值:将静态配置文件转为动态模板,通过变量、逻辑语法适配不同主机 / 环境,避免重复编写配置文件;
  • 常用语法
    • 变量引用:{{ 变量名 }}(如{{ ansible_facts['hostname'] }});
    • 条件判断:{% if 条件 %} ... {% endif %}
    • 循环:{% for item in list %} ... {% endfor %}
  • 使用场景:Nginx/Apache 配置、数据库配置、系统服务配置等需个性化的场景。

2. Block-Rescue 异常处理

  • 核心价值:实现 “异常捕获 - 处理” 逻辑,替代传统的failed_when+when组合,代码结构更清晰;
  • 扩展用法:可搭配always块(无论 block/rescue 执行结果如何,始终执行),例如:
    block: ...
    rescue: ...
    always:
      - name: Record execution end time
        ansible.builtin.debug:
          msg: "Playbook执行结束时间:{{ ansible_date_time.iso8601 }}"
    

3. Playbook 整合(import_playbook)

  • 核心价值:将复杂自动化流程拆分为多个功能独立的 Playbook,降低维护成本,提升复用性;
  • 与 include_playbook 的区别

    表格

    特性 import_playbook(静态导入) include_playbook(动态导入)
    加载时机 Playbook 执行前 Playbook 执行到该指令时
    条件判断 不支持 支持(可基于变量动态导入)
    标签继承 被导入 Playbook 继承主标签 独立标签

五、总结

  1. Jinja2 模板是 Ansible 实现配置动态化的核心,通过变量和逻辑语法可适配不同主机的配置需求,大幅减少重复配置工作;
  2. Block-Rescue结构能优雅处理 Playbook 执行中的异常,保证失败时留存关键日志,提升运维可追溯性;
  3. import_playbook实现了 Playbook 的模块化整合,将 “部署”“验证” 等独立流程串联,适配规模化自动化场景;
  4. 三者结合可构建健壮、可维护、可扩展的 Ansible 自动化方案,是 Web 服务自动化部署的核心实践
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐