Infrastruktur Testing minangka Kode karo Pulumi. Bagean 1

Sugeng sonten kanca-kanca. Ing nunggu wiwitan aliran anyar ing tingkat "Praktik lan alat DevOps" Kita nuduhake terjemahan anyar karo sampeyan. Tindak.

Infrastruktur Testing minangka Kode karo Pulumi. Bagean 1

Nggunakake Pulumi lan basa pamrograman umum kanggo kode infrastruktur (Infrastruktur minangka Kode) menehi akeh kaluwihan: kasedhiyan katrampilan lan kawruh, ngilangi boilerplate ing kode liwat abstraksi, alat sing akrab karo tim sampeyan, kayata IDE lan linter. Kabeh piranti rekayasa piranti lunak iki ora mung nggawe kita luwih produktif, nanging uga nambah kualitas kode kita. Mula, wajar yen panggunaan basa pamrograman tujuan umum ngidini kita ngenalake praktik pangembangan piranti lunak penting liyane - tes.

Ing artikel iki, kita bakal ndeleng kepiye Pulumi mbantu nguji infrastruktur-minangka-kode.

Infrastruktur Testing minangka Kode karo Pulumi. Bagean 1

Napa nguji infrastruktur?

Sadurunge nerangake rinci, kudu takon pitakonan: "Napa tes infrastruktur kabeh?" Ana akeh alasan kanggo iki lan ing ngisor iki sawetara:

  • Pengujian unit fungsi individu utawa fragmen logika program sampeyan
  • Verifikasi kahanan infrastruktur sing dikarepake nglawan kendala tartamtu.
  • Deteksi kesalahan umum, kayata kekurangan enkripsi ember panyimpenan utawa ora dilindhungi, mbukak akses saka Internet menyang mesin virtual.
  • Memeriksa implementasi penyediaan infrastruktur.
  • Nindakake tes runtime saka logika aplikasi sing mlaku ing infrastruktur "diprogram" kanggo mriksa fungsi sawise nyedhiyakake.
  • Kaya sing kita deleng, ana macem-macem pilihan tes infrastruktur. Polumi nduweni mekanisme kanggo nguji ing saben titik ing spektrum iki. Ayo miwiti lan ndeleng cara kerjane.

Pengujian unit

Program Pulumi ditulis nganggo basa pemrograman tujuan umum kayata JavaScript, Python, TypeScript utawa Go. Mula, kekuwatan lengkap basa kasebut, kalebu piranti lan perpustakaan, kalebu kerangka uji coba, kasedhiya kanggo dheweke. Pulumi minangka multi-cloud, tegese bisa digunakake kanggo tes saka panyedhiya awan.

(Ing artikel iki, senadyan multi-basa lan multicloud, kita nggunakake JavaScript lan Mocha lan fokus ing AWS. Sampeyan bisa nggunakake Python unittest, Go test framework, utawa framework test liyane sing disenengi. Lan, mesthi, Pulumi bisa digunakake kanthi apik karo Azure, Google Cloud, Kubernetes.)

Kaya sing wis dingerteni, ana sawetara sebab kenapa sampeyan pengin nyoba kode infrastruktur sampeyan. Salah sijine yaiku tes unit konvensional. Amarga kode sampeyan bisa uga duwe fungsi - contone, kanggo ngetung CIDR, ngetung jeneng, tag, lsp. - sampeyan bakal pengin nyoba. Iki padha karo nulis tes unit biasa kanggo aplikasi ing basa pamrograman favorit.
Kanggo luwih rumit, sampeyan bisa mriksa cara program sampeyan nyedhiyakake sumber daya. Kanggo ilustrasi, ayo bayangake yen kita kudu nggawe server EC2 sing prasaja lan kita pengin yakin babagan ing ngisor iki:

  • Instance duwe tag Name.
  • Instans ngirim ora nggunakake script inline userData - kita kudu nggunakake AMI (gambar).
  • Mesthine ora ana SSH sing katon ing Internet.

Conto iki adhedhasar contoku 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;

Iki minangka program Pulumi dhasar: mung nyedhiyakake grup keamanan EC2 lan conto. Nanging, kudu dicathet yen ing kene kita nglanggar kabeh telung aturan sing kasebut ing ndhuwur. Ayo nulis tes!

Tes nulis

Struktur umum tes kita bakal katon kaya tes Mocha biasa:

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

Saiki ayo nulis tes pertama: priksa manawa kedadeyan kasebut duwe tag Name. Kanggo mriksa iki, kita mung njaluk obyek conto EC2 lan mriksa properti sing cocog 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();
                }
            });
        });

Katon kaya tes biasa, nanging kanthi sawetara fitur sing kudu digatekake:

  • Amarga kita takon kahanan sumber sadurunge nyebarake, tes kita mesthi ditindakake ing mode "rencana" (utawa "pratinjau"). Mangkono, ana akeh properti sing nilaine mung ora bisa dijupuk utawa ora bakal ditetepake. Iki kalebu kabeh properti output sing diwilang dening panyedhiya awan sampeyan. Iki normal kanggo tes kita - kita mung mriksa data input. Kita bakal bali menyang masalah iki mengko, nalika nerangake tes integrasi.
  • Amarga kabeh sifat sumber Pulumi minangka output, lan akeh sing dievaluasi kanthi ora sinkron, kita kudu nggunakake metode aplikasi kanggo ngakses nilai kasebut. Iki meh padha karo janji lan fungsi then .
  • Amarga kita nggunakake sawetara sifat kanggo nuduhake URN sumber ing pesen kesalahan, kita kudu nggunakake fungsi kasebut pulumi.allkanggo gabungke.
  • Pungkasan, amarga nilai kasebut diitung kanthi ora sinkron, kita kudu nggunakake fitur panggilan balik async sing dibangun ing Mocha. done utawa bali janji.

Sawise kita wis nyetel kabeh, kita bakal duwe akses menyang input minangka nilai JavaScript prasaja. Properti tags minangka peta (array asosiatif), mula kita bakal mesthekake yen (1) ora salah, lan (2) ana kunci kanggo Name. Gampang banget lan saiki kita bisa nyoba apa wae!

Saiki ayo nulis cek kapindho. Iku malah luwih prasaja:

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

Lan pungkasane, ayo nulis tes katelu. Iki bakal dadi luwih rumit amarga kita nggoleki aturan login sing digandhengake karo grup keamanan, sing bisa uga akeh, lan kisaran CIDR ing aturan kasebut, sing bisa uga akeh. Nanging kita ngatur:

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

Mekaten. Saiki ayo nglakoni tes!

Mlaku tes

Umume kasus, sampeyan bisa nindakake tes kanthi cara biasa, nggunakake kerangka tes sing dipilih. Nanging ana siji fitur Pulumi sing worth mbayar manungsa waé kanggo.
Biasane, kanggo mbukak program Pulumi, CLI (antarmuka Command Line) digunakake, sing ngatur runtime basa, ngontrol peluncuran mesin Pulumi supaya operasi kanthi sumber daya bisa direkam lan kalebu ing rencana, lsp. Nanging, ana siji masalah. Nalika mlaku ing kontrol framework test, ora bakal ana komunikasi antarane CLI lan mesin Pulumi.

Kanggo ngatasi masalah iki, kita mung kudu nemtokake ing ngisor iki:

  • Jeneng proyek, sing ana ing variabel lingkungan PULUMI_NODEJS_PROJECT (utawa, luwih umum, PULUMI__PROJECT для других языков).
    Jeneng tumpukan sing ditemtokake ing variabel lingkungan PULUMI_NODEJS_STACK (utawa, luwih umum, PULUMI__ STACK).
    Variabel konfigurasi tumpukan sampeyan. Padha bisa dipikolehi nggunakake variabel lingkungan PULUMI_CONFIG lan format kasebut yaiku peta JSON kanthi pasangan kunci / nilai.

    Program bakal ngetokake bebaya sing nuduhake yen sambungan menyang CLI / mesin ora kasedhiya sajrone eksekusi. Iki penting amarga program sampeyan ora bakal ngetrapake apa-apa lan bisa uga kaget yen dudu sing dikarepake! Kanggo ngandhani Pulumi manawa iki pancen sampeyan butuhake, sampeyan bisa nginstal PULUMI_TEST_MODE в true.

    Mbayangno kita kudu nemtokake jeneng proyek ing my-ws, jeneng tumpukan dev, lan Wilayah AWS us-west-2. Baris printah kanggo mbukak tes Mocha bakal katon kaya iki:

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

    Nindakake iki, kaya sing dikarepake, bakal nuduhake yen kita duwe telung tes sing gagal!

    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

    Ayo ndandani program kita:

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

    Banjur tindakake tes maneh:

    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)

    Kabèh dadi apik... Hore! ✓✓✓

    Iku kabeh kanggo dina iki, nanging kita bakal ngomong babagan tes penyebaran ing bagean kapindho terjemahan 😉

Source: www.habr.com

Add a comment