Ansible Dict 和标签

Ansible Dict and Tags

我有一个使用在 vars: 中声明的字典创建 EC2 的剧本,然后将 IP 注册到一个组中以供稍后使用。

字典看起来像这样:

servers:
  serv1:
    name: tag1
    type: t2.small
    region: us-west-1
    image: ami-****
  serv2:
    name: tag2
    type: t2.medium
    region: us-east-1
    image: ami-****
  serv3:
    [...]

我想以最简单的方式将标签应用于此剧本,这样我就可以使用标签创建其中的一些。例如,运行 带有 --tags tag1,tag3 的剧本只会启动与 serv1 和 serv3 匹配的 EC2。

在字典上应用标签似乎是不可能的,我想避免做像这样的乘法任务:

虽然我已经有了一个工作循环来处理我想一次创建所有 EC2 的情况,但有什么方法可以实现这一点(不依赖 --extra-vars,这需要 key=value)?例如,通过仅保留在 运行 EC2 循环之前标记的内容来过滤掉字典 ?

我怀疑您是否可以开箱即用。并且不确定这是个好主意。
因为标签用于在 Ansible 中过滤任务,所以您必须使用 tags: always.

标记所有任务

您可以使用自定义过滤器插件来完成此操作,例如 (./filter_plugins/apply_tags.py):

try:
    from __main__ import cli
except ImportError:
    cli = False

def apply_tags(src):
  if cli:
    tags = cli.options.tags.split(',')
    res = {}
    for k,v in src.iteritems():
      keep = True
      if 'name' in v:
        if v['name'] not in tags:
          keep = False
      if keep:
        res[k] = v
    return res
  else:
    return src

class FilterModule(object):

    def filters(self):
        return {
            'apply_tags': apply_tags
        }

在你的剧本中:

- debug: msg="{{ servers | apply_tags }}"
  tags: always

我找到了一种方法来满足我的需求,而无需触及其余部分,所以我分享它以防其他人可能有类似的需求。 我需要根据标签组合字典,所以我的 "main" 字典不会是静态的。

变量变为:

- serv1:
  - name: tag1
    type: t2.small
    region: us-west-1
    image: ami-****
- serv2:
  - name: tag2
    type: t2.medium
    region: us-east-1
    image: ami-****
- serv3:
 [...]

因此,我没有重复我的任务,而是使用 set_fact 标签,如下所示:

- name: Combined dict
# Declaring empty dict
  set_fact:
    servers: []
  tags: ['always']
- name: Add Server 1
  set_fact:
    servers: "{{ servers + serv1 }}"
  tags: ['tag1']
- name: Add Server 2
  set_fact:
    servers: "{{ servers + serv2 }}"
  tags: ['tag2']
[..]

20 行,而不是为每个服务器增加任务,将 vars 从字典更改为列表,一些标签,一切都很好 :) 现在,如果我添加一个新服务器,它只需要几行。