hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.61k stars 8.99k forks source link

Support creation of Secrets Manager secrets with an initial value #10898

Open tabacco opened 4 years ago

tabacco commented 4 years ago

Community Note

Description

The Secrets Manager API's CreateSecret action allows you to include a SecretString or SecretBinary value, but this is not supported in the aws_secretsmanager_secret resource. I'd like to request that those be supported.

My use case is the desire to create a secret pre-initialized with an empty value, but to maintain the secret's actual value out of band from terraform via different tooling. Right now I would have to do that with an aws_secretsmanager_secret_version resource, but that doesn't work well because terraform won't be managing all versions of the secret, and eventually the state will drift out of sync with the actual set of versions from ListSecretVersionIds.

Put more simply, I'd like to create a secret with a fixed starting value, which Terraform will then ignore changes to.

Since CreateSecret accepts a value but DescribeSecret doesn't return any secret values, this seems doable without too much internal change (I think).

New or Affected Resource(s)

Potential Terraform Configuration

resource "aws_secretsmanager_secret" "cool_secret" {
  name          = "cool_secret"
  secret_string = ""
}

References

None

tabacco commented 4 years ago

Having suggested this, I do recognize that my potential config example would suggest to users that changing the value of the "secret_string" value would cause the secret to be updated with the new value. I'm not sure what a good solution to that is, but I'm hoping others have ideas.

pcktdmp commented 3 years ago

I think what you mean is that you want to generate an initial value for the secret upon creation just like it is possible with cloudformation here. Is this correct?

tabacco commented 3 years ago

I was thinking even simpler, which is to just initialize empty (or with a fixed value) but allowing for the generation of a seed secret would be even better.

pcktdmp commented 3 years ago

Isn't it currently already empty when just omitting secret_string in your proposed config example?

tabacco commented 3 years ago

That's hypothetical, the current implementation doesn't offer a secret_string argument. If you create just a secret and then try to pull it, you'll get an error saying that there's no version tagged as AWSCURRENT. Which isn't the same as initializing a secret with an empty value.

pcktdmp commented 3 years ago

Ah ok so the problem is that it is not initialized when created. Check. I think that would be solved by: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version

My use case is just to initialize with a secret value without even touching/handling the secret value from a terraform variable. aws-sdk-go seems to already support this: https://github.com/aws/aws-sdk-go/blob/master/service/secretsmanager/api.go#L768

tabacco commented 3 years ago

Yeah so that works for initialization. The problem is, if you rotate the secret from outside terraform it'll create a new version (with a new version id) and move the AWSCURRENT tag over. So far so good. But now if you do it again, the old version (the one terraform created) is deleted, and now you have a problem where your state references a resource that no longer exists.

In this case, what I'd like is a secret that's initialized with a starter value and then the value is forever ignored by terraform. We currently do this with a null provisioner that generates a starting value and uses the aws cli to write it, but that's far from elegant.

pcktdmp commented 3 years ago

Ok, I think implementing it via https://github.com/aws/aws-sdk-go/blob/8d9532cec876077773ac81ffffcbba1fca0ad443/service/secretsmanager/api.go#L768 with a bool as argument to generate and write as value initially solves both our use cases and the empty initial value is not needed.

tabacco commented 3 years ago

Yeah for sure, a random starting value is actually better than an empty one for me, since it saves having to fire off an initial rotation. Having a block for starting value to customize the values in https://github.com/aws/aws-sdk-go/blob/8d9532cec876077773ac81ffffcbba1fca0ad443/service/secretsmanager/api.go#L3604 would probably be a nice bonus.

casey-robertson-paypal commented 2 years ago

Exact same use case - managing secrets via Terraform is not great. I want to seed them (with random value or otherwise) then remove the secret version. I don't want to have to monkey with state or create secret versions in my TF code that I'm just going to change immediately or remove.

tabacco commented 2 months ago

I opened a PR to get some discussion around implementation going. I'm not 100% happy with the approach but it does seem to hew closest to the AWS APIs' behavior and avoids adding arguments that don't map to AWS API fields.