Comment puis-je utiliser les fonctions Lambda dans un Amazon VPC pour récupérer les secrets de Secrets Manager ?

Lecture de 5 minute(s)
0

Ma fonction AWS Lambda configurée dans un Amazon Virtual Private Cloud (Amazon VPC) ne peut pas accéder à AWS Secrets Manager.

Brève description

Les fonctions Lambda s'exécutent dans un Amazon VPC sécurisé avec accès à AWS et à Internet. Le service Lambda est propriétaire de cet Amazon VPC et n'est pas connecté à votre Amazon VPC par défaut.

Les fonctions Lambda connectées à votre Amazon VPC peuvent uniquement accéder à Internet si votre Amazon VPC a été configuré pour fournir un accès. Les interfaces réseau créées par Lambda au sein de votre Amazon VPC utilisent des adresses IP privées et ne peuvent pas se connecter à Internet via une passerelle Internet.

Pour en savoir plus, reportez-vous à Accès à Internet et aux services pour des fonctions connectées au VPC.

Remarque : il est déconseillé de placer des fonctions Lambda dans un Amazon VPC, sauf si la fonction doit accéder à d'autres ressources de l'Amazon VPC.

Résolution

Configuration du réseau Lambda

Choisissez l'une des méthodes suivantes pour autoriser une fonction Lambda connectée à un Amazon VPC à accéder à Secrets Manager :

associer une passerelle NAT à un sous-réseau privé

accorder un accès Internet à votre fonction placer la fonction dans des sous-réseaux privés, puis acheminer le trafic sortant vers une passerelle NAT dans un sous-réseau public. La passerelle NAT dispose d'une adresse IP publique et se connecte à Internet via la passerelle Internet du VPC.

Utilisation d'un point de terminaison d'interface Amazon VPC

Configurez un point de terminaison d'interface Amazon VPC pour Secrets Manager. Votre Amazon VPC se connecte alors à Secrets Manager à partir de votre fonction Lambda sans accès à Internet. Vérifiez que le groupe de sécurité du point de terminaison d'un VPC autorise le trafic entrant sur le port 443 en provenance du groupe de sécurité Lambda ou de la plage d'adresses IP. Vérifiez également que le groupe de sécurité Lambda autorise le trafic sortant sur le port 443 à destination du groupe de sécurité du point de terminaison d'un Amazon VPC ou de la plage d'adresses IP.

Remarque : si vous utilisez des points de terminaison d'un ](https://docs.aws.amazon.com/vpc/latest/privatelink/endpoint-services-overview.html)VPC AWS PrivateLink[, n'oubliez pas de configurer les options DHCP avec votre Amazon VPC pour le système de nom de domaine (DNS). Pour en savoir plus, reportez-vous à Attributs DNS pour votre Amazon VPC.

Par exemple, le modèle AWS CloudFormation suivant établit une fonction Lambda dans le sous-réseau privé d'un VPC. Cela permet d'accorder un accès privé à AWS Secrets Manager via les points de terminaison d'un 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": "*"
                        }
                    ]
                }

Autorisations relatives aux rôles d'exécution Lambda

Accordez des autorisations au rôle d'exécution Lambda pour accéder aux secrets de Secrets Manager. Utilisez l'appel d'API GetSecretValue pour obtenir le secret de Secrets Manager. Pour en savoir plus, reportez-vous à Exemple : autorisation de récupérer des valeurs de secrets.

(Facultatif) Autorisations AWS Key Management Service (AWS KMS)

Si le secret de Secrets Manager est chiffré avec une clé gérée par le client AWS KMS au lieu de la clé gérée aws/secretsmanager, une configuration supplémentaire est requise. Veillez à autoriser l'action d'API ](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html)Decrypt[ en tant que rôle d'exécution Lambda ou en tant que stratégie de clé AWS KMS.

Informations connexes

Comment puis-je résoudre les problèmes d'autorisation associés à Lambda ?