Sådan bygges en serverløs CI / CD-rørledning på AWS

Vi vil alle gerne mene, at dagene med implementering af kopi / indsæt er længe gået, desværre er dette ikke tilfældet og er stadig den foretrukne leveringsmetode for nogle udviklere. Jeg kunne nemt skrive en hel artikel om, hvorfor det er dårligt, men jeg synes, det er temmelig selvforklarende. Med tendensen mod serverløse arkitekturer spiller CI / CD-rørledninger en vigtig rolle i din applikationslevering. De indeholder også i mine 3 top tip til dit næste serverløse projekt.

Kontinuerlig integration og levering er noget, der har interesseret mig i lang tid, og jeg dyppede først tæerne i vandet med TeamCity for et par år siden. Vi bruger stadig TeamCity til størstedelen af ​​vores CI / CD-rørledninger i dag. TeamCity fungerer godt, og jeg har ikke noget imod det, men jeg ser altid på, hvordan vi kan forbedre det, vi gør. En af disse ting er at kunne bygge vores rørledninger som kode - hvilket er en af ​​de ting, TeamCity ikke er så god til.

Det er gået nogen tid, siden jeg har set detaljeret på integrations- og leveringsværktøjerne, som AWS har til rådighed, og mens vi bruger CodeDeploy til et andet projekt, der kører på EC2, har jeg aldrig brugt dem til at implementere et serverløst projekt. Efter at have været genkvalificeret med de værktøjer, jeg kunne se, er der nu en integreret integration til implementering af CloudFormation og Lambda - formodentlig med AWS 'SAM - vi bruger den serverløse ramme, og selvom den genererer CloudFormation-skabeloner, fungerer den ikke ud af boksen med værktøjerne i AWS.

Bliv forberedt

De AWS-tjenester, jeg vil bruge, er EC2, Docker, ECR, S3, IAM, CodeBuild, CodePipeline, CloudWatch, CloudTrail. Du bliver nødt til at forstå mindst et grundlæggende niveau, hvad hver af disse tjenester gør for at følge med.

Jeg skriver primært backend-kode i .NET, som denne tutorial er baseret på. Ingen af ​​de forudbyggede CodeBuild-billeder har både .NET- og NodeJS-omdrejningstider på dem (NodeJS kræves til den serverløse ramme). Hvis dine Lambda-funktioner er skrevet i NodeJS, bliver processen med at opsætte en implementeringspipeline meget enklere, da det er den eneste runtime, du har brug for installeret på dit Docker-billede (du kan potentielt springe en masse af denne tutorial over). Jeg skal også nævne, dette var min første gang, jeg blev bekendt med containere, så jeg var begejstret over at lære noget nyt.

Jeg antager også, at din kode bor i et oplagringssted af en eller anden art, såsom git. Til denne tutorial uploader vi bare en fil til S3, der indeholder en pakke med koden, der skal implementeres - hvordan du får den der, er op til dig. Du kan altid gå videre med det, jeg har opbygget, ved at forbinde din pipeline til depoter såsom github eller CodeCommit.

1. Opret en EC2-forekomst, og installer Docker

Start med at spin op en standard AWS Linux 2 EC2-instans - det skal være selvforklarende. Log ind og installer Docker med disse kommandoer:

sudo yum opdatering -y
sudo amazon-linux-extras installerer docker
sudo service docker start

Vi bliver også nødt til at tilføje ec2-brugeren til docker-gruppen, så du kan udføre Docker-kommandoer uden at bruge sudo:

sudo usermod -a -G docker ec2-bruger

Når du har udført kommandoen, skal du logge ud og logge ind på din EC2-instans, så ec2-bruger kan påtage sig de nye tilladelser. Bekræft derefter, at ec2-bruger kan køre Docker-kommandoer uden sudo:

dockerinfo
Output af dockerinfo-kommandoen

2. Byg Docker-billede, og skub til ECR

Forudsat at ovenstående trin har været en succes, er det næste trin at opbygge Docker-billedet og skubbe det til ECR. AWS leverer basisbillederne til CodeBuild på github, hvilket gør det lettere at opbygge vores eget billede.

Jeg har også offentliggjort mit billede til github, hvis du ikke ønsker at gennemgå trinnene nedenfor for at oprette dit eget: https://github.com/effectivedigital/serverless-deployment-image

Start med at klone billederne og navigere i .NET Core 2.1-biblioteket:

git klon https://github.com/aws/aws-codebuild-docker-images.git
cd aws-codebuild-docker-billeder
cd ubuntu / dot-net / core-2.1 /

Åbn Dockerfile i din foretrukne teksteditor:

nano Dockerfile

Tilføj kommandoerne for at installere NodeJS og den serverløse ramme i slutningen af ​​de andre kommandoer, der allerede er i Dockerfile. Jeg var i stand til at hente størstedelen af ​​disse kommandoer fra NodeJS Docker-billedet fra det samme arkiv fra AWS:

# Installer knudeafhængigheder
ENV NODE_VERSION = "10.14.1"
# gpg-nøgler vist på https://github.com/nodejs/node#release-team
KØR sæt -ex \
 && for indtastning \
 94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \
 B9AE9905FFD7803F25714661B63B535A4C206CA9 \
 77984A986EBC2AA786BC0F66B01FBB92821C587A \
 56730D5401028683275BD23C23EFEFE93C4CFFFE \
 71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \
 FD3A5288F042B6850C66B31F09FE44734EB7990E \
 8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600 \
 C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \
 DD8F2338BAE7501E3DD5AC78C273792F7D83545D \
 4ED778F539E3634C779C87C6D7062848A1AB005C \
 A48C2BEE680E841632CD4E44F07496B3EB3C1762 \
 ; gør \
 gpg - keyserver hkp: //p80.pool.sks-keyservers.net: 80 - recv-nøgler "$ key" || \
 gpg - keyserver hkp: //ipv4.pool.sks-keyservers.net - recv-nøgler "$ key" || \
 gpg - keyserver hkp: //pgp.mit.edu: 80 - recv-taster "$ key"; \
 Færdig
KØR sæt -ex \
 && wget "https://nodejs.org/download/release/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.gz" -O node-v $ NODE_VER $
 && wget "https://nodejs.org/download/release/v$NODE_VERSION/SHASUMS256.txt.asc" -O SHASUMS256.txt.asc \
 && gpg - batch - dekrypter - output SHASUMS256.txt SHASUMS256.txt.asc \
 && grep "node-v $ NODE_VERSION-linux-x64.tar.gz \ $" SHASUMS256.txt | sha256sum -c - \
 && tar -xzf "node-v $ NODE_VERSION-linux-x64.tar.gz" -C / usr / local - strip-component = 1 \
 && rm "node-v $ NODE_VERSION-linux-x64.tar.gz" SHASUMS256.txt.asc SHASUMS256.txt \
 && ln -s / usr / local / bin / node / usr / local / bin / nodejs \
 && rm -fr / var / lib / apt / lister / * / tmp / * / var / tmp / *
Kør npm indstille usikker-perm sand
CMD ["node"]
# Installer serverløs ramme
KØR sæt -ex \
 && npm installation -g serverløs

Nu kan billedet bygges og mærkes:

docker build -t aws / codebuild / dot-net.

Når bygningen er afsluttet, kan billedet køres for at bekræfte, at alt fungerer, og serverløs er installeret korrekt:

docker run -it --entrypoint sh aws / codebuild / dot-net -c bash
sls -v
Kører sls -v inden i den nyoprettede container

Dernæst opretter vi et lager i ECR ved hjælp af AWS CLI. Når kommandoen er kørt, vil det nye arkiv være synligt i AWS-konsollen:

aws ecr create-repository - repository-name codebuild-dotnet-node
Svar fra AWS CLI efter oprettelse af depotet i ECRDet nyoprettede oplagringssted i ECR

Nu mærker vi det aws / codebuild / dot-net-billede, vi oprettede tidligere, med repositoryUri-værdien fra det forrige trin:

docker-tag aws / codebuild / dot-net  .dkr.ecr.ap-sydøst-2.amazonaws.com / codebuild-dotnet-node

Kør kommandoen get-login for at få kommandostrengen til docker-login-godkendelse til dit container-register:

aws ecr get-login - ingen-inkluderer-e-mail
Login-kommandoen til autentificering i ECR

Kør docker-login-kommandoen, der blev returneret ved at køre get-login-kommandoen i det sidste trin.

docker login -u AWS -p eyJwYXlsb2FkIjoiNGZnd0dSaXM1L2svWWRLMmhJT1c0WWpOZEcxamJFeFJOK2VvT0Y5 [...] https: //  .dkr.ecr.ap-sydøst-2.amazon

Hvis login er vellykket, kan vi nu skubbe vores docker-billede til det depot, der er oprettet i ECR. Det kan tage et par minutter afhængigt af størrelsen på det færdige billede:

docker-push  .dkr.ecr.ap-sydøst-2.amazonaws.com / codebuild-dotnet-node
Docker på EC2 skaber vores imageDocker-billedet i ECR

Når billedet er oprettet, vil vi give nogen adgang til billedet fra ECR. Tilladelse skal være låst ned i et produktionsmiljø, men for dette eksempel vil vi tillade, at det er åbent. Gå til fanen Tilladelser i AWS-konsollen, vælg Rediger politik JSON og indsæt denne politik:

{
  "Version": "2008-10-17",
  "Udmelding": [
    {
      "Sid": "EnableAccountAccess",
      "Effekt": "Tillad",
      "Principal": "*",
      "Handling": [
        "ECR: BatchCheckLayerAvailability",
        "ECR: BatchGetImage",
        "ECR: DescribeImages",
        "ECR: DescribeRepositories",
        "ECR: GetAuthorizationToken",
        "ECR: GetDownloadUrlForLayer",
        "ECR: GetRepositoryPolicy",
        "ECR: ListImages"
      ]
    }
  ]
}

3. Opret din rørledning

Det er tid til at bygge rørledningen. For at gøre dette lettere og gentagne gange at kunne implementere og i den rigtige form for serverløse arkitekturer har jeg bygget rørledningen ved hjælp af den serverløse ramme. Du kan også opnå den samme ting ved at bygge den i CloudFormation.

Jeg vil ikke indsætte hele kilden fra min serverless.yml-fil, du kan klone den fra github i stedet: https://github.com/effectivedigital/serverless-deployment-pipeline

Se gennem den serverløse skabelon for at forstå nøjagtigt, hvad den vil gøre, men kort fortalt går den til opsætning:

  • 3x S3 spande
  • 1x spandpolitik
  • 3x IAM-roller
  • 1x CodeBuild-projekt
  • 1x CodePipeline-rørledning
  • 1x CloudWatch-begivenhed
  • 1x CloudTrail Trail

Når det er klonet, skal du opdatere DockerImageArn til dit billede i ECR. Hvis du skal oprette installationspakker med et andet filnavn end Deployment.zip, skal du også opdatere DeploymentFilename:

DockerImageArn:  .dkr.ecr.ap-sydøst-2.amazonaws.com / codebuild-dotnet-node: seneste
DeploymentFilename: Deployment.zip

Det er det, rørledningen er nu klar til installation. Kør den serverløse implementeringskommando, og vent, mens alt er konfigureret til dig:

sls implementere -v
Vores CloudFormation-stakke oprettet af den serverløse rammeCodePipeline-rørledningen oprettet af den serverløse rammeCodeBuild Project oprettet af den serverløse ramme

4. Føj buildSpec.yml til din applikation

Når CodePipeline registrerer en ændring af Deployment-filen i S3, vil den fortælle CodeBuild at køre og forsøge at opbygge og distribuere din applikation. Når det er sagt, skal CodeBuild også vide, hvilke kommandoer der skal køres for at opbygge og distribuere din applikation, buildSpec.yml har de instruktioner, som CodeBuild følger.

Jeg har oprettet en virkelig simpel Hello World-applikation, der inkluderer eksemplet buildSpec.yml-fil, du kan inkludere: https://github.com/effectivedigital/serverless-deployment-app

Alternativt kan du oprette en buildSpec.yml-fil i dine eksisterende applikationer og udfylde den med nedenstående instruktioner:

version: 0.2
faser:
  pre_build:
    kommandoer:
      - chmod a + x *
  bygge:
    kommandoer:
      - ./build.sh
  post_build:
    kommandoer:
      - sls implementerer -v -s $ STAGE

5. Test af din rørledning

Alt er nu på plads for at køre din rørledning for første gang. Opret en pakke kaldet Deployment.zip, som skal indeholde alle filerne til dit serverløse program og buildSpec.yml-filen.

Efter få øjeblikke skal CloudTrail logge PutObject-hændelsen, udløse en CloudWatch-hændelsesregel, som derefter udløser CodePipeline til at begynde at køre.

Deployment.zip er blevet uploadet til S3CodePipeline er begyndt, og build er i gang

Hvis vi klikker på detaljerne i AWS CodeBuild-trinnet, kan vi se på udviklingen i opbygningen og implementeringen:

CodeBuild får output fra Docker-billedet, der udfører build og implementeringVores implementering var vellykket!

Den nye app, der blev implementeret af vores rørledning, er også synlig i CloudFormation:

Vi kan teste API-endepunktet oprettet i vores enkle app (URL er i CodeBuild-output eller API Gateway) og se, at vores app fungerer med succes:

Brug af Postman til at påkalde vores API

Resumé

CodePipeline giver dig mulighed for at oprette en skalerbar, fleksibel og lav pris CI / CD-rørledning og hjælper med at løse nogle af de problemer, der er forbundet med traditionelle pipelines oprettet på servere.

Jeg ville meget gerne tage dette et skridt videre og tilføje enhedstestning i blandingen, når installationen er afsluttet, skønt den garanterer en egen artikel - noget at holde øje med i fremtiden!

Deltag i vores community Slack og læs vores ugentlige Faun-emner ⬇

Hvis dette indlæg var nyttigt, skal du klikke på klappen knappen nedenfor et par gange for at vise din støtte til forfatteren! ⬇