10

The idea is that I want to use Terraform resource aws_secretsmanager_secret to create only three secrets (not workspace-specified secret), one for the dev environment, one for preprod and the third one for production env.

Something like:

resource "aws_secretsmanager_secret" "dev_secret" {
  name = "example-secret-dev"
}

resource "aws_secretsmanager_secret" "preprod_secret" {
  name = "example-secret-preprod"
}

resource "aws_secretsmanager_secret" "prod_secret" {
  name = "example-secret-prod"
}

But after creating them, I don't want to overwrite them every time I run 'Terraform apply', is there a way to tell Terraform if any of the secrets exist, skip the creation of the secret and do not overwrite?

I had a look at this page but still doesn't have a clear solution, any suggestion will be appreciated.

Marcin
  • 215,873
  • 14
  • 235
  • 294
wawawa
  • 2,835
  • 6
  • 44
  • 105
  • TF will not overwrite your resource for no reason. And the link you provided is correct. You can't easily do what you want, as this is not what TF was designed to do. – Marcin Mar 17 '21 at 10:15
  • Why would it overwrite them? Do you mean you want to seed it with some initial secret and use secret manager's rotation to rotate the secret and don't want Terraform to change the value back to the seeded value? – ydaetskcoR Mar 17 '21 at 10:15

2 Answers2

6

You could have Terraform generate random secret values for you using:

data "aws_secretsmanager_random_password" "dev_password" {
  password_length     = 16
}

Then create the secret metadata using:

resource "aws_secretsmanager_secret" "dev_secret" {
  name                    = "dev-secret"
  recovery_window_in_days = 7
}

And then by creating the secret version:

resource "aws_secretsmanager_secret_version" "dev_sv" {
  secret_id     = aws_secretsmanager_secret.dev_secret.id
  secret_string = data.aws_secretsmanager_random_password.dev_password.random_password
  lifecycle {
    ignore_changes = [secret_string, ]
  }
}

Adding the 'ignore_changes' lifecycle block to the secret version will prevent Terraform from overwriting the secret once it has been created. I tested this just now to confirm that a new secret with a new random value will be created, and subsequent executions of terraform apply do not overwrite the secret.

nblivingston
  • 91
  • 1
  • 5
  • Wouldn't you be better off using https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password? There would be no need to ignore changes in the secret_string. As a resource, the random_password wouldn't change unless forced to change. – Rich Apr 10 '23 at 15:37
5

It will not overwrite the secret if you create it manually in the console or using AWS SDK. The aws_secretsmanager_secret creates only the secret, but not its value. To set value you have to use aws_secretsmanager_secret_version.

Anyway, this is something you can easily test yourself. Just run your code with a secret, update its value in AWS console, and re-run terraform apply. You should see no change in the secret's value.

wawawa
  • 2,835
  • 6
  • 44
  • 105
Marcin
  • 215,873
  • 14
  • 235
  • 294
  • 1
    To clarify, I used `aws_secretsmanager_secret` to create an empty secret and use `aws_secretsmanager_secret_version` to add a few placeholders: username / password, because my Terraform also need those credentials to create an RDS instance (see this question: https://stackoverflow.com/questions/66659039/issue-when-using-terraform-to-manage-credentials-that-access-rds-database), but the problem now is after the first Terraform apply, I have the RDS instance and the secret with the placeholder credentials, then I modified the placeholders to the actual credentials,(continue in the next comment) – wawawa Mar 17 '21 at 11:14
  • but I want to update the real crendentials for RDS, so I guess I need to run Terraform apply again, but the issue is `aws_secretsmanager_secret_version` will overwrite the credentials back to the placeholders.....Hope this makes sense. – wawawa Mar 17 '21 at 11:15
  • update: maybe I'm missing something here, but seems like in the second Terraform apply, `aws_secretsmanager_secret_version` won't overwrite the secret strings, so I guess thie secret is fine, but the `master_username` and `master_password` that are passed to the rds instance won't get updated.... – wawawa Mar 17 '21 at 11:20
  • @Cecilia It should not overwrite your secret. Please try, this is something that can be easily tested. – Marcin Mar 17 '21 at 11:23
  • Thanks @Marcin , please see my last comment, the problem now is that RDS resource won't get updated, it's still using the placeholder strings, do you have any suggestions? – wawawa Mar 17 '21 at 11:25
  • @Cecilia You can use data source [aws_secretsmanager_secret_version](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/secretsmanager_secret_version) to actually get the current secret values. If you do this way, they end up in plain text in the state file. You would have to update your rds outside of TF to avoid that. – Marcin Mar 17 '21 at 11:28
  • 1
    Thanks for your input @Marcin , I was using the `data` source approach previously, I agree with you, we don't want the sensitive values to be in the plain text, updating the master password seems to be a reasonable way, such a shame that master_username can't be updated manually in AWS console so I'll have to set it in Terraform I guess. – wawawa Mar 17 '21 at 13:01