Idanwo Awọn amayederun bi koodu pẹlu Pulumi. Apa 1

Ti o dara Friday ọrẹ. Ni ifojusona ti ibẹrẹ ti ṣiṣan tuntun ni oṣuwọn "Awọn iṣe DevOps ati awọn irinṣẹ" A n pin itumọ tuntun pẹlu rẹ. Lọ.

Idanwo Awọn amayederun bi koodu pẹlu Pulumi. Apa 1

Lilo Pulumi ati awọn ede siseto idi gbogbogbo fun koodu amayederun (Amayederun bi koodu) pese ọpọlọpọ awọn anfani: wiwa ti awọn ọgbọn ati imọ, imukuro igbomikana ninu koodu nipasẹ abstraction, awọn irinṣẹ ti o mọmọ si ẹgbẹ rẹ, gẹgẹ bi awọn IDE ati awọn linters. Gbogbo awọn irinṣẹ imọ-ẹrọ sọfitiwia wọnyi kii ṣe nikan jẹ ki a ni iṣelọpọ diẹ sii, ṣugbọn tun mu didara koodu wa dara. Nitorinaa, o jẹ adayeba nikan pe lilo awọn ede siseto idi gbogbogbo gba wa laaye lati ṣafihan iṣe idagbasoke sọfitiwia pataki miiran - idanwo.

Ninu nkan yii, a yoo wo bii Pulumi ṣe ṣe iranlọwọ fun wa lati ṣe idanwo awọn amayederun-bi-koodu.

Idanwo Awọn amayederun bi koodu pẹlu Pulumi. Apa 1

Kini idi ti idanwo amayederun?

Ṣaaju ki o to lọ si awọn alaye, o tọ lati beere ibeere naa: “Kini idi ti idanwo awọn amayederun rara?” Awọn idi pupọ lo wa fun eyi ati pe eyi ni diẹ ninu wọn:

  • Idanwo apakan ti awọn iṣẹ kọọkan tabi awọn ajẹkù ti ọgbọn eto rẹ
  • Ṣe idaniloju ipo ti o fẹ ti amayederun lodi si awọn idiwọ kan.
  • Wiwa awọn aṣiṣe ti o wọpọ, gẹgẹbi aini fifi ẹnọ kọ nkan ti garawa ibi ipamọ tabi ti ko ni aabo, iraye si lati Intanẹẹti si awọn ẹrọ foju.
  • Ṣiṣayẹwo imuse ti ipese amayederun.
  • Ṣiṣe idanwo akoko asiko ti oye ohun elo nṣiṣẹ inu awọn amayederun “eto” rẹ lati ṣayẹwo iṣẹ ṣiṣe lẹhin ipese.
  • Gẹgẹbi a ti le rii, ọpọlọpọ awọn aṣayan idanwo amayederun wa. Polumi ni awọn ọna ṣiṣe fun idanwo ni gbogbo aaye lori iwoye yii. Jẹ ká to bẹrẹ ati ki o wo bi o ti ṣiṣẹ.

Idanwo kuro

Awọn eto Pulumi jẹ kikọ ni awọn ede siseto idi gbogbogbo gẹgẹbi JavaScript, Python, TypeScript tabi Go. Nitorinaa, agbara kikun ti awọn ede wọnyi, pẹlu awọn irinṣẹ ati awọn ile-ikawe wọn, pẹlu awọn ilana idanwo, wa fun wọn. Pulumi jẹ awọsanma pupọ, eyiti o tumọ si pe o le ṣee lo fun idanwo lati ọdọ olupese awọsanma eyikeyi.

(Ninu nkan yii, botilẹjẹpe o jẹ multilingual ati multicloud, a lo JavaScript ati Mocha ati idojukọ lori AWS. O le lo Python unittest, Lọ igbeyewo ilana, tabi eyikeyi miiran igbeyewo ilana ti o fẹ. Ati pe, dajudaju, Pulumi ṣiṣẹ nla pẹlu Azure, Google Cloud, Kubernetes.)

Gẹgẹbi a ti rii, awọn idi pupọ lo wa ti o le fẹ lati ṣe idanwo koodu amayederun rẹ. Ọkan ninu wọn jẹ idanwo ẹyọkan ti aṣa. Nitoripe koodu rẹ le ni awọn iṣẹ - fun apẹẹrẹ, lati ṣe iṣiro CIDR, ṣe iṣiro awọn orukọ, awọn afi, ati bẹbẹ lọ. - o yoo jasi fẹ lati se idanwo fun wọn. Eyi jẹ kanna bi kikọ awọn idanwo ẹyọkan deede fun awọn ohun elo ni ede siseto ayanfẹ rẹ.
Lati ni idiju diẹ sii, o le ṣayẹwo bi eto rẹ ṣe n pin awọn orisun. Lati ṣapejuwe, jẹ ki a fojuinu pe a nilo lati ṣẹda olupin EC2 ti o rọrun ati pe a fẹ lati ni idaniloju awọn atẹle wọnyi:

  • Awọn apẹẹrẹ ni aami kan Name.
  • Awọn apẹẹrẹ ko yẹ ki o lo iwe afọwọkọ inline userData - a gbọdọ lo AMI (aworan).
  • Ko yẹ ki SSH han si Intanẹẹti.

Apeere yii da lori apẹẹrẹ mi aws-js-webserver:

atọka.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;

Eyi ni eto Pulumi ipilẹ: o kan sọtọ ẹgbẹ aabo EC2 ati apẹẹrẹ kan. Sibẹsibẹ, o yẹ ki o ṣe akiyesi pe nibi a npa gbogbo awọn ofin mẹta ti a sọ loke. Jẹ ki a kọ awọn idanwo!

Awọn idanwo kikọ

Eto gbogbogbo ti awọn idanwo wa yoo dabi awọn idanwo Mocha deede:

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, открытого в Интернет.
    });
});

Bayi jẹ ki a kọ idanwo akọkọ wa: rii daju pe awọn iṣẹlẹ ni tag Name. Lati ṣayẹwo eyi a nìkan gba ohun apẹẹrẹ EC2 ati ṣayẹwo ohun-ini ti o baamu 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();
                }
            });
        });

O dabi idanwo deede, ṣugbọn pẹlu awọn ẹya diẹ ti o tọ lati ṣe akiyesi:

  • Nitoripe a beere ipo orisun ṣaaju imuṣiṣẹ, awọn idanwo wa nigbagbogbo ni ṣiṣe ni ipo “eto” (tabi “awotẹlẹ”). Nitorinaa, ọpọlọpọ awọn ohun-ini wa ti awọn iye wọn kii yoo gba pada tabi kii yoo ṣe asọye. Eyi pẹlu gbogbo awọn ohun-ini iṣelọpọ ti a ṣe iṣiro nipasẹ olupese awọsanma rẹ. Eyi jẹ deede fun awọn idanwo wa - a ṣayẹwo data titẹ sii nikan. A yoo pada si atejade yii nigbamii, nigbati o ba de si awọn idanwo iṣọpọ.
  • Niwọn bi gbogbo awọn ohun-ini orisun Pulumi jẹ awọn abajade, ati pe ọpọlọpọ ninu wọn ni iṣiro asynchronously, a nilo lati lo ọna lilo lati wọle si awọn iye. Eleyi jẹ gidigidi iru si awọn ileri ati iṣẹ then .
  • Niwọn igba ti a ti nlo awọn ohun-ini pupọ lati ṣafihan URN orisun ninu ifiranṣẹ aṣiṣe, a nilo lati lo iṣẹ naa pulumi.alllati darapo wọn.
  • Ni ipari, niwọn bi a ti ṣe iṣiro awọn iye wọnyi ni asynchronously, a nilo lati lo ẹya async ti a ṣe sinu Mocha done tabi pada ileri.

Ni kete ti a ti ṣeto ohun gbogbo soke, a yoo ni iwọle si awọn igbewọle bi awọn iye JavaScript ti o rọrun. Ohun ini tags jẹ maapu kan (orun associative), nitorinaa a yoo rii daju pe (1) kii ṣe eke, ati (2) bọtini kan wa fun Name. O rọrun pupọ ati bayi a le ṣe idanwo ohunkohun!

Bayi jẹ ki a kọ ayẹwo keji wa. Paapaa o rọrun julọ:

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

Ati nikẹhin, jẹ ki a kọ idanwo kẹta. Eyi yoo jẹ idiju diẹ sii nitori a n wa awọn ofin iwọle ti o ni nkan ṣe pẹlu ẹgbẹ aabo, eyiti o le jẹ ọpọlọpọ, ati awọn sakani CIDR ninu awọn ofin yẹn, eyiti o tun le jẹ pupọ. Ṣugbọn a ṣakoso:

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

Gbogbo ẹ niyẹn. Bayi jẹ ki ká ṣiṣe awọn igbeyewo!

Awọn idanwo ṣiṣe

Ni ọpọlọpọ igba, o le ṣiṣe awọn idanwo ni ọna deede, ni lilo ilana idanwo ti o fẹ. Ṣugbọn ẹya kan wa ti Pulumi ti o tọ lati san ifojusi si.
Ni deede, lati mu awọn eto Pulumi ṣiṣẹ, a lo pulimi CLI (Ni wiwo Laini Aṣẹ), eyiti o tunto akoko asiko ede, ṣakoso ifilọlẹ ẹrọ Pulumi ki awọn iṣẹ ṣiṣe pẹlu awọn orisun le ṣe igbasilẹ ati pẹlu ero naa, ati bẹbẹ lọ. Sibẹsibẹ, iṣoro kan wa. Nigbati o ba nṣiṣẹ labẹ iṣakoso ti ilana idanwo rẹ, kii yoo ni ibaraẹnisọrọ laarin CLI ati ẹrọ Pulumi.

Lati yanju iṣoro yii, a kan nilo lati pato awọn atẹle:

  • Orukọ iṣẹ akanṣe, eyiti o wa ninu oniyipada ayika PULUMI_NODEJS_PROJECT (tabi, diẹ sii ni gbogbogbo, PULUMI__PROJECT для других языков).
    Orukọ akopọ ti o jẹ pato ni oniyipada ayika PULUMI_NODEJS_STACK (tabi, diẹ sii ni gbogbogbo, PULUMI__ STACK).
    Awọn oniyipada akopọ akopọ rẹ. Wọn le gba nipa lilo iyipada ayika PULUMI_CONFIG ati ọna kika wọn jẹ maapu JSON pẹlu awọn orisii bọtini / iye.

    Eto naa yoo fun awọn ikilọ ti o fihan pe asopọ si CLI / ẹrọ ko si lakoko ipaniyan. Eyi ṣe pataki nitori pe eto rẹ kii yoo fi ohunkohun ranṣẹ ati pe o le jẹ iyalẹnu ti iyẹn kii ṣe ohun ti o pinnu lati ṣe! Lati sọ fun Pulumi pe eyi ni deede ohun ti o nilo, o le fi sii PULUMI_TEST_MODE в true.

    Fojuinu pe a nilo lati pato orukọ iṣẹ akanṣe ni my-ws, akopọ orukọ dev, ati AWS Ekun us-west-2. Laini aṣẹ fun ṣiṣe awọn idanwo Mocha yoo dabi eyi:

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

    Ṣiṣe eyi, bi o ti ṣe yẹ, yoo fihan wa pe a ni awọn idanwo mẹta ti o kuna!

    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

    Jẹ ki a ṣatunṣe eto wa:

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

    Ati lẹhinna ṣiṣe awọn idanwo lẹẹkansi:

    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)

    Ohun gbogbo lọ daradara ... Hurray! ✓✓✓

    Iyẹn jẹ gbogbo fun oni, ṣugbọn a yoo sọrọ nipa idanwo imuṣiṣẹ ni apakan keji ti itumọ 😉

orisun: www.habr.com

Fi ọrọìwòye kun