ВСстированиС инфраструктуры ΠΊΠ°ΠΊ ΠΊΠΎΠ΄ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Pulumi. Π§Π°ΡΡ‚ΡŒ 2

ВсСм ΠΏΡ€ΠΈΠ²Π΅Ρ‚. БСгодня дСлимся с Π²Π°ΠΌΠΈ Π·Π°ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ Ρ‡Π°ΡΡ‚ΡŒΡŽ ΡΡ‚Π°Ρ‚ΡŒΠΈ «ВСстированиС инфраструктуры ΠΊΠ°ΠΊ ΠΊΠΎΠ΄ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ PulumiΒ», ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²Π»Π΅Π½ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ для студСнтов курса Β«DevOps ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠΈ ΠΈ инструмСнты».

ВСстированиС инфраструктуры ΠΊΠ°ΠΊ ΠΊΠΎΠ΄ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Pulumi. Π§Π°ΡΡ‚ΡŒ 2

ВСстированиС развСртывания

РассмотрСнный ΡΡ‚ΠΈΠ»ΡŒ тСстирования β€” это ΠΌΠΎΡ‰Π½Ρ‹ΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄, ΠΎΠ½ позволяСт Π½Π°ΠΌ ΠΏΡ€ΠΎΠ²ΠΎΠ΄ΠΈΡ‚ΡŒ тСстированиС Π±Π΅Π»ΠΎΠ³ΠΎ ящика для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ внутрСнностСй Ρ€Π°Π±ΠΎΡ‚Ρ‹ нашСго инфраструктурного ΠΊΠΎΠ΄Π°. Однако ΠΎΠ½ нСсколько ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ. ВСсты Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ Π½Π° основС in-memory ΠΏΠ»Π°Π½Π° развСртывания, созданного Pulumi ΠΏΠ΅Ρ€Π΅Π΄ нСпосрСдствСнным Ρ€Π°Π·Π²Π΅Ρ€Ρ‚Ρ‹Π²Π°Π½ΠΈΠ΅ΠΌ ΠΈ поэтому само Ρ€Π°Π·Π²Π΅Ρ€Ρ‚Ρ‹Π²Π°Π½ΠΈΠ΅ Π½Π΅ ΠΏΡ€ΠΎΡ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ. Для Ρ‚Π°ΠΊΠΈΡ… случаСв Π² Pulumi Π΅ΡΡ‚ΡŒ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Ρ… тСстов. И эти Π΄Π²Π° ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° ΠΎΡ‚Π»ΠΈΡ‡Π½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ вмСстС!

Π€Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ тСстирования Pulumi написан Π½Π° Go, ΠΈ ΠΈΠΌΠ΅Π½Π½ΠΎ с Π΅Π³ΠΎ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΡ‹ тСстируСм Π±ΠΎΠ»ΡŒΡˆΡƒΡŽ Ρ‡Π°ΡΡ‚ΡŒ нашСго Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π³ΠΎ ΠΊΠΎΠ΄Π°. Если рассмотрСнный Ρ€Π°Π½Π΅Π΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½ΠΎΠ³ΠΎ тСстирования Π±Ρ‹Π» большС ΠΏΠΎΡ…ΠΎΠΆ Π½Π° тСстированиС Π±Π΅Π»ΠΎΠ³ΠΎ ящика, Ρ‚ΠΎ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ΅ тСстированиС β€” это Ρ‡Π΅Ρ€Π½Ρ‹ΠΉ ящик. (Π•ΡΡ‚ΡŒ Ρ‚Π°ΠΊΠΆΠ΅ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ Ρ‚Ρ‰Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π³ΠΎ тСстирования.) Π­Ρ‚ΠΎΡ‚ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ Π±Ρ‹Π» создан для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Π·ΡΡ‚ΡŒ ΠΏΠΎΠ»Π½ΡƒΡŽ Pulumi-ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ для Π½Π΅Π΅ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠ³ΠΎ Ρ†ΠΈΠΊΠ»Π°, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ Ρ€Π°Π·Π²Π΅Ρ€Ρ‚Ρ‹Π²Π°Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ стСка с нуля, Π΅Π³ΠΎ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ с вариациями ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ нСсколько Ρ€Π°Π·. ΠœΡ‹ запускаСм ΠΈΡ… рСгулярно (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π½ΠΎΡ‡ΡŒΡŽ) ΠΈ Π² качСствС стрСсс-тСстов.

(ΠœΡ‹ Ρ€Π°Π±ΠΎΡ‚Π°Π΅ΠΌ Π½Π°Π΄ Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Ρ‹Π΅ возмоТности ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ тСстирования Π±Ρ‹Π»ΠΈ Π² Ρ€ΠΎΠ΄Π½ΠΎΠΌ SDK языков. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ тСстирования Go нСзависимо ΠΎΡ‚ языка, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ написана ваша Pulumi-ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°).

Запустив ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ этого Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ° Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅:

  • Код вашСго ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° синтаксичСски ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π±Π΅Π· ошибок.
  • Настройки ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ стСка ΠΈ сСкрСтов Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ ΠΈ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ.
  • Π’Π°Ρˆ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ Ρ€Π°Π·Π²Π΅Ρ€Π½ΡƒΡ‚ Π² Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠΌ Π²Π°ΠΌΠΈ ΠΎΠ±Π»Π°Ρ‡Π½ΠΎΠΌ ΠΏΡ€ΠΎΠ²Π°ΠΉΠ΄Π΅Ρ€Π΅.
  • Π’Π°Ρˆ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ с Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ состояния Π΄ΠΎ N Π΄Ρ€ΡƒΠ³ΠΈΡ… состояний.
  • Π’Π°Ρˆ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ΅Π½ ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ ΠΈΠ· вашСго ΠΎΠ±Π»Π°Ρ‡Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΠ²Π°ΠΉΠ΄Π΅Ρ€Π°.

Как ΠΌΡ‹ скоро ΡƒΠ²ΠΈΠ΄ΠΈΠΌ, этот Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΆΠ΅ для выполнСния runtime-Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ.

ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст

Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ это Π² дСйствии, ΠΌΡ‹ посмотрим Π½Π° Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ pulumi/examples, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ наша ΠΊΠΎΠΌΠ°Π½Π΄Π° ΠΈ сообщСство Pulumi, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Π΅Π³ΠΎ для тСстирования собствСнных ΠΏΡƒΠ» рСквСстов, ΠΊΠΎΠΌΠΌΠΈΡ‚ΠΎΠ² ΠΈ Π½ΠΎΡ‡Π½Ρ‹Ρ… сборок.

НиТС ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ ΡƒΠΏΡ€ΠΎΡ‰Π΅Π½Π½Ρ‹ΠΉ тСст нашСго ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π΄Π΅Π»Π°Π΅Ρ‚ ΠΏΡ€ΠΎΠ²ΠΈΠΆΠ΅Π½ΠΈΠ½Π³ S3 bucket ΠΈ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²:

example_test.go:

package test
 
import (
    "os"
    "path"
    "testing"
 
    "github.com/pulumi/pulumi/pkg/testing/integration"
)
 
func TestExamples(t *testing.T) {
    awsRegion := os.Getenv("AWS_REGION")
    if awsRegion == "" {
        awsRegion = "us-west-1"
    }
    cwd, _ := os.Getwd()
    integration.ProgramTest(t, &integration.ProgramTestOptions{
        Quick:       true,
        SkipRefresh: true,
        Dir:         path.Join(cwd, "..", "..", "aws-js-s3-folder"),
        Config: map[string]string{
            "aws:region": awsRegion,
        },
    })
}

Π­Ρ‚ΠΎΡ‚ тСст ΠΏΡ€ΠΎΡ…ΠΎΠ΄ΠΈΡ‚ Ρ‡Π΅Ρ€Π΅Π· Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ ΠΆΠΈΠ·Π½Π΅Π½Π½Ρ‹ΠΉ Ρ†ΠΈΠΊΠ» создания, измСнСния ΠΈ уничтоТСния стСка для ΠΏΠ°ΠΏΠΊΠΈ aws-js-s3-folder. Он Π·Π°ΠΉΠΌΠ΅Ρ‚ ΠΎΠΊΠΎΠ»ΠΎ ΠΌΠΈΠ½ΡƒΡ‚Ρ‹, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠΎΠ±Ρ‰ΠΈΡ‚ΡŒ ΠΎ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½Π½ΠΎΠΌ тСстС:

$ go test .
PASS
ok      ... 43.993s

Π•ΡΡ‚ΡŒ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² для настройки повСдСния этих тСстов. ΠŸΠΎΠ»Π½Ρ‹ΠΉ список ΠΎΠΏΡ†ΠΈΠΉ см. Π² структурС ProgramTestOptions. НапримСр, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Jaeger endpoint для трассировки (Tracing), ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚Π΅ падСния тСста ΠΏΡ€ΠΈ Π½Π΅Π³Π°Ρ‚ΠΈΠ²Π½ΠΎΠΌ тСстировании (ExpectFailure), ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΡΠ΅Ρ€ΠΈΡŽ β€œΠΏΡ€Π°Π²ΠΎΠΊβ€ ΠΊ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ для ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄Π° состояний (EditDirs) ΠΈ ΠΌΠ½ΠΎΠ³ΠΎΠ΅ Π΄Ρ€ΡƒΠ³ΠΎΠ΅. Π”Π°Π²Π°ΠΉΡ‚Π΅ посмотрим, ΠΊΠ°ΠΊ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ… для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ развСртывания прилоТСния.

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° свойств рСсурсов

Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡ, ΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π³ΠΎΠ²ΠΎΡ€ΠΈΠ»ΠΈ Π²Ρ‹ΡˆΠ΅, Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎ наша ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Β«Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚Β» β€” ΠΎΠ½Π° Π½Π΅ ΠΏΠ°Π΄Π°Π΅Ρ‚. Но Ρ‡Ρ‚ΠΎ, Ссли ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ свойства ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠ³ΠΎ стСка? НапримСр, Ρ‡Ρ‚ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Π΅ Π²ΠΈΠ΄Ρ‹ рСсурсов Π±Ρ‹Π»ΠΈ (ΠΈΠ»ΠΈ Π½Π΅ Π±Ρ‹Π»ΠΈ) ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²Π»Π΅Π½Ρ‹ ΠΈ Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ ΠΈΠΌΠ΅ΡŽΡ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Π΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹.

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ExtraRuntimeValidation для ProgramTestOptions позволяСт Π½Π°ΠΌ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π½Π° состояниС, зафиксированноС Pulumi послС развСртывания (post-deployment state), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΌΡ‹ ΠΌΠΎΠ³Π»ΠΈ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ. Бюда Π²Ρ…ΠΎΠ΄ΠΈΡ‚ ΠΏΠΎΠ»Π½Ρ‹ΠΉ снимок состояния Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ стСка, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ, экспортируСмыС Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Π΅ значСния, всС рСсурсы ΠΈ значСния ΠΈΡ… свойств, Π° Ρ‚Π°ΠΊΠΆΠ΅ всС зависимости ΠΌΠ΅ΠΆΠ΄Ρƒ рСсурсами.

Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ этого, Π΄Π°Π²Π°ΠΉΡ‚Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ, Ρ‡Ρ‚ΠΎ наша ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° создаСт ΠΎΠ΄ΠΈΠ½ S3 Bucket:

  integration.ProgramTest(t, &integration.ProgramTestOptions{
        // as before...
        ExtraRuntimeValidation: func(t *testing.T, stack integration.RuntimeValidationStackInfo) {
            var foundBuckets int
            for _, res := range stack.Deployment.Resources {
                if res.Type == "aws:s3/bucket:Bucket" {
                    foundBuckets++
                }
            }
            assert.Equal(t, 1, foundBuckets, "Expected to find a single AWS S3 Bucket")
        },
    })

Π’Π΅ΠΏΠ΅Ρ€ΡŒ, ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ запустим go test, ΠΎΠ½ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΎΠΉΠ΄Π΅Ρ‚ Ρ‡Π΅Ρ€Π΅Π· Π±Π°Ρ‚Π°Ρ€Π΅ΡŽ тСстов ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠ³ΠΎ Ρ†ΠΈΠΊΠ»Π°, Π½ΠΎ Ρ‚Π°ΠΊΠΆΠ΅, послС ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ³ΠΎ развСртывания стСка, Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ состояния.

Runtime-тСсты

Π”ΠΎ сих ΠΏΠΎΡ€ всС тСсты Π±Ρ‹Π»ΠΈ ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΎ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠΈ ΠΏΡ€ΠΈ Ρ€Π°Π·Π²Π΅Ρ€Ρ‚Ρ‹Π²Π°Π½ΠΈΠΈ ΠΈ ΠΎ ΠΌΠΎΠ΄Π΅Π»ΠΈ рСсурсов Pulumi. Π§Ρ‚ΠΎ Π΄Π΅Π»Π°Ρ‚ΡŒ, Ссли Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ваша подготовлСнная инфраструктура Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚? НапримСр, Ρ‡Ρ‚ΠΎ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Π°Ρ машина Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚, S3 bucket содСрТит Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ, ΠΈ Ρ‚Π°ΠΊ Π΄Π°Π»Π΅Π΅.

Π’Ρ‹, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΡƒΠΆΠ΅ догадались, ΠΊΠ°ΠΊ это ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ: опция ExtraRuntimeValidation для ProgramTestOptions β€” это отличная Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ для этого. На этом этапС Π²Ρ‹ запускаСтС ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ тСст Go с доступом ΠΊ ΠΏΠΎΠ»Π½ΠΎΠΌΡƒ ΡΠΎΡΡ‚ΠΎΡΠ½ΠΈΡŽ рСсурсов вашСй ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Π­Ρ‚ΠΎ состояниС Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Π² сСбя Ρ‚Π°ΠΊΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ, ΠΊΠ°ΠΊ IP-адрСса Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… машин, URL-адрСса ΠΈ всС, Ρ‡Ρ‚ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ для Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ взаимодСйствия с ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΌΠΈ ΠΎΠ±Π»Π°Ρ‡Π½Ρ‹ΠΌΠΈ прилоТСниями ΠΈ инфраструктурой.

НапримСр, наша тСстовая ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° экспортируСт свойство webEndpoint bucket’Π° ΠΏΠΎΠ΄ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ websiteUrl, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ прСдставляСт собой ΠΏΠΎΠ»Π½Ρ‹ΠΉ URL-адрСс, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ настроСнный index document. Π₯отя ΠΌΡ‹ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ‹ ΠΏΠΎΠΊΠΎΠΏΠ°Ρ‚ΡŒΡΡ Π² Ρ„Π°ΠΉΠ»Π΅ состояния, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π°ΠΉΡ‚ΠΈ bucket ΠΈ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ это свойство Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ, Π½ΠΎ Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ… случаях наши стСки ΡΠΊΡΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Π΅ свойства, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ это, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π°ΠΌ ΡƒΠ΄ΠΎΠ±Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ:

integration.ProgramTest(t, &integration.ProgramTestOptions{
            // as before ...
        ExtraRuntimeValidation: func(t *testing.T, stack integration.RuntimeValidationStackInfo) {
            url := "http://" + stack.Outputs["websiteUrl"].(string)
            resp, err := http.Get(url)
            if !assert.NoError(t, err) {
                return
            }
            if !assert.Equal(t, 200, resp.StatusCode) {
                return
            }
            defer resp.Body.Close()
            body, err := ioutil.ReadAll(resp.Body)
            if !assert.NoError(t, err) {
                return
            }
            assert.Contains(t, string(body), "Hello, Pulumi!")
        },
    })

Как ΠΈ наши ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠ΅ runtime-ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ, эта ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ сразу послС поднятия стСка, ΠΈ всС это Π² ΠΎΡ‚Π²Π΅Ρ‚ Π½Π° простой Π²Ρ‹Π·ΠΎΠ² go test. И это Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²Π΅Ρ€ΡˆΠΈΠ½Π° айсбСрга β€” доступны всС тСстовыС возмоТности Go, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π² ΠΊΠΎΠ΄Π΅.

НСпрСрывная интСграция инфраструктуры

Π₯ΠΎΡ€ΠΎΡˆΠΎ ΠΈΠΌΠ΅Ρ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ тСсты Π½Π° Π½ΠΎΡƒΡ‚Π±ΡƒΠΊΠ΅, ΠΊΠΎΠ³Π΄Π° дСлаСтся ΠΌΠ½ΠΎΠ³ΠΎ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π² инфраструктурС, для ΠΈΡ… ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΠΏΠ΅Ρ€Π΅Π΄ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΎΠΉ Π½Π° Ρ€Π΅Π²ΡŒΡŽ ΠΊΠΎΠ΄Π°. Но ΠΌΡ‹ ΠΈ ΠΌΠ½ΠΎΠ³ΠΈΠ΅ наши ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρ‹ тСстируСм инфраструктуру Π½Π° Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… этапах ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠ³ΠΎ Ρ†ΠΈΠΊΠ»Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ:

  • Π’ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠΌ ΠΏΡƒΠ» рСквСстС для тСста ΠΏΠ΅Ρ€Π΅Π΄ слияниСм.
  • Π’ ΠΎΡ‚Π²Π΅Ρ‚ Π½Π° ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΊΠΎΠΌΠΌΠΈΡ‚, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠ΅Ρ€Π΅ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ слияниС Π±Ρ‹Π»ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ.
  • ΠŸΠ΅Ρ€ΠΈΠΎΠ΄ΠΈΡ‡Π΅ΡΠΊΠΈ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π½ΠΎΡ‡ΡŒΡŽ ΠΈΠ»ΠΈ СТСнСдСльно для Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ тСстирования.
  • Π’ Ρ€Π°ΠΌΠΊΠ°Ρ… тСстирования ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΈΠ»ΠΈ стрСсс-тСстирования, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ Π² Ρ‚Π΅Ρ‡Π΅Π½ΠΈΠ΅ Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΏΠ΅Ρ€ΠΈΠΎΠ΄Π° Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΈ Π·Π°ΠΏΡƒΡΠΊΠ°ΡŽΡ‚ тСсты ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ ΠΈ/ΠΈΠ»ΠΈ Ρ€Π°Π·Π²Π΅Ρ€Ρ‚Ρ‹Π²Π°ΡŽΡ‚ ΠΎΠ΄Π½Ρƒ ΠΈ Ρ‚Ρƒ ΠΆΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ нСсколько Ρ€Π°Π·.

Для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΈΠ· Π½ΠΈΡ… Pulumi ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡŽ с вашСй любимой систСмой Π½Π΅ΠΏΡ€Π΅Ρ€Ρ‹Π²Π½ΠΎΠΉ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΈ. ΠŸΡ€ΠΈ Π½Π΅ΠΏΡ€Π΅Ρ€Ρ‹Π²Π½ΠΎΠΉ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΈ это Π΄Π°Π΅Ρ‚ Π²Π°ΠΌ Ρ‚Π°ΠΊΠΎΠ΅ ΠΆΠ΅ ΠΏΠΎΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ тСстами для вашСй инфраструктуры, ΠΊΠ°ΠΊ ΠΈ для ΠΏΡ€ΠΈΠΊΠ»Π°Π΄Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ обСспСчСния.

Π’ Pulumi Π΅ΡΡ‚ΡŒ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° распространСнных CI-систСм. Π’ΠΎΡ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠ· Π½ΠΈΡ…:

Для получСния Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ΡΡŒ ΠΊ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ ΠΏΠΎ Continuous Delivery.

Π­Ρ„Π΅ΠΌΠ΅Ρ€Π½Ρ‹Π΅ окруТСния

ΠžΡ‡Π΅Π½ΡŒ мощная Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ, которая открываСтся β€” это Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Ρ‚ΡŒ эфСмСрныС окруТСния ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ для Ρ†Π΅Π»Π΅ΠΉ ΠΏΡ€ΠΈΠ΅ΠΌΠΎΡ‡Π½ΠΎΠ³ΠΎ тСстирования. ΠšΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΡ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠ² ΠΈ стСков Pulumi Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π½Π° Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π»Π΅Π³ΠΊΠΎ Ρ€Π°Π·Π²Π΅Ρ€Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΈ ΡΠ½ΠΎΡΠΈΡ‚ΡŒ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ ΠΈ нСзависимыС окруТСния, всС Π² нСсколько простых ΠΊΠΎΠΌΠ°Π½Π΄ CLI ΠΈΠ»ΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ° ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ тСстирования.

Если Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ GitHub, Ρ‚ΠΎ Pulumi ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ GitHub App, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚ Π²Π°ΠΌ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈΠ΅ΠΌΠΎΡ‡Π½ΠΎΠ΅ тСстированиС ΠΊ ΠΏΡƒΠ» рСквСстам Π²Π½ΡƒΡ‚Ρ€ΠΈ вашСго CI-ΠΏΠ°ΠΉΠΏΠ»Π°ΠΉΠ½Π°. ΠŸΡ€ΠΎΡΡ‚ΠΎ установитС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ GitHub, Π° Pulumi Π² ваш CI ΠΈ Π² ΠΏΡƒΠ» рСквСсты Π±ΡƒΠ΄Π΅Ρ‚ Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒΡΡ информация ΠΎ ΠΏΡ€Π΅Π²ΡŒΡŽ инфраструктуры, обновлСниях ΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°Ρ… тСстирования:

ВСстированиС инфраструктуры ΠΊΠ°ΠΊ ΠΊΠΎΠ΄ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Pulumi. Π§Π°ΡΡ‚ΡŒ 2

ΠŸΡ€ΠΈ использовании Pulumi для Π²Π°ΡˆΠΈΡ… основных ΠΏΡ€ΠΈΠ΅ΠΌΠΎΡ‡Π½Ρ‹Ρ… тСстов, Ρƒ вас появятся Π½ΠΎΠ²Ρ‹Π΅ возмоТности Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·Π°Ρ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΠ»ΡƒΡ‡ΡˆΠ°Ρ‚ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ ΠΈ ΠΏΡ€ΠΈΠ΄Π°Π΄ΡƒΡ‚ ΡƒΠ²Π΅Ρ€Π΅Π½Π½ΠΎΡΡ‚ΡŒ Π² качСствС ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ.

Π˜Ρ‚ΠΎΠ³

Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ ΡƒΠ²ΠΈΠ΄Π΅Π»ΠΈ, Ρ‡Ρ‚ΠΎ, ΠΏΡ€ΠΈ использовании языков программирования ΠΎΠ±Ρ‰Π΅Π³ΠΎ назначСния, Π½Π°ΠΌ становятся доступны ΠΌΠ½ΠΎΠ³ΠΈΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ обСспСчСния, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±Ρ‹Π»ΠΈ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ ΠΏΡ€ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ Π½Π°ΡˆΠΈΡ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ. Они Π²ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ Π² сСбя ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½ΠΎΠ΅ тСстированиС, ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ΅ тСстированиС, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΡ… взаимодСйствиС для провСдСния ΠΎΠ±ΡˆΠΈΡ€Π½ΠΎΠ³ΠΎ runtime-тСстирования. ВСсты Π»Π΅Π³ΠΊΠΎ Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ ΠΏΠΎ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΡŽ ΠΈΠ»ΠΈ Π² вашСй CI-систСмС.

Pulumi β€” ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ΅ обСспСчСниС с ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ исходным ΠΊΠΎΠ΄ΠΎΠΌ, ΠΎΠ½ΠΎ бСсплатно для использования ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ с вашими Π»ΡŽΠ±ΠΈΠΌΡ‹ΠΌΠΈ языками программирования ΠΈ ΠΎΠ±Π»Π°ΠΊΠ°ΠΌΠΈ β€” ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠΉΡ‚Π΅ Π΅Π³ΠΎ сСгодня!

β†’ ΠŸΠ΅Ρ€Π²Π°Ρ Ρ‡Π°ΡΡ‚ΡŒ

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com