Search code examples
mysqlamazon-web-servicesamazon-rdsterraformamazon-kms

AWS: Using a KMS-encrypted master password to create a RDS instance


When creating a new RDS instance on AWS via the aws cli tools, is it possible to use a master password which is encrypted with an AWS KMS key? E.g. using this command: http://docs.aws.amazon.com/cli/latest/reference/rds/create-db-instance.html

I'm asking because I don't want to store clear text passwords in my dev environment (using terraform or cloud formation), instead encrypted values which are transparently decrypted by the according AWS components.


Solution

  • If you wanted to do this with the CLI you could always encrypt the password with a KMS key and then run two commands to decrypt the password and create the database.

    So something like this might work:

    aws rds create-instance ... \
    --master-username admin-user \
    --master-user-password `aws kms decrypt --ciphertext-blob fileb://path/to/kms/encrypted/file/with/password --output text --query Plaintext | base64 --decode`
    

    If you wanted to still use Terraform for creating your database instances then I've previously answered a question along similar lines. Although that question is more concerned around the database being stored in a remote state file.

    If you were equally concerned about keeping the password in your code then I'd consider simply using a variable for your password and then passing that in on the CLI or using an environment variable.

    Equally you could use the aws_kms_secret data source to decrypt your password on the fly. That will leak the password to logs and state files though:

    $ echo -n 'master-password' > plaintext-password
    $ aws kms encrypt \
    > --key-id ab123456-c012-4567-890a-deadbeef123 \
    > --plaintext fileb://plaintext-example \
    > --encryption-context foo=bar \
    > --output text --query CiphertextBlob
    AQECAHgaPa0J8WadplGCqqVAr4HNvDaFSQ+NaiwIBhmm6qDSFwAAAGIwYAYJKoZIhvcNAQcGoFMwUQIBADBMBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDI+LoLdvYv8l41OhAAIBEIAfx49FFJCLeYrkfMfAw6XlnxP23MmDBdqP8dPp28OoAQ==
    

    And then in Terraform:

    data "aws_kms_secret" "db" {
      secret {
        name    = "master_password"
        payload = "AQECAHgaPa0J8WadplGCqqVAr4HNvDaFSQ+NaiwIBhmm6qDSFwAAAGIwYAYJKoZIhvcNAQcGoFMwUQIBADBMBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDI+LoLdvYv8l41OhAAIBEIAfx49FFJCLeYrkfMfAw6XlnxP23MmDBdqP8dPp28OoAQ=="
    
        context {
          foo = "bar"
        }
      }
    }
    
    resource "aws_rds_cluster" "rds" {
      master_username = "root"
      master_password = "${data.aws_kms_secret.db.master_password}"
    
      # ...
    }