Озмоиши инфрасохтор ҳамчун код бо Пулуми. Қисми 1

Субҳ ба хайр дӯстон. Дар интизори оғози ҷараёни нав бо суръати "Амалҳо ва асбобҳои DevOps" Мо бо шумо тарҷумаи навро пешкаш мекунем. Бирав.

Озмоиши инфрасохтор ҳамчун код бо Пулуми. Қисми 1

Истифодаи Plumi ва забонҳои барномасозии умумӣ барои коди инфрасохторӣ (Инфраструктура ҳамчун Кодекс) бартариҳои зиёд фароҳам меорад: мавҷудияти малака ва дониш, рафъи таблиғ дар код тавассути абстраксия, асбобҳои ба дастаи шумо шинос, аз қабили IDE ва линтерҳо. Ҳамаи ин асбобҳои муҳандисии нармафзор моро на танҳо самараноктар мекунанд, балки сифати коди моро низ беҳтар мекунанд. Аз ин рӯ, табиист, ки истифодаи забонҳои барномасозии умумӣ ба мо имкон медиҳад, ки таҷрибаи дигари муҳими таҳияи нармафзорро ҷорӣ кунем - озмоиш.

Дар ин мақола, мо дида мебароем, ки чӣ тавр Пулуми ба мо дар санҷиши инфрасохтори мо ҳамчун код кӯмак мекунад.

Озмоиши инфрасохтор ҳамчун код бо Пулуми. Қисми 1

Чаро инфрасохтори озмоишӣ?

Пеш аз он ки ба тафсилот гузаред, саволе додан лозим аст: "Чаро инфрасохторро умуман озмоиш кардан лозим аст?" Сабабҳои зиёде барои ин вуҷуд доранд ва инҳоянд баъзе аз онҳо:

  • Санҷиши воҳиди функсияҳои инфиродӣ ё порчаҳои мантиқи барномаи шумо
  • Ҳолати дилхоҳи инфрасохторро бо маҳдудиятҳои муайян тафтиш мекунад.
  • Муайян кардани хатогиҳои умумӣ, ба монанди набудани рамзгузории сатили нигаҳдорӣ ё дастрасии бемуҳофизашуда, кушода аз Интернет ба мошинҳои виртуалӣ.
  • Санҷиши иҷрои таъминоти инфрасохтор.
  • Гузаронидани санҷиши вақти корӣ мантиқи барномае, ки дар дохили инфрасохтори "барномашуда"-и шумо кор мекунад, барои санҷиши функсияҳо пас аз таъминкунӣ.
  • Тавре ки мо мебинем, доираи васеи имконоти санҷиши инфрасохтор вуҷуд дорад. Полуми дорои механизмҳои санҷиш дар ҳама нуқтаи ин спектр мебошад. Биёед оғоз кунем ва бубинем, ки он чӣ гуна кор мекунад.

Санҷиши воҳид

Барномаҳои Pulumi бо забонҳои барномасозии умумӣ ба монанди JavaScript, Python, TypeScript ё Go навишта мешаванд. Аз ин рӯ, қудрати пурраи ин забонҳо, аз ҷумла абзорҳо ва китобхонаҳои онҳо, аз ҷумла чаҳорчӯбаи санҷишӣ, дастраси онҳост. Пулуми бисёр абрӣ аст, ки маънои онро дорад, ки онро барои санҷиш аз ҳама провайдери абр истифода бурдан мумкин аст.

(Дар ин мақола, сарфи назар аз бисёрзабонӣ ва бисёрабр будан, мо JavaScript ва Mocha-ро истифода мебарем ва ба AWS тамаркуз мекунем. Шумо метавонед Python-ро истифода баред unittest, Ба чаҳорчӯбаи санҷишӣ равед ё чаҳорчӯбаи дигари санҷиши ба шумо маъқул. Ва, албатта, Пулуми бо Azure, Google Cloud, Kubernetes хуб кор мекунад.)

Тавре ки мо дидем, якчанд сабабҳо мавҷуданд, ки чаро шумо мехоҳед рамзи инфрасохтори худро санҷед. Яке аз онҳо санҷиши воҳиди муқаррарӣ мебошад. Азбаски рамзи шумо метавонад функсияҳо дошта бошад - масалан, барои ҳисоб кардани CIDR, ба таври динамикӣ ҳисоб кардани номҳо, тегҳо ва ғайра. - Шумо эҳтимол мехоҳед онҳоро санҷед. Ин ҳамон як навиштани санҷишҳои воҳиди муқаррарӣ барои барномаҳо бо забони барномасозии дӯстдоштаи шумост.
Барои каме мураккабтар шудан, шумо метавонед санҷед, ки барномаи шумо захираҳоро чӣ гуна тақсим мекунад. Барои тасвир кардан, биёед тасаввур кунем, ки мо бояд сервери оддии EC2 эҷод кунем ва мо мехоҳем ба чизҳои зерин боварӣ дошта бошем:

  • Ҳолатҳо тег доранд Name.
  • Намунаҳо набояд скрипти дохилиро истифода баранд userData - мо бояд AMI (тасвир) истифода барем.
  • Ҳеҷ гуна SSH набояд ба Интернет дучор шавад.

Ин мисол ба он асос ёфтааст мисоли ман 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;

Ин барномаи асосии Pulumi аст: он танҳо як гурӯҳи амнияти EC2 ва як мисолро ҷудо мекунад. Аммо, бояд гуфт, ки дар ин ҷо мо ҳар се қоидаи дар боло зикршударо вайрон мекунем. Биёед тестҳо нависед!

Санҷишҳои хаттӣ

Сохтори умумии санҷишҳои мо ба санҷишҳои муқаррарии 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, открытого в Интернет.
    });
});

Акнун биёед озмоиши аввалини худро нависед: боварӣ ҳосил кунед, ки инстансияҳо тег доранд Name. Барои санҷидани ин, мо танҳо объекти мисоли EC2-ро мегирем ва амволи мувофиқро тафтиш мекунем 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();
                }
            });
        });

Он ба як санҷиши муқаррарӣ монанд аст, аммо бо чанд хусусияти қобили таваҷҷӯҳ:

  • Азбаски мо ҳолати захираро пеш аз ҷойгиркунӣ пурсон мешавем, санҷишҳои мо ҳамеша дар реҷаи "нақша" (ё "пешнамоӣ") иҷро мешаванд. Ҳамин тариқ, бисёр хосиятҳое ҳастанд, ки арзишҳои онҳо танҳо гирифта намешаванд ё муайян карда намешаванд. Ин ҳама хосиятҳои баромадро дар бар мегирад, ки аз ҷониби провайдери абрии шумо ҳисоб карда шудааст. Ин барои санҷишҳои мо муқаррарӣ аст - мо танҳо маълумоти воридшударо тафтиш мекунем. Мо баъдтар ба ин масъала бармегардем, вақте ки сухан дар бораи санҷишҳои ҳамгироӣ меравад.
  • Азбаски тамоми хосиятҳои манбаи Пулуми натиҷаҳо мебошанд ва бисёре аз онҳо асинхронӣ арзёбӣ мешаванд, мо бояд барои дастрасӣ ба арзишҳо усули татбиқро истифода барем. Ин ба ваъдаҳо ва функсияҳо хеле монанд аст then .
  • Азбаски мо якчанд хосиятҳоро барои нишон додани захираи URN дар паёми хато истифода мебарем, мо бояд ин функсияро истифода барем pulumi.allки онхоро муттахид намояд.
  • Ниҳоят, азбаски ин арзишҳо асинхронӣ ҳисоб карда мешаванд, мо бояд хусусияти бозгашти асинхронии дарунсохтаи Mocha-ро истифода барем. done ё баргардонидани ваъда.

Вақте ки мо ҳама чизро танзим кардем, мо ба вурудот ҳамчун арзишҳои оддии JavaScript дастрасӣ пайдо мекунем. Амвол tags харита аст (массиви ассотсиативӣ), аз ин рӯ, мо танҳо боварӣ ҳосил мекунем, ки он (1) нодуруст нест ва (2) калид барои Name. Ин хеле содда аст ва ҳоло мо метавонем ҳама чизро санҷем!

Акнун биёед чеки дуюми худро нависед. Ин боз ҳам соддатар аст:

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

Ва ниҳоят, биёед санҷиши сеюмро нависем. Ин каме мушкилтар хоҳад буд, зеро мо қоидаҳои воридшавӣ бо гурӯҳи амниятро меҷӯем, ки онҳо метавонанд зиёд бошанд ва CIDR дар ин қоидаҳо, ки метавонанд ҳам зиёд бошанд. Аммо мо тавонистем:

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

Ҳамааш ҳамин. Акнун биёед санҷишҳоро иҷро кунем!

Санҷишҳои иҷрошаванда

Дар аксари ҳолатҳо, шумо метавонед бо истифода аз чаҳорчӯбаи санҷиши интихобкардаи худ санҷишҳоро ба таври муқаррарӣ иҷро кунед. Аммо як хусусияти Пулуми вуҷуд дорад, ки ба он таваҷҷӯҳ кардан лозим аст.
Одатан, барои иҷро кардани барномаҳои Pulumi, pulimi CLI (интерфейси хати фармон) истифода мешавад, ки вақти кори забонро танзим мекунад, ба кор андохтани муҳаррики Пулуми назорат мекунад, то ки амалиёт бо захираҳо сабт ва ба нақша дохил карда шаванд ва ғайра. Бо вуҷуди ин, як мушкилот вуҷуд дорад. Ҳангоми кор дар зери назорати чаҳорчӯбаи санҷиши шумо, ҳеҷ гуна иртибот байни CLI ва муҳаррики Пулуми вуҷуд нахоҳад дошт.

Барои бартараф кардани ин масъала, мо бояд танҳо инҳоро муайян кунем:

  • Номи лоиҳа, ки дар тағирёбандаи муҳити зист мавҷуд аст PULUMI_NODEJS_PROJECT (ё, умуман, PULUMI__PROJECT для других языков).
    Номи стек, ки дар тағирёбандаи муҳити зист муайян шудааст PULUMI_NODEJS_STACK (ё, умуман, PULUMI__ STACK).
    Тағирёбандаҳои конфигуратсияи стеки шумо. Онҳоро бо истифода аз тағирёбандаи муҳити зист ба даст овардан мумкин аст PULUMI_CONFIG ва формати онҳо харитаи JSON бо ҷуфтҳои калид/арзиш аст.

    Барнома ҳушдор медиҳад, ки пайвастшавӣ ба CLI/муҳаррик ҳангоми иҷро дастрас нест. Ин муҳим аст, зеро барномаи шумо воқеан чизеро ҷойгир намекунад ва ин метавонад тааҷҷубовар бошад, агар он чизе, ки шумо ният доштед, иҷро накунед! Барои ба Пулумӣ гуфтан, ки ин маҳз он чизест, ки ба шумо лозим аст, шумо метавонед насб кунед PULUMI_TEST_MODE в true.

    Тасаввур кунед, ки мо бояд номи лоиҳаро дар my-ws, номи стек dev, ва Минтақаи AWS us-west-2. Сатри фармон барои иҷрои санҷишҳои Mocha чунин хоҳад буд:

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

    Иҷрои ин, тавре интизор мерафт, ба мо нишон медиҳад, ки мо се санҷиши ноком дорем!

    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

    Биёед барномаи худро ислоҳ кунем:

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

    Ва он гоҳ санҷишҳоро дубора иҷро кунед:

    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)

    Ҳамааш хуб шуд... Ура! ✓✓✓

    Ин ҳама барои имрӯз аст, аммо мо дар бораи санҷиши ҷойгиркунӣ дар қисми дуюми тарҷума сӯҳбат хоҳем кард 😉

Манбаъ: will.com

Илова Эзоҳ