我尝试使用Ansible将IP地址添加到AWS安全组。
我想出了一个如下所示的任务语法:
- hosts: localhost
gather_facts: False
vars:
ip_addresses:
- 1.2.3.4/32
- 2.3.4.5/32
tasks:
- ec2_group:
name: security-group-name
description: Security group description
vpc_id: vpc-1234567
region: us-east-1
profile: profile-name
purge_rules: false
rules:
- proto: tcp
from_port: 123
to_port: 123
cidr_ip: "{{ item }}"
with_items: ip_addresses
这并没有完全符合我的要求,因为它基本上多次运行ec2_group
任务,而不是仅仅循环规则。
如果我将purge_rules
设置为true
,这也不起作用,因为它将清除每次迭代的所有现有规则,有效地删除列表中除最后一个IP地址之外的所有规则。
我想知道是否有类似于with_items
的内容可以应用于rules
属性,以便为其提供IP地址列表,但只调用ec2_task
一次?
答案 0 :(得分:2)
这并没有完全符合我的要求,因为它基本上多次运行ec2_group任务而不是仅仅循环规则。
Ansible通过为循环中的每个项调用一次任务来实现循环,这是预期的行为。
我想知道是否有类似于with_items的内容可以应用于rules属性以提供IP地址列表但只调用ec2_task一次?
由于rules
的{{1}}属性实际上是一个规则列表,您应该可以执行以下操作:
ec2_group
或者,如果您想在示例中使用预定义的变量:
- ec2_group:
name: security-group-name
description: Security group description
vpc_id: vpc-1234567
region: us-east-1
profile: profile-name
purge_rules: true
rules:
- proto: tcp
from_port: 123
to_port: 123
cidr_ip: 1.2.3.4/32
- proto: tcp
from_port: 123
to_port: 123
cidr_ip: 2.3.4.5/32
答案 1 :(得分:2)
您可以使用自定义过滤器插件实现所需的功能。
在您的剧本的根目录中创建一个名为filter_plugins
的目录,并在其中创建一个名为make_rules.py
的文件,其中包含以下内容:
def make_rules(hosts, ports, proto):
return [{"proto": proto,
"from_port": port,
"to_port": port,
"cidr_ip": host} for host in hosts for port in map(int, ports.split(","))]
class FilterModule(object):
def filters(self):
return {'make_rules': make_rules}
然后你可以这样做:
- hosts: localhost
gather_facts: False
vars:
ip_addresses:
- 1.2.3.4/32
- 2.3.4.5/32
tasks:
- ec2_group:
name: security-group-name
description: Security group description
vpc_id: vpc-1234567
region: us-east-1
profile: profile-name
purge_rules: true
rules: {{ ip_addresses | make_rules('123', 'tcp') }}