lgallard / terraform-aws-secrets-manager

Terraform module to create Amazon Secrets Manager resources.
Apache License 2.0
63 stars 50 forks source link

Using count to generate secrets, can take to secret deletion and recreation... #13

Closed marcportabellaclotet-mt closed 3 years ago

marcportabellaclotet-mt commented 3 years ago

Alternatively, it can be used for_each approach

resource "aws_secretsmanager_secret" "sm" {
  for_each =  var.secrets
  name                    = each.key
  name_prefix             = can(each.value.name_prefix) ? each.value.name_prefix : null
  description             = can(each.value.description) ? each.value.description : null
  kms_key_id              = can(each.value.kms_key_id) ? each.value.kms_key_id : null
  policy                  = can(each.value.policy) ? each.value.policy : null
  recovery_window_in_days = can(each.value.recovery_window_in_days) ? each.value.recovery_window_in_days : 7
  tags                    = can(var.tags) ? var.tags : null 
}

resource "aws_secretsmanager_secret_version" "sm-sv" {
  for_each      = var.secrets
  secret_id     = each.key
  secret_string = jsonencode(each.value.secrets)
  depends_on    = [aws_secretsmanager_secret.sm]
} 

And defining secrets like this:

module "configuration_data" {
  source = "../../../modules/aws/secrets"
  secrets = { 
      "mysecret1" : { 
          secrets = {
            key1 = "value1"
            key2 = "value2" 
          } 
      },
      "mysecret2" : { 
          secrets = {
            key1 = "value1"
            key2 = "value2" 
          } 
      }   
  }
  tags = {}

}
lgallard commented 3 years ago

@marcportabellaclotet-mt that could happen if you changes the order of the secrets definitions, for instance if you add a new secret at the top of the list.

I can change the implementacion but it will require importing the old resources to match the new map and keys.

marcportabellaclotet-mt commented 3 years ago

Yes, this can happen when you add secrets on top or delete a secret that is not the last one. This problem also can cause that you lose history. AWS secrets are versioned, so when you recreate a secret, versioning is lost. Maybe you could release a new major version with the new format. A new implementation will break all current setups, so it has to be managed properly, and add a migration guide.. Thanks for your feedback

lgallard commented 3 years ago

@marcportabellaclotet-mt PR #14 has the map implementation. Now I need to test it and as you mention I need to elaborate a migration guide or script to help in migrating to this breaking new release.

Therefore my todo list includes:

lgallard commented 3 years ago

@marcportabellaclotet-mt the map implementation is already available in version 0.5.0

marcportabellaclotet-mt commented 3 years ago

Thanks! Great job!

lgallard commented 3 years ago

You are welcome!

michalfin commented 3 years ago

Hey @lgallard,

After this change I cannot use variables in the secret names eg.


  source = "lgallard/secrets-manager/aws"

  secrets = {
   "${local.secret_prefix}/myPrefixedSecret" = {
      description = "shared banking config"
      secret_key_value = {
        token = "123456"
        url = ""
      }
    },
 }

  tags = {
    Owner       = "My team"
    Environment = var.environment
    Terraform   = true
  }

}
lgallard commented 3 years ago

@michalfin I took your code and adapted the plain tex example:

main.tf

module "secrets-manager-1" {

  source = "lgallard/secrets-manager/aws"

  secrets = {
    "${local.secret_prefix}/myPrefixedSecret" = {
      description             = "My secret x"
      recovery_window_in_days = 7
      secret_string           = "This is an example"
    },
    "${local.secret_prefix}/myPrefixedSecret-2" = {
      description             = "My secret y"
      recovery_window_in_days = 7
      secret_string           = "This is another example"
    }
  }

  tags = {
    Owner       = "DevOps team"
    Environment = var.environment
    Terraform   = true
  }

}

And It worked:

$ terraform apply

module.secrets-manager-1.aws_secretsmanager_secret.sm["dev/myPrefixedSecret-2"]: Refreshing state... [id=arn:aws:secretsmanager:us-east-1:x:secret:dev/myPrefixedSecret-2-H7zDY4]
module.secrets-manager-1.aws_secretsmanager_secret.sm["dev/myPrefixedSecret"]: Refreshing state... [id=arn:aws:secretsmanager:us-east-1:x:secret:dev/myPrefixedSecret-XD40gj]
module.secrets-manager-1.aws_secretsmanager_secret_version.sm-sv["dev/myPrefixedSecret-2"]: Refreshing state... [id=dev/myPrefixedSecret-2|AC0EF2A6-AF07-4B74-8678-31DDE177282B]
module.secrets-manager-1.aws_secretsmanager_secret_version.sm-sv["dev/myPrefixedSecret"]: Refreshing state... [id=dev/myPrefixedSecret|C47BC246-F483-4820-AE28-71BBD9E32FB1]

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

secret_arns = {
  "dev/myPrefixedSecret" = "arn:aws:secretsmanager:us-east-1:x:secret:dev/myPrefixedSecret-XD40gj"
  "dev/myPrefixedSecret-2" = "arn:aws:secretsmanager:us-east-1:x:secret:dev/myPrefixedSecret-2-H7zDY4"
}
secret_ids = {
  "dev/myPrefixedSecret" = "arn:aws:secretsmanager:us-east-1:x:secret:dev/myPrefixedSecret-XD40gj"
  "dev/myPrefixedSecret-2" = "arn:aws:secretsmanager:us-east-1:x:secret:dev/myPrefixedSecret-2-H7zDY4"

Here are my variables.tf and the local.tf files:

variables.tf

# General vars
variable "environment" {
  description = "Env"
  type        = string
  default     = "dev"
}

local.tf

locals {
  secret_prefix = "dev"
}

what error do you get?