1---
2- name: 'ec2_vpc_route_table integration tests'
3  collections:
4    - amazon.aws
5  module_defaults:
6    group/aws:
7      aws_access_key: '{{ aws_access_key }}'
8      aws_secret_key: '{{ aws_secret_key }}'
9      security_token: '{{ security_token | default(omit) }}'
10      region: '{{ aws_region }}'
11  block:
12
13  - name: create VPC
14    ec2_vpc_net:
15      cidr_block: 10.228.228.0/22
16      name: "{{ resource_prefix }}_vpc"
17      state: present
18    register: vpc
19
20  - name: create subnets
21    ec2_vpc_subnet:
22      cidr: "{{ item.cidr }}"
23      az: "{{ aws_region}}{{ item.az }}"
24      vpc_id: "{{ vpc.vpc.id }}"
25      state: present
26      tags:
27        Public: "{{ item.public|string }}"
28        Name: "{{ (item.public|bool)|ternary('public', 'private') }}-{{ item.az }}"
29    with_items:
30      - cidr: 10.228.228.0/24
31        az: "a"
32        public: "True"
33      - cidr: 10.228.229.0/24
34        az: "b"
35        public: "True"
36      - cidr: 10.228.230.0/24
37        az: "a"
38        public: "False"
39      - cidr: 10.228.231.0/24
40        az: "b"
41        public: "False"
42    register: subnets
43
44  - ec2_vpc_subnet_info:
45      filters:
46        vpc-id: "{{ vpc.vpc.id }}"
47    register: vpc_subnets
48
49  - set_fact:
50      public_subnets: "{{ (vpc_subnets.subnets| selectattr('tags.Public', 'equalto', 'True')| map(attribute='id')| list) }}"
51      public_cidrs: "{{ (vpc_subnets.subnets| selectattr('tags.Public', 'equalto', 'True')| map(attribute='cidr_block')| list) }}"
52      private_subnets: "{{ (vpc_subnets.subnets| selectattr('tags.Public', 'equalto', 'False')| map(attribute='id')| list)  }}"
53
54  - name: create IGW
55    ec2_vpc_igw:
56      vpc_id: "{{ vpc.vpc.id }}"
57
58  - name: create NAT GW
59    ec2_vpc_nat_gateway:
60      if_exist_do_not_create: yes
61      wait: yes
62      subnet_id: "{{ subnets.results[0].subnet.id }}"
63    register: nat_gateway
64
65  - name: CHECK MODE - route table should be created
66    ec2_vpc_route_table:
67      vpc_id: "{{ vpc.vpc.id }}"
68      tags:
69        Public: "true"
70        Name: "Public route table"
71    check_mode: true
72    register: check_mode_results
73
74  - name: assert that the public route table would be created
75    assert:
76      that:
77        - check_mode_results.changed
78
79  - name: create public route table
80    ec2_vpc_route_table:
81      vpc_id: "{{ vpc.vpc.id }}"
82      tags:
83        Public: "true"
84        Name: "Public route table"
85    register: create_public_table
86
87  - name: assert that public route table has an id
88    assert:
89      that:
90        - create_public_table.changed
91        - "create_public_table.route_table.id.startswith('rtb-')"
92        - "'Public' in create_public_table.route_table.tags and create_public_table.route_table.tags['Public'] == 'true'"
93        - create_public_table.route_table.routes|length == 1
94        - create_public_table.route_table.associations|length == 0
95        - create_public_table.route_table.vpc_id == "{{ vpc.vpc.id }}"
96        - create_public_table.route_table.propagating_vgws|length == 0
97        - create_public_table.route_table.routes|length == 1
98
99  - name: CHECK MODE - route table should already exist
100    ec2_vpc_route_table:
101      vpc_id: "{{ vpc.vpc.id }}"
102      tags:
103        Public: "true"
104        Name: "Public route table"
105    check_mode: True
106    register: check_mode_results
107
108  - name: assert the table already exists
109    assert:
110      that:
111        - not check_mode_results.changed
112
113  - name: recreate public route table
114    ec2_vpc_route_table:
115      vpc_id: "{{ vpc.vpc.id }}"
116      tags:
117        Public: "true"
118        Name: "Public route table"
119    register: recreate_public_route_table
120
121  - name: assert that public route table did not change
122    assert:
123      that:
124        - not recreate_public_route_table.changed
125        - "create_public_table.route_table.id.startswith('rtb-')"
126        - "'Public' in create_public_table.route_table.tags and create_public_table.route_table.tags['Public'] == 'true'"
127        - create_public_table.route_table.routes|length == 1
128        - create_public_table.route_table.associations|length == 0
129        - create_public_table.route_table.vpc_id == "{{ vpc.vpc.id }}"
130        - create_public_table.route_table.propagating_vgws|length == 0
131        - create_public_table.route_table.routes|length == 1
132
133  - name: CHECK MODE - add route to public route table
134    ec2_vpc_route_table:
135      vpc_id: "{{ vpc.vpc.id }}"
136      tags:
137        Public: "true"
138        Name: "Public route table"
139      routes:
140      - dest: 0.0.0.0/0
141        gateway_id: igw
142    check_mode: True
143    register: check_mode_results
144
145  - name: assert a route would be added
146    assert:
147      that:
148        - check_mode_results.changed
149
150  - name: add a route to public route table
151    ec2_vpc_route_table:
152      vpc_id: "{{ vpc.vpc.id }}"
153      tags:
154        Public: "true"
155        Name: "Public route table"
156      routes:
157      - dest: 0.0.0.0/0
158        gateway_id: igw
159    register: add_routes
160
161  - name: assert route table contains new route
162    assert:
163      that:
164        - add_routes.changed
165        - add_routes.route_table.routes|length == 2
166        - "add_routes.route_table.id.startswith('rtb-')"
167        - "'Public' in add_routes.route_table.tags and add_routes.route_table.tags['Public'] == 'true'"
168        - add_routes.route_table.routes|length == 2
169        - add_routes.route_table.associations|length == 0
170        - add_routes.route_table.vpc_id == "{{ vpc.vpc.id }}"
171        - add_routes.route_table.propagating_vgws|length == 0
172
173  - name: CHECK MODE - re-add route to public route table
174    ec2_vpc_route_table:
175      vpc_id: "{{ vpc.vpc.id }}"
176      tags:
177        Public: "true"
178        Name: "Public route table"
179      routes:
180      - dest: 0.0.0.0/0
181        gateway_id: igw
182    check_mode: True
183    register: check_mode_results
184
185  - name: assert a route would not be added
186    assert:
187      that:
188        - check_mode_results is not changed
189
190  - name: re-add a route to public route table
191    ec2_vpc_route_table:
192      vpc_id: "{{ vpc.vpc.id }}"
193      tags:
194        Public: "true"
195        Name: "Public route table"
196      routes:
197      - dest: 0.0.0.0/0
198        gateway_id: igw
199    register: add_routes
200
201  - name: assert route table contains route
202    assert:
203      that:
204        - add_routes is not changed
205        - add_routes.route_table.routes|length == 2
206
207  - name: CHECK MODE - add subnets to public route table
208    ec2_vpc_route_table:
209      vpc_id: "{{ vpc.vpc.id }}"
210      tags:
211        Public: "true"
212        Name: "Public route table"
213      routes:
214      - dest: 0.0.0.0/0
215        gateway_id: igw
216      subnets: "{{ public_subnets }}"
217    check_mode: True
218    register: check_mode_results
219
220  - name: assert the subnets would be added to the route table
221    assert:
222      that:
223        - check_mode_results.changed
224
225  - name: add subnets to public route table
226    ec2_vpc_route_table:
227      vpc_id: "{{ vpc.vpc.id }}"
228      tags:
229        Public: "true"
230        Name: "Public route table"
231      routes:
232      - dest: 0.0.0.0/0
233        gateway_id: igw
234      subnets: "{{ public_subnets }}"
235    register: add_subnets
236
237  - name: assert route table contains subnets
238    assert:
239      that:
240        - add_subnets.changed
241        - add_subnets.route_table.associations|length == 2
242
243  - name: add a route to public route table
244    ec2_vpc_route_table:
245      vpc_id: "{{ vpc.vpc.id }}"
246      tags:
247        Public: "true"
248        Name: "Public route table"
249      routes:
250      - dest: 0.0.0.0/0
251        gateway_id: igw
252    register: add_routes
253
254  - name: CHECK MODE - no routes but purge_routes set to false
255    ec2_vpc_route_table:
256      vpc_id: "{{ vpc.vpc.id }}"
257      tags:
258        Public: "true"
259        Name: "Public route table"
260      purge_routes: no
261      subnets: "{{ public_subnets }}"
262    check_mode: True
263    register: check_mode_results
264
265  - name: assert no routes would be removed
266    assert:
267      that:
268        - not check_mode_results.changed
269
270  - name: rerun with purge_routes set to false
271    ec2_vpc_route_table:
272      vpc_id: "{{ vpc.vpc.id }}"
273      tags:
274        Public: "true"
275        Name: "Public route table"
276      purge_routes: no
277      subnets: "{{ public_subnets }}"
278    register: no_purge_routes
279
280  - name: assert route table still has routes
281    assert:
282      that:
283        - not no_purge_routes.changed
284        - no_purge_routes.route_table.routes|length == 2
285        - no_purge_routes.route_table.associations|length == 2
286
287  - name: rerun with purge_subnets set to false
288    ec2_vpc_route_table:
289      vpc_id: "{{ vpc.vpc.id }}"
290      tags:
291        Public: "true"
292        Name: "Public route table"
293      purge_subnets: no
294      routes:
295      - dest: 0.0.0.0/0
296        gateway_id: igw
297    register: no_purge_subnets
298
299  - name: assert route table still has subnets
300    assert:
301      that:
302        - not no_purge_subnets.changed
303        - no_purge_subnets.route_table.routes|length == 2
304        - no_purge_subnets.route_table.associations|length == 2
305
306  - name: rerun with purge_tags not set (implicitly false)
307    ec2_vpc_route_table:
308      vpc_id: "{{ vpc.vpc.id }}"
309      routes:
310      - dest: 0.0.0.0/0
311        gateway_id: igw
312      lookup: id
313      route_table_id: "{{ create_public_table.route_table.id }}"
314      subnets: "{{ public_subnets }}"
315    register: no_purge_tags
316
317  - name: assert route table still has tags
318    assert:
319      that:
320        - not no_purge_tags.changed
321        - "'Public' in no_purge_tags.route_table.tags and no_purge_tags.route_table.tags['Public'] == 'true'"
322
323  - name: CHECK MODE - purge subnets
324    ec2_vpc_route_table:
325      vpc_id: "{{ vpc.vpc.id }}"
326      routes:
327      - dest: 0.0.0.0/0
328        gateway_id: igw
329      subnets: []
330      tags:
331        Public: "true"
332        Name: "Public route table"
333    check_mode: True
334    register: check_mode_results
335
336  - name: assert subnets would be removed
337    assert:
338      that:
339        - check_mode_results.changed
340
341  - name: purge subnets
342    ec2_vpc_route_table:
343      vpc_id: "{{ vpc.vpc.id }}"
344      routes:
345      - dest: 0.0.0.0/0
346        gateway_id: igw
347      subnets: []
348      tags:
349        Public: "true"
350        Name: "Public route table"
351    register: purge_subnets
352
353  - name: assert purge subnets worked
354    assert:
355      that:
356        - purge_subnets.changed
357        - purge_subnets.route_table.associations|length == 0
358        - purge_subnets.route_table.id == create_public_table.route_table.id
359
360  - name: CHECK MODE - purge routes
361    ec2_vpc_route_table:
362      vpc_id: "{{ vpc.vpc.id }}"
363      tags:
364        Public: "true"
365        Name: "Public route table"
366      routes: []
367    check_mode: True
368    register: check_mode_results
369
370  - name: assert routes would be removed
371    assert:
372      that:
373        - check_mode_results.changed
374
375  - name: add subnets by cidr to public route table
376    ec2_vpc_route_table:
377      vpc_id: "{{ vpc.vpc.id }}"
378      routes:
379      - dest: 0.0.0.0/0
380        gateway_id: igw
381      subnets: "{{ public_cidrs }}"
382      lookup: id
383      route_table_id: "{{ create_public_table.route_table.id }}"
384    register: add_subnets_cidr
385
386  - name: assert route table contains subnets added by cidr
387    assert:
388      that:
389        - add_subnets_cidr.changed
390        - add_subnets_cidr.route_table.associations|length == 2
391
392  - name: purge subnets added by cidr
393    ec2_vpc_route_table:
394      vpc_id: "{{ vpc.vpc.id }}"
395      routes:
396      - dest: 0.0.0.0/0
397        gateway_id: igw
398      subnets: []
399      lookup: id
400      route_table_id: "{{ create_public_table.route_table.id }}"
401    register: purge_subnets_cidr
402
403  - name: assert purge subnets added by cidr worked
404    assert:
405      that:
406        - purge_subnets_cidr.changed
407        - purge_subnets_cidr.route_table.associations|length == 0
408
409  - name: add subnets by name to public route table
410    ec2_vpc_route_table:
411      vpc_id: "{{ vpc.vpc.id }}"
412      routes:
413      - dest: 0.0.0.0/0
414        gateway_id: igw
415      subnets: "{{ public_subnets }}"
416      lookup: id
417      route_table_id: "{{ create_public_table.route_table.id }}"
418    register: add_subnets_name
419
420  - name: assert route table contains subnets added by name
421    assert:
422      that:
423        - add_subnets_name.changed
424        - add_subnets_name.route_table.associations|length == 2
425
426  - name: purge subnets added by name
427    ec2_vpc_route_table:
428      vpc_id: "{{ vpc.vpc.id }}"
429      routes:
430      - dest: 0.0.0.0/0
431        gateway_id: igw
432      subnets: []
433      lookup: id
434      route_table_id: "{{ create_public_table.route_table.id }}"
435    register: purge_subnets_name
436
437  - name: assert purge subnets added by name worked
438    assert:
439      that:
440        - purge_subnets_name.changed
441        - purge_subnets_name.route_table.associations|length == 0
442
443  - name: purge routes
444    ec2_vpc_route_table:
445      vpc_id: "{{ vpc.vpc.id }}"
446      tags:
447        Public: "true"
448        Name: "Public route table"
449      routes: []
450    register: purge_routes
451
452  - name: assert purge routes worked
453    assert:
454      that:
455        - purge_routes.changed
456        - purge_routes.route_table.routes|length == 1
457        - purge_routes.route_table.id == create_public_table.route_table.id
458
459  - name: CHECK MODE - update tags
460    ec2_vpc_route_table:
461      vpc_id: "{{ vpc.vpc.id }}"
462      route_table_id: "{{ create_public_table.route_table.id }}"
463      lookup: id
464      purge_tags: yes
465      tags:
466        Name: Public route table
467        Updated: new_tag
468    check_mode: True
469    register: check_mode_results
470
471  - name: assert tags would be changed
472    assert:
473      that:
474        - check_mode_results.changed
475
476  - name: update tags
477    ec2_vpc_route_table:
478      vpc_id: "{{ vpc.vpc.id }}"
479      route_table_id: "{{ create_public_table.route_table.id }}"
480      lookup: id
481      purge_tags: yes
482      tags:
483        Name: Public route table
484        Updated: new_tag
485    register: update_tags
486
487  - name: assert update tags worked
488    assert:
489      that:
490        - update_tags.changed
491        - "'Updated' in update_tags.route_table.tags and update_tags.route_table.tags['Updated'] == 'new_tag'"
492        - "'Public' not in update_tags.route_table.tags"
493
494  - name: create NAT GW
495    ec2_vpc_nat_gateway:
496      if_exist_do_not_create: yes
497      wait: yes
498      subnet_id: "{{ subnets.results[0].subnet.id }}"
499    register: nat_gateway
500
501  - name: CHECK MODE - create private route table
502    ec2_vpc_route_table:
503      vpc_id: "{{ vpc.vpc.id }}"
504      tags:
505        Public: "false"
506        Name: "Private route table"
507      routes:
508      - gateway_id: "{{ nat_gateway.nat_gateway_id }}"
509        dest: 0.0.0.0/0
510      subnets: "{{ private_subnets }}"
511    check_mode: True
512    register: check_mode_results
513
514  - name: assert the route table would be created
515    assert:
516      that:
517        - check_mode_results.changed
518
519  - name: create private route table
520    ec2_vpc_route_table:
521      vpc_id: "{{ vpc.vpc.id }}"
522      tags:
523        Public: "false"
524        Name: "Private route table"
525      routes:
526      - gateway_id: "{{ nat_gateway.nat_gateway_id }}"
527        dest: 0.0.0.0/0
528      subnets: "{{ private_subnets }}"
529    register: create_private_table
530
531  - name: assert creating private route table worked
532    assert:
533      that:
534        - create_private_table.changed
535        - create_private_table.route_table.id != create_public_table.route_table.id
536        - "'Public' in create_private_table.route_table.tags"
537
538  - name: CHECK MODE - destroy public route table by tags
539    ec2_vpc_route_table:
540      vpc_id: "{{ vpc.vpc.id }}"
541      state: absent
542      tags:
543        Updated: new_tag
544        Name: Public route table
545    check_mode: True
546    register: check_mode_results
547
548  - name: assert the route table would be deleted
549    assert:
550      that:
551        check_mode_results.changed
552
553  - name: destroy public route table by tags
554    ec2_vpc_route_table:
555      vpc_id: "{{ vpc.vpc.id }}"
556      state: absent
557      tags:
558        Updated: new_tag
559        Name: Public route table
560    register: destroy_table
561
562  - name: assert destroy table worked
563    assert:
564      that:
565        - destroy_table.changed
566
567  - name: CHECK MODE - redestroy public route table
568    ec2_vpc_route_table:
569      route_table_id: "{{ create_public_table.route_table.id }}"
570      lookup: id
571      state: absent
572    check_mode: True
573    register: check_mode_results
574
575  - name: assert the public route table does not exist
576    assert:
577      that:
578        - not check_mode_results.changed
579
580  - name: redestroy public route table
581    ec2_vpc_route_table:
582      route_table_id: "{{ create_public_table.route_table.id }}"
583      lookup: id
584      state: absent
585    register: redestroy_table
586
587  - name: assert redestroy table worked
588    assert:
589      that:
590        - not redestroy_table.changed
591
592  - name: destroy NAT GW
593    ec2_vpc_nat_gateway:
594      state: absent
595      wait: yes
596      release_eip: yes
597      subnet_id: "{{ subnets.results[0].subnet.id }}"
598      nat_gateway_id: "{{ nat_gateway.nat_gateway_id }}"
599    register: nat_gateway
600
601  - name: show route table info, get table using route-table-id
602    ec2_vpc_route_table_info:
603      filters:
604        route-table-id: "{{ create_private_table.route_table.id }}"
605    register: route_table_info
606
607  - name: assert route_table_info has correct attributes
608    assert:
609      that:
610        - '"route_tables" in route_table_info'
611        - 'route_table_info.route_tables | length == 1'
612        - '"id" in route_table_info.route_tables[0]'
613        - '"routes" in route_table_info.route_tables[0]'
614        - '"associations" in route_table_info.route_tables[0]'
615        - '"tags" in route_table_info.route_tables[0]'
616        - '"vpc_id" in route_table_info.route_tables[0]'
617        - 'route_table_info.route_tables[0].id == create_private_table.route_table.id'
618        - '"propagating_vgws" in route_table_info.route_tables[0]'
619
620  - name: show route table info, get table using tags
621    ec2_vpc_route_table_info:
622      filters:
623        "tag:Public": "false"
624        "tag:Name": "Private route table"
625        vpc-id: "{{ vpc.vpc.id }}"
626    register: route_table_info
627
628  - name: assert route_table_info has correct tags
629    assert:
630      that:
631        - 'route_table_info.route_tables | length == 1'
632        - '"tags" in route_table_info.route_tables[0]'
633        - '"Public" in route_table_info.route_tables[0].tags and route_table_info.route_tables[0].tags["Public"] == "false"'
634        - '"Name" in route_table_info.route_tables[0].tags and route_table_info.route_tables[0].tags["Name"] == "Private route table"'
635
636  - name: create NAT GW
637    ec2_vpc_nat_gateway:
638      if_exist_do_not_create: yes
639      wait: yes
640      subnet_id: "{{ subnets.results[0].subnet.id }}"
641    register: nat_gateway
642
643  - name: show route table info
644    ec2_vpc_route_table_info:
645      filters:
646        route-table-id: "{{ create_private_table.route_table.id }}"
647
648  - name: recreate private route table with new NAT GW
649    ec2_vpc_route_table:
650      vpc_id: "{{ vpc.vpc.id }}"
651      tags:
652        Public: "false"
653        Name: "Private route table"
654      routes:
655      - nat_gateway_id: "{{ nat_gateway.nat_gateway_id }}"
656        dest: 0.0.0.0/0
657      subnets: "{{ private_subnets }}"
658    register: recreate_private_table
659
660  - name: assert creating private route table worked
661    assert:
662      that:
663        - recreate_private_table.changed
664        - recreate_private_table.route_table.id != create_public_table.route_table.id
665
666  - name: create a VPC endpoint to test ec2_vpc_route_table ignores it
667    ec2_vpc_endpoint:
668      state: present
669      vpc_id: "{{ vpc.vpc.id }}"
670      service: "com.amazonaws.{{ aws_region }}.s3"
671      route_table_ids:
672        - "{{ recreate_private_table.route_table.route_table_id }}"
673    register: vpc_endpoint
674
675  - name: purge routes
676    ec2_vpc_route_table:
677      vpc_id: "{{ vpc.vpc.id }}"
678      tags:
679        Public: "false"
680        Name: "Private route table"
681      routes:
682      - nat_gateway_id: "{{ nat_gateway.nat_gateway_id }}"
683        dest: 0.0.0.0/0
684      subnets: "{{ private_subnets }}"
685      purge_routes: true
686    register: result
687
688  - name: Get endpoint infos to verify that it wasn't purged from the route table
689    ec2_vpc_endpoint_info:
690      query: endpoints
691      vpc_endpoint_ids:
692        - "{{ vpc_endpoint.result.vpc_endpoint_id }}"
693    register: endpoint_details
694
695  - name: assert the route table is associated with the VPC endpoint
696    assert:
697      that:
698        - endpoint_details.vpc_endpoints[0].route_table_ids[0] == recreate_private_table.route_table.route_table_id
699
700  always:
701  #############################################################################
702  # TEAR DOWN STARTS HERE
703  #############################################################################
704  - name: remove the VPC endpoint
705    ec2_vpc_endpoint:
706      state: absent
707      vpc_endpoint_id: "{{ vpc_endpoint.result.vpc_endpoint_id }}"
708    when: vpc_endpoint is defined
709    ignore_errors: yes
710
711  - name: destroy route tables
712    ec2_vpc_route_table:
713      route_table_id: "{{ item.route_table.id }}"
714      lookup: id
715      state: absent
716    with_items:
717      - "{{ create_public_table|default() }}"
718      - "{{ create_private_table|default() }}"
719    when: item and not item.failed
720    ignore_errors: yes
721
722  - name: destroy NAT GW
723    ec2_vpc_nat_gateway:
724      state: absent
725      wait: yes
726      release_eip: yes
727      subnet_id: "{{ subnets.results[0].subnet.id }}"
728      nat_gateway_id: "{{ nat_gateway.nat_gateway_id }}"
729    ignore_errors: yes
730
731  - name: destroy IGW
732    ec2_vpc_igw:
733      vpc_id: "{{ vpc.vpc.id }}"
734      state: absent
735    ignore_errors: yes
736
737  - name: destroy subnets
738    ec2_vpc_subnet:
739      cidr: "{{ item.cidr }}"
740      vpc_id: "{{ vpc.vpc.id }}"
741      state: absent
742    with_items:
743      - cidr: 10.228.228.0/24
744      - cidr: 10.228.229.0/24
745      - cidr: 10.228.230.0/24
746      - cidr: 10.228.231.0/24
747    ignore_errors: yes
748
749  - name: destroy VPC
750    ec2_vpc_net:
751      cidr_block: 10.228.228.0/22
752      name: "{{ resource_prefix }}_vpc"
753      state: absent
754    ignore_errors: yes
755