/
cloudfront.sp
594 lines (546 loc) · 23.7 KB
/
cloudfront.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
locals {
conformance_pack_cloudfront_common_tags = merge(local.aws_compliance_common_tags, {
service = "AWS/CloudFront"
})
}
control "cloudfront_distribution_no_non_existent_s3_origin" {
title = "CloudFront distributions should not point to non-existent S3 origins"
description = "This control checks whether AWS CloudFront distributions are pointing to non-existent AWS S3 origins. The control fails for a CloudFront distribution if the origin is configured to point to a non-existent bucket. This control only applies to CloudFront distributions where an S3 bucket without static website hosting is the S3 origin."
query = query.cloudfront_distribution_no_non_existent_s3_origin
tags = local.conformance_pack_cloudfront_common_tags
}
control "cloudfront_distribution_encryption_in_transit_enabled" {
title = "CloudFront distributions should require encryption in transit"
description = "This control checks whether an AWS CloudFront distribution requires viewers to use HTTPS directly or whether it uses redirection. The control fails if ViewerProtocolPolicy is set to allow-all for defaultCacheBehavior or for cacheBehaviors."
query = query.cloudfront_distribution_encryption_in_transit_enabled
tags = merge(local.conformance_pack_cloudfront_common_tags, {
gdpr = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
hipaa_security_rule_2003 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
soc_2 = "true"
})
}
control "cloudfront_distribution_geo_restrictions_enabled" {
title = "CloudFront distributions should have geo restriction enabled"
description = "Geographic restriction is used to restrict access to all of the files that are associated with a distribution at the country level."
query = query.cloudfront_distribution_geo_restrictions_enabled
tags = local.conformance_pack_cloudfront_common_tags
}
control "cloudfront_distribution_use_secure_cipher" {
title = "CloudFront distributions should use secure SSL cipher"
description = "Ensure that CloudFront distributions do not have any insecure SSL ciphers. Using insecure and deprecated ciphers could make the SSL connection between the CloudFront and the origins vulnerable to exploits."
query = query.cloudfront_distribution_use_secure_cipher
tags = local.conformance_pack_cloudfront_common_tags
}
control "cloudfront_distribution_non_s3_origins_encryption_in_transit_enabled" {
title = "CloudFront distributions should encrypt traffic to non S3 origins"
description = "This control ensures that conection between cloudfront and oriign server is encrypted. It is recommended to enforce HTTPS-only traffic between a CloudFront distribution and the origin."
query = query.cloudfront_distribution_non_s3_origins_encryption_in_transit_enabled
tags = local.conformance_pack_cloudfront_common_tags
}
control "cloudfront_distribution_no_deprecated_ssl_protocol" {
title = "CloudFront distributions should not use deprecated SSL protocols between edge locations and custom origins"
description = "This control checks if AWS CloudFront distributions are using deprecated SSL protocols for HTTPS communication between CloudFront edge locations and your custom origins. This control fails if a CloudFront distribution has a CustomOriginConfig where OriginSslProtocols includes SSLv3."
query = query.cloudfront_distribution_no_deprecated_ssl_protocol
tags = merge(local.conformance_pack_cloudfront_common_tags, {
gxp_21_cfr_part_11 = "true"
gxp_eu_annex_11 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
})
}
control "cloudfront_distribution_custom_origins_encryption_in_transit_enabled" {
title = "CloudFront distributions should encrypt traffic to custom origins"
description = "This control checks if AWS CloudFront distributions are encrypting traffic to custom origins. This control fails for a CloudFront distribution whose origin protocol policy allows 'http-only'. This control also fails if the distribution's origin protocol policy is 'match-viewer' while the viewer protocol policy is 'allow-all'."
query = query.cloudfront_distribution_custom_origins_encryption_in_transit_enabled
tags = merge(local.conformance_pack_cloudfront_common_tags, {
gxp_21_cfr_part_11 = "true"
gxp_eu_annex_11 = "true"
nist_csf = "true"
pci_dss_v321 = "true"
})
}
control "cloudfront_distribution_logging_enabled" {
title = "CloudFront distributions access logs should be enabled"
description = "This control checks if AWS CloudFront distributions are configured to capture information from AWS Simple Storage Service (AWS S3) server access logs. This rule is non-compliant if a CloudFront distribution does not have logging configured."
query = query.cloudfront_distribution_logging_enabled
tags = merge(local.conformance_pack_cloudfront_common_tags, {
cis_controls_v8_ig1 = "true"
hipaa_final_omnibus_security_rule_2013 = "true"
hipaa_security_rule_2003 = "true"
nist_csf = "true"
})
}
control "cloudfront_distribution_sni_enabled" {
title = "CloudFront distributions should use SNI to serve HTTPS requests"
description = "This control checks if AWS CloudFront distributions are using a custom SSL/TLS certificate and are configured to use SNI to serve HTTPS requests. This control fails if a custom SSL/TLS certificate is associated but the SSL/TLS support method is a dedicated IP address."
query = query.cloudfront_distribution_sni_enabled
tags = merge(local.conformance_pack_cloudfront_common_tags, {
nist_csf = "true"
})
}
control "cloudfront_distribution_waf_enabled" {
title = "CloudFront distributions should have AWS WAF enabled"
description = "This control checks whether CloudFront distributions are associated with either AWS WAF or AWS WAFv2 web ACLs. The control fails if the distribution is not associated with a web ACL."
query = query.cloudfront_distribution_waf_enabled
tags = merge(local.conformance_pack_cloudfront_common_tags, {
nist_csf = "true"
})
}
control "cloudfront_distribution_configured_with_origin_failover" {
title = "CloudFront distributions should have origin failover configured"
description = "This control checks whether an AWS CloudFront distribution is configured with an origin group that has two or more origins. CloudFront origin failover can increase availability. Origin failover automatically redirects traffic to a secondary origin if the primary origin is unavailable or if it returns specific HTTP response status codes."
query = query.cloudfront_distribution_configured_with_origin_failover
tags = merge(local.conformance_pack_cloudfront_common_tags, {
nist_csf = "true"
})
}
control "cloudfront_distribution_default_root_object_configured" {
title = "CloudFront distributions should have a default root object configured"
description = "This control checks whether an AWS CloudFront distribution is configured to return a specific object that is the default root object. The control fails if the CloudFront distribution does not have a default root object configured."
query = query.cloudfront_distribution_default_root_object_configured
tags = merge(local.conformance_pack_cloudfront_common_tags, {
nist_csf = "true"
})
}
control "cloudfront_distribution_use_custom_ssl_certificate" {
title = "CloudFront distributions should use custom SSL/TLS certificates"
description = "This control checks whether CloudFront distributions are using the default SSL/TLS certificate CloudFront provides. This control passes if the CloudFront distribution uses a custom SSL/TLS certificate. This control fails if the CloudFront distribution uses the default SSL/TLS certificate."
query = query.cloudfront_distribution_use_custom_ssl_certificate
tags = merge(local.conformance_pack_cloudfront_common_tags, {
nist_csf = "true"
})
}
control "cloudfront_distribution_origin_access_identity_enabled" {
title = "CloudFront distributions should have origin access identity enabled"
description = "This control checks whether an AWS CloudFront distribution with AWS S3 Origin type has Origin Access Identity (OAI) configured. The control fails if OAI is not configured."
query = query.cloudfront_distribution_origin_access_identity_enabled
tags = merge(local.conformance_pack_cloudfront_common_tags, {
nist_csf = "true"
})
}
control "cloudfront_distribution_field_level_encryption_enabled" {
title = "CloudFront distributions should have field level encryption enabled"
description = "This control checks whether an AWS CloudFront distribution has field-level encryption enabled. The control fails if CloudFront distribution field-level encryption is not enabled."
query = query.cloudfront_distribution_field_level_encryption_enabled
tags = local.conformance_pack_cloudfront_common_tags
}
control "cloudfront_distribution_latest_tls_version" {
title = "CloudFront distributions should have latest TLS version"
description = "This control checks whether CloudFront distribution uses latest TLS version."
query = query.cloudfront_distribution_latest_tls_version
tags = local.conformance_pack_cloudfront_common_tags
}
query "cloudfront_distribution_encryption_in_transit_enabled" {
sql = <<-EOQ
with data as (
select
distinct arn
from
aws_cloudfront_distribution,
jsonb_array_elements(
case jsonb_typeof(cache_behaviors -> 'Items')
when 'array' then (cache_behaviors -> 'Items')
else null end
) as cb
where
cb ->> 'ViewerProtocolPolicy' = 'allow-all'
)
select
b.arn as resource,
case
when d.arn is not null or (default_cache_behavior ->> 'ViewerProtocolPolicy' = 'allow-all') then 'alarm'
else 'ok'
end as status,
case
when d.arn is not null or (default_cache_behavior ->> 'ViewerProtocolPolicy' = 'allow-all') then title || ' data not encrypted in transit.'
else title || ' data encrypted in transit.'
end as reason
${local.tag_dimensions_sql}
${replace(local.common_dimensions_qualifier_sql, "__QUALIFIER__", "b.")}
from
aws_cloudfront_distribution as b
left join data as d on b.arn = d.arn;
EOQ
}
query "cloudfront_distribution_geo_restrictions_enabled" {
sql = <<-EOQ
select
arn as resource,
case
when restrictions -> 'GeoRestriction' ->> 'RestrictionType' = 'none' then 'alarm'
else 'ok'
end as status,
case
when restrictions -> 'GeoRestriction' ->> 'RestrictionType' = 'none' then title || ' Geo Restriction disabled.'
else title || ' Geo Restriction enabled.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_cloudfront_distribution;
EOQ
}
query "cloudfront_distribution_use_secure_cipher" {
sql = <<-EOQ
with origin_protocols as (
select
distinct arn,
o -> 'CustomOriginConfig' ->> 'OriginSslProtocols' as origin_ssl_policy
from
aws_cloudfront_distribution,
jsonb_array_elements(origins) as o
where
o -> 'CustomOriginConfig' -> 'OriginSslProtocols' -> 'Items' @> '["TLSv1.2%", "TLSv1.1%"]'
)
select
b.arn as resource,
case
when o.arn is not null then 'ok'
else 'alarm'
end as status,
case
when o.arn is not null then title || ' use secure cipher.'
else title || ' does not use secure cipher.'
end as reason
${local.tag_dimensions_sql}
${replace(local.common_dimensions_qualifier_sql, "__QUALIFIER__", "b.")}
from
aws_cloudfront_distribution as b
left join origin_protocols as o on b.arn = o.arn;
EOQ
}
query "cloudfront_distribution_non_s3_origins_encryption_in_transit_enabled" {
sql = <<-EOQ
with viewer_protocol_policy_value as (
select
distinct arn
from
aws_cloudfront_distribution,
jsonb_array_elements(
case jsonb_typeof(cache_behaviors -> 'Items')
when 'array' then (cache_behaviors -> 'Items')
else null end
) as cb
where
cb ->> 'ViewerProtocolPolicy' = 'allow-all'
),
origin_protocol_policy_value as (
select
distinct arn,
o -> 'CustomOriginConfig' ->> 'OriginProtocolPolicy' as origin_protocol_policy
from
aws_cloudfront_distribution,
jsonb_array_elements(origins) as o
where
o -> 'CustomOriginConfig' ->> 'OriginProtocolPolicy' = 'http-only'
or o -> 'CustomOriginConfig' ->> 'OriginProtocolPolicy' = 'match-viewer'
and o -> 'S3OriginConfig' is null
)
select
b.arn as resource,
case
when o.arn is not null and o.origin_protocol_policy = 'http-only' then 'alarm'
when o.arn is not null and o.origin_protocol_policy = 'match-viewer' and ( v.arn is not null or (default_cache_behavior ->> 'ViewerProtocolPolicy' = 'allow-all') ) then 'alarm'
else 'ok'
end as status,
case
when o.arn is not null and o.origin_protocol_policy = 'http-only' then title || ' origins traffic not encrypted in transit.'
when o.arn is not null and o.origin_protocol_policy = 'match-viewer' and ( v.arn is not null or (default_cache_behavior ->> 'ViewerProtocolPolicy' = 'allow-all') ) then title || ' origins traffic not encrypted in transit.'
else title || ' origins traffic encrypted in transit.'
end as reason
${local.tag_dimensions_sql}
${replace(local.common_dimensions_qualifier_sql, "__QUALIFIER__", "b.")}
from
aws_cloudfront_distribution as b
left join origin_protocol_policy_value as o on b.arn = o.arn
left join viewer_protocol_policy_value as v on b.arn = v.arn;
EOQ
}
query "cloudfront_distribution_no_deprecated_ssl_protocol" {
sql = <<-EOQ
with origin_ssl_protocols as (
select
distinct arn,
o -> 'CustomOriginConfig' ->> 'OriginProtocolPolicy' as origin_protocol_policy
from
aws_cloudfront_distribution,
jsonb_array_elements(origins) as o
where
o -> 'CustomOriginConfig' -> 'OriginSslProtocols' -> 'Items' @> '["SSLv3"]'
)
select
b.arn as resource,
case
when o.arn is null then 'ok'
else 'alarm'
end as status,
case
when o.arn is null then title || ' does not have deprecated SSL protocols.'
else title || ' has deprecated SSL protocols.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_cloudfront_distribution as b
left join origin_ssl_protocols as o on b.arn = o.arn;
EOQ
}
query "cloudfront_distribution_custom_origins_encryption_in_transit_enabled" {
sql = <<-EOQ
with viewer_protocol_policy_value as (
select
distinct arn
from
aws_cloudfront_distribution,
jsonb_array_elements(
case jsonb_typeof(cache_behaviors -> 'Items')
when 'array' then (cache_behaviors -> 'Items')
else null end
) as cb
where
cb ->> 'ViewerProtocolPolicy' = 'allow-all'
),
origin_protocol_policy_value as (
select
distinct arn,
o -> 'CustomOriginConfig' ->> 'OriginProtocolPolicy' as origin_protocol_policy
from
aws_cloudfront_distribution,
jsonb_array_elements(origins) as o
where
o -> 'CustomOriginConfig' ->> 'OriginProtocolPolicy' = 'http-only'
or o -> 'CustomOriginConfig' ->> 'OriginProtocolPolicy' = 'match-viewer'
)
select
b.arn as resource,
case
when o.arn is not null and o.origin_protocol_policy = 'http-only' then 'alarm'
when o.arn is not null and o.origin_protocol_policy = 'match-viewer' and ( v.arn is not null or (default_cache_behavior ->> 'ViewerProtocolPolicy' = 'allow-all') ) then 'alarm'
else 'ok'
end as status,
case
when o.arn is not null and o.origin_protocol_policy = 'http-only' then title || ' custom origins traffic not encrypted in transit.'
when o.arn is not null and o.origin_protocol_policy = 'match-viewer' and ( v.arn is not null or (default_cache_behavior ->> 'ViewerProtocolPolicy' = 'allow-all') ) then title || ' custom origins traffic not encrypted in transit.'
else title || ' custom origins traffic encrypted in transit.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_cloudfront_distribution as b
left join origin_protocol_policy_value as o on b.arn = o.arn
left join viewer_protocol_policy_value as v on b.arn = v.arn;
EOQ
}
query "cloudfront_distribution_logging_enabled" {
sql = <<-EOQ
select
arn as resource,
case
when logging ->> 'Enabled' = 'true' then 'ok'
else 'alarm'
end as status,
case
when logging ->> 'Enabled' = 'true' then title || ' logging enabled.'
else title || ' logging disabled.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_cloudfront_distribution;
EOQ
}
query "cloudfront_distribution_sni_enabled" {
sql = <<-EOQ
select
arn as resource,
case
when viewer_certificate ->> 'SSLSupportMethod' = 'sni-only' then 'ok'
else 'alarm'
end as status,
case
when viewer_certificate ->> 'SSLSupportMethod' = 'sni-only' then title || ' SNI enabled.'
else title || ' SNI disabled.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_cloudfront_distribution;
EOQ
}
query "cloudfront_distribution_waf_enabled" {
sql = <<-EOQ
select
arn as resource,
case
when web_acl_id <> '' then 'ok'
else 'alarm'
end as status,
case
when web_acl_id <> '' then title || ' associated with WAF.'
else title || ' not associated with WAF.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_cloudfront_distribution;
EOQ
}
query "cloudfront_distribution_configured_with_origin_failover" {
sql = <<-EOQ
select
arn as resource,
case
when origin_groups ->> 'Items' is not null then 'ok'
else 'alarm'
end as status,
case
when origin_groups ->> 'Items' is not null then title || ' origin group is configured.'
else title || ' origin group not configured.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_cloudfront_distribution;
EOQ
}
query "cloudfront_distribution_default_root_object_configured" {
sql = <<-EOQ
select
arn as resource,
case
when default_root_object = '' then 'alarm'
else 'ok'
end as status,
case
when default_root_object = '' then title || ' default root object not configured.'
else title || ' default root object configured.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_cloudfront_distribution;
EOQ
}
query "cloudfront_distribution_use_custom_ssl_certificate" {
sql = <<-EOQ
select
arn as resource,
case
when viewer_certificate ->> 'ACMCertificateArn' is not null and viewer_certificate ->> 'Certificate' is not null then 'ok'
else 'alarm'
end as status,
case
when viewer_certificate ->> 'ACMCertificateArn' is not null and viewer_certificate ->> 'Certificate' is not null then title || ' uses custom SSL certificate.'
else title || ' does not use custom SSL certificate.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_cloudfront_distribution;
EOQ
}
query "cloudfront_distribution_origin_access_identity_enabled" {
sql = <<-EOQ
select
arn as resource,
case
when o ->> 'DomainName' not like '%s3.amazonaws.com' then 'skip'
when o ->> 'DomainName' like '%s3.amazonaws.com'
and o -> 'S3OriginConfig' ->> 'OriginAccessIdentity' = '' then 'alarm'
else 'ok'
end as status,
case
when o ->> 'DomainName' not like '%s3.amazonaws.com' then title || ' origin type is not s3.'
when o ->> 'DomainName' like '%s3.amazonaws.com'
and o -> 'S3OriginConfig' ->> 'OriginAccessIdentity' = '' then title || ' origin access identity not configured.'
else title || ' origin access identity configured.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_cloudfront_distribution,
jsonb_array_elements(origins) as o;
EOQ
}
query "cloudfront_distribution_field_level_encryption_enabled" {
sql = <<-EOQ
select
arn as resource,
case
when default_cache_behavior ->> 'FieldLevelEncryptionId' = '' then 'alarm'
else 'ok'
end as status,
case
when default_cache_behavior ->> 'FieldLevelEncryptionId' = '' then title || ' field level encryption disabled.'
else title || ' field level encryption enabled.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_cloudfront_distribution;
EOQ
}
query "cloudfront_distribution_no_non_existent_s3_origin" {
sql = <<-EOQ
with distribution_with_non_existent_bucket as (
select
distinct d.arn as arn,
to_jsonb(string_to_array((string_agg(split_part(o ->> 'Id', '.s3', 1), ',')),',')) as bucket_name_list
from
aws_cloudfront_distribution as d,
jsonb_array_elements(d.origins) as o
left join aws_s3_bucket as b on b.name = split_part(o ->> 'Id', '.s3', 1)
where
b.name is null
and o ->> 'DomainName' like '%.s3.%'
group by
d.arn
)
select
distinct b.arn as resource,
case
when b.arn is null then 'ok'
else 'alarm'
end as status,
case
when b.arn is null then title || ' does not point to any non-existent S3 origins.'
when jsonb_array_length(b.bucket_name_list) > 0
then title ||
case
when jsonb_array_length(b.bucket_name_list) > 2
then concat(' point to non-existent S3 origins ', b.bucket_name_list #>> '{0}', ', ', b.bucket_name_list #>> '{1}', ' and ' || (jsonb_array_length(b.bucket_name_list) - 2)::text || ' more.' )
when jsonb_array_length(b.bucket_name_list) = 2
then concat(' point to non-existent S3 origins ', b.bucket_name_list #>> '{0}', ' and ', b.bucket_name_list #>> '{1}', '.')
else concat(' point to non-existent S3 origin ', b.bucket_name_list #>> '{0}', '.')
end
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_cloudfront_distribution as d
left join distribution_with_non_existent_bucket as b on b.arn = d.arn;
EOQ
}
query "cloudfront_distribution_latest_tls_version" {
sql = <<-EOQ
select
arn as resource,
case
when viewer_certificate ->> 'CertificateSource' = 'cloudfront'
and viewer_certificate ->> 'MinimumProtocolVersion' = 'TLSv1.2_2021' then 'ok'
else 'alarm'
end as status,
case
when viewer_certificate ->> 'CertificateSource' = 'cloudfront'
and viewer_certificate ->> 'MinimumProtocolVersion' = 'TLSv1.2_2021' then title || ' uses latest TLS version.'
else title || ' not uses latest TLS version.'
end as reason
${local.tag_dimensions_sql}
${local.common_dimensions_sql}
from
aws_cloudfront_distribution;
EOQ
}