将可复用自动化封装为角色

AnsibleBeginner
立即练习

介绍

角色封装可用的自动化单元,让使用方提供数据,无需复制实现。你将创建带公共默认值的角色,渲染主机特定页面,在角色内部保留配置验证和重新加载行为,并在两个清单组间复用。真实受管文件和 HTTP 响应将验证角色确实被调用。

创建并调用带默认值的角色

本步骤将把网站自动化移入角色,并通过简短 playbook 使用可复用默认输入调用它。

角色将相关任务、默认变量、模板和处理程序组织到标准目录。tasks/main.yml 是任务入口;defaults/main.yml 提供使用方可覆盖的低优先级值。模板源位于 templates,handlers/main.yml 后续将保存由更改驱动的服务操作。

预先准备的清单已将 web1 放入 canary、web2 放入 stable,两者位于父组 sites 下。nginx 已作为前置条件安装。检查组:

cd /home/labex/project
ansible-inventory --graph

使用 mkdir -p 创建角色目录。多个路径参数分别创建各个具名目录:

mkdir -p roles/managed_site/tasks roles/managed_site/defaults roles/managed_site/templates roles/managed_site/handlers

为公共角色变量加上 site_ 前缀,明确用途。先提供任何使用方都能使用的共享默认值:

cat > roles/managed_site/defaults/main.yml <<'YAML'
site_environment: training
site_port: 8080
site_maintenance: false
YAML

页面模板结合角色输入、各目标名称和收集的发行版:

cat > roles/managed_site/templates/page.txt.j2 <<'JINJA'
host={{ inventory_hostname }}
environment={{ site_environment }}
distribution={{ ansible_facts.distribution }}
JINJA

创建角色任务入口。在角色中,src: page.txt.j2 从该角色的 templates 目录解析;目标仍为绝对受管路径:

cat > roles/managed_site/tasks/main.yml <<'YAML'
- name: Prepare the role-managed website directory
  ansible.builtin.file:
    path: /var/www/role-site
    state: directory
    owner: root
    group: root
    mode: "0755"

- name: Render the role-managed page
  ansible.builtin.template:
    src: page.txt.j2
    dest: /var/www/role-site/index.html
    owner: root
    group: root
    mode: "0644"
YAML

通过 roles 关键字调用角色。外层 play 选择目标、收集事实并请求 become;角色提供可复用任务:

cat > site.yml <<'YAML'
- name: Apply the managed site role with defaults
  hosts: sites
  gather_facts: true
  become: true
  roles:
    - managed_site
YAML

通过使用方 playbook 验证并运行角色:

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

检查角色实际创建的页面:

ansible sites -m ansible.builtin.command -a 'cat /var/www/role-site/index.html'

两者都应显示来自默认值的 environment=training,以及各自主机名和 distribution=Ubuntu。仅创建角色目录不会执行角色或创建这些受管文件。

将模板和处理程序保留在可复用角色内部

本步骤将使角色配置并运行网站,包括候选验证及其自身的重新加载处理程序。

将完整 nginx 模板放在页面源旁。它使用角色的 site_ 输入、此前练习的 upper 过滤器和布尔分支:

cat > roles/managed_site/templates/nginx.conf.j2 <<'JINJA'
events {}
http {
    server_tokens off;
    server {
        listen {{ site_port }};
        root /var/www/role-site;
        index index.html;
        add_header X-Environment "{{ site_environment | upper }}" always;
{% if site_maintenance %}
        add_header X-Maintenance "enabled" always;
{% else %}
        add_header X-Maintenance "disabled" always;
{% endif %}
    }
}
JINJA

追加角色任务,在替换前验证渲染配置,并明确保持 nginx started。发生更改的配置通知角色的具名处理程序:

cat >> roles/managed_site/tasks/main.yml <<'YAML'

- name: Render and validate the role-managed nginx configuration
  ansible.builtin.template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
    owner: root
    group: root
    mode: "0644"
    validate: /usr/sbin/nginx -t -c %s
  notify: Reload managed site

- name: Keep the role-managed service running
  ansible.builtin.service:
    name: nginx
    state: started
YAML

在角色处理程序入口中编写处理程序,而非在每个使用方 playbook 中复制:

cat > roles/managed_site/handlers/main.yml <<'YAML'
- name: Reload managed site
  ansible.builtin.service:
    name: nginx
    state: reloaded
YAML

运行未更改的使用方 playbook。现在角色提供完整部署行为:

ansible-playbook site.yml

两台主机都应在默认端口 8080 启动各自网站。通过各目标自身的回环端点检查:

ansible sites -m ansible.builtin.command -a 'curl --fail --silent --show-error -i http://127.0.0.1:8080/'

各响应体应标识自身主机及 environment=training。响应头应包含 X-Environment: TRAINING 和 X-Maintenance: disabled。输出来自角色配置的运行服务,而非仅在控制节点上的演示。

通过组变量覆盖复用同一个角色

本步骤将在两个组上下文中应用相同角色,不编辑可复用默认值或任务文件。

角色默认值有意采用低优先级。清单组变量可以覆盖这些公共输入,同时保留同一实现。保持 defaults/main.yml 不变,并创建各组的使用方数据:

cat > group_vars/canary.yml <<'YAML'
site_environment: development
site_port: 8081
site_maintenance: true
YAML
cat > group_vars/stable.yml <<'YAML'
site_environment: production
site_port: 8082
site_maintenance: false
YAML

将使用方 playbook 替换为两个调用同一 managed_site 角色的 play。各组收到各自解析的输入。不要为各环境复制角色目录:

cat > site.yml <<'YAML'
- name: Apply the shared role to canary
  hosts: canary
  gather_facts: true
  become: true
  roles:
    - managed_site

- name: Apply the shared role to stable
  hosts: stable
  gather_facts: true
  become: true
  roles:
    - managed_site
YAML

验证并应用两个上下文:

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

两个环境都应通过角色内部的处理程序加载更改后的配置。在新配置的端口检查实际端点:

ansible canary -m ansible.builtin.command -a 'curl --fail --silent --show-error -i http://127.0.0.1:8081/'
ansible stable -m ansible.builtin.command -a 'curl --fail --silent --show-error -i http://127.0.0.1:8082/'

Canary 应标识 web1 和 development,响应头为 DEVELOPMENT/enabled。Stable 应标识 web2 和 production,响应头为 PRODUCTION/disabled。这些差异来自组输入,而一个共享角色仍负责默认值、任务、模板和处理程序。

重复相同的使用方 playbook:

ansible-playbook site.yml

两行汇总均应报告 changed=0、unreachable=0 和 failed=0,且未调度处理程序。可复用角色必须被调用,并产生正确收敛的受管状态;仅目录骨架不是部署。

总结

你将默认值、任务、模板和处理程序组织为一个被实际调用的角色。低优先级默认值支持使用方覆盖,两个清单组复用了同一实现,生成了不同的真实服务。候选验证、由更改驱动的重新加载以及未更改的重复执行,仍属于该可复用单元的一部分。