Skip to content

Commit e542e41

Browse files
authored
feat: Secretsmanager secret rotation for master user password (#97)
* manage master password rotation * update example * update variable description * update variable description
1 parent 1d7b385 commit e542e41

File tree

7 files changed

+76
-0
lines changed

7 files changed

+76
-0
lines changed

README.md

+7
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ No modules.
210210
| [aws_redshift_snapshot_schedule_association.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/redshift_snapshot_schedule_association) | resource |
211211
| [aws_redshift_subnet_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/redshift_subnet_group) | resource |
212212
| [aws_redshift_usage_limit.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/redshift_usage_limit) | resource |
213+
| [aws_secretsmanager_secret_rotation.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_rotation) | resource |
213214
| [random_password.master_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |
214215
| [aws_iam_policy_document.scheduled_action](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
215216
| [aws_iam_policy_document.scheduled_action_assume](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
@@ -262,8 +263,13 @@ No modules.
262263
| <a name="input_logging"></a> [logging](#input\_logging) | Logging configuration for the cluster | `any` | `{}` | no |
263264
| <a name="input_maintenance_track_name"></a> [maintenance\_track\_name](#input\_maintenance\_track\_name) | The name of the maintenance track for the restored cluster. When you take a snapshot, the snapshot inherits the MaintenanceTrack value from the cluster. The snapshot might be on a different track than the cluster that was the source for the snapshot. Default value is `current` | `string` | `null` | no |
264265
| <a name="input_manage_master_password"></a> [manage\_master\_password](#input\_manage\_master\_password) | Whether to use AWS SecretsManager to manage the cluster admin credentials. Conflicts with `master_password`. One of `master_password` or `manage_master_password` is required unless `snapshot_identifier` is provided | `bool` | `false` | no |
266+
| <a name="input_manage_master_password_rotation"></a> [manage\_master\_password\_rotation](#input\_manage\_master\_password\_rotation) | Whether to manage the master user password rotation. Setting this value to false after previously having been set to true will disable automatic rotation. | `bool` | `false` | no |
265267
| <a name="input_manual_snapshot_retention_period"></a> [manual\_snapshot\_retention\_period](#input\_manual\_snapshot\_retention\_period) | The default number of days to retain a manual snapshot. If the value is -1, the snapshot is retained indefinitely. This setting doesn't change the retention period of existing snapshots. Valid values are between `-1` and `3653`. Default value is `-1` | `number` | `null` | no |
266268
| <a name="input_master_password"></a> [master\_password](#input\_master\_password) | Password for the master DB user. (Required unless a `snapshot_identifier` is provided). Must contain at least 8 chars, one uppercase letter, one lowercase letter, and one number | `string` | `null` | no |
269+
| <a name="input_master_password_rotate_immediately"></a> [master\_password\_rotate\_immediately](#input\_master\_password\_rotate\_immediately) | Specifies whether to rotate the secret immediately or wait until the next scheduled rotation window. | `bool` | `null` | no |
270+
| <a name="input_master_password_rotation_automatically_after_days"></a> [master\_password\_rotation\_automatically\_after\_days](#input\_master\_password\_rotation\_automatically\_after\_days) | Specifies the number of days between automatic scheduled rotations of the secret. Either `master_user_password_rotation_automatically_after_days` or `master_user_password_rotation_schedule_expression` must be specified. | `number` | `null` | no |
271+
| <a name="input_master_password_rotation_duration"></a> [master\_password\_rotation\_duration](#input\_master\_password\_rotation\_duration) | The length of the rotation window in hours. For example, 3h for a three hour window. | `string` | `null` | no |
272+
| <a name="input_master_password_rotation_schedule_expression"></a> [master\_password\_rotation\_schedule\_expression](#input\_master\_password\_rotation\_schedule\_expression) | A cron() or rate() expression that defines the schedule for rotating your secret. Either `master_user_password_rotation_automatically_after_days` or `master_user_password_rotation_schedule_expression` must be specified. | `string` | `null` | no |
267273
| <a name="input_master_password_secret_kms_key_id"></a> [master\_password\_secret\_kms\_key\_id](#input\_master\_password\_secret\_kms\_key\_id) | ID of the KMS key used to encrypt the cluster admin credentials secret | `string` | `null` | no |
268274
| <a name="input_master_username"></a> [master\_username](#input\_master\_username) | Username for the master DB user (Required unless a `snapshot_identifier` is provided). Defaults to `awsuser` | `string` | `"awsuser"` | no |
269275
| <a name="input_multi_az"></a> [multi\_az](#input\_multi\_az) | Specifies if the Redshift cluster is multi-AZ | `bool` | `null` | no |
@@ -320,6 +326,7 @@ No modules.
320326
| <a name="output_cluster_preferred_maintenance_window"></a> [cluster\_preferred\_maintenance\_window](#output\_cluster\_preferred\_maintenance\_window) | The backup window |
321327
| <a name="output_cluster_public_key"></a> [cluster\_public\_key](#output\_cluster\_public\_key) | The public key for the cluster |
322328
| <a name="output_cluster_revision_number"></a> [cluster\_revision\_number](#output\_cluster\_revision\_number) | The specific revision number of the database in the cluster |
329+
| <a name="output_cluster_secretsmanager_secret_rotation_enabled"></a> [cluster\_secretsmanager\_secret\_rotation\_enabled](#output\_cluster\_secretsmanager\_secret\_rotation\_enabled) | Specifies whether automatic rotation is enabled for the secret |
323330
| <a name="output_cluster_subnet_group_name"></a> [cluster\_subnet\_group\_name](#output\_cluster\_subnet\_group\_name) | The name of a cluster subnet group to be associated with this cluster |
324331
| <a name="output_cluster_type"></a> [cluster\_type](#output\_cluster\_type) | The Redshift cluster type |
325332
| <a name="output_cluster_version"></a> [cluster\_version](#output\_cluster\_version) | The version of Redshift engine software |

examples/complete/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ No inputs.
9292
| <a name="output_endpoint_access_port"></a> [endpoint\_access\_port](#output\_endpoint\_access\_port) | The port number on which the cluster accepts incoming connections |
9393
| <a name="output_endpoint_access_vpc_endpoint"></a> [endpoint\_access\_vpc\_endpoint](#output\_endpoint\_access\_vpc\_endpoint) | The connection endpoint for connecting to an Amazon Redshift cluster through the proxy. See details below |
9494
| <a name="output_master_password_secret_arn"></a> [master\_password\_secret\_arn](#output\_master\_password\_secret\_arn) | ARN of managed master password secret |
95+
| <a name="output_master_password_secretsmanager_secret_rotation_enabled"></a> [master\_password\_secretsmanager\_secret\_rotation\_enabled](#output\_master\_password\_secretsmanager\_secret\_rotation\_enabled) | Specifies whether automatic rotation is enabled for the secret |
9596
| <a name="output_parameter_group_arn"></a> [parameter\_group\_arn](#output\_parameter\_group\_arn) | Amazon Resource Name (ARN) of the parameter group created |
9697
| <a name="output_parameter_group_id"></a> [parameter\_group\_id](#output\_parameter\_group\_id) | The name of the Redshift parameter group created |
9798
| <a name="output_scheduled_action_iam_role_arn"></a> [scheduled\_action\_iam\_role\_arn](#output\_scheduled\_action\_iam\_role\_arn) | Scheduled actions IAM role ARN |

examples/complete/main.tf

+3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ module "redshift" {
4545
# Or make Redshift manage it in secrets manager
4646
manage_master_password = true
4747

48+
manage_master_password_rotation = true
49+
master_password_rotation_schedule_expression = "rate(90 days)"
50+
4851
encrypted = true
4952
kms_key_arn = aws_kms_key.redshift.arn
5053

examples/complete/outputs.tf

+5
Original file line numberDiff line numberDiff line change
@@ -222,3 +222,8 @@ output "master_password_secret_arn" {
222222
description = "ARN of managed master password secret"
223223
value = module.redshift.master_password_secret_arn
224224
}
225+
226+
output "master_password_secretsmanager_secret_rotation_enabled" {
227+
description = "Specifies whether automatic rotation is enabled for the secret"
228+
value = module.redshift.cluster_secretsmanager_secret_rotation_enabled
229+
}

main.tf

+17
Original file line numberDiff line numberDiff line change
@@ -336,3 +336,20 @@ resource "aws_cloudwatch_log_group" "this" {
336336

337337
tags = merge(var.tags, var.cloudwatch_log_group_tags)
338338
}
339+
340+
################################################################################
341+
# Managed Secret Rotation
342+
################################################################################
343+
344+
resource "aws_secretsmanager_secret_rotation" "this" {
345+
count = var.create && var.manage_master_password && var.manage_master_password_rotation ? 1 : 0
346+
347+
secret_id = aws_redshift_cluster.this[0].master_password_secret_arn
348+
rotate_immediately = var.master_password_rotate_immediately
349+
350+
rotation_rules {
351+
automatically_after_days = var.master_password_rotation_automatically_after_days
352+
duration = var.master_password_rotation_duration
353+
schedule_expression = var.master_password_rotation_schedule_expression
354+
}
355+
}

outputs.tf

+9
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,12 @@ output "master_password_secret_arn" {
227227
description = "ARN of managed master password secret"
228228
value = try(aws_redshift_cluster.this[0].master_password_secret_arn, null)
229229
}
230+
231+
################################################################################
232+
# Managed Secret Rotation
233+
################################################################################
234+
235+
output "cluster_secretsmanager_secret_rotation_enabled" {
236+
description = "Specifies whether automatic rotation is enabled for the secret"
237+
value = try(aws_secretsmanager_secret_rotation.this[0].rotation_enabled, null)
238+
}

variables.tf

+34
Original file line numberDiff line numberDiff line change
@@ -508,3 +508,37 @@ variable "cloudwatch_log_group_tags" {
508508
type = map(string)
509509
default = {}
510510
}
511+
512+
################################################################################
513+
# Managed Secret Rotation
514+
################################################################################
515+
516+
variable "manage_master_password_rotation" {
517+
description = "Whether to manage the master user password rotation. Setting this value to false after previously having been set to true will disable automatic rotation."
518+
type = bool
519+
default = false
520+
}
521+
522+
variable "master_password_rotate_immediately" {
523+
description = "Specifies whether to rotate the secret immediately or wait until the next scheduled rotation window."
524+
type = bool
525+
default = null
526+
}
527+
528+
variable "master_password_rotation_automatically_after_days" {
529+
description = "Specifies the number of days between automatic scheduled rotations of the secret. Either `master_user_password_rotation_automatically_after_days` or `master_user_password_rotation_schedule_expression` must be specified."
530+
type = number
531+
default = null
532+
}
533+
534+
variable "master_password_rotation_duration" {
535+
description = "The length of the rotation window in hours. For example, 3h for a three hour window."
536+
type = string
537+
default = null
538+
}
539+
540+
variable "master_password_rotation_schedule_expression" {
541+
description = "A cron() or rate() expression that defines the schedule for rotating your secret. Either `master_user_password_rotation_automatically_after_days` or `master_user_password_rotation_schedule_expression` must be specified."
542+
type = string
543+
default = null
544+
}

0 commit comments

Comments
 (0)