Tere päevast, sõbrad. Uue kursuse alguse eel jagame teiega uut tõlget. Alustame. Jagame teiega uut tõlget. Alustame.

Pulumi ja üldotstarbeliste programmeerimiskeelte kasutamine infrastruktuuri koodi (Infrastructure as Code) jaoks toob palju eeliseid: oskuste ja teadmiste olemasolu, koodi boilerplate'i eemaldamine abstraktsiooni kaudu, meeskonnale tuttavad tööriistad, nagu IDE ja linterid. Kõik need tarkvaraarenduse tööriistad muudavad meid mitte ainult produktiivsemaks, vaid parendavad ka koodi kvaliteeti. Seetõttu on täiesti loomulik, et üldotstarbeliste programmeerimiskeelte kasutamine võimaldab rakendada veel ühte olulist tarkvaraarenduse praktikat — testimist.
Selles artiklis vaatame, kuidas Pulumi aitab katsetada meie „infrastruktuuri koodi”.

Miks testida infrastruktuuri?
Enne kui läheme detailsesse aruteludesse, tasub esitada küsimus: „Miks üldse testida infrastruktuuri?” Selleks on palju põhjuseid ja siin on mõned neist:
- Moodultestimine üksikute funktsioonide või teie programmi loogika fragmentide puhul
- Soovitava infrastruktuuri oleku kontrollimine teatud piirangute suhtes.
- Levinud vigade tuvastamine, näiteks salvestusruumi kausta krüpteerimise puudumine või kaitsmata, avatud juurdepääs internetist virtuaalmasinatele.
- Infrastruktuuri proviisioonimise täitmise kontrollimine.
- Rakenduse loogika runtime-testimine, mis töötab teie „programmeeritud” infrastruktuuri sees, et kontrollida funktsionaalsust pärast proviisioonimist.
- Nagu näeme, on infrastruktuuri testimiseks lai valik võimalusi. Pulumis on mehhanismid testimiseks igas selle spektri punktis. Alustame ja vaatame, kuidas see töötab.
Moodultestimine
Pulumi programmid luuakse üldotstarbelistes programmeerimiskeeltes, nagu JavaScript, Python, TypeScript või Go. Seetõttu on nende jaoks saadaval nende keelte kogu võimekus, sealhulgas nende tööriistad ja raamatukogud, sealhulgas testimise raamistikud. Pulumi on multicloud, mis tähendab, et testide jaoks saab kasutada mistahes pilvepakkujate teenuseid.
(Selles artiklis kasutame, hoolimata mitmekeelsusest ja multicloud'ist, JavaScripti ja Mocha ning Orienteerume AWS-ile. Saame kasutada ka Pythonit unittest, testimise raamistik Go või mõni muu teie lemmik testimise raamistik. Ja muidugi töötab Pulumi suurepäraselt Azure'i, Google Cloudi ja Kubernetesega.)
Kuidas me nägime, on mitu põhjust, miks võib osutuda vajalikuks testida oma infrastruktuuri koodi. Üks neist on tavaline moodulitestimine. Kuna teie kood võib sisaldada funktsioone — näiteks CIDR-i arvutamiseks, dünaamiliseks nimede ja siltide arvutamiseks jne — soovite tõenäoliselt neid testida. See on sama, mis tavaliste moodulitestide kirjutamine rakendustes teie lemmikprogrammeermiskeeles.
Kui asju natuke keerulisemaks muuta, võib kontrollida, kuidas teie programm jagab ressursse. Illustreerimiseks kujutame ette, et peame looma lihtsa EC2-serveri ja tahame veenduda järgmistes punktides:
- Instantsidel on silt
Nimi. - Instantsid ei tohiks kasutada inline-skripti
userData— peame kasutama AMI (pilt). - SSH-d ei tohi Internetis avada.
See näide on kirjutatud minu näite järgi :
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 ], // viidake ülalolevale grupi objektile
ami: "ami-c55673a0" // AMI us-east-2 (Ohio),
userData: userData // käivitage lihtne veebiserver
});
exports.group = group;
exports.server = server;
exports.publicIp = server.publicIp;
exports.publicHostName = server.publicDns;
See on põhi Pulumi programm: see lihtsalt allocate'ib EC2 turvagruppi ja instantsi. Siiski on oluline märkida, et siin rikume kõiki kolme eespool mainitud reeglit. Alustame testide kirjutamist!
Kirjutame testid
Meie testide üldine struktuur näeb välja nagu tavalised Mocha testid:
ec2tests.js
test.js:
let assert = require("assert");
let mocha = require("mocha");
let pulumi = require("@pulumi/pulumi");
let infra = require("./index");
describe("Infrastructure", function() {
let server = infra.server;
describe("#server", function() {
// TODO(check 1): Peab olema nime silt.
// TODO(check 2): Inline-skripti userData ei tohiks olla.
});
let group = infra.group;
describe("#group", function() {
// TODO(check 3): SSH-d ei tohiks olla Internetis avatud.
});
}); Nüüd kirjutame oma esimese testi: veendume, et instantsidel on silt Nimi. Selle kontrollimiseks saame lihtsalt EC2 instantsi objekti ja kontrollime vastavat omadust. tags:
// 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();
}
});
});Tundub nagu tavaline test, kuid mitmete tähelepanuväärsete omadustega.
- Kuna me küsime ressursi seisundit enne juurutamist, viiakse meie testid alati läbi "plaan" (või "eelvaade") režiimis. Seega on palju omadusi, mille väärtused lihtsalt ei pruugi olla saadaval või on määratlemata. Siia kuuluvad kõik väljundomadused, mida teie pilveteenuse pakkuja arvutab. Meie testide jaoks on see normaalne – me kontrollime ainult sisendeid. Sellele küsimusele naasema hiljem, kui jõuame integreerimistestide juurde.
- Kuna kõik Pulumi ressursside omadused on "väljundid" ning paljusid neist arvutatakse asünkroonselt, peame väärtuste juurde pääsemiseks kasutama meetodit apply. See on väga sarnane lubadustele ja afunktsioonile.
siis. - Kuna me kasutame mitmeid omadusi ressursi URN-i kuvamiseks veateates, peame kasutama funktsiooni.
pulumi.all, et need kokku liita. - Lõpuks, kuna need väärtused arvutatakse asünkroonselt, peame kasutama Mocha sisseehitatud asünkroonset funktsionaalsust tagasisidega.
donevõi lubade tagastamisega.
Pärast kõigi seadistamist saame juurde pääseda sisenditele nagu JavaScripti tavalistele väärtustele. Omadus tags on map (assotsiatiivne massiiv), seega veendume, et see (1) ei ole false ja (2) on võtme olemasolu. Nimi. See on väga lihtne ja nüüd saame kontrollida kõike, mida soovime!
Nüüd kirjutame oma teise testi. See on veelgi lihtsam:
// 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();
}
});
});Ja lõpuks kirjutame kolmanda testi. See on natuke keerulisem, kuna otsime sisenemisreegleid, mis on seotud turvagruppidega, mida võib olla palju, ja nende reeglite CIDR vahemikke, mida võib samuti palju olla. Kuid me saime hakkama:
// 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();
}
});
});Siin see on. Nüüd käivitame testid!
Testide käivitamine
Testide käivitamine on enamasti võimalik tavalise viisi kaudu, kasutades valitud testiraamistiku. Kuid on üks Pulumi omadus, millele tasub tähelepanu pöörata.
Tavaliselt käivitatakse Pulumi programme pulumi CLI (komandoridade liides), mis seadistab keele jooksutavate keskkondade, kontrollib Pulumi mootori käivitusi, et saaks dokumenteerida ressursitoiminguid ja neid plaani lisada jne. Kuid on üks probleem. Testimise käigus teie raamistikus ei ole CLI ja Pulumi mootori vahel ühendust.
Selle probleemi vältimiseks peame lihtsalt määrama järgmised:
- projekti nimi, mis on keskkonnamuutujas
PULUMI_NODEJS_PROJECT(või, üldisemalt,PULUMI__PROJECT teiste keelte jaoks).
steigi nimi, mis on määratud keskkonnamuutujasPULUMI_NODEJS_STACK(või, üldisemalt,PULUMI__STACK).
Teie steigi konfiguratsioonimuutujad. Need on saadaval keskkonnamuutujate kauduPULUMI_CONFIGja nende vorm on JSON kaardina võtme/väärtuse paaridega.Programm annab hoiatusi, et käitamise ajal ei ole võimalik CLI/mootoriga ühendust saada. See on oluline, kuna teie programm ei rakenda tegelikult midagi ja see võib olla üllatus, kui see pole see, mida soovisite teha! Et öelda Pulumile, et see on just see, mida te vajate, saate määrata
PULUMI_TEST_MODEjatrue.Kujutage ette, et peame määrama projekti nime
my-ws, steigi nimedev, ja AWS piirkonnaus-west-2. Mocha-testide käskude rida näeb välja järgmine:$ PULUMI_TEST_MODE=true PULUMI_NODEJS_STACK="my-ws" PULUMI_NODEJS_PROJECT="dev" PULUMI_CONFIG='{ "aws:region": "us-west-2" }' mocha tests.jsSelle täitmine näitab, et meil on kolm ebaõnnestunud testi!
Infrastructure #server 1) peab olema nime silt 2) ei tohi kasutada userData (kasutage selle asemel AMI-d) #group 3) ei tohi avada porti 22 (SSH) Internetile 0 möödumist (17ms) 3 ebaõnnestumist 1) Infrastructure #server peab olema nime silt: Error: Puudub nime silt serveril urn:pulumi:my-ws::my-dev::aws:ec2/instance:Instance::web-server-www 2) Infrastructure #server ei tohi kasutada userData (kasutage selle asemel AMI-d): Error: Ebaseaduslik userData kasutamine serveris urn:pulumi:my-ws::my-dev::aws:ec2/instance:Instance::web-server-www 3) Infrastructure #group ei tohi avada porti 22 (SSH) Internetile: Error: Ebaseaduslik SSH port 22 avatud Internetile (CIDR 0.0.0.0/0) grupisParandame meie programmi:
"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 ], // viitame ülal olevale grupi objektile ami: "ami-c55673a0" // AMI us-east-2 (Ohio), }); exports.group = group; exports.server = server; exports.publicIp = server.publicIp; exports.publicHostName = server.publicDns;Ja seejärel käivitame testid uuesti:
Infrastruktuur #server ✓ peab olema nime silt ✓ ei tohi kasutada userData (kasutage selle asemel AMI-d) #group ✓ ei tohi avada porti 22 (SSH) Internetile 3 läbitud (16ms)Kõik läks hästi… Hurraa! ✓✓✓
Täna on kõik, aga räägime juurutamise testimisest tõlke teises osas 😉
Allikas: habr.com
