Дэд бүтцийг Пулуми код болгон турших. 1-р хэсэг

Өдрийн мэнд найзуудаа. ханшаар шинэ урсгал эхлэхийг хүлээж байна "DevOps практик ба хэрэгслүүд" Та бүхэндээ шинэ орчуулгыг хүргэж байна. Яв.

Дэд бүтцийг Пулуми код болгон турших. 1-р хэсэг

Дэд бүтцийн код (Infrastructure as Code)-д Плуми болон ерөнхий зориулалтын програмчлалын хэлийг ашиглах нь олон давуу талыг бий болгодог: ур чадвар, мэдлэгийн хүртээмжтэй байх, хийсвэрлэх замаар кодонд агуулагдах шахалтыг арилгах, IDE, линтер зэрэг таны багт мэддэг хэрэгслүүд. Эдгээр бүх програм хангамжийн инженерийн хэрэгслүүд нь биднийг илүү бүтээмжтэй болгодог төдийгүй кодын чанарыг сайжруулдаг. Тиймээс ерөнхий зориулалтын програмчлалын хэлийг ашиглах нь програм хангамж хөгжүүлэх өөр нэг чухал практикийг нэвтрүүлэх боломжийг бидэнд олгох нь зүйн хэрэг юм. туршилт.

Энэ нийтлэлд бид Пулуми манай дэд бүтцийг код болгон туршихад хэрхэн туслахыг авч үзэх болно.

Дэд бүтцийг Пулуми код болгон турших. 1-р хэсэг

Яагаад дэд бүтцийг турших ёстой вэ?

Дэлгэрэнгүй ярихаасаа өмнө "Яагаад дэд бүтцийг туршиж үзэх хэрэгтэй вэ?" Гэсэн асуултыг асуух нь зүйтэй. Үүнд олон шалтгаан байгаа бөгөөд тэдгээрийн заримыг энд дурдъя.

  • Таны програмын логикийн бие даасан функц эсвэл хэсгүүдийн нэгжийн туршилт
  • Тодорхой хязгаарлалтын эсрэг дэд бүтцийн хүссэн төлөвийг шалгана.
  • Хадгалах савны шифрлэлт дутмаг эсвэл интернетээс виртуал машин руу хамгаалалтгүй, нээлттэй хандалт хийх зэрэг нийтлэг алдааг илрүүлэх.
  • Дэд бүтцийн хангамжийн хэрэгжилтийг шалгаж байна.
  • Бэлтгэсний дараа функцийг шалгахын тулд таны "програмчлагдсан" дэд бүтцийн дотор ажиллаж байгаа програмын логикийн ажиллах үеийн туршилтыг хийж байна.
  • Бидний харж байгаагаар дэд бүтцийн туршилтын олон сонголтууд байдаг. Полуми нь энэ спектрийн цэг бүрт туршилт хийх механизмтай байдаг. Эхэлж, хэрхэн ажилладагийг харцгаая.

Нэгжийн туршилт

Пулуми программуудыг 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;

Энэ бол Пулумигийн үндсэн програм юм: энэ нь зүгээр л 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();
                }
            });
        });

Энэ нь ердийн тест мэт боловч хэд хэдэн онцлог шинж чанаруудыг анхаарч үзэх хэрэгтэй:

  • Байршуулахын өмнө бид нөөцийн төлөвийг асуудаг тул бидний туршилтууд үргэлж "төлөвлөгөө" (эсвэл "урьдчилан харах") горимд явагддаг. Тиймээс утгыг нь олж авахгүй эсвэл тодорхойлохгүй олон шинж чанарууд байдаг. Үүнд таны клоуд үйлчилгээ үзүүлэгчийн тооцоолсон бүх гаралтын шинж чанарууд орно. Энэ нь бидний туршилтын хувьд хэвийн үзэгдэл юм - бид зөвхөн оролтын өгөгдлийг шалгадаг. Интеграцийн тестийн талаар бид дараа нь энэ асуудалд эргэн орох болно.
  • Пулуми нөөцийн бүх шинж чанарууд нь гаралт бөгөөд тэдгээрийн ихэнх нь асинхрон байдлаар үнэлэгддэг тул утгуудад хандахын тулд бид application аргыг ашиглах хэрэгтэй. Энэ нь амлалт, үйлдэлтэй маш төстэй юм 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();
                }
            });
        });

Тэгээд л болоо. Одоо туршилтаа явуулцгаая!

Ажиллаж байгаа тестүүд

Ихэнх тохиолдолд та өөрийн сонгосон тестийн хүрээг ашиглан тестийг ердийн аргаар явуулж болно. Гэхдээ Пулумигийн нэг онцлог шинжийг анхаарч үзэх хэрэгтэй.
Ихэвчлэн Пулуми програмуудыг ажиллуулахын тулд хэлний ажиллах хугацааг тохируулдаг, Пулуми хөдөлгүүрийг ажиллуулахыг удирддаг pulimi CLI (Command Line интерфэйс) ашигладаг бөгөөд ингэснээр нөөцтэй холбоотой үйлдлүүдийг бүртгэж, төлөвлөгөөнд тусгах гэх мэт. Гэсэн хэдий ч нэг асуудал байна. Туршилтын системийн хяналтан дор ажиллах үед 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)

    Бүх зүйл сайхан болсон... Уяа! ✓✓✓

    Энэ бол өнөөдрийнх, гэхдээ бид орчуулгын хоёрдугаар хэсэгт байршуулах туршилтын талаар ярих болно 😉

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх