Hvis der ellers er nogen, der skulle være i tvivl, har Version2 lavet en hjemmestrikket machine learning-løsning, der gætter emneord til nye artikler.
Programmet kørte først på min egen pc på kontoret, som resten af kollegerne kunne tilgå med en bookmarklet i browseren. Men det var lige en tand for interimistisk. Og en dag slukkede it-afdelingen for ip-kommunikation mellem kontor-pc’er - fornuftigt nok. Hvis der kommer malware på matriklen, er det nok ikke så smart, at der kan snakkes fra pc til pc.
Vi flyttede systemet til skyen, og indtil videre har det ikke kostet en krone, da vi har brugt gratis tilbud og tjenester som Let’s Encrypt, der byder på omkostningsfri SSL-certifikater.
Vi stod altså ombord i cloud’en, hos Amazon. Det er egentlig ikke så svært, det der sky. Hvis man har lidt erfaring med Linux' bash-terminal - og mine evner er kun lige til øllet - så er det nemt at have med at gøre, synes jeg.
Man trykker på en knap i en web-konsol, og et par minutter efter - simsalabim - så har man en sprit-ny server til rådighed, som man kan logge ind på med terminalen på ens egen pc. Det er dælme smart.
Men, men. Som vi også har kigget på i et par artikler, så følger der lidt mere med en server, end bare det at afvikle et program. Når jeg logger ind på serveren, spørger den om ikke jeg har lyst til at 'update' softwaren med yum, som er det pakkeprogram, serveren benytter.
Jeg har altså med i købet fået noget uønsket arbejde med at vedligeholde og sikre min server. Det handler ikke blot om mit eget programs velfærd.
Hvis jeg bommer med en sikkerhedsopdatering, eller har lavet en bøf i egen kode, kan ondskabsfulde typer måske overtage min server og benytte den til kriminelle formål mod andre. Det opdager jeg nok ikke lige med det samme, i mit hygge-skygge-opsæt.
Jeg har altså en eller anden slags forpligtelse til at sørge for, at min server hos Amazon ikke er sårbar for angreb. Det arbejde får jeg strengt taget ikke bonus for, ud over god samvittighed. Og - ærlig talt - jeg er ikke devops-ekspert i Linux-sikkerhed.
Dernæst er der heller ikke noget, der hedder failover, i hvert fald ikke på min gratis-server. Hvis uheldet er ude, skal jeg bruge et script til at gendanne det hele. Sådan et lavede vi i en tidligere artikel, og det tog et stykke tid at finde ud af alle kommandoerne.
Vores program har også sin egen webserver indbygget. Den snakker med webudvidelsen, som maler spåkonens emneords-bud med gult i cms’et.
Det ville jeg ikke have behov for i serverless, for der er HTTP indbygget fra starten af som tjeneste.
Derfor serverless
Nu har jeg stort set nævnt de fleste af argumenterne for at gå serverless.
Det handler om kode, der kører i skyen, uden at man skal bekymre sig om kørselsmiljø, patches, sikkerhed, failover eller noget som helst andet, og hvor basal funktionalitet som HTTP kommer med som standard.
Hvordan det ser ud med økonomien ved et større produktionsscenarie, i forhold til alternativerne, vil vi glemme alt om her.
Serverless løser i hvert fald problemet med de arbejdsopgaver, der fulgte med min server, og som jeg ikke lige synes, jeg har bedt om.
Men kan vores hjemmelavede machine learning køre på serverless? Der er jo de kæmpemæssige hyppighedstabeller, der volder mig så mange kvaler.
Kan det fungere i et letvægts-miljø? Jeg har ganske simpelt aldrig tænkt tanken.
Men det har cloud-konsulent Henrik Oddershede til gengæld. Han skriver til mig en dag i september:
Hej Tania. I opbygningen af din skygge-it har du brugt 'gammeldags' virtuelle maskiner (ec2- instanser), som tydeligvis kræver en del scripting at få til at fungere. Jeg mener, det er en oplagt mulighed at skrive en artikel om, hvordan du kan få den samme funktionalitet med mindre indsats ved at køre serverless. Her overlader du meget mere arbejde til AWS, og kan fokusere på at skrive Javakoden. Hvis du er interesseret i det, vil jeg gerne sætte en dag af til at vise dig, hvor let det er.
Sådan et tilbud og generøsitet kan jeg naturligvis ikke sige nej til.
Men jeg er ret skeptisk overfor ideen, og det lader jeg Henrik vide. De der hyppighedstabeller er jo kæmpestore? Det er vel næppe letvægt?
Han holder dog fast i sit, og man må jo tage hatten af for sagkundskaben. Så et par uger senere sidder vi i verdens mindste mødelokale i Teknologiens Mediehus, med hver vores terminal åben. Jeg bruger Windows Subsystem for Linux med Ubuntu, mens Henrik kører Red Hat på sin laptop.
Dårlig kaffe
Der er en hel masse, der skal installeres, for at komme til serverless.
Først skal vi installere Pythons pakke-værktøj Pip med kommandoen
sudo apt install python3-pip
Det går frygtelig langsomt - om det er vores wifi-netværk eller min Windows Subsystem for Linux, der skaber flaskehalsen, bliver aldrig helt klart.
Vores fancy kapsel-kaffemaskine er gået i stykker, og der er kun almindelig filterkaffe til rådighed på fjerde sal. Henrik vil hellere have et glas vand fra vandhanen. Det kan jeg godt forstå - kaffen dufter og smager aldeles grufuldt. Jeg føler mig lidt pinligt berørt, det må jeg indrømme. Det er altså ikke det indtryk, som Version2 og Teknologiens Mediehus ønsker, at kilderne går hjem med.
Jeg siger til Henrik:
»Hvad nu, hvis du giver mig nogle fingerpeg, og så tager jeg den herfra?«
Den er han med på, og vi går hver til sit. Jeg er på egen hånd nu, lidt ligesom Jean-Claude Van Damme i en intens scene i en 80’er action-film. Det er altså bare min oplevelse.
Tilbage til installeringen af pip. Det driller, men jeg tilføjer flaget --fix-missing
, og så virker det.
Vi skal bruge pip til at installere Amazons kommandolinjeværktøj til skyen. Det hedder awscli
og installeres sådan her:
sudo pip3 install awscli --upgrade
Det tager også en hulens tid, og et par forsøg - jeg har vist ikke lige den skarpeste tænkehat på hovedet denne dag.
Ny bruger
Nu skal der oprettes en ‘Identity and Access Management’-bruger. Det havde jeg nok aldrig fundet ud af, hvis ikke Henrik havde fortalt mig om det.
Det er en speciel bruger, som benyttes i forbindelse med kommandolinje-værktøjerne. Jeg benytter Amazons webkonsol, og jeg synes dælme, man skal klikke hist og her og alle vegne. Amazon har dog en god vejledning til de 15 skridt, man skal igennem, og jeg holder tungen lige i munden.
Resultatet er to nøgler, Access Key ID og Secret Access Key, som bare er nogle lange strenge. Dem kan jeg altså ikke gengive overfor jer, kære læsere - beklager.
Nu kan jeg benytte aws-kommandoen, vi installerede før, til at konfigurere opsætningen med. Det skal kun gøres én gang.
aws configure AWS Access Key ID (None): (slettet) AWS Secret Access Key (None): (slettet) Default region name (None): us-east-1 Default output format (None): json
Så langt, så godt. Men der stadig et godt stykke vej til ‘hallo verden’ - så er I advaret.
Jeg skal nu oprette en ‘bucket’ i Amazons storage-system S3. Det er et sted, man kan gemme ting, lidt ligesom en mappe i et filsystem, uden undermapper. Den kode, vi skaber senere hen, skal op og ligge her.
Jeg kan ikke finde ud af at skabe en bucket med kommandolinje-værktøjet - den kommer hele tiden med dumme fejlmeddelelser, i stedet for at fortælle mig, hvad jeg skal skrive.
Men en bucket kan også oprettes via webkonsollen. Jeg navigerer frem til ‘S3’ og her er det legende nemt at skabe en bucket. Den er også gratis i 12 måneder, så det koster mig altså ikke yderligere.
Nu skal vi dæleme også installere pakke-programmet brew. Jeg synes ellers, at jeg har installeret rigeligt allerede. Men det ser sådan ud:
sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)" test -d ~/.linuxbrew && eval $(~/.linuxbrew/bin/brew shellenv) test -d /home/linuxbrew/.linuxbrew && eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv) test -r ~/.bash_profile && echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.profile echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.profile brew --version
Jeg læste instruktionerne et eller andet sted, og kan helt ærligt ikke rigtig huske, hvad det går ud på. Men nu er jeg i hvert fald i stand til at installere programmer med brew.
Det næste vi skal installere, er værktøjet sam. Det står for Serverless Application Model, så nu nærmer vi os langt om længe sagens kerne. Det ser sådan ud:
brew tap aws/tap brew install aws-sam-cli sam --version
Vi skal dog liiiiige installere ét værktøj til - men så er det også det sidste!
Det er Java-konfigurationsværktøjet Maven. Det er heldigvis nemt at installere i min Linux:
sudo apt install maven mvn -version
Så er vi på vej til serverless, mine damer og herrer.
Skelet til serverless-funktion
Henrik fortæller mig på mail, hvad jeg nu skal gøre. Vi bruger kommandoen:
sam init --runtime java8
– som svarer således:
[+] Initializing project structure... Project generated: ./sam-app Steps you can take next within the project folder =================================================== [+] Install dependencies [+] Invoke Function: sam local invoke HelloWorldFunction --event event.json [+] Start API Gateway locally: sam local start-api Read sam-app/README.md for further instructions [+] Project initialization is now complete
Nu kan jeg navigere til mappen sam-app/HelloWorldFunction/src/main/java/helloworld, hvor jeg finder disse to kildefiler:
App.java GatewayResponse.java
I App.java finder vi blandt andet disse linjer:
public class App implements RequestHandler<Object, Object> { public Object handleRequest(final Object input, final Context context) { Map<String, String> headers = new HashMap<>(); headers.put("Content-Type", "application/json"); headers.put("X-Custom-Header", "application/json"); try { final String pageContents = this .getPageContents("https://checkip.amazonaws.com"); String output = String .format("{ \"message\": \"hello world\", \"location\": \"%s\" }", pageContents); return new GatewayResponse(output, headers, 200); } catch (IOException e) { return new GatewayResponse("{}", headers, 500); } }
Vi ændrer output til
String output = String.format("{ \"message\": \"hej du!\", \"location\": \"%s\" }", pageContents);
– for lige at personalisere en anelse.
Jeg navigerer nu ind i mappen sam-app. Her afvikler jeg kommandoerne
sam build sam package --output-template packaged.yaml --s3-bucket taniasnyebucket sam deploy --template-file packaged.yaml --region us-east-1 \ --capabilities CAPABILITY_IAM --stack-name aws-sam-getting-started
Her bliver koden compilet, pakket og udrullet.
Nu kan jeg spørge Amazon om min serverless hallo-app:
aws cloudformation describe-stacks --stack-name aws-sam-getting-started --region us-east-1 --query "Stacks[].Outputs"
– der svarer med Json, og blandt andet fortæller dette:
{ "OutputKey": "HelloWorldApi", "OutputValue": "https://x8d598jn85.execute-api.us-east-1.amazonaws.com/Prod/hello/", "Description": "API Gateway endpoint URL for Prod stage for Hello World function" },
Her har vi funktionens endepunkt. Vi daffer ind i en browser og smider url’en i adresselinjen:
For hulen da også - så lykkedes det til sidst. Men hold dog op, hvor skulle der meget til.
Det er lidt paradoksalt, at det er så nemt at sætte en virtuel server op, mens det skal tage så lang tid at få serverless på plads. Hvis ikke Henrik Oddershede havde hjulpet mig, havde jeg måske givet op undervejs.
Nu har vi en ‘hej verden’-app på plads, og i næste artikel kigger vi på, hvorledes vi får machine learning-programmet op at køre med Henriks hjælp. Bliv på kanalen.

...men det er dyrt at lave god journalistik. Derfor beder vi dig overveje at tegne abonnement på Version2.
Digitaliseringen buldrer derudaf, og it-folkene tegner fremtidens Danmark. Derfor er det vigtigere end nogensinde med et kvalificeret bud på, hvordan it bedst kan være med til at udvikle det danske samfund og erhvervsliv.
Og der har aldrig været mere akut brug for en kritisk vagthund, der råber op, når der tages forkerte it-beslutninger.
Den rolle har Version2 indtaget siden 2006 - og det bliver vi ved med.