diff --git a/modules/secrets-manager-secret/README.md b/modules/secrets-manager-secret/README.md index b658319..bef93b4 100644 --- a/modules/secrets-manager-secret/README.md +++ b/modules/secrets-manager-secret/README.md @@ -12,14 +12,14 @@ This module creates following resources. | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 1.5 | -| [aws](#requirement\_aws) | >= 4.22 | +| [terraform](#requirement\_terraform) | >= 1.6 | +| [aws](#requirement\_aws) | >= 5.43 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | 5.19.0 | +| [aws](#provider\_aws) | 5.50.0 | ## Modules @@ -42,19 +42,18 @@ This module creates following resources. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [name](#input\_name) | (Required) Friendly name of the new secret. The secret name can consist of uppercase letters, lowercase letters, digits, and any of the following characters: `/_+=.@-`. | `string` | n/a | yes | -| [block\_public\_policy](#input\_block\_public\_policy) | (Optional) Whether to reject calls to PUT a resource policy if the policy allows public access. | `bool` | `false` | no | +| [block\_public\_policy](#input\_block\_public\_policy) | (Optional) Whether to reject calls to PUT a resource policy if the policy allows public access. Defaults to `true`. | `bool` | `true` | no | | [deletion\_window\_in\_days](#input\_deletion\_window\_in\_days) | (Optional) Duration in days after which the secret is deleted after destruction of the resource. Valid value is between `7` and `30` days. Defaults to `30`. | `number` | `30` | no | | [description](#input\_description) | (Optional) The description of the secret. | `string` | `"Managed by Terraform."` | no | | [kms\_key](#input\_kms\_key) | (Optional) The ARN or Id of the AWS KMS key to be used to encrypt the secret values in this secret. If you don't specify this value, then Secrets Manager defaults to using the AWS account's default KMS key named `aws/secretsmanager`. If the default KMS key with that name doesn't yet exist, then AWS Secrets Manager creates it for you automatically the first time. | `string` | `null` | no | | [module\_tags\_enabled](#input\_module\_tags\_enabled) | (Optional) Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no | -| [overwrite\_in\_replicas](#input\_overwrite\_in\_replicas) | (Optional) Whether to overwrite a secret with the same name in the destination region during replication. | `bool` | `false` | no | +| [overwrite\_in\_replicas](#input\_overwrite\_in\_replicas) | (Optional) Whether to overwrite a secret with the same name in the destination region during replication. Defaults to `false`. | `bool` | `false` | no | | [policy](#input\_policy) | (Optional) A valid JSON document representing a resource policy. | `string` | `null` | no | -| [replicas](#input\_replicas) | (Optional) A list of replica configurations of the Secrets Manager secret. Each value of `replicas` block as defined below.
(Required) `region` - The region for replicating the secret.
(Optional) `kms_key` - The ARN, Key ID, or Alias of the AWS KMS key within the region secret is replicated to. If one is not specified, then Secrets Manager defaults to using the AWS account's default KMS key named `aws/secretsmanager` in the region. If the default KMS key with that name doesn't yet exist, then AWS Secrets Manager creates it for you automatically the first time. | `list(map(string))` | `[]` | no | +| [replicas](#input\_replicas) | (Optional) A list of replica configurations of the Secrets Manager secret. Each value of `replicas` block as defined below.
(Required) `region` - The region for replicating the secret.
(Optional) `kms_key` - The ARN, Key ID, or Alias of the AWS KMS key within the region secret is replicated to. If one is not specified, then Secrets Manager defaults to using the AWS account's default KMS key named `aws/secretsmanager` in the region. If the default KMS key with that name doesn't yet exist, then AWS Secrets Manager creates it for you automatically the first time. |
list(object({
region = string
kms_key = optional(string)
}))
| `[]` | no | | [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no | | [resource\_group\_enabled](#input\_resource\_group\_enabled) | (Optional) Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no | | [resource\_group\_name](#input\_resource\_group\_name) | (Optional) The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. | `string` | `""` | no | -| [rotation\_duration\_in\_days](#input\_rotation\_duration\_in\_days) | (Optional) The number of days between automatic scheduled rotations of the secret. Required if `rotation_lambda_function` is configured. | `number` | `null` | no | -| [rotation\_lambda\_function](#input\_rotation\_lambda\_function) | (Optional) The ARN of the Lambda function that can rotate the secret. | `string` | `null` | no | +| [rotation](#input\_rotation) | (Optional) A rotation configurations of the Secrets Manager secret. `rotation` block as defined below.
(Optional) `enabled` - Whether to enable automatic rotation of the secret. Defaults to `false`.
(Optionial) `rotate_immediately` - Whether to rotate the secret immediately or wait until the next scheduled rotation window. The rotation schedule is defined in rotation\_rules. For secrets that use a Lambda rotation function to rotate, if you don't immediately rotate the secret, Secrets Manager tests the rotation configuration by running the testSecret step. Defaults to `true`.
(Optional) `lambda_function` - The ARN of the Lambda function that can rotate the secret.
(Optional) `schedule_frequency` - The number of days between automatic scheduled rotations of the secret. Either `schedule_frequency` or `schedule_expression` must be specified.
(Optional) `schedule_expression` - A cron expression such as `cron(a b c d e f)` or a rate expression such as `rate(10 days)`. Either `schedule_frequency` or `schedule_expression` must be specified.
(Optional) `duration` - The length of the rotation window in hours. |
object({
enabled = optional(bool, false)
rotate_immediately = optional(bool, true)
lambda_function = optional(string)
schedule_frequency = optional(number)
schedule_expression = optional(string)
duration = optional(number)
})
| `{}` | no | | [tags](#input\_tags) | (Optional) A map of tags to add to all resources. | `map(string)` | `{}` | no | | [type](#input\_type) | (Optional) The intended type of the secret. Valid values are `TEXT`, `KEY_VALUE` or `BINARY`. | `string` | `"KEY_VALUE"` | no | | [value](#input\_value) | (Optional) The secret value that you want to encrypt and store in the current version of the secret. Specify plaintext data with `string` type if `type` is `TEXT`. Specify key-value data with `map` type if `type` is `KEY_VALUE`. Specify binary data with `string` type if `type` is `BINARY`. The `aws_secretsmanager_secret_version` resource is deleted from Terraform if you set the value to `null`. However, `AWSCURRENT` staging label is still active on the version event after the resource is deleted from Terraform. | `any` | `null` | no | diff --git a/modules/secrets-manager-secret/main.tf b/modules/secrets-manager-secret/main.tf index 1ac3625..e6b2724 100644 --- a/modules/secrets-manager-secret/main.tf +++ b/modules/secrets-manager-secret/main.tf @@ -19,12 +19,14 @@ locals { # Secrets Manager Secret ################################################### +# INFO: Use a separate resource +# - 'policy' +# INFO: Not supported attributes +# - `name_prefix` resource "aws_secretsmanager_secret" "this" { name = var.name description = var.description - # Use `aws_secretsmanager_policy` instead - policy = null kms_key_id = var.kms_key recovery_window_in_days = var.deletion_window_in_days force_overwrite_replica_secret = var.overwrite_in_replicas @@ -127,12 +129,17 @@ resource "aws_secretsmanager_secret_policy" "this" { ################################################### resource "aws_secretsmanager_secret_rotation" "this" { - count = var.rotation_lambda_function != null ? 1 : 0 + count = var.rotation.enabled ? 1 : 0 - secret_id = aws_secretsmanager_secret.this.id - rotation_lambda_arn = var.rotation_lambda_function + secret_id = aws_secretsmanager_secret.this.id + + rotate_immediately = var.rotation.rotate_immediately + rotation_lambda_arn = var.rotation.lambda_function rotation_rules { - automatically_after_days = var.rotation_duration_in_days + automatically_after_days = var.rotation.schedule_frequency + schedule_expression = var.rotation.schedule_expression + + duration = var.rotation.duration != null ? "${var.rotation.duration}h" : null } } diff --git a/modules/secrets-manager-secret/outputs.tf b/modules/secrets-manager-secret/outputs.tf index 87c0305..97cb5be 100644 --- a/modules/secrets-manager-secret/outputs.tf +++ b/modules/secrets-manager-secret/outputs.tf @@ -63,9 +63,12 @@ output "deletion_window_in_days" { output "rotation" { description = "The configuration of the automatic rotation for the secret." value = { - enabled = var.rotation_lambda_function != null - lambda_function = one(aws_secretsmanager_secret_rotation.this[*].rotation_lambda_arn) - duration_in_days = var.rotation_duration_in_days + enabled = var.rotation.enabled + lambda_function = one(aws_secretsmanager_secret_rotation.this[*].rotation_lambda_arn) + + schedule_frequency = var.rotation.schedule_frequency + schedule_expression = one(aws_secretsmanager_secret_rotation.this[*].rotation_rules[0].schedule_expression) + duration_in_days = var.rotation.duration } } @@ -86,3 +89,11 @@ output "overwrite_in_replicas" { description = "Whether to overwrite a secret with the same name in the destination region during replication." value = aws_secretsmanager_secret.this.force_overwrite_replica_secret } + +# output "debug" { +# value = { +# for k, v in aws_secretsmanager_secret.this : +# k => v +# if !contains(["tags", "tags_all", "policy", "id", "arn", "name", "description", "kms_key_id", "recovery_window_in_days", "force_overwrite_replica_secret", "name_prefix", "replica"], k) +# } +# } diff --git a/modules/secrets-manager-secret/variables.tf b/modules/secrets-manager-secret/variables.tf index 67393a5..7a22aed 100644 --- a/modules/secrets-manager-secret/variables.tf +++ b/modules/secrets-manager-secret/variables.tf @@ -1,6 +1,7 @@ variable "name" { description = "(Required) Friendly name of the new secret. The secret name can consist of uppercase letters, lowercase letters, digits, and any of the following characters: `/_+=.@-`." type = string + nullable = false } variable "description" { @@ -26,6 +27,7 @@ variable "value" { description = "(Optional) The secret value that you want to encrypt and store in the current version of the secret. Specify plaintext data with `string` type if `type` is `TEXT`. Specify key-value data with `map` type if `type` is `KEY_VALUE`. Specify binary data with `string` type if `type` is `BINARY`. The `aws_secretsmanager_secret_version` resource is deleted from Terraform if you set the value to `null`. However, `AWSCURRENT` staging label is still active on the version event after the resource is deleted from Terraform." type = any default = null + nullable = true } variable "versions" { @@ -64,18 +66,20 @@ variable "kms_key" { description = "(Optional) The ARN or Id of the AWS KMS key to be used to encrypt the secret values in this secret. If you don't specify this value, then Secrets Manager defaults to using the AWS account's default KMS key named `aws/secretsmanager`. If the default KMS key with that name doesn't yet exist, then AWS Secrets Manager creates it for you automatically the first time." type = string default = null + nullable = true } variable "policy" { description = "(Optional) A valid JSON document representing a resource policy." type = string default = null + nullable = true } variable "block_public_policy" { - description = "(Optional) Whether to reject calls to PUT a resource policy if the policy allows public access." + description = "(Optional) Whether to reject calls to PUT a resource policy if the policy allows public access. Defaults to `true`." type = bool - default = false + default = true nullable = false } @@ -100,28 +104,49 @@ variable "replicas" { (Required) `region` - The region for replicating the secret. (Optional) `kms_key` - The ARN, Key ID, or Alias of the AWS KMS key within the region secret is replicated to. If one is not specified, then Secrets Manager defaults to using the AWS account's default KMS key named `aws/secretsmanager` in the region. If the default KMS key with that name doesn't yet exist, then AWS Secrets Manager creates it for you automatically the first time. EOF - type = list(map(string)) - default = [] - nullable = false + type = list(object({ + region = string + kms_key = optional(string) + })) + default = [] + nullable = false } variable "overwrite_in_replicas" { - description = "(Optional) Whether to overwrite a secret with the same name in the destination region during replication." + description = "(Optional) Whether to overwrite a secret with the same name in the destination region during replication. Defaults to `false`." type = bool default = false nullable = false } -variable "rotation_lambda_function" { - description = "(Optional) The ARN of the Lambda function that can rotate the secret." - type = string - default = null -} +variable "rotation" { + description = < 0, + ]) + error_message = "Valid value for `duration` is greater than `0`." + } } variable "tags" { diff --git a/modules/secrets-manager-secret/versions.tf b/modules/secrets-manager-secret/versions.tf index 16131a3..ebaffa6 100644 --- a/modules/secrets-manager-secret/versions.tf +++ b/modules/secrets-manager-secret/versions.tf @@ -1,10 +1,10 @@ terraform { - required_version = ">= 1.5" + required_version = ">= 1.6" required_providers { aws = { source = "hashicorp/aws" - version = ">= 4.22" + version = ">= 5.43" } } }