curve

Brug LocalStack og spar tid og besvær, når du udvikler dit AWS-system

Jacob Malling-Olesen

Software Craftsman - Graduate 23. maj 2019 øje

Hvis du arbejder med AWS, kan du nok genkende nogle af de udfordringer, der er forbundet med udvikling og test. Især hvis du er del af et større udviklingsteam, hvor I har et fælles testmiljø.

Problem 1: Flere tester på samme tid

Man ser ofte, at udviklere ikke har deres egen AWS-konto og derfor deles om adgangen til AWS, hvilket ofte resulterer i, at de skal sidde og vente på, at det bliver deres tur. Det kan også ske, at en udvikler har sat gang i en større test, der bliver afbrudt, fordi en anden udvikler lavede en ændring, mens testen kørte. Begge er problemer, der koster udviklerne tid og frustrationer.

Problem 2: Mængden af automatiserede tests

Som udvikler er det rart at kunne lægge sig op af automatiserede tests, når man sidder og ændrer/tilføjer funktionalitet, som sikkerhed for at man ikke ødelægger noget. Hvis man ikke har disse tests ved hånden, men hele tiden skal vente, før man kan få lov at teste, det man har udviklet, øger man udviklingstiden betragteligt. Dette betyder ofte, at testen lige skippes, ”fordi udviklere jo ikke laver fejl i deres kode”.

Løsningen er LocalStack

Med LocalStack kan du udvikle og teste nogle af de mest brugte AWS-services lokalt i et miljø, der fungerer på samme måde som AWS. Og dette er uden at være bundet op på en AWS-konto, du deler med andre.

De services, der er tilgængelige i LocalStack, er bl.a. S3, Lambda, SQS og API Gateway m.fl. Ligesom i AWS kan du i LocalStack sætte afhængigheder mellem dem, så fx en Lambda-funktion med en SQS EventSourceMapping reagerer, når SQS modtager en besked.

Dette tillader udvikling og test lokalt på din egen PC uden brug af AWS-ressourcer eller andre fælles miljøer. Der er ovenikøbet et lille dashboard med i LocalStack, hvor du bl.a. kan se, hvilke services du har deployet.

 

Sådan kommer du i gang med LocalStack

Der er flere måder at installere og starte for LocalStack, men den letteste måde er klart at gøre brug af Docker og Docker-compose. Udover Docker kræver dette kun, at du har installeret AWS CLI på dit system, før du er i gang.

  1. Opret docker-compose.yml fil
  2. Kør cli kommandoen “docker-compose up
  3. Når der bliver meldt ready, er LocalStack oppe at køre.
  4. Benyt AWS CLI-kommandoer med ”–endpoint-url” parameteren for at interagere med LocalStack. Fx ”aws –endpoint-url=http://localhost:4572 s3 ls” for at liste aktive buckets.
Figur 1: LocalStack is ready
Figur 1: LocalStack is ready

 

Docker-compose-eksempel

version: '2.1'

services:
  localstack:
    image: localstack/localstack:0.9.0
    ports:
      - "4567-4583:4567-4583"
      - "${PORT_WEB_UI-8080}:${PORT_WEB_UI-8080}"
    environment:
      - SERVICES=${SERVICES- }
      - DEBUG=1
      - DATA_DIR=/tmp/localstack/data
      - PORT_WEB_UI=${PORT_WEB_UI- }
      - LAMBDA_EXECUTOR=docker
      - KINESIS_ERROR_PROBABILITY=${KINESIS_ERROR_PROBABILITY- }
      - DOCKER_HOST=unix:///var/run/docker.sock
      - LOCALSTACK_HOSTNAME=${LOCALSTACK_HOSTNAME- }
      - DEFAULT_REGION=us-east-1
    volumes:
      - "localstack-vol:/tmp/localstack"
      - "/var/run/docker.sock:/var/run/docker.sock"
volumes:
  localstack-vol:

Her er et eksempel på en docker-compose.yml-fil, der starter LocalStack i version 0.9.0. Nogle vigtige punkter her er det image, der bruges, da man her bestemmer versionen, og det ikke er alle versioner af LocalStack, der fungerer på alle OS. Udover dette er det forskellige miljøvariabler, der kan sættes til forskellige ting.

DEBUG øger beskrivelsen af de fejlbeskeder, du får, når noget fejler. Det kan være en Lambda-funktion, der ikke er kodet korrekt, hvor du så får lidt mere information om, hvad der fejlede.

LAMBDA_EXECUTOR skal være sat til Docker for at køre Dotnet Lambdaer.

LOCALSTACK_HOSTNAME giver en IP-adresse, som skal bruges i Lambda-funktionerne, for at de kan kommunikere med LocalStack services.

Eksempel på Lambda-kode der konfigurerer en S3-klient til at snakke med LocalStack ved at bruge LOCALSTACK_HOSTNAME:

AmazonS3Config config = new AmazonS3Config
{
    ServiceURL = "http://" + Environment.GetEnvironmentVariable("LOCALSTACK_HOSTNAME") + ":4572",
    UseHttp = true,
    ForcePathStyle = true
};
S3Client = new AmazonS3Client("default", "default", config);

Se dette link for mere information om konfigurationer.

Virker også med Serverless

Foretrækker du at benytte Serverless, så har LocalStack lavet en Serverless LocalStack. Dette tillader dig at konfigurere dit Serverless system til at deploye til LocalStack i stedet for AWS.

 

Et lille system der fungerer ens på AWS og LocalStack

Dette er en konceptuel tegning, der viser et system, der kan køres både i AWS og LocalStack. Det består af en S3 bucket, der indeholder Dotnet Lambda-kode. Denne kode abonnerer på en SQS-besked og gemmer indholdet af den i en S3 bucket. Du kan altså sende en besked til en SQS. Dette event modtages så af en Lambda-funktion, der gemmer beskeden i en .txt fil i en S3 bucket. Denne fil kan herefter downloades, hvori du kan læse beskeden.

Figur 2: Systemarkitektur
Figur 2: Systemarkitektur

For at opsætte dette system manuelt på LocalStack køres følgende AWS CLI-kommandoer i denne rækkefølge:

  1. aws –endpoint-url=http://localhost:4572 s3api create-bucket –bucket store-bucket
  2. Byg dotnet.zip file med Lambda-funktionens kode.
  3. aws –endpoint-url=http://localhost:4574 lambda create-function –function-name SQSReader –runtime dotnetcore2.1 –handler LambdaSQSToS3::LambdaSQSToS3.Function::FunctionHandler –environment Variables={Environment=LocalStack} –role NotNeeded –zip-file fileb://dotnet.zip
  4. aws –endpoint-url=http://localhost:4576 sqs create-queue –queue-name SimpleSQS –attributes VisibilityTimeout=300
  5. aws –endpoint-url=http://localhost:4574 lambda create-event-source-mapping –batch-size 10 –event-source-arn arn:aws:sqs:elasticmq:000000000000:SimpleSQS –function-name SQSReader

Systemet kører nu og er klar til at modtage beskeder til SQS:

  1. aws –endpoint-url=http://localhost:4576 sqs send-message –queue-url http://localhost:4576/queue/SimpleSQS –message-body “testing 123”
  2. aws –endpoint-url=http://localhost:4572 s3 cp s3://store-bucket/SQSTest.txt localOutput.txt

Filen localOutput.txt vil nu indeholde beskeden ”testing 123”.

For at opsætte samme system ved brug af CloudFormation:

  1. aws –endpoint-url=http://localhost:4572 s3api create-bucket –bucket code-bucket
  2. aws –endpoint-url=http://localhost:4572 s3api put-object –body fileb://dotnet.zip –bucket code-bucket –key dotnet.zip
  3. aws –endpoint-url=http://localhost:4581 cloudformation create-stack –stack-name test –template-body file://AutomatedDeployment.yaml –parameters ParameterKey=DeploymentTarget,ParameterValue=LocalStack

Filen AutomatedDeployment.yaml er en konfigurationsfil, der beskriver systemet, som ellers opsættes manuelt ovenover. Den er lavet, så den kan deployes til både LocalStack og AWS afhængig af, hvilken miljøvariabel der bliver givet med. Det er altså muligt at benytte sig af CloudFormation i LocalStack.

Begrænsninger

Vi har opdelt de begrænsninger, vi har mødt i betydelige som nogle, der resulterer i manglende funktionalitet og mindre betydelige, som er nogle, der kræver manuel opsætning eller giver andre mindre problemer.

Betydelige begrænsninger

EC2 og ECS
Selv om LocalStack fungerer godt og har mange af de samme services som AWS, så er der nogle mangler. Den største er nok manglen af EC2 og ECS. Det er muligt at udvikle koden til EC2 og lokalt teste, at den kan snakke sammen med andre services som S3 ved at køre koden lokalt. Men dette giver langt fra EC2-fornemmelsen, og manglen af denne og ECS betyder, at services som Load Balancer og Auto Scaling heller ikke findes i LocalStack.

IAM
En anden service, der mangler, er IAM. Der er planer om at få tilføjet IAM, men det er ikke implementeret endnu. Dette gør det lettere at konfigurere services og teste funktioner, men gør også, at du ikke kan få tilføjet de rigtige IAM-tilladelser gennem sine lokale tests.

Mindre betydelige begrænsninger

API Gateway i CloudFormation
Der er også lidt problemer med CloudFormation, mere specifikt i forhold til API Gateway Methods. Disse er ikke i stand til at blive sat op gennem en CloudFormation-proces, men det er dog muligt manuelt at gøre dette. Så for at automatisere denne proces kræver det, at du manuelt opsætter scripts til at stå for opsætningen af API Gateway.

Kinesis
Kinesis har også lidt problemer. Hvis du har benyttet dig af Kinesis i LocalStack, kan du ikke starte LocalStack igen med ”docker-compose up”, da nogle interne indstillinger går i stykker. Man kan få LocalStack til at virke igen ved at genstarte Docker til fabriksindstillinger, men dette gør det besværligt at arbejde med Kinesis i LocalStack.

Forskelle mellem LocalStack og AWS

Selv om LocalStack og AWS fungerer meget ens, er der stadig forskel. Det kan gøre det lidt besværligt at arbejde med, når du har noget, der fungerer i AWS, men ikke kan genskabe det i LocalStack eller omvendt.

Krav om StartingPosition i EventSourceMappings

Et andet problem med EventSourceMappings og CloudFormation er at den kræver StartingPosition i SQS mappings. Dette er ikke et krav i AWS, da den ikke har nogen effekt for SQS, og fejlbeskeden du får fra LocalStack, er bare at din CloudFormation konfigurationsfil ikke er korrekt. Læs mere her.

Strukturen af SQS ARN

En af de store forskelle er, hvordan ARN bliver lavet til SQS. Normalt ser konstruktionen sådan ud “arn:aws:sqs:{region}:000000000000:{queue_navn}”, men i LocalStack er konstruktionen derimod “arn:aws:sqs:elasticmq:000000000000:{queue_navn}”.

Problem i CloudFormation

Især i CloudFormation er dette et problem. Hvis du laver en EventSourceMapping, er du nødt til manuelt at konstruere det meste af din ARN, da !GetAtt for SQS returnerer den forkerte ARN.

Problem i Dashboard

I LocalStacks dashboard viser dette problem sig også, da det viser den forkerte ARN til SQS. Og værre endnu, hvis du benytter dashboardet til at se dine services, og du har brugt den forkerte ARN til din EventSourceMapping. Så laves der visuelt en mapping mellem SQS og Lambda-funktionen, som ikke er korrekt. Laver du derimod en korrekt mapping, der fungerer i koden, vises denne ikke i dashboardet.

Figur 3: Dashboard der viser en Lambda-funktion “wrongReader”, der er forbundet med den forkerte ARN og derfor ikke bliver kaldt af SQS. Den rigtige Lambda-funktion “reader” er derimod korrekt forbundet og bliver kaldt af SQS.
Figur 3: Dashboard der viser en Lambda-funktion “wrongReader”, der er forbundet med den forkerte ARN og derfor ikke bliver kaldt af SQS. Den rigtige Lambda-funktion “reader” er derimod korrekt forbundet og bliver kaldt af SQS.

Samtidig er der også andre services, som slet ikke vises i dashboardet. Her er der bl.a. tale om API Gateway, som du kun kan se gennem CLI, hvis du spørger efter den.

Så skal du bruge LocalStack eller ej?

Vi har samlet fordele og ulemper, så du let kan se, om LocalStack kunne være noget for dig.

Fordele ved LocalStack

  • Kræver ingen AWS-konto.
  • Minder meget om AWS. Især hvis du er vant til at benytte AWS CLI.
  • Ingen bekymring for at gøre noget forkert og ødelægge systemet.
  • Du er hurtigt i gang, selv uden megen AWS-erfaring.
  • Bliver aktivt opdateret og vedligeholdt.
  • Udviklere bruger ikke unødvendig tid på at vente på tur til at udvikle og teste.
  • Fungerer også til Serverless hvis du henter LocalStacks Serverless plugin.
  • Fungerer godt til services, der kommunikerer med hinanden som Lambda, S3 osv.
  • Opdateres og fejlrettes aktivt og ofte.

Ulemper ved LocalStack

  • Kan være svært, indtil du finder de steder, hvor LocalStack opfører sig forskelligt fra AWS.
  • Mangler visse services som IAM, EC2 and ECS, hvilket gør det sværere at få en 1-1 oplevelse.
  • Der kan ske fejl, der kræver en genstart af LocalStack. Dette resulterer i, at alle services slettes og skal sættes op forfra, hvilket gør det svært at arbejde med store og komplekse systemer.
  • Ikke alle versioner fungerer lige godt på alle OS.

STRONGMINDS kan hjælpe dig i gang med LocalStack og AWS

Lyder LocalStack som noget, du kunne bruge, eller kunne du tænke dig at komme godt fra start med cloudbaserede systemer som AWS? I STRONGMINDS er vi certificeret AWS Partner, og vi hjælper dig gerne videre.

Om forfatteren

Jacob Malling-Olesen er datalog og graduate i vores Software Craftsman-program. Vi opmuntrer vores graduates til at skrive om det, de lærer, da vi ser software som et håndværk, hvor man kontinuerligt selv skal blive bedre og gøre andre bedre.

Lad os hjælpe jer videre

Morten Hoffmann

CEO

T: (+45) 3095 6416