ื‘ื“ื•ืง ืชืฉืชื™ืช ื›ืงื•ื“ ืขื Pulumi. ื—ืœืง 1

ืฆื”ืจื™ื™ื ื˜ื•ื‘ื™ื ื—ื‘ืจื™ื. ืœืงืจืืช ืชื—ื™ืœืช ื–ืจื™ืžื” ื—ื“ืฉื” ื‘ืงืฆื‘ "ืฉื™ื˜ื•ืช ื•ื›ืœื™ื ืฉืœ DevOps" ืื ื• ืžืฉืชืคื™ื ืืชื›ื ื‘ืชืจื’ื•ื ื—ื“ืฉ. ืœืœื›ืช.

ื‘ื“ื•ืง ืชืฉืชื™ืช ื›ืงื•ื“ ืขื Pulumi. ื—ืœืง 1

ืฉื™ืžื•ืฉ ื‘-Pulumi ื•ืฉืคื•ืช ืชื›ื ื•ืช ืœืžื˜ืจื•ืช ื›ืœืœื™ื•ืช ืœืงื•ื“ ืชืฉืชื™ืช (Infrastructure as Code) ืžืกืคืง ื™ืชืจื•ื ื•ืช ืจื‘ื™ื: ื–ืžื™ื ื•ืช ืฉืœ ืžื™ื•ืžื ื•ื™ื•ืช ื•ื™ื“ืข, ื‘ื™ื˜ื•ืœ ื”-boilerplate ื‘ืงื•ื“ ื‘ืืžืฆืขื•ืช ื”ืคืฉื˜ื”, ื›ืœื™ื ื”ืžื•ื›ืจื™ื ืœืฆื•ื•ืช ืฉืœืš, ื›ื’ื•ืŸ IDEs ื•-linters. ื›ืœ ื›ืœื™ ื”ื ื“ืกืช ื”ืชื•ื›ื ื” ื”ืœืœื• ืœื ืจืง ื”ื•ืคื›ื™ื ืื•ืชื ื• ืœื™ื•ืชืจ ืคืจื•ื“ื•ืงื˜ื™ื‘ื™ื™ื, ืืœื ื’ื ืžืฉืคืจื™ื ืืช ืื™ื›ื•ืช ื”ืงื•ื“ ืฉืœื ื•. ืœื›ืŸ, ื–ื” ืืš ื˜ื‘ืขื™ ืฉื”ืฉื™ืžื•ืฉ ื‘ืฉืคื•ืช ืชื›ื ื•ืช ืœืžื˜ืจื•ืช ื›ืœืœื™ื•ืช ื™ืืคืฉืจ ืœื ื• ืœื”ืฆื™ื’ ืคืจืงื˜ื™ืงื” ื—ืฉื•ื‘ื” ื ื•ืกืคืช ืฉืœ ืคื™ืชื•ื— ืชื•ื›ื ื” - ื‘ื“ื™ืงื•ืช.

ื‘ืžืืžืจ ื–ื”, ื ืจืื” ื›ื™ืฆื“ Pulumi ืขื•ื–ืจืช ืœื ื• ืœื‘ื“ื•ืง ืืช ื”ืชืฉืชื™ืช ืฉืœื ื• ื›ืงื•ื“.

ื‘ื“ื•ืง ืชืฉืชื™ืช ื›ืงื•ื“ ืขื Pulumi. ื—ืœืง 1

ืœืžื” ืœื‘ื“ื•ืง ืชืฉืชื™ืช?

ืœืคื ื™ ืฉื ื›ื ืก ืœืคืจื˜ื™ื, ื›ื“ืื™ ืœืฉืื•ืœ ืืช ื”ืฉืืœื”: "ืœืžื” ื‘ื›ืœืœ ืœื‘ื“ื•ืง ืชืฉืชื™ืช?" ื™ืฉ ืœื›ืš ืกื™ื‘ื•ืช ืจื‘ื•ืช ื•ื”ื ื” ื›ืžื” ืžื”ืŸ:

  • ื‘ื“ื™ืงืช ื™ื—ื™ื“ื•ืช ืฉืœ ืคื•ื ืงืฆื™ื•ืช ื‘ื•ื“ื“ื•ืช ืื• ืงื˜ืขื™ื ืžื”ืœื•ื’ื™ืงื” ืฉืœ ื”ืชื•ื›ื ื™ืช ืฉืœืš
  • ืžืืžืช ืืช ื”ืžืฆื‘ ื”ืจืฆื•ื™ ืฉืœ ื”ืชืฉืชื™ืช ืžื•ืœ ืื™ืœื•ืฆื™ื ืžืกื•ื™ืžื™ื.
  • ื–ื™ื”ื•ื™ ืฉื’ื™ืื•ืช ื ืคื•ืฆื•ืช, ื›ื’ื•ืŸ ื—ื•ืกืจ ื”ืฆืคื ื” ืฉืœ ื“ืœื™ ืื—ืกื•ืŸ ืื• ื’ื™ืฉื” ืœื ืžื•ื’ื ืช, ืคืชื•ื—ื” ืžื”ืื™ื ื˜ืจื ื˜ ืœืžื›ื•ื ื•ืช ื•ื™ืจื˜ื•ืืœื™ื•ืช.
  • ื‘ื“ื™ืงืช ื™ื™ืฉื•ื ืืกืคืงืช ืชืฉืชื™ืช.
  • ื‘ื™ืฆื•ืข ื‘ื“ื™ืงืช ื–ืžืŸ ืจื™ืฆื” ืฉืœ ืœื•ื’ื™ืงื” ืฉืœ ืืคืœื™ืงืฆื™ื” ื”ืคื•ืขืœืช ื‘ืชื•ืš ื”ืชืฉืชื™ืช ื”"ืžืชื•ื›ื ืชืช" ืฉืœืš ื›ื“ื™ ืœื‘ื“ื•ืง ืคื•ื ืงืฆื™ื•ื ืœื™ื•ืช ืœืื—ืจ ื”ืงืฆืื”.
  • ื›ืคื™ ืฉืื ื• ื™ื›ื•ืœื™ื ืœืจืื•ืช, ื™ืฉ ืžื’ื•ื•ืŸ ืจื—ื‘ ืฉืœ ืืคืฉืจื•ื™ื•ืช ืœื‘ื“ื™ืงืช ืชืฉืชื™ืช. ืœ-Polumi ื™ืฉ ืžื ื’ื ื•ื ื™ื ืœื‘ื“ื™ืงื” ื‘ื›ืœ ื ืงื•ื“ื” ื‘ืกืคืงื˜ืจื•ื ื”ื–ื”. ื‘ื•ืื• ื ืชื—ื™ืœ ื•ื ืจืื” ืื™ืš ื–ื” ืขื•ื‘ื“.

ื‘ื“ื™ืงืช ื™ื—ื™ื“ื”

ืชื•ื›ื ื™ื•ืช Pulumi ื›ืชื•ื‘ื•ืช ื‘ืฉืคื•ืช ืชื›ื ื•ืช ืœืžื˜ืจื•ืช ื›ืœืœื™ื•ืช ื›ืžื• JavaScript, Python, TypeScript ืื• Go. ืœื›ืŸ, ืžืœื•ื ื›ื•ื—ืŸ ืฉืœ ืฉืคื•ืช ืืœื•, ืœืจื‘ื•ืช ื”ื›ืœื™ื ื•ื”ืกืคืจื™ื•ืช ืฉืœื”ืŸ, ืœืจื‘ื•ืช ืžืกื’ืจื•ืช ื‘ื“ื™ืงื”, ืขื•ืžื“ ืœืจืฉื•ืชืŸ. Pulumi ื”ื•ื ืจื‘ ืขื ืŸ, ืžื” ืฉืื•ืžืจ ืฉื ื™ืชืŸ ืœื”ืฉืชืžืฉ ื‘ื• ืœื‘ื“ื™ืงื•ืช ืžื›ืœ ืกืคืง ืขื ืŸ.

(ื‘ืžืืžืจ ื–ื”, ืœืžืจื•ืช ื”ื™ื•ืชื• ืจื‘ ืœืฉื•ื ื™ ื•ืจื‘ ืขื ืŸ, ืื ื• ืžืฉืชืžืฉื™ื ื‘-JavaScript ื•ื‘-Mocha ื•ืžืชืžืงื“ื™ื ื‘-AWS. ืืชื” ื™ื›ื•ืœ ืœื”ืฉืชืžืฉ ื‘-Python unittest, Go test framework, ืื• ื›ืœ ืžืกื’ืจืช ื‘ื“ื™ืงื” ืื—ืจืช ืฉืชืจืฆื•. ื•ื›ืžื•ื‘ืŸ, Pulumi ืขื•ื‘ื“ ืžืฆื•ื™ืŸ ืขื 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 ื•ืžื•ืคืข. ืขื ื–ืืช, ื™ืฉ ืœืฆื™ื™ืŸ ื›ื™ ื›ืืŸ ืื ื• ืžืคืจื™ื ืืช ื›ืœ ืฉืœื•ืฉืช ื”ื›ืœืœื™ื ื”ืืžื•ืจื™ื ืœืขื™ืœ. ื‘ื•ืื• ื ื›ืชื•ื‘ ืžื‘ื—ื ื™ื!

ื›ืชื™ื‘ืช ืžื‘ื—ื ื™ื

ื”ืžื‘ื ื” ื”ื›ืœืœื™ ืฉืœ ื”ืžื‘ื—ื ื™ื ืฉืœื ื• ื™ื™ืจืื” ื›ืžื• ืžื‘ื—ื ื™ ืžื•ืงื” ืจื’ื™ืœื™ื:

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 ืฉื›ื“ืื™ ืœืฉื™ื ืืœื™ื” ืœื‘.
ื‘ื“ืจืš ื›ืœืœ, ื›ื“ื™ ืœื”ืคืขื™ืœ ืชื•ื›ื ื™ื•ืช ืฉืœ Pulumi, ื ืขืฉื” ืฉื™ืžื•ืฉ ื‘-pulimi CLI (ืžืžืฉืง ืงื• ืคืงื•ื“ื”), ืฉืžื’ื“ื™ืจ ืืช ื–ืžืŸ ื”ืจื™ืฆื” ืฉืœ ื”ืฉืคื”, ืฉื•ืœื˜ ื‘ื”ืฉืงื” ืฉืœ ืžื ื•ืข ื”-Pulumi ื›ืš ืฉื ื™ืชืŸ ืœื”ืงืœื™ื˜ ืคืขื•ืœื•ืช ืขื ืžืฉืื‘ื™ื ื•ืœื›ืœื•ืœ ืื•ืชืŸ ื‘ืชื•ื›ื ื™ืช ื•ื›ื•'. ืขื ื–ืืช, ื™ืฉ ื‘ืขื™ื” ืื—ืช. ื›ืืฉืจ ืคื•ืขืœ ืชื—ืช ืฉืœื™ื˜ื” ืฉืœ โ€‹โ€‹ืžืกื’ืจืช ื”ื‘ื“ื™ืงื” ืฉืœืš, ืœื ืชื”ื™ื” ืชืงืฉื•ืจืช ื‘ื™ืŸ ื”-CLI ืœืžื ื•ืข Pulumi.

ื›ื“ื™ ืœืขืงื•ืฃ ืืช ื”ื‘ืขื™ื” ื”ื–ื•, ืื ื—ื ื• ืจืง ืฆืจื™ื›ื™ื ืœืฆื™ื™ืŸ ืืช ื”ื“ื‘ืจื™ื ื”ื‘ืื™ื:

  • ืฉื ื”ืคืจื•ื™ืงื˜, ื”ื›ืœื•ืœ ื‘ืžืฉืชื ื” ื”ืกื‘ื™ื‘ื” 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. ืฉื•ืจืช ื”ืคืงื•ื“ื” ืœื”ืคืขืœืช ืžื‘ื—ื ื™ ืžื•ืงื” ืชื™ืจืื” ื›ืš:

    $ 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

ื”ื•ืกืคืช ืชื’ื•ื‘ื”