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
- 注册信息
- 从以前注册的信息中获取私有 IP
- 正在将主机添加到组
虽然我已经有了一个工作循环来处理我想一次创建所有 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 从字典更改为列表,一些标签,一切都很好 :) 现在,如果我添加一个新服务器,它只需要几行。
我有一个使用在 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
- 注册信息
- 从以前注册的信息中获取私有 IP
- 正在将主机添加到组
虽然我已经有了一个工作循环来处理我想一次创建所有 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 从字典更改为列表,一些标签,一切都很好 :) 现在,如果我添加一个新服务器,它只需要几行。