Өдрийн мэнд найзуудаа. ханшаар шинэ урсгал эхлэхийг хүлээж байна
Дэд бүтцийн код (Infrastructure as Code)-д Плуми болон ерөнхий зориулалтын програмчлалын хэлийг ашиглах нь олон давуу талыг бий болгодог: ур чадвар, мэдлэгийн хүртээмжтэй байх, хийсвэрлэх замаар кодонд агуулагдах шахалтыг арилгах, IDE, линтер зэрэг таны багт мэддэг хэрэгслүүд. Эдгээр бүх програм хангамжийн инженерийн хэрэгслүүд нь биднийг илүү бүтээмжтэй болгодог төдийгүй кодын чанарыг сайжруулдаг. Тиймээс ерөнхий зориулалтын програмчлалын хэлийг ашиглах нь програм хангамж хөгжүүлэх өөр нэг чухал практикийг нэвтрүүлэх боломжийг бидэнд олгох нь зүйн хэрэг юм. туршилт.
Энэ нийтлэлд бид Пулуми манай дэд бүтцийг код болгон туршихад хэрхэн туслахыг авч үзэх болно.
Яагаад дэд бүтцийг турших ёстой вэ?
Дэлгэрэнгүй ярихаасаа өмнө "Яагаад дэд бүтцийг туршиж үзэх хэрэгтэй вэ?" Гэсэн асуултыг асуух нь зүйтэй. Үүнд олон шалтгаан байгаа бөгөөд тэдгээрийн заримыг энд дурдъя.
- Таны програмын логикийн бие даасан функц эсвэл хэсгүүдийн нэгжийн туршилт
- Тодорхой хязгаарлалтын эсрэг дэд бүтцийн хүссэн төлөвийг шалгана.
- Хадгалах савны шифрлэлт дутмаг эсвэл интернетээс виртуал машин руу хамгаалалтгүй, нээлттэй хандалт хийх зэрэг нийтлэг алдааг илрүүлэх.
- Дэд бүтцийн хангамжийн хэрэгжилтийг шалгаж байна.
- Бэлтгэсний дараа функцийг шалгахын тулд таны "програмчлагдсан" дэд бүтцийн дотор ажиллаж байгаа програмын логикийн ажиллах үеийн туршилтыг хийж байна.
- Бидний харж байгаагаар дэд бүтцийн туршилтын олон сонголтууд байдаг. Полуми нь энэ спектрийн цэг бүрт туршилт хийх механизмтай байдаг. Эхэлж, хэрхэн ажилладагийг харцгаая.
Нэгжийн туршилт
Пулуми программуудыг JavaScript, Python, TypeScript эсвэл Go гэх мэт ерөнхий зориулалтын програмчлалын хэлээр бичдэг. Тиймээс эдгээр хэл, тэдгээрийн хэрэгсэл, номын сангууд, түүний дотор тестийн хүрээг бүрэн ашиглах боломжтой. Пулуми нь олон үүлтэй тул ямар ч үүл үйлчилгээ үзүүлэгчээс туршилт хийхэд ашиглаж болно гэсэн үг юм.
(Энэ нийтлэлд бид олон хэлтэй, олон үүлтэй хэдий ч JavaScript болон Mocha ашигладаг бөгөөд AWS дээр анхаарлаа хандуулдаг. Та Python ашиглаж болно. unittest
, Тестийн хүрээ эсвэл өөрт таалагдсан бусад тестийн хүрээ рүү оч. Мэдээжийн хэрэг, Пулуми нь Azure, Google Cloud, Kubernetes-тэй маш сайн ажилладаг.)
Бидний харж байгаагаар, та дэд бүтцийн кодоо туршиж үзэхийг хүсч болох хэд хэдэн шалтгаан бий. Үүний нэг нь ердийн нэгжийн туршилт юм. Учир нь таны код нь CIDR-ийг тооцоолох, нэр, шошго гэх мэт функцтэй байж болно. - Та тэдгээрийг туршиж үзэхийг хүсэх байх. Энэ нь таны дуртай програмчлалын хэлээр программуудад зориулсан тогтмол нэгж тест бичихтэй адил юм.
Бага зэрэг төвөгтэй болгохын тулд та программынхаа нөөцийг хэрхэн хуваарилж байгааг шалгаж болно. Үүнийг харуулахын тулд бид энгийн EC2 сервер үүсгэх хэрэгтэй гэж төсөөлөөд үз дээ, бид дараахь зүйлд итгэлтэй байхыг хүсч байна.
- Тохиолдолд шошго байдаг
Name
. - Тохиолдолд шугаман скрипт ашиглах ёсгүй
userData
- бид AMI (зураг) ашиглах ёстой. - Интернетэд өртөх ямар ч SSH байх ёсгүй.
Энэ жишээн дээр үндэслэсэн болно
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