Skip to content

Commit e409429

Browse files
darenjacobsclaude
andauthored
DND-1537: export RDS error/slowquery logs to CloudWatch, with retention (#69)
* DND-1537: export RDS error/slowquery logs to CloudWatch, with retention A fleet audit for DND-1537 found EnabledCloudwatchLogsExports null on all 16 STSaaS Aurora clusters. The module never had the attribute, so there was no per-env knob to set — this was not an oversight per environment. That gap blocked the CUST-6816 post-mortem: agentro is granted rds:DescribeDBLogFiles but not rds:DownloadDBLogFilePortion, so the investigation could see that the reader's error log was 254 KB in the failure hour against a ~100 KB/hour baseline, and could not read a byte of it. Exporting to CloudWatch Logs closes that without widening the read-only role. Adds: rds_enabled_cloudwatch_logs_exports default ["error", "slowquery"] rds_log_retention_days default 90 The log groups are created explicitly rather than left to RDS. RDS auto-creates /aws/rds/cluster/<id>/<type> at "never expire" the instant an export is enabled — that is how the pre-rebuild zoox slowquery group came to hold 3.65 GB of dead data indefinitely, and it would leave 16 clusters' worth of groups unmanaged and needing import. depends_on makes the ordering explicit so the groups exist, with retention, before the export switches on. Measured cost across the whole fleet: 0.093 GB/day of raw log generation, so ~$1.39/month ingestion and ~$1.47/month with 90-day retention. Note "slowquery" produces nothing until slow_query_log=1 is also set via rds_cluster_parameters, which is off on 15 of 16 clusters today. It is enabled here anyway so the group exists and is retention-managed from the moment that parameter is turned on. Enabling the parameter itself is deliberately not part of this change: the slow query log records full SQL text including literals, so it needs a data-governance decision for the regulated single-tenant customers first. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * DND-1537: keep log groups on disable; validate at the root too Review follow-ups on this PR. skip_destroy on the log groups. Dropping a type from rds_enabled_cloudwatch_logs_exports removes it from the for_each, which would otherwise destroy the group and every log in it — turning an export off must not delete the evidence already collected. The cost is that a real teardown leaves the groups behind, but they carry retention now and expire on their own, unlike the never-expire orphan DND-1537 had to clean up. Root-level validation on both variables. The inner module already validated them, so this is not a behaviour change; it surfaces a bad value at the env config rather than one layer deeper. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * DND-1537: decouple log-group lifecycle from the export list; add KMS + outputs Review findings from @jms200 on #69. 1. skip_destroy made disabling an export a one-way door. Dropping a type from rds_enabled_cloudwatch_logs_exports removed it from the for_each — gone from state, still in AWS — so re-enabling it later would fail on ResourceAlreadyExistsException. That is the same collision this change exists to prevent, deferred and self-inflicted, and it was introduced by the skip_destroy fix earlier in this PR rather than being in the original design. Fixed as suggested, by splitting the two lifecycles: the log groups now for_each over a new rds_managed_log_group_types, and rds_enabled_cloudwatch_logs_exports controls only the cluster attribute. Toggling an export is now purely a cluster modify and never touches group state. A type managed but not exported yields an empty group with retention already applied, which is exactly the desired state for slowquery on the 15 clusters where slow_query_log=0. skip_destroy stays as belt-and-braces. 2. Added rds_log_kms_key_id (default null, no behaviour change). The cluster and Performance Insights both take a key and the groups did not. Cheap now; after this reaches 16 clusters it means touching every env a second time, at exactly the moment slow_query_log=1 starts putting customer SQL text in these groups. Also what trivy AVD-AWS-0017 asks for. 3. Added mysql_log_group_names / mysql_log_group_arns outputs, at module and root. The rollout needs the names to build terraform import addresses for every cluster enabled out-of-band, and alarms and metric filters will want the ARNs. Also, from the Baz review: rds_log_retention_days no longer accepts 0. Never-expire is what RDS applies on its own and the reason DND-1537 found a 3.65 GB orphan; a module whose purpose is preventing that should not offer it. These groups carry customer SQL text once slow_query_log is on. 3653 days remains available. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * DND-1537: enforce exports subset of managed log groups; note KMS key policy Both non-blocking notes from @jms200's approving review. Cheap enough to take now rather than leave for DND-1549. Exporting a type with no managed log group hands group creation back to RDS, which makes it at never-expire — this module's own failure mode through a new door. Both variables default to the same list so it is correct out of the box, but by the same standard applied to retention 0, it should be unreachable rather than documented. Implemented as a lifecycle.precondition rather than a cross-variable validation block: the latter needs Terraform 1.9 and this repo's floor is >= 1.5.7. Also documents that a KMS key policy must grant logs.<region>.amazonaws.com before rds_log_kms_key_id can be set, since CreateLogGroup otherwise fails with InvalidParameterException, which reads like a terraform fault and is not. Default null means nobody hits this today. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * DND-1537: outputs say MANAGED, not exported; add mysql_exported_log_types Baz finding on b23500b, and a genuine defect I introduced: the outputs were added when the log groups were keyed by the export list, and their descriptions still said "for the exported RDS logs". Decoupling the two lifecycles made that false — they are keyed by rds_managed_log_group_types now, so `slowquery` appears in them on all 15 clusters where slow_query_log=0 and nothing is written. Keeping them keyed by managed types is correct for their primary purpose: import needs every group under management, including an empty one. So the fix is to say so, and to give consumers the filter they actually need — a metric filter or alarm attached to the slowquery group today would sit on a group nothing writes to. Adds mysql_exported_log_types (the cluster's live enabled_cloudwatch_logs_exports) at module and root, and rewords both existing outputs to state that they are a superset. Note a type can be exported and still produce nothing: slowquery stays empty until slow_query_log=1 is set via rds_cluster_parameters, which is DND-1549's problem 2. The output cannot express that, so both descriptions say it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent db26ec5 commit e409429

6 files changed

Lines changed: 212 additions & 1 deletion

File tree

‎main.tf‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,12 @@ module "comet_rds" {
440440
rds_performance_insights_kms_key_id = var.rds_performance_insights_kms_key_id
441441
rds_enhanced_monitoring_interval = var.rds_enhanced_monitoring_interval
442442

443+
# CloudWatch Logs export (DND-1537)
444+
rds_enabled_cloudwatch_logs_exports = var.rds_enabled_cloudwatch_logs_exports
445+
rds_managed_log_group_types = var.rds_managed_log_group_types
446+
rds_log_retention_days = var.rds_log_retention_days
447+
rds_log_kms_key_id = var.rds_log_kms_key_id
448+
443449
# Deletion protection
444450
rds_deletion_protection = var.rds_deletion_protection
445451

‎modules/comet_rds/main.tf‎

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
locals {
22
mysql_port = 3306
33
enhanced_monitoring_enabled = var.rds_enhanced_monitoring_interval > 0
4+
5+
# Named once so the CloudWatch log groups can be built from the same identifier the
6+
# cluster uses — the group names RDS writes to are /aws/rds/cluster/<id>/<type>, so a
7+
# drift between the two would silently leave the real groups unmanaged (DND-1537).
8+
rds_cluster_identifier = coalesce(var.rds_cluster_identifier, "cometml-rds-cluster-${var.environment}")
49
}
510

611
# IAM role for Enhanced Monitoring
@@ -67,8 +72,39 @@ resource "aws_rds_cluster_instance" "comet-ml-rds-mysql" {
6772
)
6873
}
6974

75+
# DND-1537: create the log groups ourselves, with retention, so they exist BEFORE the
76+
# export is switched on below. If RDS gets there first it creates them with no retention
77+
# ("never expire") and terraform then collides with an unmanaged resource — which is both
78+
# how the orphaned zoox slowquery group came to bill 3.65 GB indefinitely, and an import
79+
# nobody wants to do 16 times.
80+
resource "aws_cloudwatch_log_group" "rds_exported_logs" {
81+
# Driven by rds_managed_log_group_types, NOT by the export list — see that variable for
82+
# why. Toggling an export off leaves the group in state, so re-enabling it later is a
83+
# no-op rather than a ResourceAlreadyExistsException.
84+
for_each = toset(var.rds_managed_log_group_types)
85+
86+
name = "/aws/rds/cluster/${local.rds_cluster_identifier}/${each.value}"
87+
retention_in_days = var.rds_log_retention_days
88+
kms_key_id = var.rds_log_kms_key_id
89+
90+
# Turning an export off must not delete the evidence already collected — that is the whole
91+
# point of exporting. Belt-and-braces now that the two lifecycles are decoupled: it only
92+
# bites when a type is removed from rds_managed_log_group_types, which is an explicit
93+
# "stop managing this group" rather than a side effect of changing the export list.
94+
# The cost is that a real teardown leaves the groups behind, but they carry finite
95+
# retention and expire on their own, unlike the never-expire orphan DND-1537 cleaned up.
96+
skip_destroy = true
97+
98+
tags = merge(
99+
var.common_tags,
100+
{
101+
Name = "/aws/rds/cluster/${local.rds_cluster_identifier}/${each.value}"
102+
}
103+
)
104+
}
105+
70106
resource "aws_rds_cluster" "cometml-db-cluster" {
71-
cluster_identifier = coalesce(var.rds_cluster_identifier, "cometml-rds-cluster-${var.environment}")
107+
cluster_identifier = local.rds_cluster_identifier
72108
db_subnet_group_name = aws_db_subnet_group.comet-ml-rds-subnet.name
73109
availability_zones = var.availability_zones
74110
database_name = var.rds_snapshot_identifier == null ? var.rds_database_name : null
@@ -90,6 +126,11 @@ resource "aws_rds_cluster" "cometml-db-cluster" {
90126
deletion_protection = var.rds_deletion_protection
91127
storage_type = var.rds_storage_type
92128
apply_immediately = true
129+
enabled_cloudwatch_logs_exports = var.rds_enabled_cloudwatch_logs_exports
130+
131+
# The log groups must exist with their retention already set before RDS starts
132+
# exporting, otherwise RDS creates them itself at "never expire" (DND-1537).
133+
depends_on = [aws_cloudwatch_log_group.rds_exported_logs]
93134

94135
dynamic "serverlessv2_scaling_configuration" {
95136
for_each = var.rds_serverless_v2_enabled ? [1] : []
@@ -113,6 +154,20 @@ resource "aws_rds_cluster" "cometml-db-cluster" {
113154
# dependents to "known after apply"). It only matters at destroy time as the
114155
# snapshot name, so ignore in-place changes and keep the value first stored.
115156
ignore_changes = [final_snapshot_identifier]
157+
158+
# Exporting a type that has no managed log group hands group creation back to
159+
# RDS, which makes it at never-expire — this module's own failure mode, through
160+
# a new door. Both variables default to the same list so this holds out of the
161+
# box; the precondition stops someone adding e.g. "general" to the export list
162+
# alone. A cross-variable `validation` block would be the natural home, but that
163+
# needs Terraform 1.9 and this repo's floor is >= 1.5.7.
164+
precondition {
165+
condition = alltrue([
166+
for t in var.rds_enabled_cloudwatch_logs_exports :
167+
contains(var.rds_managed_log_group_types, t)
168+
])
169+
error_message = "Every exported log type must also be in rds_managed_log_group_types, or RDS creates its log group at never-expire."
170+
}
116171
}
117172
}
118173

‎modules/comet_rds/outputs.tf‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,26 @@ output "mysql_sg_id" {
2727
description = "Security group ID of the MySQL cluster"
2828
value = aws_security_group.mysql_sg.id
2929
}
30+
31+
# DND-1537: every cluster whose export was enabled out-of-band needs its existing group
32+
# imported before it can adopt this module, so the import address has to be derivable
33+
# rather than hand-assembled up to fifteen times.
34+
#
35+
# These are the MANAGED groups (rds_managed_log_group_types), deliberately not the exported
36+
# ones — import needs every group under management, including a `slowquery` group that is
37+
# still empty because slow_query_log=0. Consumers wiring alarms or metric filters want
38+
# mysql_exported_log_types below to filter by, or they will alarm on a group nothing writes to.
39+
output "mysql_log_group_names" {
40+
description = "CloudWatch log group names for the RDS log groups this module MANAGES, keyed by log type. Superset of what is actively exported — cross-reference mysql_exported_log_types. Use when adopting a cluster whose export was enabled out-of-band: terraform import 'module.<path>.aws_cloudwatch_log_group.rds_exported_logs[\"error\"]' <name>"
41+
value = { for t, lg in aws_cloudwatch_log_group.rds_exported_logs : t => lg.name }
42+
}
43+
44+
output "mysql_log_group_arns" {
45+
description = "CloudWatch log group ARNs for the RDS log groups this module MANAGES, keyed by log type. Superset of what is actively exported — filter by mysql_exported_log_types before attaching metric filters, subscription filters or alarms, or you will target a group nothing writes to."
46+
value = { for t, lg in aws_cloudwatch_log_group.rds_exported_logs : t => lg.arn }
47+
}
48+
49+
output "mysql_exported_log_types" {
50+
description = "MySQL log types the cluster is actively exporting. Subset of the keys in mysql_log_group_names / mysql_log_group_arns. Note a type can be exported and still produce nothing — 'slowquery' stays empty until slow_query_log=1 is set via rds_cluster_parameters."
51+
value = aws_rds_cluster.cometml-db-cluster.enabled_cloudwatch_logs_exports
52+
}

‎modules/comet_rds/variables.tf‎

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,74 @@ variable "rds_enhanced_monitoring_interval" {
163163
default = 60
164164
}
165165

166+
# DND-1537: without these, no STSaaS cluster exported anything and the MySQL error log
167+
# was unreadable — agentro is granted rds:DescribeDBLogFiles but not
168+
# rds:DownloadDBLogFilePortion, so an investigation could see that a log file existed
169+
# and how large it was, but not a byte of its contents. Exporting to CloudWatch Logs
170+
# closes that without widening the IAM role.
171+
variable "rds_enabled_cloudwatch_logs_exports" {
172+
description = "MySQL log types the CLUSTER exports to CloudWatch Logs. 'error' carries the entries that matter for post-mortems (CUST-6816). 'slowquery' produces nothing unless slow_query_log=1 is also set via rds_cluster_parameters — it is enabled here so the log group exists and is retention-managed from the moment that parameter is turned on. Pass [] to stop exporting; the log groups themselves are governed separately by rds_managed_log_group_types, so disabling an export never removes a group from state."
173+
type = list(string)
174+
default = ["error", "slowquery"]
175+
176+
validation {
177+
condition = alltrue([for t in var.rds_enabled_cloudwatch_logs_exports : contains(["audit", "error", "general", "slowquery"], t)])
178+
error_message = "Valid Aurora MySQL log types are: audit, error, general, slowquery."
179+
}
180+
}
181+
182+
# Deliberately separate from rds_enabled_cloudwatch_logs_exports: one variable driving both
183+
# the cluster attribute and the log-group for_each would make disabling an export a one-way
184+
# door. The group would leave state while surviving in AWS (skip_destroy), and re-enabling
185+
# the export later would fail on ResourceAlreadyExistsException — the same collision this
186+
# whole change exists to prevent, just deferred and self-inflicted.
187+
#
188+
# Keeping them apart means toggling an export is purely a cluster-attribute change. A type
189+
# listed here but not exported yields an empty log group with retention already set, which
190+
# is the desired state for slowquery on the 15 clusters where slow_query_log=0.
191+
variable "rds_managed_log_group_types" {
192+
description = "MySQL log types whose CloudWatch log groups this module creates and manages retention for. Should be a superset of rds_enabled_cloudwatch_logs_exports — a type listed here but not exported simply yields an empty group with retention already applied, ready for when the export (or slow_query_log) is switched on. Removing a type here stops managing its group; it is NOT deleted, because of skip_destroy."
193+
type = list(string)
194+
default = ["error", "slowquery"]
195+
196+
validation {
197+
condition = alltrue([for t in var.rds_managed_log_group_types : contains(["audit", "error", "general", "slowquery"], t)])
198+
error_message = "Valid Aurora MySQL log types are: audit, error, general, slowquery."
199+
}
200+
}
201+
202+
# The cluster and Performance Insights both take a KMS key; the log groups should too.
203+
# Left at the service-managed key by default (no behaviour change), but exposed now rather
204+
# than after this reaches 16 clusters — retrofitting it later means touching every env a
205+
# second time, at exactly the moment DND-1537 flips slow_query_log=1 and the groups start
206+
# carrying customer SQL text. Also what trivy AVD-AWS-0017 asks for.
207+
variable "rds_log_kms_key_id" {
208+
description = "ARN of a KMS key to encrypt the RDS CloudWatch log groups. Default null uses the CloudWatch service-managed key. Worth setting for environments whose slow query log will carry customer SQL text. When first setting this, the KMS key policy must grant logs.<region>.amazonaws.com permission to use the key, or CreateLogGroup fails with InvalidParameterException — which reads like a terraform problem and is not."
209+
type = string
210+
default = null
211+
}
212+
213+
# RDS auto-creates /aws/rds/cluster/<id>/<type> with NO retention ("never expire") the
214+
# instant an export is enabled. That is how the pre-rebuild zoox slowquery group came to
215+
# hold 3.65 GB of dead data indefinitely (DND-1537). The groups are therefore created
216+
# explicitly, with retention, and the cluster depends on them so they exist first.
217+
# 0 ("never expire") is deliberately NOT accepted. It is what RDS applies when it creates
218+
# these groups itself, and the reason DND-1537 found an orphan holding 3.65 GB of dead data
219+
# indefinitely — a module whose purpose is to prevent that should not offer it as an option.
220+
# These groups carry error and slow-query logs, i.e. customer SQL text once slow_query_log
221+
# is on, so unbounded retention is the wrong default to make reachable. 3653 (10 years) is
222+
# available if something genuinely needs to keep them a long time.
223+
variable "rds_log_retention_days" {
224+
description = "Retention for the RDS CloudWatch log groups, in days. Must be finite — 'never expire' is not offered, see DND-1537."
225+
type = number
226+
default = 90
227+
228+
validation {
229+
condition = contains([1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1096, 1827, 2192, 2557, 2922, 3288, 3653], var.rds_log_retention_days)
230+
error_message = "Must be a finite retention period CloudWatch Logs accepts (1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1096, 1827, 2192, 2557, 2922, 3288, 3653). 0 / never-expire is intentionally not permitted."
231+
}
232+
}
233+
166234
variable "rds_deletion_protection" {
167235
description = "Enable deletion protection for RDS cluster"
168236
type = bool

‎outputs.tf‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,21 @@ output "mysql_database_name" {
5353
value = var.enable_rds ? module.comet_rds[0].mysql_database_name : null
5454
}
5555

56+
output "mysql_log_group_names" {
57+
description = "CloudWatch log group names for the RDS log groups this module MANAGES, keyed by log type. Superset of what is actively exported — cross-reference mysql_exported_log_types. Needed to build the terraform import address when adopting a cluster whose export was enabled out-of-band (DND-1537)."
58+
value = var.enable_rds ? module.comet_rds[0].mysql_log_group_names : null
59+
}
60+
61+
output "mysql_log_group_arns" {
62+
description = "CloudWatch log group ARNs for the RDS log groups this module MANAGES, keyed by log type. Superset of what is actively exported — filter by mysql_exported_log_types before attaching metric filters, subscription filters or alarms, or you will target a group nothing writes to."
63+
value = var.enable_rds ? module.comet_rds[0].mysql_log_group_arns : null
64+
}
65+
66+
output "mysql_exported_log_types" {
67+
description = "MySQL log types the cluster is actively exporting. Subset of the keys in mysql_log_group_names / mysql_log_group_arns. A type can be exported and still produce nothing — 'slowquery' stays empty until slow_query_log=1 is set via rds_cluster_parameters."
68+
value = var.enable_rds ? module.comet_rds[0].mysql_exported_log_types : null
69+
}
70+
5671
output "rds_password_auto_generated" {
5772
description = "Whether the RDS master password was auto-generated (true) or provided explicitly (false)"
5873
value = var.enable_rds ? nonsensitive(var.rds_master_password == null) : null

‎variables.tf‎

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,6 +1168,50 @@ variable "rds_enhanced_monitoring_interval" {
11681168
default = 60
11691169
}
11701170

1171+
# DND-1537: a fleet audit found EnabledCloudwatchLogsExports null on all 16 STSaaS Aurora
1172+
# clusters, which left the MySQL error log unreadable during CUST-6816 — agentro holds
1173+
# rds:DescribeDBLogFiles but not rds:DownloadDBLogFilePortion, so the investigation could
1174+
# see a 254 KB error-log spike in the failure hour and could not read it. Exporting to
1175+
# CloudWatch Logs closes that without widening the read-only role.
1176+
variable "rds_enabled_cloudwatch_logs_exports" {
1177+
description = "MySQL log types the CLUSTER exports to CloudWatch Logs. 'error' carries the entries that matter for post-mortems. 'slowquery' produces nothing unless slow_query_log=1 is also set via rds_cluster_parameters — it is enabled here so the log group exists and is retention-managed from the moment that parameter is turned on. Pass [] to stop exporting; the log groups are governed separately by rds_managed_log_group_types, so disabling an export never removes a group from state."
1178+
type = list(string)
1179+
default = ["error", "slowquery"]
1180+
1181+
validation {
1182+
condition = alltrue([for t in var.rds_enabled_cloudwatch_logs_exports : contains(["audit", "error", "general", "slowquery"], t)])
1183+
error_message = "Valid Aurora MySQL log types are: audit, error, general, slowquery."
1184+
}
1185+
}
1186+
1187+
variable "rds_managed_log_group_types" {
1188+
description = "MySQL log types whose CloudWatch log groups are created and retention-managed here. Kept separate from rds_enabled_cloudwatch_logs_exports so that disabling an export is not a one-way door: the group stays in state, and re-enabling later is a no-op instead of a ResourceAlreadyExistsException. Should be a superset of the export list."
1189+
type = list(string)
1190+
default = ["error", "slowquery"]
1191+
1192+
validation {
1193+
condition = alltrue([for t in var.rds_managed_log_group_types : contains(["audit", "error", "general", "slowquery"], t)])
1194+
error_message = "Valid Aurora MySQL log types are: audit, error, general, slowquery."
1195+
}
1196+
}
1197+
1198+
variable "rds_log_kms_key_id" {
1199+
description = "ARN of a KMS key to encrypt the RDS CloudWatch log groups. Default null uses the CloudWatch service-managed key. Worth setting for environments whose slow query log will carry customer SQL text. When first setting this, the KMS key policy must grant logs.<region>.amazonaws.com permission to use the key, or CreateLogGroup fails with InvalidParameterException — which reads like a terraform problem and is not."
1200+
type = string
1201+
default = null
1202+
}
1203+
1204+
variable "rds_log_retention_days" {
1205+
description = "Retention for the RDS CloudWatch log groups, in days. Must be finite — 'never expire' is intentionally not offered: that is what RDS applies when it creates the groups itself, and the reason DND-1537 found an orphan holding 3.65 GB of dead data indefinitely."
1206+
type = number
1207+
default = 90
1208+
1209+
validation {
1210+
condition = contains([1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1096, 1827, 2192, 2557, 2922, 3288, 3653], var.rds_log_retention_days)
1211+
error_message = "Must be a finite retention period CloudWatch Logs accepts (1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1096, 1827, 2192, 2557, 2922, 3288, 3653). 0 / never-expire is intentionally not permitted."
1212+
}
1213+
}
1214+
11711215
#### comet_s3 ####
11721216
variable "s3_bucket_name" {
11731217
description = "Name for S3 bucket"

0 commit comments

Comments
 (0)