How to use Terraform to store a new secret in AWS Secrets Manager using already KMS-encrypted string?

Solution 1:

If your goal is to keep secret values out of the statefile, then you have two choices:

  1. Encrypt the secret outside of Terraform, then store the encrypted value in Secrets Manager.

    This will force all consumers of the secret to decrypt it before use. Since an encrypted secret includes the CMK used to encrypt it, there's no need for you to separately track the key ID.

    There are several drawbacks to this approach. For one thing, you have to do two steps to use any secret: retrieve it and decrypt it. If you use ECS, you can't provide the name of the secret and let ECS to provide the decrypted value to your container.

    A bigger drawback is that it can be very easy to forget which CMK is used for which secret, and accidentally delete the CMK (at which point the secret becomes unusable). Related is knowing which permissions to grant to the consumers, especially if you have a lot of CMKs.

  2. Create the secret inside Terraform, and set its value manually.

    This keeps the actual value in Secrets Manager, so you don't need to use two steps to decrypt it.

    It is possible to use local-exec to generate the secret within the Terraform configuration: write a script that generates random data and then invokes the AWS CLI to store the value. However, this technique is more frequently used for things like SSH private keys that are created outside of the Terraform provisioning process.

Better than either of these solutions is to store your statefile somewhere that it isn't generally accessible. There are a bunch of backends that can do this for you.