Pagsulay sa Infrastruktura isip Code sa Pulumi. Bahin 1

Maayong hapon mga higala. Sa pagpaabut sa pagsugod sa usa ka bag-ong dagan sa rate "Mga gawi ug himan sa DevOps" Gipaambit namo kanimo ang usa ka bag-ong hubad. Lakaw.

Pagsulay sa Infrastruktura isip Code sa Pulumi. Bahin 1

Ang paggamit sa Pulumi ug kinatibuk-ang katuyoan nga mga programming language alang sa code sa imprastraktura (Infrastructure as Code) naghatag daghang mga bentaha: ang pagkaanaa sa mga kahanas ug kahibalo, pagwagtang sa boilerplate sa code pinaagi sa abstraction, mga himan nga pamilyar sa imong team, sama sa mga IDE ug linter. Ang tanan niini nga mga himan sa software engineering dili lamang naghimo kanato nga mas produktibo, apan nagpauswag usab sa kalidad sa atong code. Busa, natural lang nga ang paggamit sa mga general-purpose programming language nagtugot kanato sa pagpaila sa laing importante nga software development practice - pagsulay.

Niini nga artikulo, atong tan-awon kung giunsa pagtabang ni Pulumi nga masulayan ang among imprastraktura-as-code.

Pagsulay sa Infrastruktura isip Code sa Pulumi. Bahin 1

Nganong sulayan ang imprastraktura?

Sa wala pa moadto sa detalye, angay nga ipangutana ang pangutana: "Ngano nga gisulayan ang imprastraktura?" Adunay daghang mga hinungdan niini ug ania ang pipila niini:

  • Pagsulay sa yunit sa indibidwal nga mga gimbuhaton o mga tipik sa imong lohika sa programa
  • Gipamatud-an ang gitinguha nga kahimtang sa imprastraktura batok sa pipila nga mga pagpugong.
  • Ang pagtuki sa kasagarang mga sayop, sama sa kakulang sa encryption sa usa ka storage bucket o walay panalipod, bukas nga access gikan sa Internet ngadto sa mga virtual machine.
  • Pagsusi sa pagpatuman sa paghatag sa imprastraktura.
  • Ang paghimo sa runtime nga pagsulay sa aplikasyon nga lohika nga nagdagan sa sulod sa imong "giprograma" nga imprastraktura aron masusi ang pagpaandar pagkahuman sa paghatag.
  • Sama sa atong nakita, adunay daghang mga kapilian sa pagsulay sa imprastraktura. Ang Polumi adunay mga mekanismo sa pagsulay sa matag punto niini nga spectrum. Magsugod ta ug tan-awon kung giunsa kini paglihok.

Pagsulay sa yunit

Ang mga programa sa Pulumi gisulat sa kinatibuk-ang katuyoan nga mga programming language sama sa JavaScript, Python, TypeScript o Go. Busa, ang bug-os nga gahum niini nga mga pinulongan, lakip ang ilang mga galamiton ug mga librarya, lakip ang mga test frameworks, anaa kanila. Ang Pulumi usa ka multi-cloud, nga nagpasabut nga kini magamit alang sa pagsulay gikan sa bisan unsang cloud provider.

(Niining artikuloha, bisan pa sa multilingual ug multicloud, gigamit namo ang JavaScript ug Mocha ug nagtutok sa AWS. Mahimo nimong gamiton ang Python unittest, Go test framework, o bisan unsang ubang test framework nga gusto nimo. Ug, siyempre, maayo ang pagtrabaho ni Pulumi sa Azure, Google Cloud, Kubernetes.)

Sama sa among nakita, adunay daghang mga hinungdan ngano nga gusto nimo sulayan ang imong code sa imprastraktura. Usa niini mao ang conventional unit testing. Tungod kay ang imong code mahimong adunay mga gimbuhaton - pananglitan, aron makalkulo ang CIDR, dinamikong pagkalkula sa mga ngalan, tag, ug uban pa. - tingali gusto nimo nga sulayan sila. Parehas kini sa pagsulat sa regular nga mga pagsulay sa yunit alang sa mga aplikasyon sa imong paboritong programming language.
Aron mahimong mas komplikado, mahimo nimong susihon kung giunsa paggahin sa imong programa ang mga kapanguhaan. Sa pag-ilustrar, atong hunahunaon nga kita kinahanglan nga maghimo og usa ka yano nga EC2 server ug gusto namong masiguro ang mosunod:

  • Ang mga higayon adunay tag Name.
  • Ang mga higayon kinahanglan dili mogamit sa inline nga script userData - kinahanglan natong gamiton ang AMI (imahe).
  • Kinahanglang walay SSH nga ma-expose sa Internet.

Kini nga pananglitan gibase sa akong pananglitan 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;

Kini ang batakang programa sa Pulumi: naggahin lang kini usa ka grupo sa seguridad sa EC2 ug usa ka pananglitan. Bisan pa, kinahanglan nga hinumdoman nga dinhi gilapas namon ang tanan nga tulo nga mga lagda nga gipahayag sa ibabaw. Magsulat ta ug mga pagsulay!

Mga pagsulay sa pagsulat

Ang kinatibuk-ang istruktura sa among mga pagsulay sama sa naandan nga mga pagsulay sa Mocha:

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

Karon atong isulat ang atong unang pagsulay: siguruha nga ang mga higayon adunay tag Name. Aron masusi kini makuha lang nato ang EC2 instance object ug susihon ang katugbang nga kabtangan 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();
                }
            });
        });

Morag usa kini ka regular nga pagsulay, apan adunay pipila ka mga bahin nga angay hinumdoman:

  • Tungod kay among gipangutana ang kahimtang sa usa ka kapanguhaan sa wala pa i-deploy, ang among mga pagsulay kanunay nga gipadagan sa mode nga "plano" (o "preview"). Sa ingon, adunay daghang mga kabtangan kansang mga kantidad dili makuha o dili mahibal-an. Naglakip kini sa tanan nga mga kabtangan sa output nga gikalkula sa imong cloud provider. Normal kini sa among mga pagsulay - among gisusi lang ang input data. Mobalik kami sa kini nga isyu sa ulahi, kung bahin sa mga pagsulay sa panagsama.
  • Tungod kay ang tanan nga mga kabtangan sa kapanguhaan sa Pulumi mga output, ug kadaghanan niini gi-evaluate nga asynchronously, kinahanglan namon nga gamiton ang pamaagi sa paggamit aron ma-access ang mga kantidad. Kini susama kaayo sa mga saad ug afunction then .
  • Tungod kay naggamit kami daghang mga kabtangan aron ipakita ang kapanguhaan nga URN sa mensahe sa sayup, kinahanglan namon nga gamiton ang function pulumi.allsa paghiusa kanila.
  • Sa katapusan, tungod kay kini nga mga kantidad gikalkula nga asynchronously, kinahanglan namon gamiton ang built-in nga async callback nga bahin ni Mocha done o pagbalik sa usa ka saad.

Kung na-set up na namo ang tanan, aduna na kami access sa mga input isip yanong JavaScript values. Property tags usa ka mapa (associative array), mao nga atong siguroon nga kini (1) dili bakak, ug (2) adunay yawe alang sa Name. Yano ra kaayo ug karon masulayan na namon ang bisan unsang butang!

Karon atong isulat ang atong ikaduhang tseke. Mas simple pa kini:

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

Ug sa katapusan, atong isulat ang ikatulo nga pagsulay. Kini mahimong usa ka gamay nga mas komplikado tungod kay kami nangita alang sa mga lagda sa pag-login nga may kalabutan sa grupo sa seguridad, diin adunay daghan, ug ang CIDR naglangkob sa mga lagda, diin mahimo usab nga daghan. Apan nakahimo kami:

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

Mao ra. Karon atong padaganon ang mga pagsulay!

Nagdagan nga mga pagsulay

Sa kadaghanan nga mga kaso, mahimo nimong ipadagan ang mga pagsulay sa naandan nga paagi, gamit ang balangkas sa pagsulay nga imong gipili. Apan adunay usa ka bahin sa Pulumi nga angay hatagan pagtagad.
Kasagaran, sa pagpadagan sa mga programa sa Pulumi, gigamit ang pulimi CLI (Command Line interface), nga nag-configure sa runtime sa lengguwahe, nagkontrol sa paglansad sa Pulumi engine aron ang mga operasyon nga adunay mga kapanguhaan marekord ug maapil sa plano, ug uban pa. Apan, adunay usa ka problema. Kung nagdagan ubos sa kontrol sa imong balangkas sa pagsulay, wala’y komunikasyon tali sa CLI ug sa Pulumi nga makina.

Aron masulbad kini nga isyu, kinahanglan lang naton ipiho ang mga musunud:

  • Ngalan sa proyekto, nga naa sa variable sa palibot PULUMI_NODEJS_PROJECT (o, mas kasagaran, PULUMI__PROJECT для других языков).
    Ang ngalan sa stack nga gipiho sa variable sa palibot PULUMI_NODEJS_STACK (o, mas kasagaran, PULUMI__ STACK).
    Ang imong stack configuration variables. Makuha sila gamit ang environment variable PULUMI_CONFIG ug ang ilang format kay JSON nga mapa nga naay key/value pairs.

    Ang programa mag-isyu og mga pasidaan nga nagpakita nga ang koneksyon sa CLI/engine dili magamit sa panahon sa pagpatay. Importante kini tungod kay ang imong programa dili gayud mag-deploy ug bisan unsa ug kini mahimong usa ka katingala kung dili kana ang imong gituyo nga buhaton! Aron isulti si Pulumi nga mao gyud kini ang imong kinahanglan, mahimo nimong i-install PULUMI_TEST_MODE в true.

    Hunahunaa nga kinahanglan naton ipiho ang ngalan sa proyekto sa my-ws, ngalan sa stack dev, ug AWS Region us-west-2. Ang command line alang sa pagpadagan sa mga pagsulay sa Mocha mahimong sama niini:

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

    Ang pagbuhat niini, sama sa gipaabut, magpakita kanamo nga kami adunay tulo nga napakyas nga mga pagsulay!

    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

    Ayuhon nato ang atong programa:

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

    Ug dayon pagdagan ang mga pagsulay pag-usab:

    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)

    Maayo ang tanan... Hurray! ✓✓✓

    Kanang tanan alang sa karon, apan maghisgot kami bahin sa pagsulay sa pag-deploy sa ikaduhang bahin sa paghubad 😉

Source: www.habr.com

Idugang sa usa ka comment