【问题标题】:AWS Lambda access Secrets Manager from within VPCAWS Lambda 从 VPC 中访问 Secrets Manager
【发布时间】:2020-09-28 03:02:40
【问题描述】:

我有一个 lambda,它需要与私有 VPC 中的 EC2 实例进行“本地”通信。 API 密钥存储在 Secrets Manager 中。

使用 Secrets Manager 提供的默认代码和必要的 IAM 角色,我可以在我的 Lambda 中从 Secrets Manager 读取 API 密钥:

# Use this code snippet in your app.
# If you need more information about configurations or implementing the sample code, visit the AWS docs:   
# https://aws.amazon.com/developers/getting-started/python/

import boto3
import base64
from botocore.exceptions import ClientError

def get_secret():

    secret_name = "MYSECRET"
    region_name = "ap-southeast-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:
 ... # Default error handling..
    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']
            return secret
        else:
            decoded_binary_secret = base64.b64decode(get_secret_value_response['SecretBinary'])
            return decoded_binary_secret
 
def lambda_handler(event, context):
    secrt = get_secret()

    return {
        'statusCode': 200,
        "headers": {
            'Access-Control-Allow-Origin': '*',
            'Content-Type': 'application/json'
        },
        'body': secrt 
    }             

此 Lambda 能够从 Secrets Manager 成功检索和打印 API 密钥。

为了与 EC2 实例通信,我有一个带有帮助层和一些简单测试代码的 Lambda:

import apihelper
import json

def lambda_handler(event, context):
  conn = apihelper.getConnection('API KEY')
  return {
    'statusCode': 200,
    "headers": {
      "Access-Control-Allow-Origin": "*"
    },
    'body': json.dumps(conn.listProducts())
  }

此 lambda 位于 VPC 子网中,并具有与 EC2 实例通信所需的安全组规则。硬编码API KEY 它成功地从 EC2 实例返回预期数据。

当我尝试组合它们以便 API 密钥不是硬编码时,Lambda 不再工作。没有错误消息,只是超时。

我试过了:

  • 将超时时间增加到一分钟以上
  • 在安全组上放置allow all入站和出站规则
  • 为 Secrets Manager 配置 VPC 终端节点

我认为我已将其范围缩小到 VPC。第一个打印出秘密的 Lambda 可以完美运行,直到我将它放入 VPC。但我不知道在哪里查看或如何配置它以允许 Lambda 与 VPC 内的 EC2 以及 Secrets Manager 进行通信。

【问题讨论】:

    标签: amazon-web-services amazon-ec2 aws-lambda amazon-vpc aws-secrets-manager


    【解决方案1】:

    没有错误消息,只是超时。

    很遗憾,VPC 中的 lambda 函数没有互联网访问权限,也没有公共 IP。来自docs

    将函数连接到公共子网不会为其提供互联网访问权限或公共 IP 地址

    因此,当你使用boto3:

        client = session.client(
            service_name='secretsmanager',
            region_name=region_name
        )
    

    连接到 Secrets Manager 超时,因为 boto3 无法从 VPC 连接到 Secrets Manager 管理器。

    有两种方法可以解决这个问题

    1. 将您的函数放在私有子网中,并使用NAT gateway/instance 和正确配置的路由表来提供互联网访问,从而提供对Secrets Manager 的访问。

    2. 在私有子网中设置 VPC interface endpoint for Secrets Manager。这样,您的 lambda 函数将能够使用端点连接到 Secrets Manager,而无需互联网。

    【讨论】:

    • 我在 Lambda 中使用 boto 来获取秘密(不在帮助程序中),但感谢您提供信息和参考。我会做一些研究,希望我可以调用 VPC 端点,而不是默认情况下调用任何 boto。
    • @react-dev 即使它的boto3 互联网连接或 VPC 端点也是必需的。我将修改答案以包括 boto3。
    • 谢谢。我现在正在研究这一切。我们希望避免使用路由表,因此请查看 VPC 端点。甚至直接通过python代码调用而不使用boto。
    • 谢谢。让它与 VPC 终端节点和安全组规则一起使用。正如你所说,我仍然可以使用本机 boto 来阅读秘密。
    • 嗨@react-dev,你能分享一下你是如何配置安全组的吗?我有相同的设置(VPC 中的 lambda,其端点连接到 secretmanager),但它仍然超时。谢谢
    猜你喜欢
    • 2023-01-01
    • 2020-10-26
    • 2021-10-03
    • 2021-01-19
    • 2020-11-27
    • 2023-03-18
    • 2017-02-08
    • 2020-04-24
    • 2018-11-20
    相关资源
    最近更新 更多