Բարի երեկո ընկերներ: տոկոսադրույքով նոր հոսքի մեկնարկի ակնկալիքով
Ենթակառուցվածքի կոդի համար Pulumi-ի և ընդհանուր նշանակության ծրագրավորման լեզուների օգտագործումը (Ենթակառուցվածքը որպես կոդ) տալիս է բազմաթիվ առավելություններ՝ հմտությունների և գիտելիքների առկայություն, աբստրակցիայի միջոցով կոդի մեջ կաթսայի վերացում, ձեր թիմին ծանոթ գործիքներ, ինչպիսիք են IDE-ները և linters-երը: Ծրագրային ինժեներական այս բոլոր գործիքները ոչ միայն մեզ ավելի արդյունավետ են դարձնում, այլև բարելավում են մեր կոդի որակը: Հետևաբար, բնական է, որ ընդհանուր նշանակության ծրագրավորման լեզուների օգտագործումը թույլ է տալիս մեզ ներկայացնել ծրագրային ապահովման մշակման ևս մեկ կարևոր պրակտիկա. փորձարկում.
Այս հոդվածում մենք կնայենք, թե ինչպես է Pulumi-ն օգնում մեզ փորձարկել մեր ենթակառուցվածքը որպես կոդ:
Ինչու՞ փորձարկել ենթակառուցվածքը:
Նախքան մանրամասնելը, արժե հարց տալ. «Ինչո՞ւ ընդհանրապես փորձարկել ենթակառուցվածքը»: Դրա համար շատ պատճառներ կան, և ահա դրանցից մի քանիսը.
- Ձեր ծրագրի տրամաբանության առանձին ֆունկցիաների կամ դրվագների միավորի փորձարկում
- Ստուգում է ենթակառուցվածքի ցանկալի վիճակը՝ ընդդեմ որոշակի սահմանափակումների:
- Ընդհանուր սխալների հայտնաբերում, ինչպիսիք են պահեստավորման դույլի գաղտնագրման բացակայությունը կամ անապահով, բաց մուտքը ինտերնետից դեպի վիրտուալ մեքենաներ:
- Ենթակառուցվածքների ապահովման իրականացման ստուգում:
- Ձեր «ծրագրավորված» ենթակառուցվածքի ներսում գործարկվող կիրառական տրամաբանության գործարկման ժամանակի թեստավորում՝ տրամադրումից հետո ֆունկցիոնալությունը ստուգելու համար:
- Ինչպես տեսնում ենք, ենթակառուցվածքի փորձարկման տարբերակների լայն շրջանակ կա: Polumi-ն ունի այս սպեկտրի յուրաքանչյուր կետում փորձարկման մեխանիզմներ: Եկեք սկսենք և տեսնենք, թե ինչպես է այն աշխատում:
Միավորի փորձարկում
Pulumi ծրագրերը գրված են ընդհանուր նշանակության ծրագրավորման լեզուներով, ինչպիսիք են JavaScript, Python, TypeScript կամ Go: Հետևաբար, այս լեզուների ողջ հզորությունը, ներառյալ դրանց գործիքներն ու գրադարանները, ներառյալ թեստային շրջանակները, հասանելի են նրանց համար: Pulumi-ն բազմաբնույթ ամպ է, ինչը նշանակում է, որ այն կարող է օգտագործվել ցանկացած ամպային մատակարարի փորձարկման համար:
(Այս հոդվածում, չնայած բազմալեզու և բազմալեզու լինելուն, մենք օգտագործում ենք JavaScript և Mocha և կենտրոնանում ենք AWS-ի վրա: Կարող եք օգտագործել Python-ը unittest
, Գնացեք թեստային շրջանակ կամ ցանկացած այլ թեստային շրջանակ, որը Ձեզ դուր է գալիս: Եվ, իհարկե, Pulumi-ն հիանալի է աշխատում 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;
Սա 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();
}
});
});
Դա սովորական թեստ է թվում, բայց մի քանի առանձնահատկություններով, որոնք արժե ուշադրություն դարձնել.
- Քանի որ մենք հարցնում ենք ռեսուրսի վիճակը նախքան տեղակայումը, մեր թեստերը միշտ գործարկվում են «պլան» (կամ «նախադիտում») ռեժիմում: Այսպիսով, կան բազմաթիվ հատկություններ, որոնց արժեքները պարզապես չեն վերականգնվի կամ չեն սահմանվի: Սա ներառում է ձեր ամպային մատակարարի կողմից հաշվարկված բոլոր ելքային հատկությունները: Սա նորմալ է մեր թեստերի համար. մենք ստուգում ենք միայն մուտքային տվյալները: Այս հարցին մենք կանդրադառնանք ավելի ուշ, երբ խոսքը վերաբերում է ինտեգրացիոն թեստերին:
- Քանի որ Pulumi ռեսուրսի բոլոր հատկությունները ելքեր են, և դրանցից շատերը գնահատվում են ասինխրոն, մենք պետք է օգտագործենք կիրառել մեթոդը արժեքներին մուտք գործելու համար: Սա շատ նման է խոստումներին և գործառույթներին
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 (Command Line ինտերֆեյս), որը կարգավորում է լեզվի գործարկման ժամանակը, վերահսկում է Pulumi շարժիչի գործարկումը, որպեսզի ռեսուրսներով գործողությունները կարողանան գրանցվել և ներառվել պլանում և այլն: Այնուամենայնիվ, կա մեկ խնդիր. Երբ աշխատում եք ձեր փորձարկման շրջանակի հսկողության ներքո, CLI-ի և Pulumi շարժիչի միջև հաղորդակցություն չի լինի:
Այս խնդիրը շրջանցելու համար մենք պարզապես պետք է նշենք հետևյալը.
- Ծրագրի անվանումը, որը պարունակվում է շրջակա միջավայրի փոփոխականում
PULUMI_NODEJS_PROJECT
(կամ, ավելի ընդհանուր,PULUMI__PROJECT для других языков).
Դույլի անվանումը, որը նշված է շրջակա միջավայրի փոփոխականումPULUMI_NODEJS_STACK
(կամ, ավելի ընդհանուր,PULUMI__ STACK).
Ձեր բուրգի կազմաձևման փոփոխականները: Դրանք կարելի է ձեռք բերել՝ օգտագործելով շրջակա միջավայրի փոփոխականPULUMI_CONFIG
և դրանց ձևաչափը JSON քարտեզ է՝ բանալին/արժեք զույգերով:Ծրագիրը կհրապարակի նախազգուշացումներ՝ նշելով, որ միացումը CLI/շարժիչին հասանելի չէ կատարման ընթացքում: Սա կարևոր է, քանի որ ձեր ծրագիրը իրականում ոչինչ չի տեղակայի և կարող է անակնկալ լինել, եթե դա այն չէ, ինչ դուք մտադիր էիք անել: Pulumi-ին ասելու համար, որ դա հենց այն է, ինչ ձեզ հարկավոր է, կարող եք տեղադրել
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)
Ամեն ինչ լավ անցավ... Ուռա՜ ✓✓✓
Այսօրվա համար այսքանն է, բայց թարգմանության երկրորդ մասում կխոսենք տեղակայման թեստավորման մասին 😉
Source: www.habr.com