首页 > 解决方案 > Ansible:如何替换嵌套字典中的值?

问题描述

如何用过滤器或 jinja 替换嵌套 dict 中的值,只要它有效,我不在乎该方法。

我在 group_vars 中定义了一个服务映射,如下所示:

backend_services:
  svc1:
    env_vars:
      DB_DATABASE: svc1_db
      DB_HOST: "{{postgres_db.host}}"
      DB_PASSWORD: "{{postgres_db.password}}"
      DB_PORT: "{{postgres_db.port}}"
      DB_USER: "{{postgres_db.username}}"
      ENVIRONMENT: "{{environment_name}}"
      LOG_LEVEL: "{{default_log_level}}"
  svc2:
    env_vars:
      DB_DATABASE: svc2_db
      DB_HOST: "{{postgres_db.host}}"
      DB_PASSWORD: "{{postgres_db.password}}"
      DB_PORT: "{{postgres_db.port}}"
      DB_USER: "{{postgres_db.username}}"
      ENVIRONMENT: "{{environment_name}}"
      LOG_LEVEL: "{{default_log_level}}"

  svc3:
    env_vars:
      DB_DATABASE: svc3_db
      DB_HOST: "{{postgres_db.host}}"
      DB_PASSWORD: "{{postgres_db.password}}"
      DB_PORT: "{{postgres_db.port}}"
      DB_USER: "{{postgres_db.username}}"
      ENVIRONMENT: "{{environment_name}}"
      LOG_LEVEL: "{{default_log_level}}"

我想要做的是遍历这个 backend_services 变量,并用我从主机环境中动态检索的值替换所有 DB_HOST 值(目前是硬编码的)。对于上下文,我正在使用已使用 Terraform 配置的托管 SQL 实例部署到云环境中。我可以将该托管 sql 主机放入具有设置事实的变量中,但随后需要修改此映射。

我尝试了不同的循环方法,使用组合,使用带有 include_tasks 文件的嵌套循环,以及使用带有 jinja 的 set_fact 而不是过滤器。

可以去工作的是:

set_fact:
  new_service: "{{ backend_services['svc1'] | combine({'env_vars': {'DB_HOST': 'foo'} }, recursive=True)}}"

但是,我不知道如何用 backend_services 的所有元素循环它。

标签: ansible

解决方案


set_fact:
  new_service: "{{ backend_services['svc1'] |
                   combine({'env_vars': {'DB_HOST': 'foo'} }, recursive=True)}}"

问:“如何用 backend_services 的所有元素循环它?”

A:下面的任务可以完成工作

    - set_fact:
        my_services: "{{ backend_services.keys()|list }}"
    - set_fact:
        new_service: "{{ new_service|
                         default({})|
                         combine({item:
                                 {'env_vars':
                                  backend_services[item].env_vars|
                                  combine({'DB_HOST': 'foo'})}}) }}"
      loop: "{{ my_services }}"

推荐阅读