Aws lambda 如何解密terraform数据资源返回的ssm参数安全字符串值

Aws lambda 如何解密terraform数据资源返回的ssm参数安全字符串值,aws-lambda,terraform,boto3,terraform-provider-aws,aws-kms,Aws Lambda,Terraform,Boto3,Terraform Provider Aws,Aws Kms,我有一个下面的terraofrm代码从存储中获取参数 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

我有一个下面的terraofrm代码从存储中获取参数

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)
如何在lambda函数中将其解密为纯文本

我一直在尝试的示例代码

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)

经过一些研究,我发现AWS Encryption SDK以加密方式将加密上下文绑定到加密数据,因此我们必须使用加密上下文进行解密。EncryptionContext为我解决了这个问题

注意:这是节点js代码

地形变化

lambda控制台上的环境变量看起来像


通过这种方式,我们还可以避免在代码中硬编码参数ARN。

下面是带有硬编码参数ARN的python代码

import base64
import boto3
import os
def decrypt(session, secret):
    client = session.client('kms')
    plaintext = client.decrypt(
        CiphertextBlob=bytes(base64.b64decode(secret)),
        EncryptionContext={
        'PARAMETER_ARN': 'arn:aws:ssm:us-east-1:xxxxx:parameter/password'
    }
    )
    return plaintext["Plaintext"]

session = boto3.session.Session()
encrypted = os.environ['New_password']

print decrypt(session, encrypted)

为什么不使用boto3来检索解密后的参数,而不是将该逻辑拆分为两个?您当前遇到的错误是什么?是否使用默认密钥加密ssm参数?如果是:您是否更改了该密钥的密钥策略?你的lambda可以解密任何东西吗?有什么问题吗?有错误消息吗?我不懂python,我要的是示例代码。我刚刚在Google上试过一次这个例子,得到了错误invalidciphertextexception。为什么你要将加密的秘密传递给Lambda函数,而不是从Lambda函数中解密的SSM参数存储中获取它?你不应该在回答中问问题。但答案是:与获得加密密码的方式相同,通过将arn作为环境变量传递。但问题仍然存在:为什么你首先要传递加密密码,输入密码名称,只需在ssm上调用get_参数,而不是在kms上调用decrypt。从您自己链接的文档中:您可以通过调用AWS kms decrypt操作来解密加密的安全字符串参数值,方法是使用正确的加密上下文和Systems Manager GetParameter操作提供的加密参数值返回。但是,我们鼓励您使用带有WithDecryption参数的GetParameter操作对参数存储参数值进行解密。因为在我们的示例中,从SSM进行解密的API调用数量非常多,这比kms要昂贵。因此,正如使用Kms而不是SSM解密的经济高效的解决方案一样,您应该将参数检索缓存在lambda中,无限期地缓存,因为它无论如何都不会更改。没有必要为每个lambda调用解密/获取参数,而只需在创建lambda执行环境时解密/获取一次。
module "lambda_env_vars" {
New_password = jsonencode(data.aws_ssm_parameter.foo)
}
New_password {"arn":"arn:aws:ssm:xxxxx:41xxxxx:parameter/password","id":"password","name":"password","type":"SecureString","value":"xxxxxxxx","version":2,"with_decryption":false}
import base64
import boto3
import os
def decrypt(session, secret):
    client = session.client('kms')
    plaintext = client.decrypt(
        CiphertextBlob=bytes(base64.b64decode(secret)),
        EncryptionContext={
        'PARAMETER_ARN': 'arn:aws:ssm:us-east-1:xxxxx:parameter/password'
    }
    )
    return plaintext["Plaintext"]

session = boto3.session.Session()
encrypted = os.environ['New_password']

print decrypt(session, encrypted)