Search code examples
aws-lambdaterraformboto3terraform-provider-awsamazon-kms

How to decrypt ssm parameter secure string value returned by terraform data resource


I have a below terraofrm code to fetch parameter from store

data "aws_ssm_parameter" "foo" {
 name = "password"
with_decryption = false
}

module "lambda_env_vars" {
New_password = data.aws_ssm_parameter.foo.value
}

plan output:-
New_password = Q#iuws##)9ssdhs(some encryptrd value)

How can I decrypt this to plain text in the lambda function?

sample code I have been trying.

import boto3
import os

from base64 import b64decode

def lambda_handler(event, context):
    encrypted = os.environ['New_password']
    decrypted = boto3.client('kms').decrypt(CiphertextBlob=b64decode(encrypted))['Plaintext']

    print("Decrypted value:", decrypted)

Solution

  • After some research, I found that The AWS Encryption SDK cryptographically binds the encryption context to the encrypted data reference so we have to use the same to decrypt. EncryptionContext solved the issue for me.

    Note: This is Node js code

    const aws = require('aws-sdk')
    const kms = new aws.KMS()
    exports.handler = async (event, context, callback) => {
      var password_json = JSON.parse(process.env.New_password)
      let params = {
        CiphertextBlob: Buffer.from(password_json['value'], 'base64'),
         EncryptionContext: {
            'PARAMETER_ARN': password_json['arn']
        }
      }
    
      let secret = null
        const decrypted = await kms.decrypt(params).promise()
    
              secret = decrypted.Plaintext.toString('utf-8')
        
      return secret;
    }
    

    Terraform Change

    module "lambda_env_vars" {
    New_password = jsonencode(data.aws_ssm_parameter.foo)
    }
    

    ENV vars at lambda console looks like

    New_password {"arn":"arn:aws:ssm:xxxxx:41xxxxx:parameter/password","id":"password","name":"password","type":"SecureString","value":"xxxxxxxx","version":2,"with_decryption":false}
    

    This way(jsonencode) we can also avoid hardcoding parameter ARN inside code.