Kujaribu Miundombinu kama Kanuni na Pulumi. Sehemu 1

Habari za mchana marafiki. Kwa kutarajia kuanza kwa mtiririko mpya kwa kiwango "Mazoea na zana za DevOps" Tunashiriki nawe tafsiri mpya. Nenda.

Kujaribu Miundombinu kama Kanuni na Pulumi. Sehemu 1

Kutumia Pulumi na lugha za programu za madhumuni ya jumla kwa msimbo wa miundombinu (Miundombinu kama Kanuni) hutoa faida nyingi: ujuzi na ujuzi, kuondokana na boilerplate katika msimbo kupitia uondoaji, zana zinazojulikana kwa timu yako, kama vile IDE na linters. Zana hizi zote za uhandisi wa programu sio tu hutufanya tuwe na tija zaidi, lakini pia kuboresha ubora wa msimbo wetu. Kwa hivyo, ni kawaida kwamba utumiaji wa lugha za kusudi la jumla hukuruhusu kuanzisha mazoezi mengine muhimu ya ukuzaji wa programu - kupima.

Katika makala haya, tutaangalia jinsi Pulumi inatusaidia kupima miundombinu yetu kama kanuni.

Kujaribu Miundombinu kama Kanuni na Pulumi. Sehemu 1

Kwa nini upimaji miundombinu?

Kabla ya kwenda kwa undani, inafaa kuuliza swali: "Kwa nini jaribu miundombinu hata kidogo?" Kuna sababu nyingi za hii na hapa ni baadhi yao:

  • Jaribio la kitengo cha utendakazi mahususi au vipande vya mantiki ya programu yako
  • Inathibitisha hali inayotakiwa ya miundombinu dhidi ya vikwazo fulani.
  • Ugunduzi wa makosa ya kawaida, kama vile ukosefu wa usimbaji fiche wa ndoo ya kuhifadhi au bila ulinzi, ufikiaji wazi kutoka kwa Mtandao hadi kwa mashine pepe.
  • Kuangalia utekelezaji wa utoaji wa miundombinu.
  • Kufanya majaribio ya wakati wa utekelezaji wa mantiki ya programu inayoendeshwa ndani ya miundombinu yako "iliyoratibiwa" ili kuangalia utendakazi baada ya utoaji.
  • Kama tunavyoona, kuna anuwai ya chaguzi za upimaji wa miundombinu. Polumi ina njia za majaribio katika kila hatua kwenye wigo huu. Hebu tuanze na tuone jinsi inavyofanya kazi.

Mtihani wa kitengo

Programu za Pulumi zimeandikwa kwa lugha za kusudi la jumla kama vile JavaScript, Python, TypeScript au Go. Kwa hivyo, uwezo kamili wa lugha hizi, pamoja na zana na maktaba zao, pamoja na mifumo ya majaribio, inapatikana kwao. Pulumi ina wingu nyingi, ambayo inamaanisha inaweza kutumika kwa majaribio kutoka kwa mtoaji wowote wa wingu.

(Katika makala haya, licha ya kuwa na lugha nyingi na wingu nyingi, tunatumia JavaScript na Mocha na tunazingatia AWS. Unaweza kutumia Python unittest, Mfumo wa jaribio la Nenda, au mfumo mwingine wowote wa majaribio unaopenda. Na, bila shaka, Pulumi hufanya kazi vizuri na Azure, Google Cloud, Kubernetes.)

Kama tulivyoona, kuna sababu kadhaa kwa nini unaweza kutaka kujaribu nambari yako ya miundombinu. Mmoja wao ni upimaji wa kitengo cha kawaida. Kwa sababu nambari yako inaweza kuwa na utendakazi - kwa mfano, kukokotoa CIDR, kuhesabu kwa nguvu majina, vitambulisho, n.k. - labda utataka kuwajaribu. Hii ni sawa na kuandika majaribio ya kitengo cha kawaida kwa programu katika lugha unayopenda ya upangaji.
Ili kupata ugumu zaidi, unaweza kuangalia jinsi programu yako inavyogawa rasilimali. Ili kutoa mfano, hebu tufikirie kwamba tunahitaji kuunda seva rahisi ya EC2 na tunataka kuwa na uhakika wa yafuatayo:

  • Matukio yana lebo Name.
  • Matukio hayapaswi kutumia maandishi ya ndani userData - lazima tutumie AMI (picha).
  • Haipaswi kuwa na SSH inayoonyeshwa kwenye Mtandao.

Mfano huu unategemea mfano wangu aws-js-webserver:

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;

Huu ndio programu ya msingi ya Pulumi: inatenga tu kikundi cha usalama cha EC2 na mfano. Hata hivyo, ni lazima ieleweke kwamba hapa tunavunja sheria zote tatu zilizoelezwa hapo juu. Hebu tuandike vipimo!

Kuandika vipimo

Muundo wa jumla wa vipimo vyetu utaonekana kama vipimo vya kawaida vya Mocha:

ec2tess.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, ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ Π² Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚.
    });
});

Sasa hebu tuandike jaribio letu la kwanza: hakikisha kuwa visa vina lebo Name. Ili kuangalia hii tunapata tu kitu cha mfano cha EC2 na angalia mali inayolingana 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();
                }
            });
        });

Inaonekana kama jaribio la kawaida, lakini kwa vipengele vichache vya kuzingatia:

  • Kwa sababu tunauliza hali ya nyenzo kabla ya kutumwa, majaribio yetu yanaendeshwa katika hali ya "mpango" (au "hakiki"). Kwa hivyo, kuna mali nyingi ambazo maadili yake hayatapatikana tena au hayatafafanuliwa. Hii inajumuisha sifa zote za pato zilizokokotolewa na mtoa huduma wako wa wingu. Hii ni kawaida kwa majaribio yetu - tunaangalia data ya ingizo pekee. Tutarejea suala hili baadaye, linapokuja suala la majaribio ya ujumuishaji.
  • Kwa kuwa mali zote za rasilimali za Pulumi ni matokeo, na nyingi hutathminiwa kwa usawa, tunahitaji kutumia mbinu ya kutumia ili kufikia thamani. Hii ni sawa na ahadi na kazi then .
  • Kwa kuwa tunatumia sifa kadhaa ili kuonyesha URN ya rasilimali katika ujumbe wa hitilafu, tunahitaji kutumia chaguo la kukokotoa pulumi.allkuzichanganya.
  • Mwishowe, kwa kuwa maadili haya yamehesabiwa kwa usawa, tunahitaji kutumia kipengee cha kurudisha simu cha Mocha kilichojengwa ndani. done au kurudisha ahadi.

Mara tu tumeweka kila kitu, tutaweza kufikia ingizo kama maadili rahisi ya JavaScript. Mali tags ni ramani (safu shirikishi), kwa hivyo tutahakikisha tu (1) si ya uwongo, na (2) kuna ufunguo wa Name. Ni rahisi sana na sasa tunaweza kujaribu chochote!

Sasa hebu tuandike cheki yetu ya pili. Ni rahisi zaidi:

 // 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();
                }
            });
        });

Na hatimaye, hebu tuandike mtihani wa tatu. Hii itakuwa ngumu zaidi kwa sababu tunatafuta sheria za kuingia zinazohusiana na kikundi cha usalama, ambacho kinaweza kuwa nyingi, na safu za CIDR katika sheria hizo, ambazo zinaweza pia kuwa nyingi. Lakini tuliweza:

    // 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();
                }
            });
        });

Ni hayo tu. Sasa hebu tufanye majaribio!

Kuendesha vipimo

Katika hali nyingi, unaweza kufanya majaribio kwa njia ya kawaida, kwa kutumia mfumo wa majaribio unaopenda. Lakini kuna kipengele kimoja cha Pulumi ambacho kinafaa kuzingatia.
Kwa kawaida, ili kuendesha programu za Pulumi, pulimi CLI (Kiolesura cha Mstari wa Amri) hutumiwa, ambayo inasanidi wakati wa kukimbia kwa lugha, inadhibiti uzinduzi wa injini ya Pulumi ili uendeshaji na rasilimali zinaweza kurekodi na kuingizwa katika mpango, nk. Hata hivyo, kuna tatizo moja. Unapofanya kazi chini ya udhibiti wa mfumo wako wa majaribio, hakutakuwa na mawasiliano kati ya CLI na injini ya Pulumi.

Ili kukabiliana na suala hili, tunahitaji tu kutaja yafuatayo:

  • Jina la mradi, ambalo liko katika utofauti wa mazingira PULUMI_NODEJS_PROJECT (au, kwa ujumla zaidi, PULUMI__PROJECT для Π΄Ρ€ΡƒΠ³ΠΈΡ… языков).
    Jina la safu ambayo imebainishwa katika kigezo cha mazingira PULUMI_NODEJS_STACK (au, kwa ujumla zaidi, PULUMI__ STACK).
    Vigezo vya usanidi wa rafu yako. Wanaweza kupatikana kwa kutumia mabadiliko ya mazingira PULUMI_CONFIG na umbizo lao ni ramani ya JSON iliyo na ufunguo/thamani jozi.

    Programu itatoa maonyo yanayoonyesha kuwa muunganisho wa CLI/injini haupatikani wakati wa utekelezaji. Hii ni muhimu kwa sababu programu yako haitakuwa inapeleka chochote na inaweza kushangaza ikiwa sivyo ulikusudia kufanya! Ili kumwambia Pulumi kwamba hii ndiyo hasa unayohitaji, unaweza kusakinisha PULUMI_TEST_MODE Π² true.

    Fikiria tunahitaji kutaja jina la mradi ndani my-ws, jina la safu dev, na Mkoa wa AWS us-west-2. Mstari wa amri ya kuendesha vipimo vya Mocha itaonekana kama hii:

    $ PULUMI_TEST_MODE=true 
        PULUMI_NODEJS_STACK="my-ws" 
        PULUMI_NODEJS_PROJECT="dev" 
        PULUMI_CONFIG='{ "aws:region": "us-west-2" }' 
        mocha tests.js

    Kufanya hivi, kama inavyotarajiwa, kutatuonyesha kuwa tuna mitihani mitatu iliyofeli!

    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

    Wacha turekebishe programu yetu:

    "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;
    

    Na kisha endesha majaribio tena:

    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)

    Kila kitu kilikwenda vizuri ... Hurray! βœ“βœ“βœ“

    Ni hayo tu kwa leo, lakini tutazungumza kuhusu majaribio ya utumaji katika sehemu ya pili ya tafsiri πŸ˜‰

Chanzo: mapenzi.com

Kuongeza maoni