-
Notifications
You must be signed in to change notification settings - Fork 26
/
setup_aws_network.yml
333 lines (303 loc) · 14.5 KB
/
setup_aws_network.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
---
# Copyright 2021 Cloudera, Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
- name: Update existing AWS VPC
when: infra__aws_vpc_id != ""
block:
- name: Prepare AWS VPC tags
ansible.builtin.set_fact:
__aws_vpc_tags: "{{ __aws_vpc_tags | default([]) | union([tag_entry]) }}"
vars:
tag_entry: "Key={{ __tag.key }},Value={{ __tag.value |quote}}"
loop: "{{ infra__tags | dict2items }}"
loop_control:
loop_var: __tag
# Using CLI due to hardcoded module behavior - see https://github.com/boto/boto3/issues/2929
- name: Update AWS VPC
when: __aws_vpc_tags is defined and __aws_vpc_tags | length > 0
ansible.builtin.command: "aws ec2 create-tags --region {{ infra__region }} --resources {{ infra__aws_vpc_id }} --tags {{ __aws_vpc_tags | join(' ') }}"
- name: Set up AWS VPC
when: infra__aws_vpc_id == ""
block:
- name: Create AWS VPC
amazon.aws.ec2_vpc_net:
region: "{{ infra__region }}"
name: "{{ infra__vpc_name }}"
cidr_block: "{{ infra__vpc_cidr }}"
tags: "{{ infra__tags }}" # TODO - Filter out name, per module warning
state: present
register: __aws_vpc_info
- name: Set fact for AWS VPC ID
ansible.builtin.set_fact:
infra__aws_vpc_id: "{{ __aws_vpc_info.vpc.id }}"
- name: Update existing AWS VPC Public Subnets
when: infra__aws_public_subnet_ids | count > 0
amazon.aws.ec2_vpc_subnet:
region: "{{ infra__region }}"
vpc_id: "{{ infra__aws_vpc_id }}"
cidr: "{{ __aws_public_subnet_item.cidr }}"
map_public: "{{ __aws_public_subnet_item.map_public }}"
assign_instances_ipv6: "{{ __aws_public_subnet_item.assign_instances_ipv6 }}"
state: present
purge_tags: no
tags: "{{ infra__tags | combine(__aws_public_subnet_item.tags, recursive=True) }}"
loop_control:
loop_var: __aws_public_subnet_item
index_var: __aws_public_subnet_index
loop: "{{ infra__vpc_public_subnets_info }}"
- name: Update existing AWS VPC Private Subnets
when: infra__aws_private_subnet_ids | count > 0
amazon.aws.ec2_vpc_subnet:
region: "{{ infra__region }}"
vpc_id: "{{ infra__aws_vpc_id }}"
cidr: "{{ __aws_private_subnet_item.cidr }}"
state: present
purge_tags: no
tags: "{{ infra__tags | combine(__aws_private_subnet_item.tags, recursive=True) }}"
loop_control:
loop_var: __aws_private_subnet_item
index_var: __aws_private_subnet_index
loop: "{{ infra__vpc_private_subnets_info }}"
- name: Set up AWS Public Network infrastructure
when: infra__aws_subnet_ids is undefined # L0 (fully public), L1 (semi-private), or L2 (fully-private), but not for existing network or L3 (outbound restricted)
# when: not (infra__tunnel and not infra__public_endpoint_access) and infra__aws_subnet_ids is undefined # L0 (all public) or L1 (public/private)
block:
- name: Create AWS Internet Gateway (IGW)
community.aws.ec2_vpc_igw:
vpc_id: "{{ infra__aws_vpc_id }}"
region: "{{ infra__region }}"
state: present
tags: "{{ infra__tags | combine({ 'Name': infra__aws_igw_name }, recursive=True) }}"
register: __aws_igw
- name: Set fact for AWS IGW ID
when: __aws_igw.gateway_id is defined
ansible.builtin.set_fact:
infra__aws_igw_id: "{{ __aws_igw.gateway_id }}"
- name: Create AWS VPC Public Subnets
amazon.aws.ec2_vpc_subnet:
region: "{{ infra__region }}"
vpc_id: "{{ infra__aws_vpc_id }}"
cidr: "{{ __aws_public_subnet_item.cidr }}"
state: present
tags: "{{ infra__tags | combine(__aws_public_subnet_item.tags, recursive=True) }}"
map_public: yes
az: "{{ __aws_az_info.availability_zones[__aws_subnet_index % infra__aws_vpc_az_count | int].zone_name }}"
loop_control:
loop_var: __aws_public_subnet_item
index_var: __aws_subnet_index
loop: "{{ infra__vpc_public_subnets_info }}"
register: __aws_public_subnets
- name: Set fact for AWS Public Subnet IDs
ansible.builtin.set_fact:
infra__aws_public_subnet_ids: "{{ infra__aws_public_subnet_ids | default([]) | union([__aws_subnet_item.subnet.id | default('')]) }}"
loop_control:
loop_var: __aws_subnet_item
loop: "{{ __aws_public_subnets.results }}"
- name: List the Route Tables for the AWS VPC
community.aws.ec2_vpc_route_table_info:
region: "{{ infra__region }}"
filters:
vpc-id: "{{ infra__aws_vpc_id }}"
register: __aws_route_table_list
- name: Configure the Public Route Table for the AWS VPC
community.aws.ec2_vpc_route_table:
region: "{{ infra__region }}"
vpc_id: "{{ infra__aws_vpc_id }}"
route_table_id: "{{ __aws_route_table_id }}"
lookup: id
state: present
tags: "{{ infra__tags | combine({ 'Name': infra__aws_public_route_table_name }, recursive=True) }}"
routes:
- dest: "0.0.0.0/0"
gateway_id: "{{ infra__aws_igw_id }}"
subnets: "{{ infra__aws_public_subnet_ids }}"
vars:
__aws_route_table_id: "{{ __aws_route_table_list.route_tables | json_query(__aws_rtb_jq) | flatten | first }}"
__aws_rtb_jq: "[*].associations[?main == `true` ].route_table_id"
- name: Set facts for AWS Subnet IDs with Public Subnet details if not CCM Tunneled
when: not infra__tunnel
ansible.builtin.set_fact:
infra__aws_subnet_ids: "{{ infra__aws_public_subnet_ids }}"
- name: Setup AWS Private Networking infrastructure
when: infra__tunnel and infra__aws_subnet_ids is undefined # L1 (semi-private) or L2 (fully private), but not for existing network or L0 (fully public) or L3 (outbound restricted)
block:
- name: Create AWS VPC Private Subnets
amazon.aws.ec2_vpc_subnet:
region: "{{ infra__region }}"
vpc_id: "{{ infra__aws_vpc_id }}"
cidr: "{{ __aws_private_subnet_item.cidr }}"
state: present
tags: "{{ infra__tags | combine(__aws_private_subnet_item.tags, recursive = true) }}"
map_public: no
az: "{{ __aws_az_info.availability_zones[__aws_subnet_index % infra__aws_vpc_az_count | int].zone_name }}"
loop_control:
loop_var: __aws_private_subnet_item
index_var: __aws_subnet_index
label: "{{ __aws_private_subnet_item.name }}"
loop: "{{ infra__vpc_private_subnets_info }}"
register: __aws_private_subnets
- name: Set fact for AWS Private Subnet IDs
ansible.builtin.set_fact:
infra__aws_private_subnet_ids: "{{ infra__aws_private_subnet_ids | default([]) | union([__aws_subnet_item.subnet.id | default('')]) }}"
loop_control:
loop_var: __aws_subnet_item
loop: "{{ __aws_private_subnets.results }}"
- name: Configure Private Route Table for the AWS VPC
when: no
#when: not infra__public_endpoint_access
community.aws.ec2_vpc_route_table:
vpc_id: "{{ infra__aws_vpc_id }}"
region: "{{ infra__region }}"
tags: "{{ infra__tags | combine({ 'Name': infra__aws_private_route_table_name }, recursive=True) }}"
subnets: "{{ infra__aws_private_subnet_ids }}"
routes: []
- name: Create Network Gateways (NAT) # and allocate Elastic IP Addresses (EIP) for Public Endpoint Access
#when: infra__public_endpoint_access
# Might want a net new flag -- disconnected -- that will not set up any routes to outside, i.e. Level3
community.aws.ec2_vpc_nat_gateway:
state: present
subnet_id: "{{ __aws_public_subnet_id }}"
wait: true
if_exist_do_not_create: true
region: "{{ infra__region }}"
tags: "{{ infra__tags | combine({ 'Name': '-'.join([infra__aws_nat_gateway_name, __aws_public_subnet_index | string]) }, recursive=True) }}"
loop_control:
loop_var: __aws_public_subnet_id
index_var: __aws_public_subnet_index
loop: "{{ infra__aws_public_subnet_ids }}"
register: __aws_ngws
- name: Configure Private Route Tables #for the AWS VPC for Public Endpoint Access
#when: infra__public_endpoint_access
# See above
community.aws.ec2_vpc_route_table:
vpc_id: "{{ infra__aws_vpc_id }}"
region: "{{ infra__region }}"
tags: "{{ infra__tags | combine({ 'Name': '-'.join([infra__aws_private_route_table_name, __aws_private_subnet_id_index | string]) }, recursive=True) }}"
subnets: "{{ __aws_private_subnet_id_item }}"
routes:
- dest: "0.0.0.0/0"
nat_gateway_id: "{{ __aws_ngws.results[ __aws_private_subnet_id_index % __aws_ngws.results | length ].nat_gateway_id }}"
loop_control:
loop_var: __aws_private_subnet_id_item
index_var: __aws_private_subnet_id_index
loop: "{{ infra__aws_private_subnet_ids }}"
- name: Set fact for AWS Subnet IDs
ansible.builtin.set_fact:
infra__aws_subnet_ids: "{{ infra__aws_public_subnet_ids | default([]) | union(infra__aws_private_subnet_ids) }}"
- name: Create AWS Security Groups
amazon.aws.ec2_group:
state: present
region: "{{ infra__region }}"
vpc_id: "{{ infra__aws_vpc_id }}"
name: "{{ __security_group_name_item }}"
description: "{{ __security_group_name_item }}"
tags: "{{ infra__tags | combine({ 'Name': __security_group_name_item }, recursive=True) }}"
rules: "{{ infra__aws_security_group_rules | union([rule])}}"
vars:
rule:
proto: all
group_name: "{{ __security_group_name_item }}"
loop_control:
loop_var: __security_group_name_item
loop:
- "{{ infra__security_group_knox_name }}"
- "{{ infra__security_group_default_name }}"
register: __aws_security_group_info
- name: Set fact for Security Group IDs
ansible.builtin.set_fact:
infra__aws_security_group_knox_id: "{{ __aws_security_group_info | community.general.json_query(knox) | first }}"
infra__aws_security_group_default_id: "{{ __aws_security_group_info | community.general.json_query(default) | first }}"
vars:
knox: "results[?group_name=='{{ infra__security_group_knox_name }}'].group_id"
default: "results[?group_name=='{{ infra__security_group_default_name }}'].group_id"
- name: Setup AWS Private Endpoints
when: infra__aws_private_endpoints | bool
block:
- name: Create VPC Endpoint Security Group (Skip if infra__aws_private_endpoints is false)
amazon.aws.ec2_group:
state: present
region: "{{ infra__region }}"
vpc_id: "{{ infra__aws_vpc_id }}"
tags: "{{ infra__tags | combine({ 'Name': 'infra__security_group_vpce_name' }, recursive=True) }}"
name: "{{ infra__security_group_vpce_name }}"
description: "{{ infra__security_group_vpce_name }}"
rules:
- proto: all
cidr_ip: "{{ infra__vpc_cidr }}"
register: __aws_vpce_security_group_info
- name: List the Route Tables for the AWS VPC (Skip if infra__aws_private_endpoints is false)
community.aws.ec2_vpc_route_table_info:
region: "{{ infra__region }}"
filters:
vpc-id: "{{ infra__aws_vpc_id }}"
register: __aws_route_table_list_again
- name: Set fact for All Route Table IDs (Skip if infra__aws_private_endpoints is false)
ansible.builtin.set_fact:
infra__route_table_ids: "{{ infra__route_table_ids | default([]) | union([route_table_id]) }}"
vars:
route_table_id: "{{ __aws_route_tables.associations[0].route_table_id }}"
loop: "{{ __aws_route_table_list_again.route_tables }}"
loop_control:
label: "{{ __aws_route_tables.associations[0].route_table_id }}"
loop_var: __aws_route_tables
- name: Create Gateway VPC Endpoints (Skip if infra__aws_private_endpoints is false)
community.aws.ec2_vpc_endpoint:
state: present
region: "{{ infra__region }}"
vpc_id: "{{ infra__aws_vpc_id }}"
service: "{{ __infra_gateway_vpc_endpoint }}"
route_table_ids: "{{ infra__route_table_ids }}"
tags: "{{ infra__tags | combine({ 'Name': infra__namespace + __infra_gateway_vpc_endpoint.split(infra__region)[1] }, recursive=True) }}"
vars:
route_table_id: "{{ route_tables.associations[0].route_table_id }}"
loop: "{{ infra__aws_gateway_vpc_private_endpoints }}"
loop_control:
loop_var: __infra_gateway_vpc_endpoint
register: __aws_gateway_vpc_endpoints
- name: Create Interface VPC Endpoints (Skip if infra__aws_private_endpoints is false)
community.aws.ec2_vpc_endpoint:
state: present
region: "{{ infra__region }}"
vpc_id: "{{ infra__aws_vpc_id }}"
service: "{{ __infra_interface_vpc_endpoint }}"
vpc_endpoint_type: Interface
wait: true
tags: "{{ infra__tags | combine({ 'Name': infra__namespace + __infra_interface_vpc_endpoint.split(infra__region)[1] }, recursive=True) }}"
loop: "{{ infra__aws_interface_vpc_private_endpoints }}"
loop_control:
loop_var: __infra_interface_vpc_endpoint
register: __aws_interface_vpc_endpoints
- name: List Default Security Group for VPC (Skip if infra__aws_private_endpoints is false)
amazon.aws.ec2_group_info:
filters:
vpc-id: "{{ infra__aws_vpc_id }}"
group-name:
- default
register: __aws_vpc_default_sg
- name: Add Subnets and Security Groups to Interface VPC Endpoints (Skip if infra__aws_private_endpoints is false)
when:
- __aws_interface_vpc_endpoints is defined
- __aws_interface_vpc_endpoints.results is defined
command: >
aws ec2 modify-vpc-endpoint
--region {{ infra__region }}
--vpc-endpoint-id {{ __infra_vpce_loop_var.result.vpc_endpoint_id }}
--add-subnet-ids {{ infra__aws_public_subnet_ids | join(' ') }}
--add-security-group-ids {{ __aws_vpce_security_group_info.group_id }}
--remove-security-group-ids {{ __aws_vpc_default_sg.security_groups[0].group_id }}
--private-dns-enabled
loop_control:
label: "{{ __infra_vpce_loop_var.result.vpc_endpoint_id | default('') }}" # Default empty string to avoid ansible label undef error
loop_var: __infra_vpce_loop_var
loop: "{{ __aws_interface_vpc_endpoints.results }}"