Ansible 自定义变量与 role 默认变量的合并方法

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 如果你遇到 failed to combine variables, expected dicts but got a 'NoneType' and a 'dict' 这样的报错,你可以看看本文。

场景预设

  1. role 的默认变量文件里,有不同类型的变量,K/V、Dict、List 都有。
  2. 目标 host 同时归属于几个分组(groups)

期望结果

可以在 group_vars 里给某些组自定义一些变量,可以与 role 默认变量合并,优先使用自定义变量。

举例

role 默认变量 defaults/main.yml

  # mysql 配置,只包含基本设置,优化参数请自行决定。
  pxc_custom_cnf:
    mysqld:
      ssl_ca: "/cert/ca.pem"
      ssl_cert: "/cert/server-cert.pem"
      ssl_key: "/cert/server-key.pem"
      bind_address: "{
  { global_bond_ip }}"
      wsrep_node_address: "{
  { global_bond_ip }}"
      wsrep_node_name: "{
  { ansible_hostname }}"
      server_id: "{
  { global_bond_ip | ipaddr('int') }}"
      wsrep_cluster_address: "gcomm://{
  { gcomm_nodes }}"
      wsrep_node_incoming_address: "{
  { global_bond_ip }}:{
  { combined_vars.pxc_port | default(pxc_port) }}"
      port: "{
  { combined_vars.pxc_port | default(pxc_port) }}"
      skip_name_resolve: "on"
    client:
      ssl_ca: "/cert/ca.pem"
      ssl_cert: "/cert/client-cert.pem"
      ssl_key: "/cert/client-key.pem"
    sst:
      encrypt: "4"
      ssl_ca: "/cert/ca.pem"
      ssl_cert: "/cert/server-cert.pem"
      ssl_key: "/cert/server-key.pem"
    xtrabackup:
      host: "{
  { global_bond_ip }}"
      user: "{
  { mysql_backup_username }}"
      password: "{
  { mysql_backup_password }}"
      port: "{
  { combined_vars.pxc_port | default(pxc_port) }}"
      target_dir: "/backup"

自定义变量 group_vars/pxc.yml

# mysql 配置
pxc_custom_cnf:
  mysqld:
# 自定义配置,替代 role 对应的默认值,并合并其余默认值。
    character_set_server: "utf8mb4"
    collation_server: "utf8mb4_unicode_ci"
    max_connections: "1000"
    open_files_limit: "200000"
    pxc_strict_mode: "PERMISSIVE"
    skip_name_resolve: "on"
    expire_logs_days: "7"
    max_prepared_stmt_count: "65528"
    innodb_buffer_pool_instances: "16"
    innodb_buffer_pool_chunk_size: "256M"

合并后的变量内容

"pxc_custom_cnf": {
    "client": {
        "ssl_ca": "/cert/ca.pem",
        "ssl_cert": "/cert/client-cert.pem",
        "ssl_key": "/cert/client-key.pem"
    },
    "mysqld": {
        "bind_address": "192.168.56.16",
        "character_set_server": "utf8mb4",
        "collation_server": "utf8mb4_unicode_ci",
        "expire_logs_days": "7",
        "innodb_buffer_pool_chunk_size": "256M",
        "innodb_buffer_pool_instances": "16",
        "max_connections": "1000",
        "max_prepared_stmt_count": "65528",
        "open_files_limit": "200000",
        "port": "13306",
        "pxc_strict_mode": "PERMISSIVE",
        "server_id": "3232249872",
        "skip_name_resolve": "on",
        "ssl_ca": "/cert/ca.pem",
        "ssl_cert": "/cert/server-cert.pem",
        "ssl_key": "/cert/server-key.pem",
        "wsrep_cluster_address": "gcomm://192.168.56.17,192.168.56.18",
        "wsrep_node_address": "192.168.56.16",
        "wsrep_node_incoming_address": "192.168.56.16:13306",
        "wsrep_node_name": "192-168-56-16"
    },
    "sst": {
        "encrypt": "4",
        "ssl_ca": "/cert/ca.pem",
        "ssl_cert": "/cert/server-cert.pem",
        "ssl_key": "/cert/server-key.pem"
    },
    "xtrabackup": {
        "host": "192.168.56.16",
        "password": "jNeYsi0ATJkyDTh1vXs4",
        "port": "13306",
        "target_dir": "/backup",
        "user": "bkuser"
    }
}

playbook 代码

首先,在需要合并变量的 role 里,调用合并变量的 tasks

- name: Pre tasks
  block:
    - name: Combine role vars and group vars
      import_role:
        name: pre-tasks
        tasks_from: vars_combine
  tags: always

完整代码:https://gitee.com/bottlelee/haibinlee-ansible-roles/blob/develop/percona-xtradb-cluster/tasks/main.yml

roles/pre-tasks/vars_combine.yml 内容

- name: Combine default vars and custom vars
  block:
    - name: "Include role's defaults vars"
      ansible.builtin.include_vars:
        dir: "{
  { item }}/defaults"
        name: "temp_role_vars"
      loop: "{
  { ansible_parent_role_paths }}"

    - name: Assembling group vars files
      assemble:
        src: "{
  { inventory_dir }}/group_vars"
        dest: "{
  { inventory_dir }}/assembled_vars/{
  { group_names | hash('md5') }}.yml"
        regexp: "({
  { group_names | join('|') }})"
      delegate_to: localhost
      become: false

    - name: "Include group custom vars"
      ansible.builtin.include_vars:
        file: "{
  { inventory_dir }}/assembled_vars/{
  { group_names | hash('md5') }}.yml"
        name: "temp_group_vars"

    - name: Combine vars from role and groups
      set_fact:
        combined_vars: "{
  { role_vars | combine(group_vars, recursive=true) }}"
      vars:
        role_vars: "{
  { lookup('vars', 'temp_role_vars') }}"
        group_vars: "{
  { lookup('vars', 'temp_group_vars') }}"

  rescue:
    - name: "Create {
  { inventory_dir }}/assembled_vars"
      file:
        path: "{
  { inventory_dir }}/assembled_vars"
        state: directory
      delegate_to: localhost
      become: false

    - include_tasks: vars_combine.yml

完整代码:https://gitee.com/bottlelee/haibinlee-ansible-roles/blob/develop/pre-tasks/tasks/vars_combine.yml

变量调用

合并的变量,以 combined_vars 开头,那么变量的使用就从原来的 var_a 变成 combined_vars.var_a 即可。

这种方法,方便了使用者用最少的代码量,自定义所需的变量。尤其是你遇到 failed to combine variables, expected dicts but got a 'NoneType' and a 'dict' 这样的报错。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
运维 Kubernetes 网络安全
Ansible自动化运维工具之主机管理与自定义配置文件(2)
Ansible自动化运维工具之主机管理与自定义配置文件(2)
140 0
|
3月前
|
运维 应用服务中间件 nginx
自动化运维的利剑:Ansible Role 打造标准化配置
【8月更文挑战第31天】在追求效率和稳定性的今天,自动化运维不再是奢侈品,而是必需品。Ansible Role,作为自动化配置管理的利器,它如何帮助我们实现标准化部署和维护?本文将通过一个简单示例,带你了解 Ansible Role 的魅力所在,并探讨其在现代 IT 架构中的应用价值。
|
4月前
|
运维 测试技术 调度
自动化测试框架的设计与实现自动化运维的利器:Ansible Role 实践指南
【7月更文挑战第31天】随着软件开发周期的缩短和迭代速度的加快,手动软件测试已难以满足效率与质量的双重需求。本文将深入探讨如何设计并实现一个高效的自动化测试框架,以提升测试工作的效率和准确性。我们将通过具体的代码示例,展示框架的核心组件和实现逻辑,帮助读者理解自动化测试框架的构建过程及其在实际项目中的应用价值。
47 5
|
4月前
|
JSON 数据格式 索引
Ansible fact变量与魔法变量
Ansible fact变量与魔法变量
65 6
|
4月前
|
存储 网络安全 数据安全/隐私保护
Ansible的变量
Ansible的变量
44 6
|
缓存 运维 监控
【运维知识进阶篇】Ansible变量详解(变量定义+变量优先级+变量注册+层级定义变量+facts缓存变量)
【运维知识进阶篇】Ansible变量详解(变量定义+变量优先级+变量注册+层级定义变量+facts缓存变量)
359 0
|
存储 JSON 数据安全/隐私保护
ansible定义变量和管理事实
ansible定义变量和管理事实
151 0
|
存储 缓存 监控
【2023】ansible-variables变量详解
【2023】ansible-variables变量详解
132 0
|
存储 JSON 缓存
ansible学习之旅(facts变量)
ansible学习之旅(facts变量)
176 0
ansible学习之旅(初识变量)
ansible学习之旅(初识变量)
82 0