Ansible 循环遍历 glob

标签 ansible

我正在尝试为变量创建一个 super 复杂但很酷的数据结构。

defaults/main.yml:

docker_compose_keycloak_config_cli_keycloak_url: http://keycloak:8080
docker_compose_keycloak_config_cli_user: admin
docker_compose_keycloak_config_cli_user_password: ~
docker_compose_keycloak_config_cli_client_id: admin-cli                                                                                                                                                                       
docker_compose_keycloak_config_cli_clientsecret: ~                        

使用这些变量的模板

#templates/env-vars-keycloak-config-cli
#jinja2: lstrip_blocks: "True"
{% if docker_compose_keycloak_config_cli_keycloak_url %}
KEYCLOAK_URL={{ docker_compose_keycloak_config_cli_keycloak_url }}
{% endif %}
{% if docker_compose_keycloak_config_cli_user %}                                                         
KEYCLOAK_USER={{ docker_compose_keycloak_config_cli_user }}
{% endif %}
{% if docker_compose_keycloak_config_cli_user_password %}
KEYCLOAK_PASSWORD={{ docker_compose_keycloak_config_cli_user_password }}
{% endif %}
{% if docker_compose_keycloak_config_cli_client_id %}
KEYCLOAK_CLIENTID={{ docker_compose_keycloak_config_cli_client_id }}
{% endif %}
{% if docker_compose_keycloak_config_cli_clientsecret %}
KEYCLOAK_CLIENTSECRET={{ docker_compose_keycloak_config_cli_clientsecret }}
{% endif %}
{% if docker_compose_keycloak_config_cli_granttype %}
KEYCLOAK_GRANTTYPE={{ docker_compose_keycloak_config_cli_granttype}}
{% endif %}
{% if docker_compose_keycloak_config_cli_loginrealm %}
KEYCLOAK_LOGINREALM={{ docker_compose_keycloak_config_cli_loginrealm }}
{% endif %}
{% if docker_compose_keycloak_config_cli_sslverify %}
KEYCLOAK_SSLVERIFY={{ docker_compose_keycloak_config_cli_sslverify }}
{% endif %}
{% if docker_compose_keycloak_config_cli_httpproxy %}
KEYCLOAK_HTTPPROXY={{ docker_compose_keycloak_config_cli_httpproxy }}
{% endif %}
{% if docker_compose_keycloak_config_cli_connecttimeout %}
KEYCLOAK_CONNECTTIMEOUT={{ docker_compose_keycloak_config_cli_connecttimeout }}
{% endif %}
{% if docker_compose_keycloak_config_cli_readtimeout %}
KEYCLOAK_READTIMEOUT={{ docker_compose_keycloak_config_cli_readtimeout }}
{% endif %}
{% if docker_compose_keycloak_config_cli_availabilitycheck_enabled %}
KEYCLOAK_AVAILABILITYCHECK_ENABLED={{ docker_compose_keycloak_config_cli_availabilitycheck_enabled }}
{% endif %}
{% if docker_compose_keycloak_config_cli_availabilitycheck_timeout %}                                                                                                                                                         
KEYCLOAK_AVAILABILITYCHECK_TIMEOUT={{ docker_compose_keycloak_config_cli_availabilitycheck_timeout }}                                                                                                                         
{% endif %}                                                                                                                                                                                                                                                                                                                                                                                                  

现在,对于环境变量,您真的不想添加空变量 (~)。

做这样的事情会很酷:

#templates/env-vars-keycloak-config-cli
#jinja2: lstrip_blocks: "True"
{% for key, value in docker_compose_keycloak_config_cli_envvar_* %}
{% if value -%}
{{key}}={{value}}
{% endif -%}
{% endfor %}

这将使我的模板变得非常短,而且我不必浪费时间输入那么多变量。

另外,我不必依赖保存环境变量的单个变量。我可以仅使用一个特定变量来编辑 host_varsgroup_vars 而无需重写大变量。

即让我的 defaults/main.yml 看起来像这样:

docker_compose_keycloak_config_cli_envvar_keycloak_url: 
  KEYCLOAK_URL: http://keycloak:8080

我正在测试如何循环这些变量。

例如

- name: Create list of vars
  debug:
    msg: "{{ item }}"
  loop: "{{ docker_compose_keycloak_config_cli_envvar_* }}"
  tags: test

这给了我错误:

fatal: [login.cyber.ee]: FAILED! => {"msg": "template error while templating string: unexpected 'end of print statement'. String: {{ docker_compose_keycloak_config_envvar_* }}"}

如何使用 glob 收集这些类型的变量?

最佳答案

安逸自己的生活,化繁为简/DRY你的变量。

让你的 defaults/main.yml 看起来像这样,你不必为每个字典重复 docker_compose_keycloak_config_cli键:

docker_compose_keycloak_config_cli:
  keycloak_url: http://keycloak:8080
  user: admin
  password: ~
  client_id: admin-cli
  clientsecret: ~
  envvar:
    keycloak_url: http://keycloak:8080

那么你的要求就变得微不足道了:

{% for key, value in docker_compose_keycloak_config_cli.envvar.items() %}
{{ key | upper }}={{ value }}
{% endfor %}

这会给你:

KEYCLOAK_URL=http://keycloak:8080

为了更好地减少重复,请使用 YAML anchors :

docker_compose_keycloak_config_cli:
  keycloak_url: &keycloak_url http://keycloak:8080
  user: admin
  password: ~
  client_id: admin-cli
  clientsecret: ~
  envvar:
    keycloak_url: *keycloak_url

为了允许覆盖它,递归地 combine覆盖字典到现有变量中。然后如上所述使用它。

- set_fact:
    docker_compose_keycloak_config_cli: >-
      {{
        docker_compose_keycloak_config_cli
        | combine(
          docker_compose_keycloak_config_cli_override | default({}),
          recursive=True
        )
      }}

两个任务:

- set_fact:
    docker_compose_keycloak_config_cli: >-
      {{
        docker_compose_keycloak_config_cli
        | combine(
          docker_compose_keycloak_config_cli_override | default({}),
          recursive=True
        )
      }}
  vars:
    docker_compose_keycloak_config_cli:
      keycloak_url: &keycloak_url http://keycloak:8080
      user: admin
      password: ~
      client_id: admin-cli
      clientsecret: ~
      envvar:
        keycloak_url: *keycloak_url
        other_env: foo
    docker_compose_keycloak_config_cli_override:
      envvar:
        keycloak_url: http://keycloak:80

- debug:
    var: docker_compose_keycloak_config_cli

会产生:

docker_compose_keycloak_config_cli:
  client_id: admin-cli
  clientsecret: null
  envvar:
    keycloak_url: http://keycloak:80
    other_env: foo
  keycloak_url: http://keycloak:8080
  password: null
  user: admin

关于Ansible 循环遍历 glob,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73305807/

相关文章:

mysql - 使用ansible安装和配置mysql

ansible - 以最有效的方式删除多个文件(ansible)

jenkins - Ansible 无法读取 Jenkins 多行参数传递的带有空格的文件名

ansible - 防止 Ansible 2 中出现重复的键警告

windows - 在 AWS 上使用 packer 和 ansible 创建 Windows AMI

linux - 使用 ansible 查找和复制文件

ubuntu - 如何从 json 输出中使用 ad hoc 和 jq 获取操作系统版本

Ansible 中的 Powershell 复制项目

ssh - Ansible: "sudo: a password is required\r\n"

ansible - 你需要 root 才能执行 - ansible