Introduksjon til AWS serverløs applikasjonsmodell

1. Oversikt

I vår forrige artikkel implementerte vi allerede en full stack serverløs applikasjon på AWS, ved hjelp av API Gateway for REST-endepunkter, AWS Lambda for forretningslogikk, samt en DynamoDB som en database.

Imidlertid består distribusjonen av mange manuelle trinn, som kan bli uhåndterlig med økende kompleksitet og med antall miljøer.

I denne opplæringen vil vi nå diskutere hvordan du bruker AWS Serverless Application Model (SAM), som muliggjør en malbasert beskrivelse og automatisk distribusjon av serverløse applikasjoner på AWS.

I detalj vil vi se på følgende emner:

  • Grunnleggende om den serverløse applikasjonsmodellen (SAM), samt den underliggende CloudFormation
  • Definisjon av et serverfritt program ved bruk av SAM-mal-syntaksen
  • Automatisert distribusjon av applikasjonen ved hjelp av CloudFormation CLI

2. Grunnleggende

Som diskutert tidligere, gjør AWS oss i stand til å implementere helt serverløse applikasjoner ved hjelp av API Gateway, Lambda-funksjoner og DynamoDB. Utvilsomt gir det allerede mange fordeler for ytelse, pris og skalerbarhet.

Ulempen er imidlertid at vi trenger mange manuelle trinn i AWS-konsollen for øyeblikket, som å opprette hver funksjon, laste opp kode, opprette DynamoDB-tabellen, lage IAM-roller, lage API og API-struktur, etc.

For komplekse applikasjoner og med flere miljøer som test, iscenesettelse og produksjon, multipliserer innsatsen raskt.

Det er her CloudFormation for applikasjoner på AWS generelt, og Serverless Application Model (SAM) spesielt for serverløse applikasjoner, kommer til spill.

2.1. AWS CloudFormation

CloudFormation er en AWS-tjeneste for automatisk levering av AWS-infrastrukturressurser. En bruker definerer alle nødvendige ressurser i en tegning (kalt mal), og AWS tar seg av klargjøring og konfigurasjon.

Følgende begreper og konsepter er avgjørende for å forstå CloudFormation og SAM:

En mal er en beskrivelse av en applikasjon, hvordan den skal være strukturert i løpetid. Vi kan definere et sett med nødvendige ressurser, samt hvordan disse ressursene skal konfigureres. CloudFormation gir et vanlig språk for å definere maler, og støtter JSON og YAML som et format.

Ressurser er byggesteinene i CloudFormation. En ressurs kan være hva som helst, som en RestApi, en fase av en RestApi, en batch-jobb, en DynamoDB-tabell, en EC2-forekomst, et nettverksgrensesnitt, en IAM-rolle og mange flere. Den offisielle dokumentasjonen viser for øyeblikket rundt 300 ressurstyper for CloudFormation.

En bunke er instantiering av en mal. CloudFormation tar seg av klargjøring og konfigurering av stabelen.

2.2. Serverløs applikasjonsmodell (SAM)

Som så ofte kan bruk av kraftige verktøy bli veldig komplisert og uhåndterlig, noe som også er tilfelle for CloudFormation.

Derfor introduserte Amazon serverløs applikasjonsmodell (SAM). SAM startet med kravet om å gi en ren og grei syntaks for å definere serverløse applikasjoner. Foreløpig har den bare tre ressurstyper, som er Lambda-funksjoner, DynamoDB-tabeller og API-er.

SAM er basert på CloudFormation mal-syntaksen, slik at vi kan definere malen vår ved hjelp av den enkle SAM-syntaksen, og CloudFormation vil videre behandle den malen.

Mer informasjon er tilgjengelig på det offisielle GitHub-depotet samt i AWS-dokumentasjonen.

3. Forutsetninger

For den følgende opplæringen trenger vi en AWS-konto. En gratis nivåkonto bør være tilstrekkelig.

I tillegg til det, må vi ha AWS CLI installert.

Til slutt trenger vi en S3 Bucket i regionen vår, som kan opprettes via AWS CLI med følgende kommando:

$> aws s3 mb s3: // baeldung-sam-bucket

Mens opplæringen bruker baeldung-sam-bøtte i det følgende, vær oppmerksom på at bøttenavn må være unike, så du må velge navnet ditt.

Som demo-applikasjon bruker vi koden fra Å bruke AWS Lambda med API Gateway.

4. Opprette malen

I denne delen oppretter vi SAM-malen vår.

Vi tar først en titt på den overordnede strukturen, før vi definerer de enkelte ressursene.

4.1. Malens struktur

La oss først se på den generelle strukturen til malen vår:

AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS :: Serverless-2016-10-31' Beskrivelse: Baeldung Serverless applikasjonsmodelleksempel Ressurser: PersonTable: Type: AWS :: Serverless :: SimpleTable Properties: # Definer tabellegenskaper her StorePersonFunction: Type: AWS :: Serverless :: Funksjonsegenskaper: # Definer funksjonsegenskaper her GetPersonByHTTPParamFunction: Type: AWS :: Serverless :: Funksjonsegenskaper: # Definer funksjonsegenskaper her MyApi: Type: AWS :: Serverless :: Api Properties: # Definer API-egenskaper her

Som vi kan se, består malen av en overskrift og en kropp:

Overskriften spesifiserer versjonen av CloudFormation-malen (AWSTemplateFormatVersion) samt versjonen av SAM-malen vår (Forvandle). Vi kan også spesifisere en Beskrivelse.

Kroppen består av et sett med ressurser: hver ressurs har et navn, en ressurs Type, og et sett med Eiendommer.

SAM-spesifikasjonen støtter for tiden tre typer: AWS :: Serverløs :: Api, AWS :: Serverless :: Funksjon i tillegg til AWS :: Serverløs :: SimpleTable.

Når vi ønsker å distribuere eksempeleksemplet vårt, må vi definere en SimpleTable, to Funksjoner, samt en Api i vår mal-kropp.

4.2. DynamoDB tabelldefinisjon

La oss definere DynamoDB-tabellen vår nå:

AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS :: Serverless-2016-10-31' Beskrivelse: Baeldung Serverless applikasjonsmodelleksempel Ressurser: PersonTable: Type: AWS :: Serverless :: SimpleTable Properties: PrimaryKey: Name: id Type: Nummertabell Navn: Person

Vi trenger bare å definere to egenskaper for våre SimpleTable: tabellnavnet, samt en primærnøkkel, som kalles id og har typen Nummer i vårt tilfelle.

En full liste over støttede SimpleTable eiendommer finner du i den offisielle spesifikasjonen.

Merk: Siden vi bare vil få tilgang til tabellen ved hjelp av primærnøkkelen, er AWS :: Serverløs :: SimpleTable er tilstrekkelig for oss. For mer komplekse krav, den opprinnelige CloudFormation-typen AWS :: DynamoDB :: Tabell kan brukes i stedet.

4.3. Definisjon av Lambda-funksjonene

Deretter la oss definere våre to funksjoner:

AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS :: Serverless-2016-10-31' Beskrivelse: Baeldung Serverless applikasjonsmodelleksempel Ressurser: StorePersonFunction: Type: AWS :: Serverless :: Funksjonsegenskaper: Handler: com.baeldung .lambda.apigateway.APIDemoHandler :: handleRequest Runtime: java8 Timeout: 15 MemorySize: 512 CodeUri: ../target/aws-lambda-0.1.0-SNAPSHOT.jar Policyer: DynamoDBCrudPolicy Environment: Variables: TABLE_NAME:! Ref PersonTable Events: StoreApi: Type: Api Egenskaper: Sti: / persons Metode: PUT RestApiId: Ref: MyApi GetPersonByHTTPParamFunction: Type: AWS :: Serverless :: Funksjonsegenskaper: Handler: com.baeldung.lambda.apigateway.APIDemoHandler :: handleGetByParam Runtime: java8 Timeout : 15 MemorySize: 512 CodeUri: ../target/aws-lambda-0.1.0-SNAPSHOT.jar Policies: DynamoDBReadPolicy Environment: Variables: TABLE_NAME:! Ref PersonTable Events: GetByPathApi: Type: Api Properties: Path: / persons / { id} Metode: GET RestApiId: Ref: MyApi GetByQueryApi: Type: Api Propertie s: Sti: / personer Metode: GET RestApiId: Ref: MyApi

Som vi kan se, har hver funksjon de samme egenskapene:

Behandler definerer logikken til funksjonen. Når vi bruker Java, er det klassenavnet inkludert pakken, i forbindelse med metodens navn.

Kjøretid definerer hvordan funksjonen ble implementert, som er Java 8 i vårt tilfelle.

Pause definerer hvor lang tid utførelsen av koden maksimalt kan ta før AWS avslutter henrettelsen.

MemorySizedefinerer størrelsen på det tildelte minnet i MB. Det er viktig å vite at AWS tildeler CPU-ressurser proporsjonalt til MemorySize. Så når det gjelder en CPU-intensiv funksjon, kan det være nødvendig å øke MemorySize, selv om funksjonen ikke trenger så mye minne.

CodeUridefinerer plasseringen til funksjonskoden. Den refererer for øyeblikket til målmappen i vårt lokale arbeidsområde. Når vi laster opp funksjonen vår senere ved hjelp av CloudFormation, får vi en oppdatert fil med referanse til et S3-objekt.

Retningslinjerkan inneholde et sett med AWS-administrerte IAM-policyer eller SAM-spesifikke policymal. Vi bruker SAM-spesifikke retningslinjer DynamoDBCrudPolicy for StorePersonFunction og DynamoDBReadPolicy til GetPersonByPathParamFunction og GetPersonByQueryParamFunction.

Miljødefinerer miljøegenskaper ved kjøretid. Vi bruker en miljøvariabel for å holde navnet på DynamoDB-tabellen.

arrangementerkan holde et sett med AWS-hendelser, som skal kunne utløse funksjonen. I vårt tilfelle definerer vi en Begivenhet av typen Api. Den unike kombinasjonen av sti, en HTTP Metode, og en RestApiId kobler funksjonen til en metode for API-en vår, som vi vil definere i neste avsnitt.

En full liste over støttede Funksjon eiendommer finner du i den offisielle spesifikasjonen.

4.4. API-definisjon som Swagger File

Etter å ha definert DynamoDB-tabellen og funksjonene, kan vi nå definere API.

Den første muligheten er å definere API-en vår innebygd ved hjelp av Swagger-formatet:

AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS :: Serverless-2016-10-31' Beskrivelse: Baeldung Serverless Application Model example Resources: MyApi: Type: AWS :: Serverless :: Api Properties: StageName: test EndpointConfiguration: REGIONAL DefinitionBody: swagger: "2.0" info: title: "TestAPI" baner: / persons: get: parameters: - name: "id" in: "query" required: true type: "string" x-amazon-apigateway-request -validator: "Validate query string parameters and \ \ headers" x-amazon-apigateway-integration: uri: Fn :: Sub: arn: aws: apigateway: $ {AWS :: Region}: lambda: path / 2015-03- 31 / functions / $ {GetPersonByHTTPParamFunction.Arn} / invokations-svar: {} httpMethod: "POST" type: "aws_proxy" put: x-amazon-apigateway-integration: uri: Fn :: Sub: arn: aws: apigateway: $ {AWS :: Region}: lambda: path / 2015-03-31 / functions / $ {StorePersonFunction.Arn} / invokationssvar: {} httpMethod: "POST" type: "aws_proxy" / persons / {id}: get: parametere: - navn: "id" i: "sti" kreves: sann type: "streng" svar: {} xa mazon-apigateway-integration: uri: Fn :: Sub: arn: aws: apigateway: $ {AWS :: Region}: lambda: path / 2015-03-31 / functions / $ {GetPersonByHTTPParamFunction.Arn} / påkallingssvar: { } httpMethod: "POST" type: "aws_proxy" x-amazon-apigateway-request-validators: Validate query string parameters and headers: validateRequestParameters: true validateRequestBody: false

Våre Api har tre egenskaper: Artistnavnetdefinerer scenen for API, EndpointConfigurationdefinerer om API er regional eller kantoptimalisert, og DefinisjonBody inneholder den faktiske strukturen til API.

I DefinisjonBodydefinerer vi tre parametere: swagger versjon som “2.0”, den info: tittel: som “TestAPI”, samt et sett med stier.

Som vi kan se, er stier representerer API-strukturen, som vi måtte definere manuelt før. De stier i Swagger tilsvarer ressursene i AWS-konsollen. Akkurat slik, hver sti kan ha en eller flere HTTP-verb, som tilsvarer metodene i AWS-konsollen.

Hver metode kan ha en eller flere parametere, samt en forespørselsvalidator.

Den mest spennende delen er attributtet x-amazon-apigateway-integrasjon, som er en AWS-spesifikk utvidelse av Swagger:

uri spesifiserer hvilken Lambda-funksjon som skal påberopes.

svar spesifisere regler for hvordan du skal transformere svarene som returneres av funksjonen. Ettersom vi bruker Lambda Proxy Integration, trenger vi ingen spesifikke regler.

type definerer at vi vil bruke Lambda Proxy Integration, og dermed må vi sette httpMetode til "POST", da dette er hva Lambda-funksjoner forventer.

En full liste over støttede Api eiendommer finner du i den offisielle spesifikasjonen.

4.5. Implisitt API-definisjon

Et annet alternativ er å definere API implisitt innenfor funksjonsressursene:

AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS :: Serverless-2016-10-31' Beskrivelse: Baeldung Serverless applikasjonsmodell Eksempel med implisitt API-definisjon Globals: Api: EndpointConfiguration: REGIONALt navn: "TestAPI" Ressurser: StorePersonFunction: Type: AWS :: Serverløs :: Funksjonsegenskaper: Handler: com.baeldung.lambda.apigateway.APIDemoHandler :: handleRequest Runtime: java8 Timeout: 15 MemorySize: 512 CodeUri: ../target/aws-lambda-0.1.0-SNAPSHOT .jar Retningslinjer: - DynamoDBCrudPolicy: TableName:! Ref PersonTable Environment: Variables: TABLE_NAME:! Ref PersonTable Events: StoreApi: Type: Api Properties: Path: / persons Method: PUT GetPersonByHTTPParamFunction: Type: AWS :: Serverless :: Function Properties: Handler: com.baeldung.lambda.apigateway.APIDemoHandler :: handleGetByParam Runtime: java8 Timeout: 15 MemorySize: 512 CodeUri: ../target/aws-lambda-0.1.0-SNAPSHOT.jar Policyer: - DynamoDBReadPolicy: TableName:! Ref. PersonTable-miljø: Variabler: TABLE_NAME:! Ref PersonTable E ventiler: GetByPathApi: Type: Api Egenskaper: Sti: / persons / {id} Metode: GET GetByQueryApi: Type: Api Egenskaper: Sti: / persons Metode: GET

Som vi kan se, er malen vår litt annerledes nå: Det er ingen AWS :: Serverløs :: Api ressurs lenger.

Imidlertid tar CloudFormation arrangementer attributter av typen Api som en implisitt definisjon og oppretter en API uansett. Så snart vi tester applikasjonen vår, ser vi at den oppfører seg likt som når vi definerer API eksplisitt ved hjelp av Swagger.

Dessuten er det en Globale seksjon, der vi kan definere navnet på APIen vår, samt at endepunktet vårt skal være regionalt.

Bare en begrensning oppstår: når vi implisitt definerer API-en, kan vi ikke angi et scenenavn. Dette er grunnen til at AWS vil lage en scene kalt Prod i alle fall.

5. Implementering og test

Etter å ha opprettet malen, kan vi nå fortsette med distribusjon og testing.

For dette vil vi laste opp funksjonskoden vår til S3 før vi utløser den faktiske distribusjonen.

Til slutt kan vi teste applikasjonen vår ved hjelp av hvilken som helst HTTP-klient.

5.1. Kodeopplasting til S3

I et første trinn må vi laste opp funksjonskoden til S3.

Vi kan gjøre det ved å ringe CloudFormation via AWS CLI:

$> aws cloudformation package --template-file ./sam-templates/template.yml --s3-bucket baeldung-sam-bucket --output-template-file ./sam-templates/packaged-template.yml

Med denne kommandoen utløser vi CloudFormation for å ta funksjonskoden spesifisert i CodeUri: og å laste den opp til S3. CloudFormation vil opprette en pakket-mal.yml fil, som har samme innhold, bortsett fra det CodeUri: peker nå på S3-objektet.

La oss ta en titt på CLI-utgangen:

Laster opp til 4b445c195c24d05d8a9eee4cd07f34d0 92702076 / 92702076.0 (100,00%) Vellykkede gjenstander og skrev utskriftsmal til filen pakket-template.yml. Utfør følgende kommando for å distribuere den pakkede malen aws cloudformation deploy --template-file c: \ zz_workspace \ tutorials \ aws-lambda \ sam-templates \ packaged-template.yml - stack-name 

5.2. Utplassering

Nå kan vi utløse den faktiske distribusjonen:

$> aws cloudformation deploy --template-file ./sam-templates/packaged-template.yml - stack-name baeldung-sam-stack --capabilities CAPABILITY_IAM

Siden stakken vår også trenger IAM-roller (som funksjonenes roller for å få tilgang til DynamoDB-tabellen), må vi eksplisitt erkjenne at ved å spesifisere –Capabilities parameter.

Og CLI-utgangen skal se ut som:

Venter på at endringssett skal opprettes .. Venter på at stabelen skal opprettes / oppdateres. Fullført opprettet / oppdatert stabelen - baeldung-sam-stack

5.3. Distribusjonsgjennomgang

Etter distribusjonen kan vi se gjennom resultatet:

$> aws skyformation beskriver-stack-ressurser - stack-navn baeldung-sam-stack

CloudFormation vil liste opp alle ressurser som er en del av stakken vår.

5.4. Test

Til slutt kan vi teste applikasjonen vår ved hjelp av hvilken som helst HTTP-klient.

La oss se noen eksempler krøll kommandoer vi kan bruke til disse testene.

StorePersonFunction:

$> curl -X PUT '//0skaqfgdw4.execute-api.eu-central-1.amazonaws.com/test/persons' \ -H 'content-type: application / json' \ -d '{"id": 1, "name": "John Doe"} '

GetPersonByPathParamFunction:

$> curl -X GET '//0skaqfgdw4.execute-api.eu-central-1.amazonaws.com/test/persons/1' \ -H 'content-type: application / json'

GetPersonByQueryParamFunction:

$> curl -X GET '//0skaqfgdw4.execute-api.eu-central-1.amazonaws.com/test/persons?id=1' \ -H 'content-type: application / json'

5.5. Rydde opp

Til slutt kan vi rydde opp ved å fjerne stabelen og alle inkludert ressurser:

aws cloudformation delete-stack - stack-name baeldung-sam-stack

6. Konklusjon

I denne artikkelen så vi på AWS Serverless Application Model (SAM), som muliggjør en malbasert beskrivelse og automatisert distribusjon av serverløse applikasjoner på AWS.

I detalj diskuterte vi følgende emner:

  • Grunnleggende om den serverløse applikasjonsmodellen (SAM), samt den underliggende CloudFormation
  • Definisjon av et serverfritt program ved bruk av SAM-mal-syntaksen
  • Automatisert distribusjon av applikasjonen ved hjelp av CloudFormation CLI

Som vanlig er all koden for denne artikkelen tilgjengelig på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found