转换剧本中的字典键

convert dictionary keys in playbook

我有一个现有的剧本变量字典定义如下:

vars:
  resource_tags: {
    Name: "some name"
    Service: "some service"
  }

在这种形式的各种任务调用中使用。但是在另一个任务中,我需要不同格式的它,而不是硬编码,我想知道它是否可以在任务中构建。

我需要它看起来像:

  {
    "tag:Name": "some name"
    "tag:Service": "some service"
  }

我尝试使用 with_dict 进行迭代并使用 combine:

设置事实
  - set_fact:
        ec2_remote_facts_filter: "{{ ec2_remote_facts_filter | default({}) | combine( { 'tag:'item.name: item.val } ) }}"
    with_dict: "{{ ec2_count_resource_tags }}"

显然那是行不通的。

这可能吗?

也许您需要一个自定义查找插件。

1) 编辑文件 ansible.cfg 并取消对值为 './plugins/lookup'

的键 'lookup_plugins' 的注释

2) 在'./plugins/lookup'

中创建一个名为'ec2remote.py'的插件文件

3) 在你的剧本中使用它:

- debug:
    msg: "{{ item }}"
  with_ec2remote: "{{ ec2_count_resource_tags }}"

4) 实现您的 ec2remote.py(许多示例 here

class LookupModule(LookupBase):
  def run(self, terms, **kwargs):
    result = {}
    for k,v in terms.items():
       result["tag:"+k] = v
    return result

通常,我更喜欢开发易于使用和测试的插件,从而保留易于理解的剧本。

如果您不介意一点黑客技巧:

- debug: msg="{{ resource_tags | to_json(indent=0) | regex_replace('\n\"','\n\"tag:') }}"

这会将你的字典转换为 JSON 格式的字符串 indent=0,这意味着每个键将从新行开始;然后在每行的第一个双引号后插入 tag:
因为结果是有效的 JSON,Ansible 模板引擎会将它转换回 dict 作为变量替换的最后一步,给你:

ok: [localhost] => {
    "msg": {
        "tag:Name": "some name",
        "tag:Service": "some service"
    }
}

我想如果你的值中有换行符,可能会有一些极端情况,但一般来说应该没问题。