-
Notifications
You must be signed in to change notification settings - Fork 56
/
rds.sp
1560 lines (1443 loc) · 58.3 KB
/
rds.sp
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
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
locals {
conformance_pack_rds_common_tags = merge(local.aws_compliance_common_tags, {
service = "AWS/RDS"
})
}
control "rds_db_cluster_copy_tags_to_snapshot_enabled" {
title = "RDS DB clusters should be configured to copy tags to snapshots"
description = "This control checks whether RDS DB clusters are configured to copy all tags to snapshots when the snapshots are created."
query = query.rds_db_cluster_copy_tags_to_snapshot_enabled
tags = local.conformance_pack_rds_common_tags
}
control "rds_db_instance_copy_tags_to_snapshot_enabled" {
title = "RDS DB instances should be configured to copy tags to snapshots"
description = "This control checks whether RDS DB instances are configured to copy all tags to snapshots when the snapshots are created."
query = query.rds_db_instance_copy_tags_to_snapshot_enabled
tags = local.conformance_pack_rds_common_tags
}
control "rds_db_instance_in_vpc" {
title = "RDS instances should be deployed in a VPC"
description = "This control checks whether an RDS instance is deployed in a VPC (EC2-VPC)."
query = query.rds_db_instance_in_vpc
tags = local.conformance_pack_rds_common_tags
}
control "rds_db_cluster_events_subscription" {
title = "An RDS event notifications subscription should be configured for critical cluster events"
description = "This control checks whether an AWS RDS event subscription exists that has notifications enabled for the following source type, event category key-value pairs."
query = query.rds_db_cluster_events_subscription
tags = local.conformance_pack_rds_common_tags
}
control "rds_db_instance_events_subscription" {
title = "An RDS event notifications subscription should be configured for critical database instance events"
description = "This control checks whether an AWS RDS event subscription exists with notifications enabled for the following source type, event category key-value pairs."
query = query.rds_db_instance_events_subscription
tags = local.conformance_pack_rds_common_tags
}
control "rds_db_parameter_group_events_subscription" {
title = "An RDS event notifications subscription should be configured for critical database parameter group events"
description = "This control checks whether an AWS RDS event subscription exists with notifications enabled for the following source type, event category key-value pairs."
query = query.rds_db_parameter_group_events_subscription
tags = local.conformance_pack_rds_common_tags
}
control "rds_db_security_group_events_subscription" {
title = "An RDS event notifications subscription should be configured for critical database security group events"
description = "This control checks whether an AWS RDS event subscription exists with notifications enabled for the following source type, event category key-value pairs."
query = query.rds_db_security_group_events_subscription
tags = local.conformance_pack_rds_common_tags
}
control "rds_db_instance_and_cluster_no_default_port" {
title = "RDS databases and clusters should not use a database engine default port"
description = "This control checks whether the RDS cluster or instance uses a port other than the default port of the database engine."
query = query.rds_db_instance_and_cluster_no_default_port
tags = local.conformance_pack_rds_common_tags
}
control "rds_db_cluster_encryption_at_rest_enabled" {
title = "RDS DB clusters should be encrypted at rest"
description = "This control checks if an RDS DB cluster is encrypted at rest. The control fails if an RDS DB cluster isn't encrypted at rest."
query = query.rds_db_cluster_encryption_at_rest_enabled
tags = local.conformance_pack_rds_common_tags
}
control "rds_db_instance_backup_enabled" {
title = "RDS DB instance backup should be enabled"
description = "The backup feature of AWS RDS creates backups of your databases and transaction logs."
query = query.rds_db_instance_backup_enabled
tags = merge(local.conformance_pack_rds_common_tags, {
cis_controls_v8_ig1 = "true"
cisa_cyber_essentials = "true"
fedramp_low_rev_4 = "true"
fedramp_moderate_rev_4 = "true"
ffiec = "true"
gxp_21_cfr_part_11 = "true"
gxp_eu_annex_11 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
hipaa_security_rule_2003 = "true"
nist_800_171_rev_2 = "true"
nist_800_53_rev_4 = "true"
nist_800_53_rev_5 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
rbi_cyber_security = "true"
rbi_itf_nbfc = "true"
soc_2 = "true"
})
}
control "rds_db_instance_encryption_at_rest_enabled" {
title = "RDS DB instance encryption at rest should be enabled"
description = "To help protect data at rest, ensure that encryption is enabled for your AWS Relational Database Service (AWS RDS) instances."
query = query.rds_db_instance_encryption_at_rest_enabled
tags = merge(local.conformance_pack_rds_common_tags, {
audit_manager_control_tower = "true"
cis_controls_v8_ig1 = "true"
cisa_cyber_essentials = "true"
fedramp_moderate_rev_4 = "true"
ffiec = "true"
gdpr = "true"
gxp_21_cfr_part_11 = "true"
gxp_eu_annex_11 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
hipaa_security_rule_2003 = "true"
nist_800_171_rev_2 = "true"
nist_800_53_rev_4 = "true"
nist_800_53_rev_5 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
rbi_cyber_security = "true"
soc_2 = "true"
})
}
control "rds_db_instance_multiple_az_enabled" {
title = "RDS DB instance multiple az should be enabled"
description = "Multi-AZ support in AWS Relational Database Service (AWS RDS) provides enhanced availability and durability for database instances."
query = query.rds_db_instance_multiple_az_enabled
tags = merge(local.conformance_pack_rds_common_tags, {
cisa_cyber_essentials = "true"
fedramp_low_rev_4 = "true"
fedramp_moderate_rev_4 = "true"
ffiec = "true"
gxp_21_cfr_part_11 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
hipaa_security_rule_2003 = "true"
nist_800_171_rev_2 = "true"
nist_800_53_rev_4 = "true"
nist_800_53_rev_5 = "true"
nist_csf = "true"
rbi_itf_nbfc = "true"
})
}
control "rds_db_instance_prohibit_public_access" {
title = "RDS DB instances should prohibit public access"
description = "Manage access to resources in the AWS Cloud by ensuring that AWS Relational Database Service (AWS RDS) instances are not public."
query = query.rds_db_instance_prohibit_public_access
tags = merge(local.conformance_pack_rds_common_tags, {
audit_manager_control_tower = "true"
cis_controls_v8_ig1 = "true"
cisa_cyber_essentials = "true"
fedramp_low_rev_4 = "true"
fedramp_moderate_rev_4 = "true"
ffiec = "true"
gxp_21_cfr_part_11 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
hipaa_security_rule_2003 = "true"
nist_800_171_rev_2 = "true"
nist_800_53_rev_4 = "true"
nist_800_53_rev_5 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
rbi_cyber_security = "true"
rbi_itf_nbfc = "true"
soc_2 = "true"
})
}
control "rds_db_snapshot_encrypted_at_rest" {
title = "RDS DB snapshots should be encrypted at rest"
description = "Ensure that encryption is enabled for your AWS Relational Database Service (AWS RDS) snapshots."
query = query.rds_db_snapshot_encrypted_at_rest
tags = merge(local.conformance_pack_rds_common_tags, {
cisa_cyber_essentials = "true"
fedramp_moderate_rev_4 = "true"
gdpr = "true"
gxp_21_cfr_part_11 = "true"
gxp_eu_annex_11 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
hipaa_security_rule_2003 = "true"
nist_800_171_rev_2 = "true"
nist_800_53_rev_4 = "true"
nist_800_53_rev_5 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
rbi_cyber_security = "true"
soc_2 = "true"
})
}
control "rds_db_snapshot_prohibit_public_access" {
title = "RDS snapshots should prohibit public access"
description = "Manage access to resources in the AWS Cloud by ensuring that AWS Relational Database Service (AWS RDS) instances are not public."
query = query.rds_db_snapshot_prohibit_public_access
tags = merge(local.conformance_pack_rds_common_tags, {
audit_manager_control_tower = "true"
cis_controls_v8_ig1 = "true"
cisa_cyber_essentials = "true"
fedramp_low_rev_4 = "true"
fedramp_moderate_rev_4 = "true"
ffiec = "true"
gxp_21_cfr_part_11 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
hipaa_security_rule_2003 = "true"
nist_800_171_rev_2 = "true"
nist_800_53_rev_4 = "true"
nist_800_53_rev_5 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
rbi_cyber_security = "true"
rbi_itf_nbfc = "true"
soc_2 = "true"
})
}
control "rds_db_instance_logging_enabled" {
title = "Database logging should be enabled"
description = "To help with logging and monitoring within your environment, ensure AWS Relational Database Service (AWS RDS) logging is enabled."
query = query.rds_db_instance_logging_enabled
tags = merge(local.conformance_pack_rds_common_tags, {
cis_controls_v8_ig1 = "true"
cisa_cyber_essentials = "true"
fedramp_low_rev_4 = "true"
fedramp_moderate_rev_4 = "true"
ffiec = "true"
gdpr = "true"
gxp_21_cfr_part_11 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
hipaa_security_rule_2003 = "true"
nist_800_171_rev_2 = "true"
nist_800_53_rev_4 = "true"
nist_800_53_rev_5 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
rbi_cyber_security = "true"
rbi_itf_nbfc = "true"
soc_2 = "true"
})
}
control "rds_db_instance_in_backup_plan" {
title = "RDS DB instances should be in a backup plan"
description = "To help with data back-up processes, ensure your AWS Relational Database Service (AWS RDS) instances are a part of an AWS Backup plan."
query = query.rds_db_instance_in_backup_plan
tags = merge(local.conformance_pack_rds_common_tags, {
cis_controls_v8_ig1 = "true"
cisa_cyber_essentials = "true"
ffiec = "true"
gdpr = "true"
gxp_21_cfr_part_11 = "true"
gxp_eu_annex_11 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
hipaa_security_rule_2003 = "true"
nist_800_171_rev_2 = "true"
nist_800_53_rev_4 = "true"
nist_800_53_rev_5 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
rbi_cyber_security = "true"
rbi_itf_nbfc = "true"
soc_2 = "true"
})
}
control "rds_db_instance_and_cluster_enhanced_monitoring_enabled" {
title = "RDS DB instance and cluster enhanced monitoring should be enabled"
description = "Enable AWS Relational Database Service (AWS RDS) to help monitor AWS RDS availability. This provides detailed visibility into the health of your AWS RDS database instances."
query = query.rds_db_instance_and_cluster_enhanced_monitoring_enabled
tags = merge(local.conformance_pack_rds_common_tags, {
cisa_cyber_essentials = "true"
fedramp_low_rev_4 = "true"
fedramp_moderate_rev_4 = "true"
ffiec = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
nist_800_171_rev_2 = "true"
nist_800_53_rev_4 = "true"
nist_800_53_rev_5 = "true"
nist_csf = "true"
rbi_itf_nbfc = "true"
})
}
control "rds_db_instance_deletion_protection_enabled" {
title = "RDS DB instances should have deletion protection enabled"
description = "Ensure AWS Relational Database Service (AWS RDS) instances have deletion protection enabled."
query = query.rds_db_instance_deletion_protection_enabled
tags = merge(local.conformance_pack_rds_common_tags, {
cisa_cyber_essentials = "true"
fedramp_low_rev_4 = "true"
fedramp_moderate_rev_4 = "true"
ffiec = "true"
gxp_21_cfr_part_11 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
nist_800_171_rev_2 = "true"
nist_800_53_rev_4 = "true"
nist_800_53_rev_5 = "true"
nist_csf = "true"
rbi_itf_nbfc = "true"
soc_2 = "true"
})
}
control "rds_db_instance_iam_authentication_enabled" {
title = "RDS DB instances should have iam authentication enabled"
description = "Checks if an AWS Relational Database Service (AWS RDS) instance has AWS Identity and Access Management (IAM) authentication enabled."
query = query.rds_db_instance_iam_authentication_enabled
tags = merge(local.conformance_pack_rds_common_tags, {
hipaa_final_omnibus_security_rule_2013 = "true"
hipaa_security_rule_2003 = "true"
nist_800_171_rev_2 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
soc_2 = "true"
})
}
control "rds_db_cluster_iam_authentication_enabled" {
title = "IAM authentication should be configured for RDS clusters"
description = "Checks if an AWS RDS Cluster has AWS Identity and Access Management (IAM) authentication enabled. The rule is non-compliant if an RDS Cluster does not have IAM authentication enabled."
query = query.rds_db_cluster_iam_authentication_enabled
tags = merge(local.conformance_pack_rds_common_tags, {
nist_800_171_rev_2 = "true"
nist_csf = "true"
})
}
control "rds_db_cluster_aurora_protected_by_backup_plan" {
title = "RDS Aurora clusters should be protected by backup plan"
description = "Checks if AWS Aurora DB clusters are protected by a backup plan. The rule is non-compliant if the AWS Relational Database Service (AWS RDS) Database Cluster is not protected by a backup plan."
query = query.rds_db_cluster_aurora_protected_by_backup_plan
tags = merge(local.conformance_pack_rds_common_tags, {
cisa_cyber_essentials = "true"
fedramp_low_rev_4 = "true"
fedramp_moderate_rev_4 = "true"
ffiec = "true"
gxp_21_cfr_part_11 = "true"
gxp_eu_annex_11 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
hipaa_security_rule_2003 = "true"
nist_800_171_rev_2 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
rbi_itf_nbfc = "true"
soc_2 = "true"
})
}
control "rds_db_instance_protected_by_backup_plan" {
title = "RDS DB instance should be protected by backup plan"
description = "Ensure that AWS Relational Database Service (AWS RDS) instances are protected by a backup plan. The rule is non-compliant if the AWS RDS Database instance is not covered by a backup plan."
query = query.rds_db_instance_protected_by_backup_plan
tags = merge(local.conformance_pack_rds_common_tags, {
fedramp_low_rev_4 = "true"
fedramp_moderate_rev_4 = "true"
ffiec = "true"
gxp_21_cfr_part_11 = "true"
gxp_eu_annex_11 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
hipaa_security_rule_2003 = "true"
nist_800_171_rev_2 = "true"
nist_800_53_rev_5 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
soc_2 = "true"
})
}
control "rds_db_instance_automatic_minor_version_upgrade_enabled" {
title = "RDS DB instance automatic minor version upgrade should be enabled"
description = "Ensure that AWS Relational Database Service (RDS) database instances are configured for automatic minor version upgrades. The rule is non-compliant if the value of 'autoMinorVersionUpgrade' is false."
query = query.rds_db_instance_automatic_minor_version_upgrade_enabled
tags = merge(local.conformance_pack_rds_common_tags, {
cisa_cyber_essentials = "true"
ffiec = "true"
nist_csf = "true"
pci_dss_v321 = "true"
rbi_cyber_security = "true"
rbi_itf_nbfc = "true"
})
}
control "rds_db_cluster_deletion_protection_enabled" {
title = "RDS clusters should have deletion protection enabled"
description = "This control checks whether RDS clusters have deletion protection enabled. This control is intended for RDS DB instances. However, it can also generate findings for Aurora DB instances, Neptune DB instances, and AWS DocumentDB clusters. If these findings are not useful,then you can suppress them."
severity = "low"
query = query.rds_db_cluster_deletion_protection_enabled
tags = merge(local.conformance_pack_rds_common_tags, {
nist_csf = "true"
})
}
control "rds_db_instance_cloudwatch_logs_enabled" {
title = "RDS DB instances should be integrated with CloudWatch logs"
description = "Use AWS CloudWatch to centrally collect and manage RDS DB instance activity."
query = query.rds_db_instance_cloudwatch_logs_enabled
tags = local.conformance_pack_rds_common_tags
}
control "rds_db_instance_ca_certificate_expires_7_days" {
title = "RDS DB instances CA certificates should not expire within next 7 days"
description = "Ensure RDS DB instances CA certificates are not getting expired within the next 7 days."
query = query.rds_db_instance_ca_certificate_expires_7_days
tags = local.conformance_pack_rds_common_tags
}
control "rds_db_instance_no_default_admin_name" {
title = "RDS database instances should use a custom administrator username"
description = "This control checks whether you've changed the administrative username for AWS Relational Database Service (AWS RDS) database instances from the default value. The control fails if the administrative username is set to the default value."
query = query.rds_db_instance_no_default_admin_name
tags = merge(local.conformance_pack_rds_common_tags, {
nist_csf = "true"
pci_dss_v321 = "true"
})
}
control "rds_db_cluster_no_default_admin_name" {
title = "RDS database clusters should use a custom administrator username"
description = "This control checks whether an AWS RDS database cluster has changed the admin username from its default value. This rule will fail if the admin username is set to the default value."
query = query.rds_db_cluster_no_default_admin_name
tags = merge(local.conformance_pack_rds_common_tags, {
nist_csf = "true"
pci_dss_v321 = "true"
})
}
control "rds_db_cluster_aurora_backtracking_enabled" {
title = "RDS Aurora clusters should have backtracking enabled"
description = "This control checks whether AWS Aurora clusters have backtracking enabled. Backups help you to recover more quickly from a security incident. They also strengthen the resilience of your systems. Aurora backtracking reduces the time to recover a database to a point in time. It does not require a database restore to so."
query = query.rds_db_cluster_aurora_backtracking_enabled
tags = merge(local.conformance_pack_rds_common_tags, {
nist_csf = "true"
})
}
control "rds_db_cluster_multiple_az_enabled" {
title = "RDS DB clusters should be configured for multiple Availability Zones"
description = "This control checks whether high availability is enabled for your RDS DB clusters. RDS DB clusters should be configured for multiple Availability Zones to ensure availability of the data that is stored."
query = query.rds_db_cluster_multiple_az_enabled
tags = merge(local.conformance_pack_rds_common_tags, {
nist_csf = "true"
})
}
control "rds_db_instance_connections_encryption_enabled" {
title = "RDS DB instances connections should be encrypted"
description = "This control checks if RDS DB instance connections are encrypted. Secure Sockets Layer (SSL) is used to encrypt between client applications and AWS RDS DB instances running Microsoft SQL Server or PostgreSQL."
query = query.rds_db_instance_connections_encryption_enabled
tags = local.conformance_pack_rds_common_tags
}
control "rds_db_cluster_aurora_postgres_not_exposed_to_local_file_read_vulnerability" {
title = "RDS Aurora PostgreSQL clusters should not be exposed to local file read vulnerability"
description = "This control checks whether AWS Aurora PostgreSQL clusters are exposed to local file read vulnerability by ensuring that AWS RDS PostgreSQL instances use a non-vulnerable version of the log_fdw."
query = query.rds_db_cluster_aurora_postgres_not_exposed_to_local_file_read_vulnerability
tags = local.conformance_pack_rds_common_tags
}
control "rds_db_cluster_encrypted_with_cmk" {
title = "RDS DB clusters should be encrypted with CMK"
description = "Ensure RDS DB cluster is encrypted using CMK. The rule is non-compliant if the RDS DB cluster is not encrypted using CMK."
query = query.rds_db_cluster_encrypted_with_cmk
tags = local.conformance_pack_rds_common_tags
}
control "rds_db_instance_backup_retention_period_less_than_7" {
title = "RDS DB instances backup retention period should be greater than or equal to 7"
description = "Ensure RDS DB instance backup retention period is greater than or equal to 7."
query = query.rds_db_instance_backup_retention_period_less_than_7
tags = local.conformance_pack_rds_common_tags
}
control "rds_db_instance_no_public_subnet" {
title = "RDS DB instances should not use public subnet"
description = "This control checks if RDS DB instance is configured with public subnet as there is a risk of exposing sensitive data."
query = query.rds_db_instance_no_public_subnet
tags = local.conformance_pack_rds_common_tags
}
control "rds_db_instance_postgres_not_exposed_to_local_file_read_vulnerability" {
title = "RDS PostgreSQL DB instances should not be exposed to local file read vulnerability"
description = "This control checks whether AWS PostgreSQL DB isntance are exposed to local file read vulnerability by ensuring that AWS RDS PostgreSQL instances use a non-vulnerable version of the log_fdw."
query = query.rds_db_instance_postgres_not_exposed_to_local_file_read_vulnerability
tags = local.conformance_pack_rds_common_tags
}
control "rds_db_cluster_automatic_minor_version_upgrade_enabled" {
title = "RDS DB clusters should have automatic minor version upgrade enabled"
description = "This control checks if automatic minor version upgrade is enabled for an Amazon RDS database cluster. The control fails if automatic minor version upgrade isn't enabled for an RDS cluster."
query = query.rds_db_cluster_automatic_minor_version_upgrade_enabled
tags = local.foundational_security_rds_common_tags
}
control "rds_db_cluster_aurora_mysql_audit_logging_enabled" {
title = "Aurora MySQL DB clusters should publish audit logs to CloudWatch Logs"
description = "This control checks whether an Amazon Aurora MySQL DB cluster is configured to publish audit logs to Amazon CloudWatch Logs. The control fails if the cluster isn't configured to publish audit logs to CloudWatch Logs."
query = query.rds_db_cluster_aurora_mysql_audit_logging_enabled
tags = local.foundational_security_rds_common_tags
}
query "rds_db_instance_backup_enabled" {
sql = <<-EOQ
select
arn as resource,
case
when backup_retention_period < 1 then 'alarm'
else 'ok'
end as status,
case
when backup_retention_period < 1 then title || ' backups not enabled.'
else title || ' backups enabled.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_rds_db_instance;
EOQ
}
query "rds_db_instance_backup_retention_period_less_than_7" {
sql = <<-EOQ
select
arn as resource,
case
when backup_retention_period < 7 then 'alarm'
else 'ok'
end as status,
title || ' backup retention period set to ' || backup_retention_period || '.' as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_rds_db_instance;
EOQ
}
query "rds_db_instance_encryption_at_rest_enabled" {
sql = <<-EOQ
select
arn as resource,
case
when storage_encrypted then 'ok'
else 'alarm'
end as status,
case
when storage_encrypted then title || ' encrypted at rest.'
else title || ' not encrypted at rest.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_rds_db_instance;
EOQ
}
query "rds_db_instance_multiple_az_enabled" {
sql = <<-EOQ
select
arn as resource,
case
when engine ilike any (array ['%aurora-mysql%', '%aurora-postgres%']) then 'skip'
when multi_az then 'ok'
else 'alarm'
end as status,
case
when engine ilike any (array ['%aurora-mysql%', '%aurora-postgres%']) then title || ' cluster instance.'
when multi_az then title || ' Multi-AZ enabled.'
else title || ' Multi-AZ disabled.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_rds_db_instance;
EOQ
}
query "rds_db_instance_prohibit_public_access" {
sql = <<-EOQ
select
arn as resource,
case
when publicly_accessible then 'alarm'
else 'ok'
end status,
case
when publicly_accessible then title || ' publicly accessible.'
else title || ' not publicly accessible.'
end reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_rds_db_instance;
EOQ
}
query "rds_db_snapshot_encrypted_at_rest" {
sql = <<-EOQ
(
select
arn as resource,
case
when storage_encrypted then 'ok'
else 'alarm'
end as status,
case
when storage_encrypted then title || ' encrypted at rest.'
else title || ' not encrypted at rest.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_rds_db_cluster_snapshot
)
union
(
select
arn as resource,
case
when encrypted then 'ok'
else 'alarm'
end as status,
case
when encrypted then title || ' encrypted at rest.'
else title || ' not encrypted at rest.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_rds_db_snapshot
);
EOQ
}
query "rds_db_snapshot_prohibit_public_access" {
sql = <<-EOQ
(
select
arn as resource,
case
when cluster_snapshot -> 'AttributeValues' = '["all"]' then 'alarm'
else 'ok'
end status,
case
when cluster_snapshot -> 'AttributeValues' = '["all"]' then title || ' publicly restorable.'
else title || ' not publicly restorable.'
end reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_rds_db_cluster_snapshot,
jsonb_array_elements(db_cluster_snapshot_attributes) as cluster_snapshot
)
union
(
select
arn as resource,
case
when database_snapshot -> 'AttributeValues' = '["all"]' then 'alarm'
else 'ok'
end status,
case
when database_snapshot -> 'AttributeValues' = '["all"]' then title || ' publicly restorable.'
else title || ' not publicly restorable.'
end reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_rds_db_snapshot,
jsonb_array_elements(db_snapshot_attributes) as database_snapshot
);
EOQ
}
query "rds_db_instance_logging_enabled" {
sql = <<-EOQ
select
arn as resource,
case
when engine = 'docdb' then 'skip'
when engine like any (array ['mariadb', '%mysql']) and enabled_cloudwatch_logs_exports ?& array ['audit','error','general','slowquery'] then 'ok'
when engine like any (array['%postgres%']) and enabled_cloudwatch_logs_exports ?& array ['postgresql','upgrade'] then 'ok'
when engine like 'oracle%' and enabled_cloudwatch_logs_exports ?& array ['alert','audit', 'trace','listener'] then 'ok'
when engine = 'sqlserver-ex' and enabled_cloudwatch_logs_exports ?& array ['error'] then 'ok'
when engine like 'sqlserver%' and enabled_cloudwatch_logs_exports ?& array ['error','agent'] then 'ok'
else 'alarm'
end as status,
case
when engine = 'docdb' then title || ' is docdb instance.'
when engine like any (array ['mariadb', '%mysql']) and enabled_cloudwatch_logs_exports ?& array ['audit','error','general','slowquery']
then title || ' ' || engine || ' logging enabled.'
when engine like any (array['%postgres%']) and enabled_cloudwatch_logs_exports ?& array ['postgresql','upgrade']
then title || ' ' || engine || ' logging enabled.'
when engine like 'oracle%' and enabled_cloudwatch_logs_exports ?& array ['alert','audit', 'trace','listener']
then title || ' ' || engine || ' logging enabled.'
when engine = 'sqlserver-ex' and enabled_cloudwatch_logs_exports ?& array ['error']
then title || ' ' || engine || ' logging enabled.'
when engine like 'sqlserver%' and enabled_cloudwatch_logs_exports ?& array ['error','agent']
then title || ' ' || engine || ' logging enabled.'
else title || ' logging not enabled.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_rds_db_instance;
EOQ
}
query "rds_db_instance_in_backup_plan" {
sql = <<-EOQ
with mapped_with_id as (
select
jsonb_agg(elems) as mapped_ids
from
aws_backup_selection,
jsonb_array_elements(resources) as elems
group by backup_plan_id
),
mapped_with_tags as (
select
jsonb_agg(elems ->> 'ConditionKey') as mapped_tags
from
aws_backup_selection,
jsonb_array_elements(list_of_tags) as elems
group by backup_plan_id
),
backed_up_instance as (
select
i.db_instance_identifier
from
aws_rds_db_instance as i
join mapped_with_id as t on t.mapped_ids ?| array[i.arn]
union
select
i.db_instance_identifier
from
aws_rds_db_instance as i
join mapped_with_tags as t on t.mapped_tags ?| array(select jsonb_object_keys(tags))
)
select
i.arn as resource,
case
when b.db_instance_identifier is null then 'alarm'
else 'ok'
end as status,
case
when b.db_instance_identifier is null then i.title || ' not in backup plan.'
else i.title || ' in backup plan.'
end as reason
${local.tag_dimensions_sql}
${replace(local.common_dimensions_qualifier_sql, "__QUALIFIER__", "i.")}
from
aws_rds_db_instance as i
left join backed_up_instance as b on i.db_instance_identifier = b.db_instance_identifier;
EOQ
}
query "rds_db_instance_and_cluster_enhanced_monitoring_enabled" {
sql = <<-EOQ
(
select
arn as resource,
case
when enabled_cloudwatch_logs_exports is not null then 'ok'
else 'alarm'
end as status,
case
when enabled_cloudwatch_logs_exports is not null then title || ' enhanced monitoring enabled.'
else title || ' enhanced monitoring not enabled.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_rds_db_cluster
)
union
(
select
arn as resource,
case
when class = 'db.m1.small' then 'skip'
when enhanced_monitoring_resource_arn is not null then 'ok'
else 'alarm'
end as status,
case
when class = 'db.m1.small' then title || ' enhanced monitoring not supported.'
when enhanced_monitoring_resource_arn is not null then title || ' enhanced monitoring enabled.'
else title || ' enhanced monitoring not enabled.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_rds_db_instance
);
EOQ
}
query "rds_db_instance_deletion_protection_enabled" {
sql = <<-EOQ
select
arn as resource,
case
when engine like any(array['aurora%', 'docdb', 'neptune']) then 'skip'
when deletion_protection then 'ok'
else 'alarm'
end status,
case
when engine like any(array['aurora%', 'docdb', 'neptune']) then title || ' has engine ' || engine || ' cluster, deletion protection is set at cluster level.'
when deletion_protection then title || ' deletion protection enabled.'
else title || ' deletion protection not enabled.'
end reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_rds_db_instance;
EOQ
}
query "rds_db_instance_iam_authentication_enabled" {
sql = <<-EOQ
select
arn as resource,
case
when iam_database_authentication_enabled then 'ok'
else 'alarm'
end as status,
case
when iam_database_authentication_enabled then title || ' IAM authentication enabled.'
else title || ' IAM authentication not enabled.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_rds_db_instance;
EOQ
}
query "rds_db_cluster_iam_authentication_enabled" {
sql = <<-EOQ
select
arn as resource,
case
when iam_database_authentication_enabled then 'ok'
else 'alarm'
end as status,
case
when iam_database_authentication_enabled then title || ' IAM authentication enabled.'
else title || ' IAM authentication not enabled.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_rds_db_cluster;
EOQ
}
query "rds_db_cluster_aurora_protected_by_backup_plan" {
sql = <<-EOQ
with backup_protected_cluster as (
select
resource_arn as arn
from
aws_backup_protected_resource as b
where
resource_type = 'Aurora'
)
select
c.arn as resource,
case
when c.engine not like '%aurora%' then 'skip'
when b.arn is not null then 'ok'
else 'alarm'
end as status,
case
when c.engine not like '%aurora%' then c.title || ' not Aurora resources.'
when b.arn is not null then c.title || ' is protected by backup plan.'
else c.title || ' is not protected by backup plan.'
end as reason
${local.tag_dimensions_sql}
${replace(local.common_dimensions_qualifier_sql, "__QUALIFIER__", "c.")}
from
aws_rds_db_cluster as c
left join backup_protected_cluster as b on c.arn = b.arn;
EOQ
}
query "rds_db_instance_protected_by_backup_plan" {
sql = <<-EOQ
with backup_protected_rds_isntance as (
select
resource_arn as arn
from
aws_backup_protected_resource as b
where
resource_type = 'RDS'
)
select
r.arn as resource,
case
when b.arn is not null then 'ok'
else 'alarm'
end as status,
case
when b.arn is not null then r.title || ' is protected by backup plan.'
else r.title || ' is not protected by backup plan.'
end as reason
${local.tag_dimensions_sql}
${replace(local.common_dimensions_qualifier_sql, "__QUALIFIER__", "r.")}
from
aws_rds_db_instance as r
left join backup_protected_rds_isntance as b on r.arn = b.arn;
EOQ
}
query "rds_db_instance_automatic_minor_version_upgrade_enabled" {
sql = <<-EOQ
select
arn as resource,
case
when auto_minor_version_upgrade then 'ok'
else 'alarm'
end as status,
case
when auto_minor_version_upgrade then title || ' automatic minor version upgrades enabled.'
else title || ' automatic minor version upgrades not enabled.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_rds_db_instance;
EOQ
}
query "rds_db_cluster_deletion_protection_enabled" {
sql = <<-EOQ
select
db_cluster_identifier as resource,
case
when deletion_protection then 'ok'
else 'alarm'
end as status,
case
when deletion_protection then title || ' deletion protection enabled.'
else title || ' deletion protection not enabled.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_rds_db_cluster;
EOQ
}
query "rds_db_instance_cloudwatch_logs_enabled" {
sql = <<-EOQ
select
arn as resource,
case
when enabled_cloudwatch_logs_exports is not null then 'ok'
else 'alarm'
end as status,
case
when enabled_cloudwatch_logs_exports is not null then title || ' integrated with CloudWatch logs.'
else title || ' not integrated with CloudWatch logs.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_rds_db_instance;