Góðan daginn vinir. Í aðdraganda upphafs nýs flæðis á genginu
Að nota Pulumi og almenn forritunarmál fyrir innviðakóða (Infrastructure as Code) veitir marga kosti: aðgengi að færni og þekkingu, útrýming á ketilplötu í kóðanum með útdrætti, verkfæri sem teymið þitt kannast við, svo sem IDE og linters. Öll þessi hugbúnaðarverkfæri gera okkur ekki aðeins afkastameiri heldur bæta gæði kóðans okkar. Þess vegna er eðlilegt að notkun almennra forritunarmála geri okkur kleift að kynna aðra mikilvæga hugbúnaðarþróunaraðferð - Prófun.
Í þessari grein munum við skoða hvernig Pulumi hjálpar okkur að prófa innviði okkar sem kóða.
Af hverju að prófa innviði?
Áður en farið er í smáatriði er þess virði að spyrja spurningarinnar: „Af hverju að prófa innviði yfirleitt? Það eru margar ástæður fyrir þessu og hér eru nokkrar þeirra:
- Einingaprófun á einstökum aðgerðum eða brotum af rökfræði forritsins
- Staðfestir æskilegt ástand innviða gegn ákveðnum takmörkunum.
- Uppgötvun algengra villna, svo sem skortur á dulkóðun á geymslufötu eða óvarinn, opnar aðgang frá internetinu að sýndarvélum.
- Athugun á innleiðingu innviðaútvegunar.
- Framkvæma keyrslutímaprófun á rökfræði forrita sem keyrir inni í „forrituðum“ innviðum þínum til að athuga virkni eftir úthlutun.
- Eins og við sjáum er mikið úrval af innviðaprófunarvalkostum. Polumi hefur aðferðir til að prófa á hverjum stað á þessu litrófi. Við skulum byrja og sjá hvernig það virkar.
Einingaprófun
Pulumi forrit eru skrifuð á almennum forritunarmálum eins og JavaScript, Python, TypeScript eða Go. Þess vegna er fullur kraftur þessara tungumála, þar á meðal verkfæri þeirra og bókasöfn, þar með talið prófunarramma, í boði fyrir þá. Pulumi er multi-ský, sem þýðir að það er hægt að nota það til að prófa frá hvaða skýjafyrirtæki sem er.
(Í þessari grein, þrátt fyrir að vera fjöltyngd og fjölský, notum við JavaScript og Mokka og leggjum áherslu á AWS. Þú getur notað Python unittest
, Farðu í prófunarramma eða hvaða prófunarramma sem þú vilt. Og auðvitað virkar Pulumi frábærlega með Azure, Google Cloud, Kubernetes.)
Eins og við höfum séð eru nokkrar ástæður fyrir því að þú gætir viljað prófa innviðakóðann þinn. Ein þeirra er hefðbundin einingaprófun. Vegna þess að kóðinn þinn gæti haft aðgerðir - til dæmis til að reikna út CIDR, reikna nöfn, merki, o.s.frv. - þú vilt líklega prófa þá. Þetta er það sama og að skrifa venjuleg einingapróf fyrir forrit á uppáhalds forritunarmálinu þínu.
Til að verða aðeins flóknari geturðu athugað hvernig forritið þitt úthlutar fjármagni. Til að sýna fram á það skulum við ímynda okkur að við þurfum að búa til einfaldan EC2 netþjón og við viljum vera viss um eftirfarandi:
- Tilvik eru með merki
Name
. - Tilvik ættu ekki að nota inline skriftu
userData
- við verðum að nota AMI (mynd). - Það ætti ekki að vera SSH útsett fyrir internetinu.
Þetta dæmi er byggt á
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 ], // reference the group object above
ami: "ami-c55673a0" // AMI for us-east-2 (Ohio),
userData: userData // start a simple web server
});
exports.group = group;
exports.server = server;
exports.publicIp = server.publicIp;
exports.publicHostName = server.publicDns;
Þetta er grunnPulumi forritið: það úthlutar einfaldlega EC2 öryggishópi og tilviki. Hins vegar skal tekið fram að hér er verið að brjóta allar þrjár reglurnar sem tilgreindar eru hér að ofan. Skrifum próf!
Að skrifa próf
Almenn uppbygging prófana okkar mun líta út eins og venjuleg mokkapróf:
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): Должен быть тэг Name.
// TODO(check 2): Не должно быть inline-скрипта userData.
});
let group = infra.group;
describe("#group", function() {
// TODO(check 3): Не должно быть SSH, открытого в Интернет.
});
});
Nú skulum við skrifa fyrsta prófið okkar: vertu viss um að tilvikin hafi merkið Name
. Til að athuga þetta fáum við einfaldlega EC2 tilvikshlutinn og athugum samsvarandi eiginleika 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();
}
});
});
Það lítur út eins og venjulegt próf, en með nokkrum eiginleikum sem vert er að taka eftir:
- Vegna þess að við spyrjum um stöðu tilföngs fyrir uppsetningu, eru prófin okkar alltaf keyrð í „áætlun“ (eða „forskoðun“) ham. Þannig eru margar eignir þar sem gildi þeirra verða einfaldlega ekki sótt eða verða ekki skilgreind. Þetta felur í sér alla framleiðslueiginleika sem reiknaðir eru af skýjaveitunni þinni. Þetta er eðlilegt fyrir prófin okkar - við athugum aðeins inntaksgögnin. Við munum koma aftur að þessu máli síðar, þegar kemur að samþættingarprófum.
- Þar sem allir Pulumi auðlindareiginleikar eru úttak, og margir þeirra eru metnir ósamstillt, þurfum við að nota umsóknaraðferðina til að fá aðgang að gildunum. Þetta er mjög svipað loforðum og óvirkni
then
. - Þar sem við erum að nota nokkra eiginleika til að sýna auðlindina URN í villuboðunum, þurfum við að nota aðgerðina
pulumi.all
að sameina þau. - Að lokum, þar sem þessi gildi eru reiknuð ósamstillt, þurfum við að nota innbyggða ósamstillta svarhringingareiginleika Mocha
done
eða skila loforði.
Þegar við höfum sett allt upp höfum við aðgang að inntakunum sem einföld JavaScript gildi. Eign tags
er kort (associative array), svo við munum bara ganga úr skugga um að það sé (1) ekki falskt og (2) að það sé lykill fyrir Name
. Það er mjög einfalt og nú getum við prófað hvað sem er!
Nú skulum við skrifa aðra ávísunina okkar. Það er jafnvel einfaldara:
// 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();
}
});
});
Og að lokum skulum við skrifa þriðja prófið. Þetta verður aðeins flóknara vegna þess að við erum að leita að innskráningarreglum sem tengjast öryggishópnum, sem þeir geta verið margir af, og CIDR sviðum í þeim reglum, sem það geta líka verið margar af. En okkur tókst:
// 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();
}
});
});
Það er allt og sumt. Nú skulum við keyra prófin!
Hlaupapróf
Í flestum tilfellum geturðu keyrt próf á venjulegan hátt með því að nota prófunarrammann að eigin vali. En það er einn eiginleiki Pulumi sem vert er að gefa gaum að.
Venjulega, til að keyra Pulumi forrit, er pulimi CLI (Command Line tengi) notað, sem stillir tungumálakjörtímann, stjórnar ræsingu Pulumi vélarinnar þannig að hægt sé að skrá aðgerðir með tilföngum og taka með í áætlun o.s.frv. Hins vegar er eitt vandamál. Þegar keyrt er undir stjórn prófunarramma þíns verða engin samskipti milli CLI og Pulumi vélarinnar.
Til að komast í kringum þetta mál þurfum við bara að tilgreina eftirfarandi:
- Heiti verkefnis, sem er að finna í umhverfisbreytunni
PULUMI_NODEJS_PROJECT
(eða, almennt séð,PULUMI__PROJECT для других языков).
Heiti staflans sem er tilgreint í umhverfisbreytunniPULUMI_NODEJS_STACK
(eða, almennt séð,PULUMI__ STACK).
Stafla stillingarbreytur þínar. Hægt er að fá þær með því að nota umhverfisbreytuPULUMI_CONFIG
og snið þeirra er JSON kort með lykil/gildi pörum.Forritið mun gefa út viðvaranir sem gefa til kynna að tengingin við CLI/vélina sé ekki tiltæk meðan á framkvæmd stendur. Þetta er mikilvægt vegna þess að forritið þitt mun í rauninni ekki dreifa neinu og það gæti komið á óvart ef það er ekki það sem þú ætlaðir að gera! Til að segja Pulumi að þetta sé nákvæmlega það sem þú þarft geturðu sett upp
PULUMI_TEST_MODE
вtrue
.Ímyndaðu þér að við þurfum að tilgreina verkefnisheitið í
my-ws
, heiti stafladev
, og AWS svæðinuus-west-2
. Skipanalínan til að keyra Mokka próf mun líta svona út:$ PULUMI_TEST_MODE=true PULUMI_NODEJS_STACK="my-ws" PULUMI_NODEJS_PROJECT="dev" PULUMI_CONFIG='{ "aws:region": "us-west-2" }' mocha tests.js
Að gera þetta, eins og búist var við, mun sýna okkur að við erum með þrjú misheppnuð próf!
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 group
Við skulum laga forritið okkar:
"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 ], // reference the group object above ami: "ami-c55673a0" // AMI for us-east-2 (Ohio), }); exports.group = group; exports.server = server; exports.publicIp = server.publicIp; exports.publicHostName = server.publicDns;
Og keyrðu síðan prófin aftur:
Infrastructure #server ✓ must have a name tag ✓ must not use userData (use an AMI instead) #group ✓ must not open port 22 (SSH) to the Internet 3 passing (16ms)
Allt gekk vel... Húrra! ✓✓✓
Þetta er allt í dag, en við munum tala um dreifingarprófanir í seinni hluta þýðingarinnar 😉
Heimild: www.habr.com