简体   繁体   English

将 AWS Secrets Manager 与 Python 结合使用(Lambda 控制台)

[英]Using AWS Secrets Manager with Python (Lambda Console)

I am attempting to use Secrets Manager a Lambda function in AWS.我正在尝试在 AWS 中使用 Secrets Manager a Lambda function。 Secrets a manager is used to store database credentials to Snowflake (username, password).秘密管理器用于将数据库凭据存储到雪花(用户名、密码)。

I managed to set up a secret in Secrets Manager which contains several key/value pairs (eg one for username, another for password).我设法在 Secrets Manager 中设置了一个秘密,其中包含几个键/值对(例如,一个用于用户名,另一个用于密码)。

Now I am trying to refer to these values in my Python function code.现在我试图在我的 Python function 代码中引用这些值。 AWS documentation kindly provides the following snippet: AWS 文档提供了以下代码段:

import boto3
import base64
from botocore.exceptions import ClientError


def get_secret():

    secret_name = "MY/SECRET/NAME"
    region_name = "us-west-2"

    # Create a Secrets Manager client
    session = boto3.session.Session()
    client = session.client(
        service_name='secretsmanager',
        region_name=region_name
    )

    # In this sample we only handle the specific exceptions for the 'GetSecretValue' API.
    # See https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html
    # We rethrow the exception by default.

    try:
        get_secret_value_response = client.get_secret_value(
            SecretId=secret_name
        )
    except ClientError as e:
        if e.response['Error']['Code'] == 'DecryptionFailureException':
            # Secrets Manager can't decrypt the protected secret text using the provided KMS key.
            # Deal with the exception here, and/or rethrow at your discretion.
            raise e
        elif e.response['Error']['Code'] == 'InternalServiceErrorException':
            # An error occurred on the server side.
            # Deal with the exception here, and/or rethrow at your discretion.
            raise e
        elif e.response['Error']['Code'] == 'InvalidParameterException':
            # You provided an invalid value for a parameter.
            # Deal with the exception here, and/or rethrow at your discretion.
            raise e
        elif e.response['Error']['Code'] == 'InvalidRequestException':
            # You provided a parameter value that is not valid for the current state of the resource.
            # Deal with the exception here, and/or rethrow at your discretion.
            raise e
        elif e.response['Error']['Code'] == 'ResourceNotFoundException':
            # We can't find the resource that you asked for.
            # Deal with the exception here, and/or rethrow at your discretion.
            raise e
    else:
        # Decrypts secret using the associated KMS CMK.
        # Depending on whether the secret is a string or binary, one of these fields will be populated.
        if 'SecretString' in get_secret_value_response:
            secret = get_secret_value_response['SecretString']
        else:
            decoded_binary_secret = base64.b64decode(get_secret_value_response['SecretBinary'])

    # Your code goes here.

Later in my def lambda_handler(event, context) function, I have the following snippet to establish a connection to my database:稍后在我的def lambda_handler(event, context) function 中,我有以下片段来建立与我的数据库的连接:

        conn = snowflake.connector.connect(
            user=USERNAME,
            password=PASSWORD,
            account=ACCOUNT,
            warehouse=WAREHOUSE,
            role=ROLE
            )

However, I am unable to figure out how to use the get_secret() function to return values for parameters like USERNAME or PASSWORD .但是,我无法弄清楚如何使用get_secret() function 来返回USERNAMEPASSWORD等参数的值。

How can this be accomplished?如何实现? Thank you for the help!感谢您的帮助!

update the last part of get_secret() to:将 get_secret() 的最后一部分更新为:

else:
        # Decrypts secret using the associated KMS CMK.
        # Depending on whether the secret is a string or binary, one of these fields will be populated.
        if 'SecretString' in get_secret_value_response:
            secret = get_secret_value_response['SecretString']
        else:
            secret = base64.b64decode(get_secret_value_response['SecretBinary'])

return json.loads(secret)  # returns the secret as dictionary

This will return a dictionary where you'll have the keys you specified in AWS Secret Manager console.这将返回一个字典,其中包含您在 AWS Secret Manager 控制台中指定的密钥。

  • Here is how i have used it using arn, following this bloc hope that helps you.这是我使用arn的方式,希望对您有所帮助。
  • Worth checking what you have used to store and accordingly use one SecretString or SecretBinary值得检查您用来存储的内容并相应地使用一个SecretStringSecretBinary
    secrets_client = boto3.client('secretsmanager')
    secret_arn = 'arn:aws:secretsmanager:eu-west-2:xxxxxxxxxxxx:secret:dashboard/auth_token'
    auth_token = secrets_client.get_secret_value(SecretId=secret_arn).get('SecretString')
  • boto3 docs boto3 文档
  • get_secret_value Retrieves the contents of the encrypted fields SecretString or SecretBinary from the specified version of a secret, whichever contains content. get_secret_value从指定的密钥版本中检索加密字段SecretStringSecretBinary的内容,以包含内容者为准。
  • Your lambda role should have the following permissions depending on what is used您的 lambda 角色应具有以下权限,具体取决于所使用的权限
    • secretsmanager:GetSecretValue
    • kms:Decrypt required only if you use a customer-managed AWS KMS key to encrypt the secret. kms:Decrypt You do not need this permission to use the account's default AWS managed CMK for Secrets Manager.您不需要此权限即可将账户的默认 AWS 托管 CMK 用于 Secrets Manager。

hi @Prashanth kumar did u mean something as this: def get_secret():嗨@Prashanth kumar,你的意思是这样的:def get_secret():

secret_name = "MySecretForRedshift"
region_name = "us-east-1"

# Create a Secrets Manager client
session = boto3.session.Session()
client = session.client(
    service_name='secretsmanager',
    region_name=region_name
)

# In this sample we only handle the specific exceptions for the 'GetSecretValue' API.
# See https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html
# We rethrow the exception by default.

try:
    get_secret_value_response = client.get_secret_value(
        SecretId=secret_name
    )
except ClientError as e:
    if e.response['Error']['Code'] == 'DecryptionFailureException':
        # Secrets Manager can't decrypt the protected secret text using the provided KMS key.
        # Deal with the exception here, and/or rethrow at your discretion.
        raise e
    elif e.response['Error']['Code'] == 'InternalServiceErrorException':
        # An error occurred on the server side.
        # Deal with the exception here, and/or rethrow at your discretion.
        raise e
    elif e.response['Error']['Code'] == 'InvalidParameterException':
        # You provided an invalid value for a parameter.
        # Deal with the exception here, and/or rethrow at your discretion.
        raise e
    elif e.response['Error']['Code'] == 'InvalidRequestException':
        # You provided a parameter value that is not valid for the current state of the resource.
        # Deal with the exception here, and/or rethrow at your discretion.
        raise e
    elif e.response['Error']['Code'] == 'ResourceNotFoundException':
        # We can't find the resource that you asked for.
        # Deal with the exception here, and/or rethrow at your discretion.
        raise e
else:
    # Decrypts secret using the associated KMS CMK.
    # Depending on whether the secret is a string or binary, one of these fields will be populated.
    if 'SecretString' in get_secret_value_response:
        secret = json.loads(get_secret_value_response['SecretString'])
    else:
        secret = json.loads(base64.b64decode(get_secret_value_response['SecretBinary']))
return secret

I created an open source library called pysecret, here's the documentation of AWS Secret Manager integration: https://github.com/MacHu-GWU/pysecret-project#aws-key-management-service-and-secret-manager-integration我创建了一个名为 pysecret 的开源库,这里是 AWS Secret Manager 集成的文档: https://github.com/MacHu-GWU/pysecret-project#aws-key-management-service-and-secret-manager-integration

I can walk you through the easiest way to do that:我可以引导您完成最简单的方法:

  1. manually put your secret value in json or create one with pysecret .手动将您的秘密值放入 json 或使用pysecret创建一个。
from pysecret import AWSSecret

aws_profile = "my_aws_profile"
aws = AWSSecret(profile_name=aws_profile)

secret_id = "my-example-secret"
secret_data = {
    "host": "www.example.com",
    "port": 1234,
    "database": "mydatabase",
    "username": "admin",
    "password": "mypassword",
    "metadata": {
        "creator": "Alice"
    }
}
aws.deploy_secret(name=secret_id, secret_data=secret_data) # or you can pass kms_key_id if you created a custom kms key

Then you should be able to see the secret been created in your aws console.然后您应该能够在您的 aws 控制台中看到已创建的密钥。

  1. read your secret value in lambda function or in any of your python code .在 lambda function 或任何 python 代码中读取您的秘密值
aws = AWSSecret(profile_name=aws_profile) # in lambda code, don't need ``profile_name=aws_profile``
password = aws.get_secret_value(secret_id="my-example-secret", key="password") # mypassword
creator = aws.get_secret_value(secret_id="my-example-secret", key="metadata.creator") # Alice

NOTE, Lambda Function IAM Role Requirement to access the secret注意,Lambda Function IAM 角色要求访问密钥

  1. your Lambda IAM role has to have Secret Manager read access.您的 Lambda IAM 角色必须具有 Secret Manager 读取权限。 the aws built-in policy arn:aws:iam::aws:policy/SecretsManagerReadWrite has both read and write, if you are lazy, you can use it. aws 内置策略 arn:aws:iam::aws:policy/SecretsManagerReadWrite 具有读写功能,如果你很懒,可以使用它。 But I recommend you to create a custom policy only has the Read access.但我建议您创建一个只有读取权限的自定义策略。
  2. if you use auto-generated kms key for your secret, you have to use aws kms create-grant command to grant the Lambda Function IAM Role to access the kms key for encryption, here's how https://docs.aws.amazon.com/cli/latest/reference/kms/create-grant.html如果您为您的秘密使用自动生成的 kms 密钥,则必须使用aws kms create-grant命令来授予 Lambda Function IAM 角色以访问 kms 密钥以进行加密,以下是 Z5E056C500A1C4B6A7110B50A1C4B6A7110B5ADE 的方法Z5E056C500A1C4B6A7110B5ADE /cli/latest/reference/kms/create-grant.html
  3. if you use custom kms key, you should be able to edit the user of your kms key, select the Lambda Function IAM Role in your aws console.如果您使用自定义 kms 密钥,您应该能够在您的 aws 控制台中编辑您的 kms 密钥的用户 select Lambda Function IAM 角色。

Hope this answers your question.希望这能回答你的问题。

If this help, please Star my project https://github.com/MacHu-GWU/pysecret-project .如果这有帮助,请给我的项目https://github.com/MacHu-GWU/pysecret-project 加注星标。

AWS provide some template for some supported database engines such as MySQL etc, please take a look at this template : AWS 为一些受支持的数据库引擎提供了一些模板,例如 MySQL 等,请查看此模板

For unsupported db, check this对于不受支持的数据库,请检查

The template provided above will give you an example for customizing for your own function.上面提供的模板将为您提供自定义 function 的示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在没有 AWS 机密管理器的情况下使用本地机密测试 Lambda function - Test Lambda function with secrets locally without AWS secrets manager 从 Lambda function 中的 AWS Secrets Manager 检索密钥 - Retrieve secrets from AWS Secrets Manager in a Lambda function 如何通过 python 更新 AWS Secrets Manager? - How to update AWS Secrets Manager via python? 使用AWS Secrets Manager连接到Postgres数据库 - Connect to Postgres database using AWS Secrets Manager 使用 GetSecretValue AWS 机密管理器时出现 InvalidSignatureException API - InvalidSignatureException in using GetSecretValue AWS secrets manager API 如何使用 python 从存储在 AWS 的 Secrets Manager 中的私钥生成 OpenSSH RSA 密钥? - How can I generate OpenSSH RSA key using python from the private key stored in Secrets manager in AWS? 如何使用Secrets Manager编写用于旋转RDS密码的lambda函数? - How to write lambda function for Rotation of RDS password using secrets manager? 在 AWS Glue 中管理 AWS Secrets Manager - Managing AWS Secrets Manager in AWS Glue 如何使用 aws 控制台将带有库的 python 代码从 Windows 本地机器上传到 aws lambda - how to upload python code with libraries to aws lambda from windows local machine using aws console 将 RDS 机密注入 Lambda 中的 Python - Inject RDS secrets to Python in Lambda
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM