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)
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.