Üdvözlet, barátok. A „DevOps gyakorlatok és eszközök” kurzus új előadásának kezdete előtt A Pulumi és általános célú programozási nyelvek használata az infrastruktúrakódhoz (Infrastructure as Code) számos előnnyel jár: a készségek és tudás rendelkezésre állása, a kód boilerplate eltüntetése absztrakcióval, és a csapatotok által ismert eszközök, mint az IDE-k és linterek. Ezek a szoftvermérnöki eszközök nemcsak hogy termelékenyebbé tesznek minket, hanem javítják a kód minőségét is. Ezért teljesen természetes, hogy az általános célú programozási nyelvek használata lehetővé teszi egy másik fontos szoftverfejlesztési gyakorlat bevezetését -

Ebben a cikkben megvizsgáljuk, hogyan segít a Pulumi tesztelni az „infrastruktúránkat mint kódot”. tesztelés.
Miért teszteljük az infrastruktúrát?

Mielőtt a részletekbe mennénk, érdemes feltenni a kérdést: „Miért is teszteljük az infrastruktúrát?” Sok oka van, és az alábbiak néhány közülük:
Az egyes funkciók vagy a programod logikai töredékeinek moduláris tesztelése.
- Az infrastruktúra kívánt állapotának ellenőrzése bizonyos korlátozásoknak való megfelelés szempontjából.
- Gyakori hibák észlelése, például a storage bucket titkosításának hiánya vagy védtelen, nyilvános internetes hozzáférés virtuális gépekhez.
- Az infrastruktúra provisioningjának ellenőrzése.
- Runtime tesztelés végrehajtása a „programozott” infrastruktúrádba telepített alkalmazás logikáján a provisioning utáni működés ellenőrzésére.
- Ahogy látjuk, széles spektrum áll rendelkezésre az infrastruktúra tesztelésére. A Pulumi rendelkezik mechanizmusokkal a spektrum minden pontjában történő teszteléshez. Kezdjük el, és nézzük meg, hogyan működik ez.
- Moduláris tesztelés
A Pulumi programokat általános célú programozási nyelveken, például JavaScript, Python, TypeScript vagy Go nyelveken hozzák létre. Ezért ezen nyelvek teljes ereje, beleértve az eszközeiket és könyvtáraikat, köztük a tesztkeretrendszereket is, rendelkezésre áll számukra. A Pulumi multicloud, ami lehetővé teszi bármilyen felhőszolgáltató használatát a tesztekhez.
A Pulumi programok általános célú programozási nyelveken készülnek, mint például JavaScript, Python, TypeScript vagy Go. Ezért ezek a nyelvek teljes ereje, beleértve az eszközkészleteket és könyvtárakat, például a tesztkeretrendszereket is, elérhető számukra. A Pulumi többfelhős, ami azt jelenti, hogy bármely felhőszolgáltató használható a tesztelés során.
(A cikkben, a többnyelvűség és a többfelhős környezet ellenére, JavaScriptet és Mocha-t használunk, és az AWS-re összpontosítunk. Python is használható unittest, a Go tesztkeretrendszer vagy bármely más kedvenc tesztkeretrendszere. És természetesen a Pulumi remekül működik az Azure-val, a Google Cloud-dal és a Kubernetes-szel.)
Ahogy láttuk, számos oka lehet annak, hogy tesztelni kell a infrastrukturális kódot. Az egyik ok a szokásos egységtesztelés. Mivel kódodnak lehetnek funkciói — például a CIDR kiszámítása, dinamikus nevek vagy címkék generálása stb. — valószínűleg tesztelni szeretnéd őket. Ez ugyanolyan, mint a szokásos egységtesztek írása a kedvenc programozási nyelveden.
Ha egy kicsit bonyolultabbá tesszük, ellenőrizhetjük, hogyan osztja el a programod az erőforrásokat. Tegyük fel, hogy létre kell hoznunk egy egyszerű EC2-szervert, és biztosnak kell lennünk abban, hogy a következők teljesülnek:
- Az instance-nek van egy címke
Név. - Az instance-nek nem szabad inline szkriptet használnia
userData— használnunk kell AMI-t (képet). - Nem szabad, hogy SSH nyitva legyen az Interneten.
Ez a példa a :
index.js:
"use strict";
let aws = require("@pulumi/aws");
let group = new aws.ec2.SecurityGroup("web-secgrp", {
ingress: [
{ protocol: "tcp", fromPort: 22, toPort: 22, cidrBlocks: ["0.0.0.0/0"] },
{ protocol: "tcp", fromPort: 80, toPort: 80, cidrBlocks: ["0.0.0.0/0"] },
],
});
let userData =
`#! /bin /bash
echo "Hello, World!" > index.html
nohup python -m SimpleHTTPServer 80 &`;
let server = new aws.ec2.Instance("web-server-www", {
instanceType: "t2.micro",
securityGroups: [ group.name ], // hivatkozás a fenti csoportobjektumra
ami: "ami-c55673a0" // AMI az us-east-2 (Ohio) számára,
userData: userData // egy egyszerű webkiszolgáló indítása
});
exports.group = group;
exports.server = server;
exports.publicIp = server.publicIp;
exports.publicHostName = server.publicDns;
Ez egy alap Pulumi program: egyszerűen létrehoz egy EC2 biztonsági csoportot és egy instance-t. Fontos megjegyezni, hogy itt mindhárom fent említett szabályt megszegjük. Jöjjön a tesztelés!
Teszteket írunk
A tesztjeink általános felépítése olyan lesz, mint a szokásos Mocha teszteké:
ec2tests.js
test.js:
let assert = require("assert");
let mocha = require("mocha");
let pulumi = require("@pulumi/pulumi");
let infra = require("./index");
describe("Infrastruktúra", function() {
let server = infra.server;
describe("#server", function() {
// TODO(check 1): Kell, hogy legyen egy Name címke.
// TODO(check 2): Nem szabad inline szkript a userData.
});
let group = infra.group;
describe("#group", function() {
// TODO(check 3): Nem szabad, hogy SSH nyitva legyen az Interneten.
});
}); Most tegyük meg az első tesztünket: ellenőrizzük, hogy az instanciáknak van címkéje. NévEhhez egyszerűen lekérjük az EC2-instance objektumot, és ellenőrizzük a megfelelő tulajdonságot. címkék:
// check 1: Должен быть тэг Name.
it("must have a name tag", function(done) {
pulumi.all([server.urn, server.tags]).apply(([urn, tags]) => {
if (!tags || !tags["Name"]) {
done(new Error(`Missing a name tag on server ${urn}`));
} else {
done();
}
});
});Úgy néz ki, mint egy szokásos teszt, de van néhány figyelemre méltó sajátossága:
- Mivel az erőforrás állapotát kérjük le a telepítés előtt, a tesztjeink mindig „terv” (vagy „előnézet”) módban futnak. Így sok tulajdonság értéke egyszerűen nem lesz elérhető vagy meghatározatlan. Ide tartoznak azok a kimeneti tulajdonságok is, amelyeket a felhőszolgáltatód számít ki. A tesztjeink szempontjából ez rendben van — csak a bemeneteket ellenőrizzük. Ezzel a kérdéssel később foglalkozunk, amikor az integrációs tesztekről van szó.
- Mivel a Pulumi-erőforrások minden tulajdonsága „kimenet”, és sok közülük aszinkron módon számítódik ki, ezért használnunk kell az apply metódust az értékek eléréséhez. Ez nagyon hasonló a promiszokhoz és az afunkcióhoz.
then. - Mivel több tulajdonságot használnánk, hogy megmutassuk az erőforrás URN-jét a hibaüzenetben, szükségünk van a
pulumi.all, hogy ezeket össze tudjuk kapcsolni. - Végül, mivel ezek az értékek aszinkron módon számítódnak ki, használnunk kell a Mocha beépített aszinkron képességét visszahívással.
készvagy ígétek visszatérésével.
Miután mindent beállítottunk, a bemenetekhez egyszerű JavaScript értékekként férünk hozzá. A tulajdonság címkék térkép (asszociatív tömb), ezért egyszerűen csak ellenőrizzük, hogy (1) nem false, és (2) van egy kulcs a Név. Ez nagyon egyszerű, most már bármit ellenőrizhetünk!
Most írjuk meg a második ellenőrzésünket. Ez még egyszerűbb:
// check 2: Не должно быть inline-скрипта userData.
it("must not use userData (use an AMI instead)", function(done) {
pulumi.all([server.urn, server.userData]).apply(([urn, userData]) => {
if (userData) {
done(new Error(`Illegal use of userData on server ${urn}`));
} else {
done();
}
});
});És végül írjuk meg a harmadik tesztet. Ez kicsit bonyolultabb lesz, mivel a biztonsági csoporthoz kapcsolódó bejövő szabályokat keresünk, amelyekből sok lehet, és a CIDR tartományokat ezekben a szabályokban, amelyekből szintén sok lehet. De megoldottuk:
// check 3: Не должно быть SSH, открытого в Интернет.
it("must not open port 22 (SSH) to the Internet", function(done) {
pulumi.all([ group.urn, group.ingress ]).apply(([ urn, ingress ]) => {
if (ingress.find(rule =>
rule.fromPort == 22 && rule.cidrBlocks.find(block =>
block === "0.0.0.0/0"))) {
done(new Error(`Illegal SSH port 22 open to the Internet (CIDR 0.0.0.0/0) on group ${urn}`));
} else {
done();
}
});
});Ennyi. Most futtassuk a teszteket!
Tesztelés indítása
A teszteket a legtöbb esetben a választott tesztkeretrendszer használatával, a szokásos módon lehet futtatni. De van egy jellemző Pulumi, amire érdemes figyelni.
Általában a Pulumi programok elindításához a pulimi CLI (parancssori felület) használatos, amely beállítja a nyelv runtime-ját, ellenőrzi a Pulumi motor futásait, lehetővé téve a forrásokkal kapcsolatos műveletek rögzítését és azok beépítését a tervbe stb. Azonban van egy probléma. Ha a tesztkeretrendszered alatt fut a program, nem lesz kapcsolat a CLI és a Pulumi motor között.
A probléma megkerüléséhez csak a következőket kell megadnunk:
- A projekt neve, amely a környezeti változóban található
PULUMI_NODEJS_PROJECT(vagy általánosabb esetben,PULUMI__PROJECT más nyelvekhez).
A verem neve, amely a környezeti változóban vanPULUMI_NODEJS_STACK(vagy általánosabb esetben,PULUMI__STACK).
A veremhez tartozó konfigurációs változóid. Ezeket a környezeti változó segítségével nyerheted kiPULUMI_CONFIGés a formátumuk egy JSON térkép, amely kulcs/érték párokat tartalmaz.A program figyelmeztetéseket fog kiadni, amelyek azt jelzik, hogy a futás során nincs kapcsolat a CLI/központi egységgel. Ez fontos, mert valójában a programod semmit sem fog telepíteni, és meglepetést okozhat, ha nem ez volt a szándékod! Annak érdekében, hogy a Pulumi tudja, hogy ez pontosan az, amire szükséged van, beállíthatod a
PULUMI_TEST_MODEbe.igaz.Képzeld el, hogy meg kell adnod a projekt nevét a
my-ws, a verem nevétdev, és az AWS régiótus-west-2. A Mocha tesztek végrehajtásához használandó parancssor a következőképpen fog kinézni:$ PULUMI_TEST_MODE=true PULUMI_NODEJS_STACK="my-ws" PULUMI_NODEJS_PROJECT="dev" PULUMI_CONFIG='{ "aws:region": "us-west-2" }' mocha tests.jsEzt végrehajtva, ahogy vártuk, látni fogjuk, hogy három hibás tesztünk van!
Infrastructure #server 1) must have a name tag 2) must not use userData (use an AMI instead) #group 3) must not open port 22 (SSH) to the Internet 0 passing (17ms) 3 failing 1) Infrastructure #server must have a name tag: Error: Missing a name tag on server urn:pulumi:my-ws::my-dev::aws:ec2/instance:Instance::web-server-www 2) Infrastructure #server must not use userData (use an AMI instead): Error: Illegal use of userData on server urn:pulumi:my-ws::my-dev::aws:ec2/instance:Instance::web-server-www 3) Infrastructure #group must not open port 22 (SSH) to the Internet: Error: Illegal SSH port 22 open to the Internet (CIDR 0.0.0.0/0) on groupJavítsuk ki a programunkat:
"use strict"; let aws = require("@pulumi/aws"); let group = new aws.ec2.SecurityGroup("web-secgrp", { ingress: [ { protocol: "tcp", fromPort: 80, toPort: 80, cidrBlocks: ["0.0.0.0/0"] }, ], }); let server = new aws.ec2.Instance("web-server-www", { tags: { "Name": "web-server-www" }, instanceType: "t2.micro", securityGroups: [ group.name ], // referáljuk a fenti csoport objektumot ami: "ami-c55673a0" // AMI az us-east-2 (Ohio) számára, }); exports.group = group; exports.server = server; exports.publicIp = server.publicIp; exports.publicHostName = server.publicDns;És ezután futtassuk újra a teszteket:
Infrastruktúra #szerver ✓ név címkével kell rendelkeznie ✓ nem szabad userData-t használni (helyette használjon AMI-t) #csoport ✓ nem szabad 22-es portot (SSH) megnyitni az Internet felé 3 sikeres (16ms)Minden sikerült… Hurrá! ✓✓✓
Ma ennyi, a telepítés teszteléséről a fordítás második részében beszélünk 😉
Forrás: habr.com
