Wie kann ich Lambda-Funktionen in einer Amazon VPC verwenden, um Secrets Manager-Geheimnisse abzurufen?

Lesedauer: 4 Minute
0

Meine AWS-Lambda-Funktion in einer Amazon Virtual Private Cloud (Amazon VPC) kann nicht auf AWS Secrets Manager zugreifen.

Kurzbeschreibung

Lambda-Funktionen werden in einer sicheren Amazon VPC mit Zugriff auf AWS-Services und das Internet ausgeführt. Der Lambda-Service besitzt diese Amazon VPC und ist nicht mit Ihrer standardmäßigen Amazon VPC verbunden.

Lambda-Funktionen, die mit Ihrer Amazon VPC verbunden sind, können nur dann auf das Internet zugreifen, wenn Sie Ihre Amazon VPC so konfigurieren, dass sie den Zugriff ermöglicht. Die Netzwerkschnittstellen, die Lambda innerhalb Ihrer Amazon VPC erstellt, verwenden private IP-Adressen und können keine Verbindung zum Internet über ein Internet-Gateway herstellen.

Weitere Informationen finden Sie unter Internet- und Servicezugriff für VPC-verbundene Funktionen.

Hinweis: Es empfiehlt sich, Lambda-Funktionen nicht in einer Amazon VPC zu platzieren, es sei denn, die Funktion muss auf andere Ressourcen in der Amazon VPC zugreifen.

Behebung

Lambda-Netzwerkkonfiguration

Befolgen Sie eine der folgenden Methoden, um einer Lambda-Funktion, die mit einer Amazon VPC verbunden ist, den Zugriff auf Secrets Manager zu ermöglichen:

Hängen Sie ein NAT-Gateway an ein privates Subnetz an

Geben Sie Ihrer Funktion Internetzugang. Platzieren Sie die Funktion in private Subnetze und leiten Sie den ausgehenden Datenverkehr an ein NAT-Gateway in einem öffentlichen Subnetz weiter. Das NAT-Gateway hat eine öffentliche IP-Adresse und stellt über das Internet-Gateway der VPC eine Verbindung zum Internet her.

Verwenden Sie einen Amazon VPC-Schnittstellenendpunkt

Richten Sie einen Endpunkt der Amazon-VPC-Schnittstelle für Secrets Manager ein. Ihre Amazon VPC verbindet dann Secrets Manager über Ihre Lambda-Funktion ohne Internetzugang. Überprüfen Sie, ob die Sicherheitsgruppe des Amazon VPC-Endpunkts eingehenden Datenverkehr über Port 443 aus der Lambda-Sicherheitsgruppe oder dem IP-Adressenbereich zulässt. Überprüfen Sie außerdem, ob die Sicherheitsgruppe ausgehenden Datenverkehr über Port 443 an die Sicherheitsgruppe des Amazon VPC-Endpunkts oder den IP-Adressenbereich zulässt.

Hinweis: Wenn Sie VPC-Endpunkte von AWS PrivateLink verwenden, stellen Sie sicher, dass Sie die DHCP-Optionen mit Ihrer Amazon VPC for Domain Name System (DNS) konfigurieren. Weitere Informationen finden Sie unter DNS-Attribute für Ihre Amazon VPC.

Die folgende AWS CloudFormation-Vorlage richtet beispielsweise eine Lambda-Funktion innerhalb des privaten Subnetzes einer VPC ein. Dies ermöglicht den privaten Zugriff auf den AWS Secrets Manager über VPC-Endpunkte:

AWSTemplateFormatVersion: "2010-09-09"
Description: "Lambda Secrets Manager"
Resources:
    EC2SecurityGroup:
        Type: "AWS::EC2::SecurityGroup"
        Properties:
            GroupDescription: "launch-wizard-19 created 2022-03-23T11:10:16.721+05:30"
            GroupName: "launch-wizard-19"
            VpcId: !Ref EC2VPC
            SecurityGroupIngress:
              -
                CidrIp: "10.0.0.0/16"
                FromPort: 443
                IpProtocol: "tcp"
                ToPort: 443
            SecurityGroupEgress:
              -
                CidrIp: "10.0.0.0/16"
                FromPort: 443
                IpProtocol: "tcp"
                ToPort: 443


    LambdaFunction:
        Type: "AWS::Lambda::Function"
        Properties:
            Description: "AWS Lambda to AWS Secrets Manager"
            FunctionName: "SecretsManagerLambda"
            Handler: "index.lambda_handler"
            Architectures:
              - "x86_64"
            Code:
              ZipFile: |
                import json
                import boto3
                client = boto3.client('secretsmanager')

                def lambda_handler(event, context):
                    response = client.get_secret_value(
                    SecretId='string',
                    VersionId='string',
                    VersionStage='string'
                    )
                    print(response)
                    # TODO implement
                    return {
                        'statusCode': 200,
                        'body': json.dumps('Hello from Lambda!')
                    }



            MemorySize: 128
            Role: !GetAtt IAMRole.Arn
            Runtime: "python3.11"
            Timeout: 30
            TracingConfig:
                Mode: "PassThrough"
            EphemeralStorage:
                Size: 512
            VpcConfig:
              SecurityGroupIds:
                - !Ref EC2SecurityGroup
              SubnetIds:
                - !Ref EC2Subnet

    EC2VPC:
        Type: "AWS::EC2::VPC"
        Properties:
            CidrBlock: "10.0.0.0/16"
            EnableDnsSupport: true
            EnableDnsHostnames: true
            InstanceTenancy: "default"

    EC2Subnet:
        Type: "AWS::EC2::Subnet"
        Properties:
            AvailabilityZone: !Sub "${AWS::Region}b"
            CidrBlock: "10.0.7.0/24"
            VpcId: !Ref EC2VPC
            MapPublicIpOnLaunch: false
            Tags:
              -
                Key: "Name"
                Value: "Private-new-availability"

    EC2VPCEndpoint:
        Type: "AWS::EC2::VPCEndpoint"
        Properties:
            VpcEndpointType: "Interface"
            VpcId: !GetAtt EC2Subnet.VpcId
            ServiceName: !Sub "com.amazonaws.${AWS::Region}.secretsmanager"
            PolicyDocument: |
                {
                  "Statement": [
                    {
                      "Action": "*",
                      "Effect": "Allow",
                      "Principal": "*",
                      "Resource": "*"
                    }
                  ]
                }
            SubnetIds:
              - !Ref EC2Subnet
            PrivateDnsEnabled: true
            SecurityGroupIds:
              - !Ref EC2SecurityGroup

    IAMRole:
        Type: "AWS::IAM::Role"
        Properties:
            Path: "/"
            RoleName: "Lambdapermissions"
            AssumeRolePolicyDocument: "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Action\":\"sts:AssumeRole\"}]}"
            ManagedPolicyArns:
              - !Ref IAMManagedPolicy


            Description: "Allows Lambda functions to call AWS services on your behalf."

    IAMManagedPolicy:
        Type: "AWS::IAM::ManagedPolicy"
        Properties:
            ManagedPolicyName: "LambdaSecretsPolicy"
            Path: "/"
            PolicyDocument: |
                {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Sid": "Statement1",
                            "Effect": "Allow",
                            "Action": [
                                "secretsmanager:GetSecretValue",
                                "ec2:CreateNetworkInterface",
                                "ec2:DescribeNetworkInterfaces",
                                "ec2:DeleteNetworkInterface"
                            ],
                            "Resource": "*"
                        }
                    ]
                }

Berechtigungen für Lambda-Ausführungsrollen

Erteilen Sie der Lambda-Ausführungsrolle Berechtigungen für den Zugriff auf Geheimnisse des Secrets Manager. Verwenden Sie den API-Aufruf GetSecretValue, um das Geheimnis des Secrets Manager abzurufen. Weitere Informationen finden Sie unter Beispiel: Berechtigung zum Abrufen geheimer Werte.

(Optional) Berechtigungen für den AWS Key Management Service (AWS KMS)

Wenn das Geheimnis des Secrets Manager mit einem vom Kunden verwalteten AWS-KMS-Schlüssel statt mit dem verwalteten Schlüssel aws/secretsmanager verschlüsselt ist, ist eine zusätzliche Konfiguration erforderlich. Stellen Sie sicher, dass Sie die API-Aktionsberechtigung Entschlüsseln entweder als Lambda-Ausführungsrolle oder als AWS-KMS-Schlüsselrichtlinie zulassen.

Ähnliche Informationen

Wie behebe ich Berechtigungsprobleme mit Lambda?