我在AWS中有一套现有的VPC,每个都有自己的CIDR块:
vpc1:20.0.0.0/16 vpc2:20.10.0.0/16
现在,我正在尝试编写一个剧本,它会拉入现有的VPC列表,然后找到一个可用的CIDR(例如在上面的示例中,下一个可用的将是20.20.0.0 / 16,虽然我并不太关心保持顺序)。
我知道这样做可以使用两个列表:
- name: Loop over all possible CIDRs
debug: msg="Found a free CIDR {{ item }}"
with_items: all_potential_cidrs
when: "\"{{ item }}\" not in {{ currently_used_cidrs }}"
但是,我获取现有CIDR列表的方式是:
- name: Get list of VPCs and their CIDR blocks
command: aws ec2 describe-vpcs --output json
register: cli_output
- name: Register variables
set_fact:
current_vpcs: "{{ cli_output.stdout | from_json }}"
该命令返回以下数据(采用JSON格式):
{
"Vpcs": [
{
"VpcId": "vpc-4aad0c23",
"InstanceTenancy": "default",
"Tags": [
{
"Value": "vpc1",
"Key": "Name"
}
],
"State": "available",
"DhcpOptionsId": "dopt-ff6b238f",
"CidrBlock": "20.0.0.0/16",
"IsDefault": false
},
{
"VpcId": "vpc-d4101abc",
"InstanceTenancy": "default",
"Tags": [
{
"Value": "vpc2",
"Key": "Name"
}
],
"State": "available",
"DhcpOptionsId": "dopt-eaaab38c",
"CidrBlock": "20.10.0.0/16",
"IsDefault": false
}
]
}
允许获取所有CIDR块如下:
- name: Print filtered VPCs and their subnets
debug: msg="VPC ID {{ item.VpcId }}, VPC CIDR block {{ item.CidrBlock }}"
with_items: current_vpcs.Vpcs
但是," CidrBlock"是列表项的属性,我无法在"当"声明,需要一个List:
when: "{{ item }}" not in {{ list_of_cidrs }}"
我怎样才能选择" CidrBlock"每个" Vpcs"项目并将其转换为自己的列表,以便将其传递给"当:...不在......"声明?
答案 0 :(得分:0)
您可以使用Jinja's map filter将VPC String
列表转换为仅包含CIDR块的列表。
我不确定你想要完成什么这个剧本,但这里有一个例子,它允许你将“Vpcs”项目列表转换为item
的{{1}}字符串列表每个vpc项目。
你可以看到它的工作原理:
CidrBlock
假设您设置了- name: Print just the CIDRS
debug: msg='{{ current_vpcs.Vpcs|map(attribute="CidrBlock")|list }}'
,则上面的行输出
current_vpcs
完整的工作示例:
TASK: [Print just the CIDRS] **************************************************
ok: [localhost] => {
"msg": "[u'20.0.0.0/16', u'20.10.0.0/16']"
}
将---
- name: ok
hosts: localhost
gather_facts: no
vars:
all_available_cidrs:
- "20.0.0.0/16"
- "20.10.0.0/16"
- "20.20.0.0/16"
tasks:
- name: Get list of VPCs and their CIDR blocks
command: aws ec2 describe-vpcs --output json
register: cli_output
- name: Register variables
set_fact:
current_vpcs: "{{ cli_output.stdout | from_json }}"
- name: Print VPCs and their subnets
debug: msg="VPC ID {{ item.VpcId }}, VPC CIDR block {{ item.CidrBlock }}"
with_items: current_vpcs.Vpcs
- name: extract list_of_cidrs into fact
set_fact:
list_of_cidrs: '{{ current_vpcs.Vpcs|map(attribute="CidrBlock")|list|to_json }}'
- name: Print just the CIDRS
debug: var=list_of_cidrs
- name: Print available unused cidrs
debug: msg="available unused VPC CIDR block {{ item }}"
with_items: all_available_cidrs
when: '"{{ item }}" not in {{ list_of_cidrs }}'
转换为列表current_vpcs.Vpcs
的行是:
["20.0.0.0/16", "20.10.0.0/16"]
注意:有必要使用set_fact:
list_of_cidrs: '{{ current_vpcs.Vpcs|map(attribute="CidrBlock")|list|to_json }}'
让Jinja正确模拟|list|to_json
语句。 in
返回一个生成器,其表示不能用作Jinja map
语句的参数。可能有更简洁的方法来执行此操作,但使用in
是人们在This ticket
修改:添加变量|list|to_json
以使完整示例更接近原始问题