Pulumi рд╕рдВрдЧ рдХреЛрдб рд░реВрдкрдорд╛ рдкреВрд░реНрд╡рд╛рдзрд╛рд░ рдкрд░реАрдХреНрд╖рдгред рднрд╛рдЧ 1

рд╢реБрдн рджрд┐рдЙрдБрд╕реЛ рд╕рд╛рдереАрд╣рд░реВред рджрд░рдорд╛ рдирдпрд╛рдБ рдкреНрд░рд╡рд╛рд╣рдХреЛ рд╕реБрд░реБрд╡рд╛рддрдХреЛ рдкреНрд░рддреНрдпрд╛рд╢рд╛рдорд╛ "DevOps рдЕрднреНрдпрд╛рд╕ рд░ рдЙрдкрдХрд░рдгрд╣рд░реВ" рд╣рд╛рдореА рддрдкрд╛рдИрд╕рдБрдЧ рдирдпрд╛рдБ рдЕрдиреБрд╡рд╛рдж рд╕рд╛рдЭрд╛ рдЧрд░реНрджреИрдЫреМрдВред рдЬрд╛рдиреБрд╣реЛрд╕реНред

Pulumi рд╕рдВрдЧ рдХреЛрдб рд░реВрдкрдорд╛ рдкреВрд░реНрд╡рд╛рдзрд╛рд░ рдкрд░реАрдХреНрд╖рдгред рднрд╛рдЧ 1

рдкреВрд░реНрд╡рд╛рдзрд╛рд░ рдХреЛрдб (рдХреЛрдбрдХреЛ рд░реВрдкрдорд╛ рдкреВрд░реНрд╡рд╛рдзрд╛рд░) рдХреЛ рд▓рд╛рдЧрд┐ Pulumi рд░ рд╕рд╛рдорд╛рдиреНрдп-рдЙрджреНрджреЗрд╢реНрдп рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдЩ рднрд╛рд╖рд╛рд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдирд╛рд▓реЗ рдзреЗрд░реИ рдлрд╛рдЗрджрд╛рд╣рд░реВ рдкреНрд░рджрд╛рди рдЧрд░реНрджрдЫ: рд╕реАрдк рд░ рдЬреНрдЮрд╛рдирдХреЛ рдЙрдкрд▓рдмреНрдзрддрд╛, рдПрдмреНрд╕реНрдЯреНрд░реНрдпрд╛рдХреНрд╢рди рдорд╛рд░реНрдлрдд рдХреЛрдбрдорд╛ рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯрдХреЛ рдЙрдиреНрдореВрд▓рди, рддрдкрд╛рдИрдВрдХреЛ рдЯреЛрд▓реАрд▓рд╛рдИ рдкрд░рд┐рдЪрд┐рдд рдЙрдкрдХрд░рдгрд╣рд░реВ, рдЬрд╕реНрддреИ IDEs рд░ lintersред рдпреА рд╕рдмреИ рд╕рдлреНрдЯрд╡реЗрдпрд░ рдЗрдиреНрдЬрд┐рдирд┐рдпрд░рд┐рдЩ рдЙрдкрдХрд░рдгрд╣рд░реВрд▓реЗ рд╣рд╛рдореАрд▓рд╛рдИ рдердк рдЙрддреНрдкрд╛рджрдХ рдорд╛рддреНрд░ рдмрдирд╛рдЙрдБрджреИрди, рддрд░ рд╣рд╛рдореНрд░реЛ рдХреЛрдбрдХреЛ рдЧреБрдгрд╕реНрддрд░рдорд╛ рдкрдирд┐ рд╕реБрдзрд╛рд░ рдЧрд░реНрджрдЫред рддреНрдпрд╕рдХрд╛рд░рдг, рдпреЛ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд╣реЛ рдХрд┐ рд╕рд╛рдорд╛рдиреНрдп-рдЙрджреНрджреЗрд╢реНрдп рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рд╣рд░реВрдХреЛ рдкреНрд░рдпреЛрдЧрд▓реЗ рд╣рд╛рдореАрд▓рд╛рдИ рдЕрд░реНрдХреЛ рдорд╣рддреНрддреНрд╡рдкреВрд░реНрдг рд╕рдлреНрдЯрд╡реЗрдпрд░ рд╡рд┐рдХрд╛рд╕ рдЕрднреНрдпрд╛рд╕ рдкрд░рд┐рдЪрдп рдЧрд░рд╛рдЙрди рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫ - рдкрд░реАрдХреНрд╖рдг рдЧрд░реНрджреИ.

рдпрд╕ рд▓реЗрдЦрдорд╛, рд╣рд╛рдореА рдХрд╕рд░реА Pulumi рд▓реЗ рд╣рд╛рдореНрд░реЛ рдкреВрд░реНрд╡рд╛рдзрд╛рд░-рдХреЛрдб-рдХреЛрдб рдкрд░реАрдХреНрд╖рдг рдЧрд░реНрди рдорджреНрджрдд рдЧрд░реНрдЫ рднрдиреЗрд░ рд╣реЗрд░реНрдиреЗрдЫреМрдВред

Pulumi рд╕рдВрдЧ рдХреЛрдб рд░реВрдкрдорд╛ рдкреВрд░реНрд╡рд╛рдзрд╛рд░ рдкрд░реАрдХреНрд╖рдгред рднрд╛рдЧ 1

рдХрд┐рди рдкреВрд░реНрд╡рд╛рдзрд╛рд░ рдкрд░реАрдХреНрд╖рдг?

рд╡рд┐рд╕реНрддрд╛рд░рдорд╛ рдЬрд╛рдиреБ рдЕрдШрд┐, рдпреЛ рдкреНрд░рд╢реНрди рд╕реЛрдзреНрди рд▓рд╛рдпрдХ рдЫ: "рдХрд┐рди рдкреВрд░реНрд╡рд╛рдзрд╛рд░ рдкрд░реАрдХреНрд╖рдг рд╕рдмреИрдорд╛?" рдпрд╕рдХрд╛ рдзреЗрд░реИ рдХрд╛рд░рдгрд╣рд░реВ рдЫрдиреН рд░ рддрд┐рдиреАрд╣рд░реВрдордзреНрдпреЗ рдХреЗрд╣реА рдпрд╣рд╛рдБ рдЫрдиреН:

  • рд╡реНрдпрдХреНрддрд┐рдЧрдд рдкреНрд░рдХрд╛рд░реНрдпрд╣рд░реВ рд╡рд╛ рддрдкрд╛рдИрдВрдХреЛ рдХрд╛рд░реНрдпрдХреНрд░рдо рддрд░реНрдХрдХреЛ рдЯреБрдХреНрд░рд╛рд╣рд░реВрдХреЛ рдПрдХрд╛рдЗ рдкрд░реАрдХреНрд╖рдг
  • рдирд┐рд╢реНрдЪрд┐рдд рдмрд╛рдзрд╛рд╣рд░реВ рд╡рд┐рд░реБрджреНрдз рдкреВрд░реНрд╡рд╛рдзрд╛рд░рдХреЛ рдЗрдЪреНрдЫрд┐рдд рдЕрд╡рд╕реНрдерд╛ рдкреНрд░рдорд╛рдгрд┐рдд рдЧрд░реНрджрдЫред
  • рд╕рд╛рдорд╛рдиреНрдп рддреНрд░реБрдЯрд┐рд╣рд░реВрдХреЛ рдкрддреНрддрд╛ рд▓рдЧрд╛рдЙрдиреЗ, рдЬрд╕реНрддреИ рднрдгреНрдбрд╛рд░рдг рдмрд╛рд▓реНрдЯреАрдХреЛ рдЗрдиреНрдХреНрд░рд┐рдкреНрд╢рдирдХреЛ рдЕрднрд╛рд╡ рд╡рд╛ рдЕрд╕реБрд░рдХреНрд╖рд┐рдд, рдЗрдиреНрдЯрд░рдиреЗрдЯрдмрд╛рдЯ рднрд░реНрдЪреБрдЕрд▓ рдореЗрд╕рд┐рдирд╣рд░реВрдорд╛ рдЦреБрд▓рд╛ рдкрд╣реБрдБрдЪред
  • рдкреВрд░реНрд╡рд╛рдзрд╛рд░ рдкреНрд░рд╛рд╡рдзрд╛рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЬрд╛рдБрдЪ рдЧрд░реНрджреИред
  • рдкреНрд░рд╛рд╡рдзрд╛рди рдкрдЫрд┐ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдЬрд╛рдБрдЪ рдЧрд░реНрди рддрдкрд╛рдИрдВрдХреЛ "рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЧрд░рд┐рдПрдХреЛ" рдкреВрд░реНрд╡рд╛рдзрд╛рд░ рднрд┐рддреНрд░ рдЪрд▓рд┐рд░рд╣реЗрдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╕рди рддрд░реНрдХрдХреЛ рд░рдирдЯрд╛рдЗрдо рдкрд░реАрдХреНрд╖рдг рдкреНрд░рджрд░реНрд╢рди рдЧрд░реНрджреИред
  • рд╣рд╛рдореА рджреЗрдЦреНрди рд╕рдХреНрдЫреМрдВ, рддреНрдпрд╣рд╛рдБ рдкреВрд░реНрд╡рд╛рдзрд╛рд░ рдкрд░реАрдХреНрд╖рдг рд╡рд┐рдХрд▓реНрдкрд╣рд░реВрдХреЛ рдПрдХ рд╡рд┐рд╕реНрддреГрдд рд╢реНрд░реГрдВрдЦрд▓рд╛ рдЫред рдкреЛрд▓реБрдореАрд╕рдБрдЧ рдпрд╕ рд╕реНрдкреЗрдХреНрдЯреНрд░рдордорд╛ рдкреНрд░рддреНрдпреЗрдХ рдмрд┐рдиреНрджреБрдорд╛ рдкрд░реАрдХреНрд╖рдг рдЧрд░реНрдиреЗ рд╕рдВрдпрдиреНрддреНрд░ рдЫред рд╕реБрд░реБ рдЧрд░реМрдВ рд░ рдпреЛ рдХрд╕рд░реА рдХрд╛рдо рдЧрд░реНрдЫ рд╣реЗрд░реМрдВред

рдПрдХрд╛рдЗ рдкрд░реАрдХреНрд╖рдг

Pulumi рдкреНрд░реЛрдЧреНрд░рд╛рдорд╣рд░реВ JavaScript, Python, TypeScript рд╡рд╛ Go рдЬрд╕реНрддрд╛ рд╕рд╛рдорд╛рдиреНрдп-рдЙрджреНрджреЗрд╢реНрдпреАрдп рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдЩ рднрд╛рд╖рд╛рд╣рд░реВрдорд╛ рд▓реЗрдЦрд┐рдиреНрдЫрдиреНред рддрд╕рд░реНрде, рдпреА рднрд╛рд╖рд╛рд╣рд░реВрдХреЛ рдкреВрд░реНрдг рд╢рдХреНрддрд┐, рддрд┐рдиреАрд╣рд░реВрдХрд╛ рдЙрдкрдХрд░рдгрд╣рд░реВ рд░ рдкреБрд╕реНрддрдХрд╛рд▓рдпрд╣рд░реВ, рдкрд░реАрдХреНрд╖рдг рдврд╛рдБрдЪрд╛рд╣рд░реВ рд╕рд╣рд┐рдд, рддрд┐рдиреАрд╣рд░реВрдХрд╛ рд▓рд╛рдЧрд┐ рдЙрдкрд▓рдмреНрдз рдЫред Pulumi рдмрд╣реБ-рдХреНрд▓рд╛рдЙрдб рд╣реЛ, рдЬрд╕рдХреЛ рдорддрд▓рдм рдпреЛ рдХреБрдиреИ рдкрдирд┐ рдХреНрд▓рд╛рдЙрдб рдкреНрд░рджрд╛рдпрдХрдмрд╛рдЯ рдкрд░реАрдХреНрд╖рдгрдХреЛ рд▓рд╛рдЧрд┐ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫред

(рдпрд╕ рд▓реЗрдЦрдорд╛, рдмрд╣реБрднрд╛рд╖реА рд░ рдмрд╣реБрдХреНрд▓рд╛рдЙрдб рднрдПрддрд╛ рдкрдирд┐, рд╣рд╛рдореА JavaScript рд░ Mocha рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдЫреМрдВ рд░ AWS рдорд╛ рдлреЛрдХрд╕ рдЧрд░реНрдЫреМрдВред рддрдкрд╛рдИрдВ рдкрд╛рдЗрдерди рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫред unittest, рдЬрд╛рдиреБрд╣реЛрд╕реН рдкрд░реАрдХреНрд╖рдг рдлреНрд░реЗрдорд╡рд░реНрдХ, рд╡рд╛ рддрдкрд╛рдЗрдБрд▓рд╛рдИ рдордирдкрд░реНрдиреЗ рдХреБрдиреИ рдЕрдиреНрдп рдкрд░реАрдХреНрд╖рдг рдлреНрд░реЗрдорд╡рд░реНрдХред рд░, рдирд┐рд╕реНрд╕рдиреНрджреЗрд╣, 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 рдХреЛ рдирд┐рд░реНрдорд┐рдд async рдХрд▓рдмреНрдпрд╛рдХ рд╕реБрд╡рд┐рдзрд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫред done рд╡рд╛ рд╡рд╛рдЪрд╛ рдлрд┐рд░реНрддрд╛ рдЧрд░реНрджреИред

рдПрдХрдкрдЯрдХ рд╣рд╛рдореАрд▓реЗ рд╕рдмреИ рдХреБрд░рд╛ рд╕реЗрдЯ рдЕрдк рдЧрд░рд┐рд╕рдХреЗрдкрдЫрд┐, рд╣рд╛рдореАрд╕рдБрдЧ рд╕рд╛рдзрд╛рд░рдг JavaScript рдорд╛рдирд╣рд░реВрдХреЛ рд░реВрдкрдорд╛ рдЗрдирдкреБрдЯрд╣рд░реВрдорд╛ рдкрд╣реБрдБрдЪ рд╣реБрдиреЗрдЫред рд╕рдореНрдкрддреНрддрд┐ tags рдирдХреНрд╕рд╛ (рд╕рд╣рдпреЛрдЧреА рдПрд░реЗ) рд╣реЛ, рддреНрдпрд╕реИрд▓реЗ рд╣рд╛рдореА рдпреЛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдЧрд░реНрдиреЗрдЫреМрдВ рдХрд┐ рдпреЛ (рез) рдЧрд▓рдд рдЫреИрди, рд░ (реи) рдХреЛ рд▓рд╛рдЧрд┐ рдПрдЙрдЯрд╛ рдХреБрдЮреНрдЬреА рдЫ 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();
                }
            });
        });

рдпрддрд┐ рдиреИред рдЕрдм рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рдЪрд▓рд╛рдЙрдиреБрд╣реЛрд╕реН!

рдЪрд▓рд┐рд░рд╣реЗрдХреЛ рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ

рдзреЗрд░реИрдЬрд╕реЛ рдЕрд╡рд╕реНрдерд╛рдорд╛, рддрдкрд╛рдЗрдБ рддрдкрд╛рдЗрдБрдХреЛ рд░реЛрдЬрд╛рдЗрдХреЛ рдкрд░реАрдХреНрд╖рдг рдврд╛рдБрдЪрд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реА рд╕рд╛рдорд╛рдиреНрдп рддрд░рд┐рдХрд╛рдорд╛ рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рдЪрд▓рд╛рдЙрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫред рддрд░ рдкреБрд▓реБрдореАрдХреЛ рдПрдЙрдЯрд╛ рд╡рд┐рд╢реЗрд╖рддрд╛ рдЫ рдЬреБрди рдзреНрдпрд╛рди рджрд┐рди рд▓рд╛рдпрдХ рдЫред
рд╕рд╛рдорд╛рдиреНрдпрддрдпрд╛, рдкреБрд▓реБрдореА рдкреНрд░реЛрдЧреНрд░рд╛рдорд╣рд░реВ рдЪрд▓рд╛рдЙрдирдХреЛ рд▓рд╛рдЧрд┐, рдкреБрд▓рд┐рдореА рд╕реАрдПрд▓рдЖрдИ (рдХрдорд╛рдиреНрдб рд▓рд╛рдЗрди рдЗрдиреНрдЯрд░рдлреЗрд╕) рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдиреНрдЫ, рдЬрд╕рд▓реЗ рднрд╛рд╖рд╛ рд░рдирдЯрд╛рдЗрдо рдХрдиреНрдлрд┐рдЧрд░ рдЧрд░реНрджрдЫ, рдкреБрд▓реБрдореА рдЗрдиреНрдЬрд┐рдирдХреЛ рд╕реБрд░реБрд╡рд╛рддрд▓рд╛рдИ рдирд┐рдпрдиреНрддреНрд░рдг рдЧрд░реНрджрдЫ рддрд╛рдХрд┐ рд╕реНрд░реЛрддрд╣рд░реВ рд╕рд╣рд┐рдд рд╕рдЮреНрдЪрд╛рд▓рдирд╣рд░реВ рд░реЗрдХрд░реНрдб рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ рд░ рдпреЛрдЬрдирд╛рдорд╛ тАЛтАЛрд╕рдорд╛рд╡реЗрд╢ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫред рддрд░, рддреНрдпрд╣рд╛рдБ рдПрдЙрдЯрд╛ рд╕рдорд╕реНрдпрд╛ рдЫред рддрдкрд╛рдИрдВрдХреЛ рдкрд░реАрдХреНрд╖рдг рдврд╛рдБрдЪрд╛рдХреЛ рдирд┐рдпрдиреНрддреНрд░рдгрдорд╛ рдЪрд▓реНрджрд╛, 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)

    рд╕рдмреИ рд░рд╛рдореНрд░реЛ рднрдпреЛ... рд╣реБрд░реНрд░реЗ! тЬУтЬУтЬУ

    рдЖрдЬрдХреЛ рд▓рд╛рдЧрд┐ рдпрддрд┐ рдорд╛рддреНрд░ рд╣реЛ, рддрд░ рд╣рд╛рдореА рдЕрдиреБрд╡рд╛рджрдХреЛ рджреЛрд╕реНрд░реЛ рднрд╛рдЧрдорд╛ рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдкрд░реАрдХреНрд╖рдгрдХреЛ рдмрд╛рд░реЗрдорд╛ рдХреБрд░рд╛ рдЧрд░реНрдиреЗрдЫреМрдВ ЁЯШЙ

рд╕реНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдердкреНрди