Test Infrastructure li Code nrog Pulumi. Ntu 1

Nyob zoo os phooj ywg. Nyob rau hauv kev cia siab ntawm qhov pib ntawm qhov tshiab ntws ntawm tus nqi "DevOps kev coj ua thiab cov cuab yeej" Peb tab tom muab kev txhais lus tshiab rau koj. Mus.

Test Infrastructure li Code nrog Pulumi. Ntu 1

Siv Pulumi thiab cov hom phiaj dav dav ntawm cov lus programming rau cov txheej txheem kev cai (Infrastructure li Code) muab ntau yam zoo: muaj kev txawj ntse thiab kev paub, tshem tawm cov boilerplate hauv cov cai los ntawm kev paub daws teeb meem, cov cuab yeej paub txog koj pab neeg, xws li IDEs thiab linters. Tag nrho cov software engineering cov cuab yeej no tsis tsuas yog ua rau peb ua tau zoo, tab sis kuj txhim kho peb cov cai. Yog li ntawd, nws tsuas yog ntuj uas siv cov hom phiaj dav dav dav dav tso cai rau peb los qhia lwm qhov tseem ceeb software txhim kho kev xyaum - xeem.

Hauv tsab xov xwm no, peb yuav saib yuav ua li cas Pulumi pab peb sim peb cov txheej txheem-raws li-code.

Test Infrastructure li Code nrog Pulumi. Ntu 1

Vim li cas thiaj kuaj xyuas infrastructure?

Ua ntej nkag mus rau hauv kev nthuav dav, nws tsim nyog nug cov lus nug: "Vim li cas kuaj kev tsim kho txhua qhov?" Muaj ntau qhov laj thawj rau qhov no thiab ntawm no yog qee qhov ntawm lawv:

  • Chav ntsuas kev ua haujlwm ntawm tus kheej lossis cov khoom tawg ntawm koj qhov kev pabcuam logic
  • Tshawb xyuas lub xeev xav tau ntawm cov infrastructure tiv thaiv qee qhov kev txwv.
  • Kev tshawb pom ntawm qhov yuam kev, xws li tsis muaj kev nkag siab ntawm lub thoob ntim khoom lossis tsis muaj kev tiv thaiv, qhib kev nkag los ntawm Is Taws Nem mus rau cov tshuab virtual.
  • Txheeb xyuas qhov kev siv ntawm kev tsim kho vaj tse.
  • Ua lub sijhawm ua haujlwm ntawm cov ntawv thov logic khiav hauv koj qhov "programmed" infrastructure los xyuas kev ua haujlwm tom qab muab.
  • Raws li peb tuaj yeem pom, muaj ntau yam kev sim ntsuas kev ua haujlwm. Polumi muaj cov txheej txheem rau kev sim ntawm txhua qhov chaw ntawm qhov spectrum no. Cia peb pib thiab saib seb nws ua haujlwm li cas.

Chav ntsuas

Pulumi cov kev pab cuam raug sau ua hom lus siv dav dav xws li JavaScript, Python, TypeScript lossis Go. Yog li ntawd, tag nrho lub zog ntawm cov lus no, suav nrog lawv cov cuab yeej thiab cov tsev qiv ntawv, suav nrog cov qauv ntsuas, muaj rau lawv. Pulumi yog ntau huab, uas txhais tau tias nws tuaj yeem siv rau kev sim los ntawm txhua tus neeg muab kev pabcuam huab.

(Nyob rau hauv tsab xov xwm no, txawm hais tias nws yog ntau hom lus thiab multicloud, peb siv JavaScript thiab Mocha thiab tsom mus rau AWS. Koj tuaj yeem siv Python. unittest, Mus xeem lub moj khaum, los yog lwm yam kev xeem lub moj khaum koj nyiam. Thiab, tau kawg, Pulumi ua haujlwm zoo nrog Azure, Google Huab, Kubernetes.)

Raws li peb tau pom, muaj ntau qhov laj thawj vim li cas koj thiaj li xav sim koj cov cai hauv vaj tse. Ib tug ntawm lawv yog cov pa ntsuas chav tsev. Vim hais tias koj cov cai yuav muaj nuj nqi - piv txwv li, xam CIDR, dynamically xam cov npe, cim npe, thiab lwm yam. - Tej zaum koj yuav xav sim lawv. Qhov no yog tib yam li kev sau cov ntawv xeem tsis tu ncua rau cov ntawv thov hauv koj cov lus programming nyiam.
Kom tau txais qhov nyuaj me ntsis, koj tuaj yeem tshawb xyuas seb koj qhov program faib cov peev txheej li cas. Txhawm rau ua piv txwv, cia peb xav txog tias peb yuav tsum tsim ib qho yooj yim EC2 server thiab peb xav kom paub tseeb txog cov hauv qab no:

  • Piv txwv muaj tag Name.
  • Cov xwm txheej yuav tsum tsis txhob siv cov ntawv sau hauv kab userData - Peb yuav tsum siv AMI (daim duab).
  • Yuav tsum tsis muaj SSH nthuav tawm hauv Is Taws Nem.

Qhov piv txwv no yog nyob ntawm my example 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;

Qhov no yog qhov kev pab cuam Pulumi yooj yim: nws tsuas yog faib pawg EC2 kev ruaj ntseg thiab ib qho piv txwv. Txawm li cas los xij, nws yuav tsum raug sau tseg tias ntawm no peb tab tom ua txhaum tag nrho peb txoj cai tau teev tseg saum toj no. Wb sau ntawv xeem!

Kev xeem sau ntawv

Cov qauv dav dav ntawm peb qhov kev xeem yuav zoo li kev xeem Mocha li niaj zaus:

ec2tests.js ua

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

Tam sim no cia peb sau peb qhov kev sim thawj zaug: xyuas kom meej tias cov xwm txheej muaj tag Name. Txhawm rau txheeb xyuas qhov no peb tsuas yog tau txais EC2 piv txwv khoom thiab tshawb xyuas cov khoom sib xws 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();
                }
            });
        });

Nws zoo li kev sim tsis tu ncua, tab sis nrog ob peb yam tsim nyog sau cia:

  • Vim tias peb nug txog lub xeev ntawm cov peev txheej ua ntej xa mus, peb cov kev xeem yeej ib txwm khiav hauv "plam" (lossis "saib ua ntej") hom. Yog li, muaj ntau yam khoom uas nws cov txiaj ntsig yuav tsuas tsis tau muab los yog yuav tsis raug txhais. Qhov no suav nrog tag nrho cov khoom tsim tawm los ntawm koj tus kws kho mob huab. Qhov no yog ib txwm rau peb qhov kev xeem - peb tsuas yog xyuas cov ntaub ntawv nkag. Peb yuav rov qab mus rau qhov teeb meem no tom qab, thaum nws los txog rau kev xeem kev sib koom ua ke.
  • Txij li tag nrho cov peev txheej Pulumi yog cov khoom tsim tawm, thiab ntau ntawm lawv tau soj ntsuam asynchronously, peb yuav tsum siv txoj kev thov kom nkag mus rau qhov tseem ceeb. Qhov no zoo ib yam li cov lus cog tseg thiab kev ua haujlwm then .
  • Txij li thaum peb siv ntau lub zog los qhia cov peev txheej URN hauv cov lus yuam kev, peb yuav tsum siv cov haujlwm pulumi.allua ke lawv.
  • Thaum kawg, txij li cov txiaj ntsig no suav nrog asynchronously, peb yuav tsum siv Mocha's built-in async callback feature done los yog rov qab cog lus.

Thaum peb tau teeb tsa txhua yam, peb yuav muaj kev nkag mus rau cov khoom siv raws li qhov yooj yim JavaScript qhov tseem ceeb. Khoom tags yog ib daim ntawv qhia (associative array), ces peb mam li paub tseeb tias nws yog (1) tsis yog cuav, thiab (2) muaj ib tug tseem ceeb rau Name. Nws yooj yim heev thiab tam sim no peb tuaj yeem sim txhua yam!

Tam sim no cia peb sau peb daim tshev thib ob. Nws tseem yooj yim dua:

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

Thiab thaum kawg, cia peb sau qhov kev xeem thib peb. Qhov no yuav nyuaj me ntsis vim tias peb tab tom nrhiav rau cov kev cai nkag mus cuam tshuam nrog pab pawg kev nyab xeeb, uas tuaj yeem muaj ntau, thiab CIDR ntau yam hauv cov cai, uas kuj tseem muaj ntau. Tab sis peb tswj tau:

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

Yog tag nrho. Tam sim no cia peb khiav cov kev xeem!

Kev xeem khiav

Feem ntau, koj tuaj yeem khiav cov kev xeem raws li ib txwm muaj, siv cov qauv ntsuas koj xaiv. Tab sis muaj ib qho feature ntawm Pulumi uas tsim nyog them rau.
Feem ntau, kom khiav Pulumi cov kev pab cuam, lub pulimi CLI (Command Line interface) yog siv, uas teeb tsa lub sijhawm ua haujlwm, tswj kev tso tawm ntawm Pulumi lub cav kom ua haujlwm nrog cov peev txheej tuaj yeem sau thiab suav nrog hauv txoj kev npaj, thiab lwm yam. Txawm li cas los xij, muaj ib qho teeb meem. Thaum khiav hauv kev tswj hwm ntawm koj lub hauv paus kev xeem, yuav tsis muaj kev sib txuas lus ntawm CLI thiab Pulumi lub cav.

Yuav kom daws tau qhov teeb meem no, peb tsuas yog yuav tsum qhia cov hauv qab no:

  • Lub npe qhov project, uas muaj nyob rau hauv ib puag ncig hloov pauv PULUMI_NODEJS_PROJECT (los yog, feem ntau, PULUMI__PROJECT для других языков).
    Lub npe ntawm pawg uas tau teev tseg hauv ib puag ncig hloov pauv PULUMI_NODEJS_STACK (los yog, feem ntau, PULUMI__ STACK).
    Koj pawg teeb tsa kev hloov pauv. Lawv tuaj yeem tau txais los ntawm kev hloov pauv ib puag ncig PULUMI_CONFIG thiab lawv hom ntawv yog JSON daim ntawv qhia nrog tus yuam sij / tus nqi khub.

    Qhov kev zov me nyuam yuav tshaj tawm cov lus ceeb toom qhia tias kev sib txuas rau CLI / cav tsis muaj nyob rau thaum ua tiav. Qhov no yog qhov tseem ceeb vim tias koj qhov kev zov me nyuam yuav tsis tau siv dab tsi thiab nws yuav tuaj yeem xav tsis thoob yog tias tsis yog qhov koj xav ua! Qhia Pulumi tias qhov no yog qhov koj xav tau, koj tuaj yeem nruab PULUMI_TEST_MODE в true.

    Xav txog tias peb yuav tsum qhia lub npe qhov project hauv my-ws, npe dev, and AWS Region us-west-2. Cov kab hais kom ua rau kev xeem Mocha yuav zoo li no:

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

    Ua li no, raws li kev cia siab, yuav qhia peb tias peb muaj peb qhov kev xeem ua tsis tiav!

    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

    Cia peb kho peb qhov program:

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

    Thiab tom qab ntawd khiav cov kev sim dua:

    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)

    Txhua yam mus zoo...Hurray! ✓✓✓

    Qhov ntawd yog txhua yam rau hnub no, tab sis peb yuav tham txog kev sim xa mus rau qhov thib ob ntawm kev txhais lus 😉

Tau qhov twg los: www.hab.com

Ntxiv ib saib