Prófa innviði sem kóða með Pulumi. 1. hluti

Góðan daginn vinir. Í aðdraganda upphafs nýs flæðis á genginu „DevOps venjur og verkfæri“ Við erum að deila með þér nýrri þýðingu. Farðu.

Prófa innviði sem kóða með Pulumi. 1. hluti

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.

Prófa innviði sem kóða með Pulumi. 1. hluti

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 á dæmið mitt aws-js-vefþjónn:

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.allað 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 í umhverfisbreytunni PULUMI_NODEJS_STACK (eða, almennt séð, PULUMI__ STACK).
    Stafla stillingarbreytur þínar. Hægt er að fá þær með því að nota umhverfisbreytu PULUMI_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 stafla dev, og AWS svæðinu us-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

Bæta við athugasemd