VPC中的AWS Lambda访问Secrets Manager

问题描述 投票:0回答:1

我有一个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。直到我将其放入VPC之前,第一个仅输出秘密的Lambda都可以正常工作。但是我不知道在哪里寻找或如何配置它以允许Lambda与VPC内的EC2以及Secrets Manager进行通信。

amazon-web-services amazon-ec2 aws-lambda amazon-vpc aws-secrets-manager
1个回答
0
投票

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

不幸的是,VPC中的Lambda函数既没有Internet访问,也没有公共IP。从docs

将功能连接到公共子网不会赋予它Internet访问或公共IP地址

因此,当您使用boto3时:

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

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

两种纠正方法

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

  2. 专用子网中的设置VPC interface endpoint for Secrets Manager。这样,您的lambda函数将可以使用端点连接到Secrets Manager,而无需Internet。

© www.soinside.com 2019 - 2024. All rights reserved.