我正在嘗試將 aws api 網關連接到駐留在 VPC 中的 lambda 函式,然后檢索密鑰管理器以使用帶有 boto3 的 python 代碼訪問資料庫。資料庫和 vpc 端點是在私有子網中創建的。
拉姆達函式
def test_secret():
secret = "mysecret"
region = "MY-REGION" :)
session = boto3.session.Session()
client = session.client(
service_name="secretsmanager",
region_name=region
)
secret_value_response = client.get_secret_value(SecretId=secret)
try:
result = json.loads(secret_value_response["SecretString"])
except Exception as e:
result = "Error found: {}".format(e)
return result
def handler(event, context):
get_secrets = test_secret() # THE CODE FAIL HERE IN CLOUDWATCH
try:
some_string = event["queryStringParameters"]["some_string"]
response = {}
response["statusCode"] = 200
response["body"] = some_string " " get_secrets["name"]
print("secrets: ", some_string " " get_secrets["name"])
except Exception as e:
response = "Error: {}".format(e)
return response
地形
安全組
resource "aws_security_group" "db" {
name = "db"
vpc_id = aws_vpc.default.id
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 5432
to_port = 5432
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
拉姆達
resource "aws_lambda_function" "lambda_test" {
function_name = "lambda-test"
...
# Attach Lambda to VPC
vpc_config {
subnet_ids = [aws_subnet.private_subnet.id]
security_group_ids = [aws_security_group.db.id]
}
}
resource "aws_iam_policy" "lambda_test" {
name = "lambda-test"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:CreateLogGroup",
"logs:PutLogEvents",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSubnets",
"ec2:DescribeVpcs",
"ec2:DescribeNetworkInterfaces",
"ec2:CreateNetworkInterface",
"ec2:DeleteNetworkInterface",
"ec2:AttachNetworkInterface",
"ec2:AssignPrivateIpAddresses",
"ec2:UnassignPrivateIpAddresses",
"autoscaling:CompleteLifecycleAction",
"secretsmanager:GetSecretValue"
],
"Resource": [
"arn:aws:lambda:::${aws_lambda_function.lambda_test.arn}",
"arn:aws:lambda:::${aws_lambda_function.lambda_test.arn}/*"
]
},
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": [
"arn:aws:lambda:::${data.aws_secretsmanager_secret.my_secret.arn}",
"arn:aws:lambda:::${data.aws_secretsmanager_secret.my_secret.arn}/*"
]
}
]
}
EOF
}
resource "aws_iam_role" "lambda_test_role" {
name = "lambda-test-role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Id": "",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": [
"lambda.amazonaws.com",
"secretsmanager.amazonaws.com"
]
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "lambda_test" {
policy_arn = aws_iam_policy.lambda_test.arn
role = aws_iam_role.lambda_test_role.name
}
resource "aws_iam_role_policy_attachment" "lambda_test_vpc_access" {
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
role = aws_iam_role.lambda_test_role.name
}
vpc 端點
resource "aws_vpc_endpoint" "vpc_endpoint" {
vpc_id = aws_vpc.default.id
service_name = "com.amazonaws.${var.AWS_REGION}.secretsmanager"
vpc_endpoint_type = "Interface"
security_group_ids = [aws_security_group.db.id]
private_dns_enabled = true
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Principal": "*",
"Resource": "*"
}
]
}
EOF
}
在不嘗試訪問secretsmanager的情況下,lambda 本身作業正常,我可以訪問 url 端點,提供引數然后在 cloudwatch 日志中查看結果,但是一旦我嘗試呼叫secretsmanagerlambda 函式端點,頁面就會回傳{"message": "Internal server error"},當我查看時在它說的日志上{"errorMessage": "Could not connect to the endpoint URL: \"https://secretsmanager.REGIONHIDDEN.amazonaws.com/\"", "errorType": "EndpointConnectionError"
上面有什么我做錯了嗎?
uj5u.com熱心網友回復:
如果您可以從 API Gateway 呼叫 Lambda 函式,那么您的問題標題“如何將 aws api 網關連接到 vpc 內的私有 lambda 函式”已經完成并且可以正常作業。
您的實際問題似乎只是從 VPC 中運行的 Lambda 函式內部訪問 Secrets Manager。
您將“db”安全組分配給 Lambda 函式也很奇怪。該安全組的入站/出站規則是什么?
完全不清楚您創建 VPC 終端節點的原因。我們應該做什么service_name = "foo"?什么是服務“foo”?這個 VPC 終端節點與 Lambda 函式有什么關系?如果這應該是 Secrets Manager 的 VPC 終端節點,則服務名稱應該是 "com.amazonaws.YOUR-REGION.secretsmanager".
如果您需要更多幫助,您需要編輯您的問題以提供以下資訊:任何相關安全組的入站和出站規則,以及嘗試呼叫 SecretsManager 的 Lambda 函式代碼。
更新:在評論和更新問題的澄清后,我認為問題是您缺少 VPC 端點的任何子網分配。此外,由于您要添加具有完全訪問權限的 VPC 策略,因此您可以完全忽略它,因為默認策略是完全訪問權限。我建議將 VPC 端點更改為以下內容:
resource "aws_vpc_endpoint" "vpc_endpoint" {
vpc_id = aws_vpc.default.id
service_name = "com.amazonaws.${var.AWS_REGION}.secretsmanager"
vpc_endpoint_type = "Interface"
subnet_ids = [aws_subnet.private_subnet.id]
security_group_ids = [aws_security_group.db.id]
private_dns_enabled = true
}
更新 2:您的 Lambda 函式的 IAM 策略的這一部分是錯誤的:
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": [
"arn:aws:lambda:::${data.aws_secretsmanager_secret.my_secret.arn}",
"arn:aws:lambda:::${data.aws_secretsmanager_secret.my_secret.arn}/*"
]
}
這使 Lambda 可以使用 Lambda 函式的 ARN 訪問密鑰,該 ARN 不是有效的密鑰 ARN。它應該是以下內容:
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "${data.aws_secretsmanager_secret.my_secret.arn}"
}
您的這部分政策也搞砸了:
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:CreateLogGroup",
"logs:PutLogEvents",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSubnets",
"ec2:DescribeVpcs",
"ec2:DescribeNetworkInterfaces",
"ec2:CreateNetworkInterface",
"ec2:DeleteNetworkInterface",
"ec2:AttachNetworkInterface",
"ec2:AssignPrivateIpAddresses",
"ec2:UnassignPrivateIpAddresses",
"autoscaling:CompleteLifecycleAction",
"secretsmanager:GetSecretValue"
],
"Resource": [
"arn:aws:lambda:::${aws_lambda_function.lambda_test.arn}",
"arn:aws:lambda:::${aws_lambda_function.lambda_test.arn}/*"
]
您正在將此策略分配給 Lambda 函式。您在策略中列出的資源是 Lambda 函式應該有權訪問的資源。您沒有將 Lambda 函式本身列為資源。我不確定如何修復該部分策略,需要將其拆分為多個部分,或者只需將資源串列替換為"*".
此外,當您在 Terraform 中參考資源的.arn值時,您將獲得完整的 ARN,因此您不應為其添加任何前綴。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/430426.html
