¿Cómo puedo utilizar las funciones de Lambda en una Amazon VPC para recuperar los secretos de Secrets Manager?

5 minutos de lectura
0

Mi función de AWS Lambda en una Amazon Virtual Private Cloud (Amazon VPC) no puede acceder a AWS Secrets Manager.

Breve descripción

Las funciones de Lambda se ejecutan en una Amazon VPC segura con acceso a los servicios de AWS e Internet. El servicio de Lambda es propietario de esta Amazon VPC y no está conectado a la Amazon VPC predeterminada.

Las funciones de Lambda conectadas a su Amazon VPC solo pueden acceder a Internet si configura su Amazon VPC de modo que les proporcione acceso. Las interfaces de red que Lambda crea en la Amazon VPC utilizan direcciones IP privadas y no pueden conectarse a Internet mediante una puerta de enlace de Internet.

Para obtener más información, consulte Acceso a Internet y a los servicios para funciones conectadas a la VPC.

Nota: Se recomienda no colocar funciones de Lambda en una Amazon VPC a menos que la función deba acceder a otros recursos de la Amazon VPC.

Solución

Configuración de una red de Lambda

Para permitir que una función de Lambda conectada a una Amazon VPC acceda a Secrets Manager, elija uno de estos métodos:

Asociación de una puerta de enlace NAT a una subred privada

Proporcione acceso a Internet a su función. Coloque la función en subredes privadas y dirija el tráfico de salida hacia una puerta de enlace NAT en una subred pública. La puerta de enlace NAT tiene una dirección IP pública y se conecta a Internet a través de la puerta de enlace de Internet de la VPC.

Utilización de un punto de conexión de la interfaz de Amazon VPC

Configure un punto de conexión de la interfaz de Amazon VPC para Secrets Manager. A continuación, su Amazon VPC se conectará a Secrets Manager desde su función de Lambda sin acceso a Internet. Compruebe que el grupo de seguridad del punto de conexión de Amazon VPC permita el tráfico de entrada en el puerto 443 desde el grupo de seguridad de Lambda o desde el intervalo de direcciones IP. Asimismo, compruebe que el grupo de seguridad de Lambda permita el tráfico de salida en el puerto 443 hacia el grupo de seguridad del punto de conexión de Amazon VPC o hacia el intervalo de direcciones IP.

Nota: Si utiliza puntos de conexión de VPC de AWS PrivateLink, asegúrese de configurar las opciones de DHCP con su Amazon VPC para el sistema de nombres de dominio (DNS). Para obtener más información, consulte Atributos DNS para la VPC.

Por ejemplo, la siguiente plantilla de AWS CloudFormation establece una función Lambda dentro de una subred privada de una VPC. Esto permite el acceso privado a AWS Secrets Manager a través de puntos de conexión de VPC:

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": "*"
                        }
                    ]
                }

Permisos del rol de ejecución de Lambda

Otorgue permisos al rol de ejecución de Lambda para acceder a los secretos de Secrets Manager. Utilice la llamada a la API GetSecretValue para obtener el secreto de Secrets Manager. Para obtener más información, consulte Ejemplo: permiso para recuperar valores secretos.

(Opcional) Permisos de AWS Key Management Service (AWS KMS)

Si el secreto de Secrets Manager está cifrado con una clave administrada por el cliente de AWS KMS en lugar de la clave administrada aws/secretsmanager, se requiere configuración adicional. Asegúrese de otorgar el permiso de acción de la API Decrypt como rol de ejecución de Lambda o como política de claves de AWS KMS.

Información relacionada

¿Cómo soluciono los problemas de permisos con Lambda?