Search code examples
amazon-web-servicesterraformamazon-eksaws-secrets-manager

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


I need to write Git-revisioned Terraform code to put a secret string into AWS Secrets Manager. Given a secret string in a textfile:

% cat /tmp/plaintext-password
my-super-secret-password

I am able to make an encrypted version of it using a KMS key:

# Prints base64-encoded, encrypted string.
aws kms encrypt --key-id my_kms_uuid --plaintext fileb:///tmp/plaintext-password --output text --query CiphertextBlob
# abcdef...123456789/==

What Terraform code can be written to get that base64 string in AWS Secrets Manager, such that AWS knows it was encrypted with my_kms_uuid? I have tried the following:

resource "aws_secretsmanager_secret" "testing-secrets-secret" {
  name = "secret-for-testing"
  kms_key_id = "<my_kms_uuid>"
}

resource "aws_secretsmanager_secret_version" "testing-secrets-version" {
  secret_string = "abcdef...123456789/=="
}

The problem is I can't figure out a way to tell AWS Secrets Manager that the string is already encrypted by KMS so it doesn't have to encrypt it again. Can this be done?


Solution

  • When encrypting a secret string with KMS, the key that was used is actually specified within the output of the resulting ciphertext. This means we can do this the following way:

    1. Encrypt the secret string with an existing KMS key in AWS aws kms encrypt --key-id arn:aws:kms:us-east-1:<account_id>:key/mrk-blahblahblah --plaintext fileb://<(printf 'SOME_SECRET_TEXT') --output text --query CiphertextBlob --region us-east-1
    2. Then use aws_kms_secrets to decrypt it within Terraform (something like this).
    3. Then you push the decrypted secret up into AWS Secrets Manager using aws_secretsmanager_secret_version.

    The net result is only the encoded secret is kept in version control, but the password that's actually stored in Secrets Manager is the decoded string.