Toegang tot AWS S3 vanaf Lambda binnen VPC

Over het algemeen ben ik behoorlijk in de war door AWS Lambda binnen een VPC te gebruiken. Het probleem is dat Lambda een time-out heeft terwijl hij probeert toegang te krijgen tot een S3-bucket. De oplossing lijkt een VPC-eindpunt te zijn.

Ik heb de Lambda-functie aan een VPC toegevoegd zodat deze toegang heeft tot een door RDS gehoste database (niet weergegeven in de onderstaande code, maar functioneel). Nu heb ik echter geen toegang tot S3 en bij elke poging om dit te doen, treedt een time-out op.

Ik heb geprobeerd een VPC S3-eindpunt te maken, maar er is niets veranderd.

VPC-configuratie

Ik gebruik een eenvoudige VPC die standaard is gemaakt wanneer ik voor het eerst een EC2-instantie heb gemaakt. Het heeft vier subnetten, allemaal standaard gemaakt.

VPC-routetabel

_Destination - Target - Status - Propagated_
172.31.0.0/16 - local - Active - No
pl-63a5400a (com.amazonaws.us-east-1.s3) - vpce-b44c8bdd - Active - No
0.0.0.0/0 - igw-325e6a56 - Active - No

Eenvoudige S3-download Lambda:

import boto3
import pymysql
from StringIO import StringIO
def lambda_handler(event, context):
    s3Obj = StringIO()
    return boto3.resource('s3').Bucket('marineharvester').download_fileobj('Holding - Midsummer/sample', s3Obj)

Antwoord 1, autoriteit 100%

Er is een andere oplossing met betrekking tot VPC-eindpunten.

Kies op de AWS-console VPC-service en vervolgens Eindpunten. Maak een nieuw eindpunt, koppel het aan de s3-service

Selectie van VPC S3-eindpunt

en selecteer vervolgens de VPC en routetabel.

Selecteer vervolgens het toegangsniveau (volledig of aangepast) en het zal werken.


Antwoord 2, autoriteit 73%

Bij boto3 zijn de S3-urls standaard virtueel, waarvoor vervolgens internettoegang moet worden omgezet in regiospecifieke URL’s. Dit zorgt ervoor dat de Lambda-functie blijft hangen tot de time-out.

Om dit op te lossen, moet u een Config-object gebruiken bij het maken van de client, dat boto3 vertelt om in plaats daarvan op padgebaseerde S3-urls te maken:

import boto3 
import botocore
client = boto3.client('s3', 'ap-southeast-2', config=botocore.config.Config(s3={'addressing_style':'path'}))

Houd er rekening mee dat de regio in de aanroep de regio moet zijn waarnaar u de lambda en het VPC-eindpunt implementeert.

Dan kunt u de prefixlijst pl-xxxxxxgebruiken voor het VPC-eindpunt binnen de Lambda-beveiligingsgroep en toch toegang krijgen tot S3.

Hier is een werkend CloudFormation-scriptdat dit aantoont. Het creëert een S3-bucket, een lambda (die records in de bucket plaatst) die is gekoppeld aan een VPC die alleen privésubnetten en het VPC-eindpunt bevat, en noodzakelijke IAM-rollen.


Antwoord 3, autoriteit 17%

Er is nog een probleem dat te maken heeft met subnetten en routes dat niet in de andere antwoorden wordt behandeld, dus ik maak een apart antwoord aan met de voorwaarde dat alle bovenstaande antwoorden van toepassing zijn. Je moet ze allemaal goed hebben voor de lambda-functie om toegang te krijgen tot S3.

Als u een nieuw AWS-account aanmaakt, wat ik afgelopen herfst heb gedaan, wordt er geen routetabel automatisch gekoppeld aan uw standaard VPC (zie Routetabellen -> Subnetkoppelingen in de console).

Dus als je de instructies volgt om een ​​eindpunt te maken en een route voor dat eindpunt te maken, wordt er geen route toegevoegd, omdat er geen subnet is om het op te zetten. En zoals gewoonlijk krijg je bij AWS geen foutmelding…

Wat u moet doen is een subnet maken voor uw lambda-functie, dat subnet koppelen aan de routetabel en de lambda-functie, en dan de Endpoint-instructies opnieuw uitvoeren en u zult, indien succesvol, een routetabel vinden met drie items zoals dit:

Destination     Target
10.0.0.0/16     Local
0.0.0.0/0       igw-1a2b3c4d
pl-1a2b3c4d     vpce-11bb22cc

Als je maar twee items hebt (geen ‘pl-xxxxx’ entry), dan ben je er nog niet in geslaagd.

Einde denk ik dat het geen verrassing zou moeten zijn dat een Lambda-functie een subnet nodig heeft om op te leven, zoals elke andere entiteit in een netwerk. En het is waarschijnlijk aan te raden dat het niet op hetzelfde subnet leeft als uw EC2-instanties omdat Lambda mogelijk verschillende routes of beveiligingsmachtigingen nodig heeft. Merk op dat de GUI in Lambda echt wil dat je twee subnetten hebt in twee verschillende Azs die ook een goed idee is.


4, Autoriteit 12%

De oorzaak van mijn probleem heeft de uitgaande regels van mijn beveiligingsgroep niet correct geconfigureerd. Specifiek moest ik aangepaste protocol uitgaande regel toevoegen met een bestemming PL-XXXXXXXX (de S3-service. De werkelijke waarde werd verstrekt door de AWS-console).

Other episodes