เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเป‚เบ„เบ‡เบชเป‰เบฒเบ‡เบžเบทเป‰เบ™เบ–เบฒเบ™เป€เบ›เบฑเบ™เบฅเบฐเบซเบฑเบ”เบเบฑเบš Pulumi. เบžเบฒเบเบ—เบต 1

เบชเบฐเบšเบฒเบเบ”เบตเบ•เบญเบ™เบšเปˆเบฒเบเบซเบกเบนเปˆเป€เบžเบทเปˆเบญเบ™. เปƒเบ™เบ„เบงเบฒเบกเบ„เบฒเบ”เบซเบงเบฑเบ‡เบ‚เบญเบ‡เบเบฒเบ™เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบ‚เบญเบ‡เบเบฒเบ™เป„เบซเบผเป€เบ‚เบปเป‰เบฒเปƒเบซเบกเปˆเปƒเบ™เบญเบฑเบ”เบ•เบฒ "เบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เปเบฅเบฐเป€เบ„เบทเปˆเบญเบ‡เบกเบท DevOps" เบžเบงเบเป€เบฎเบปเบฒเบเบณเบฅเบฑเบ‡เปเบšเปˆเบ‡เบ›เบฑเบ™เบเบฒเบ™เปเบ›เปƒเปเปˆเปƒเบซเป‰เบเบฑเบšเป€เบˆเบปเป‰เบฒ. เป„เบ›.

เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเป‚เบ„เบ‡เบชเป‰เบฒเบ‡เบžเบทเป‰เบ™เบ–เบฒเบ™เป€เบ›เบฑเบ™เบฅเบฐเบซเบฑเบ”เบเบฑเบš Pulumi. เบžเบฒเบเบ—เบต 1

เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบžเบฒเบชเบฒ Pulumi เปเบฅเบฐเบžเบฒเบชเบฒเบเบฒเบ™เบ‚เบฝเบ™เป‚เบ›เบฅเปเบเบฅเบกเบ—เบปเปˆเบงเป„เบ›เบชเปเบฒเบฅเบฑเบšเบฅเบฐเบซเบฑเบ”เป‚เบ„เบ‡เบชเป‰เบฒเบ‡เบžเบทเป‰เบ™เบ–เบฒเบ™ (Infrastructure as Code) เบชเบฐเบซเบ™เบญเบ‡เบœเบปเบ™เบ›เบฐเป‚เบซเบเบ”เบซเบผเบฒเบเบขเปˆเบฒเบ‡: เบ—เบฑเบเบชเบฐเปเบฅเบฐเบ„เบงเบฒเบกเบฎเบนเป‰, เบเบฒเบ™เบเปเบฒเบˆเบฑเบ” boilerplate เปƒเบ™เบฅเบฐเบซเบฑเบ”เป‚เบ”เบเบœเปˆเบฒเบ™เบเบฒเบ™ abstraction, เป€เบ„เบทเปˆเบญเบ‡เบกเบทเบ—เบตเปˆเบ„เบธเป‰เบ™เป€เบ„เบตเบเบเบฑเบšเบ—เบตเบกเบ‡เบฒเบ™เบ‚เบญเบ‡เบ—เปˆเบฒเบ™เป€เบŠเบฑเปˆเบ™ IDEs เปเบฅเบฐ linters. เป€เบ„เบทเปˆเบญเบ‡เบกเบทเบงเบดเบชเบฐเบงเบฐเบเปเบฒเบŠเบญเบšเปเบงเบ—เบฑเบ‡เบซเบกเบปเบ”เป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เบšเปเปˆเบžเบฝเบ‡เปเบ•เปˆเป€เบฎเบฑเบ”เปƒเบซเป‰เบžเบงเบเป€เบฎเบปเบฒเบกเบตเบœเบปเบ™เบœเบฐเบฅเบดเบ”เบซเบผเบฒเบ, เปเบ•เปˆเบเบฑเบ‡เบ›เบฑเบšเบ›เบธเบ‡เบ„เบธเบ™เบ™เบฐเบžเบฒเบšเบ‚เบญเบ‡เบฅเบฐเบซเบฑเบ”เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒ. เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบกเบฑเบ™เป€เบ›เบฑเบ™เป€เบฅเบทเปˆเบญเบ‡เบ—เปเบฒเบกเบฐเบŠเบฒเบ”เบ—เบตเปˆเบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบžเบฒเบชเบฒเบเบฒเบ™เบ‚เบฝเบ™เป‚เบ›เบฅเปเบเบฅเบกเบ—เบปเปˆเบงเป„เบ›เบŠเปˆเบงเบเปƒเบซเป‰เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เปเบ™เบฐเบ™เปเบฒเบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™เบžเบฑเบ”เบ—เบฐเบ™เบฒเบŠเบญเบšเปเบงเบ—เบตเปˆเบชเปเบฒเบ„เบฑเบ™เบญเบตเบเบญเบฑเบ™เบซเบ™เบถเปˆเบ‡ - เบเบฒเบ™เบ—เบปเบ”เบชเบญเบš.

เปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบกเบ™เบตเป‰, เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเป€เบšเบดเปˆเบ‡เบงเบดเบ—เบตเบ—เบตเปˆ Pulumi เบŠเปˆเบงเบเบžเบงเบเป€เบฎเบปเบฒเบ—เบปเบ”เบชเบญเบšเป‚เบ„เบ‡เบชเป‰เบฒเบ‡เบžเบทเป‰เบ™เบ–เบฒเบ™เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒ.

เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเป‚เบ„เบ‡เบชเป‰เบฒเบ‡เบžเบทเป‰เบ™เบ–เบฒเบ™เป€เบ›เบฑเบ™เบฅเบฐเบซเบฑเบ”เบเบฑเบš Pulumi. เบžเบฒเบเบ—เบต 1

เป€เบ›เบฑเบ™เบซเบเบฑเบ‡เบ•เป‰เบญเบ‡เบ—เบปเบ”เบชเบญเบšเป‚เบ„เบ‡เบชเป‰เบฒเบ‡เบžเบทเป‰เบ™เบ–เบฒเบ™?

เบเปˆเบญเบ™เบ—เบตเปˆเบˆเบฐเป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เบฅเบฒเบเบฅเบฐเบญเบฝเบ”, เบกเบฑเบ™เป€เบ›เบฑเบ™เบกเบนเบ™เบ„เปˆเบฒเบ—เบตเปˆเบˆเบฐเบ–เบฒเบกเบ„เปเบฒเบ–เบฒเบก: "เป€เบ›เบฑเบ™เบซเบเบฑเบ‡เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเป‚เบ„เบ‡เบชเป‰เบฒเบ‡เบžเบทเป‰เบ™เบ–เบฒเบ™เบ—เบฑเบ‡เบซเบกเบปเบ”?" เบกเบตเบซเบผเบฒเบเป€เบซเบ”เบœเบปเบ™เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ™เบตเป‰เปเบฅเบฐเบ™เบตเป‰เปเบกเปˆเบ™เบšเบฒเบ‡เบชเปˆเบงเบ™เบ‚เบญเบ‡เบžเบงเบเป€เบ‚เบปเบฒ:

  • เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบซเบ™เปˆเบงเบเบ‡เบฒเบ™เบ‚เบญเบ‡เปเบ•เปˆเบฅเบฐเบซเบ™เป‰เบฒเบ—เบตเปˆเบซเบผเบทเบŠเบดเป‰เบ™เบชเปˆเบงเบ™เบ‚เบญเบ‡เป€เบซเบ”เบœเบปเบ™เบ‚เบญเบ‡เป‚เบ›เบผเปเบเบผเบกเบ‚เบญเบ‡เบ—เปˆเบฒเบ™
  • เบขเบทเบ™เบขเบฑเบ™เบชเบฐเบ–เบฒเบ™เบฐเบ—เบตเปˆเบ•เป‰เบญเบ‡เบเบฒเบ™เบ‚เบญเบ‡เป‚เบ„เบ‡เบชเป‰เบฒเบ‡เบžเบทเป‰เบ™เบ–เบฒเบ™เบ•เปเปˆเบเบฑเบšเบ‚เปเป‰เบˆเปเบฒเบเบฑเบ”เบšเบฒเบ‡เบขเปˆเบฒเบ‡.
  • เบเบฒเบ™เบเบงเบ”เบชเบญเบšเบ„เบงเบฒเบกเบœเบดเบ”เบžเบฒเบ”เบ—เบปเปˆเบงเป„เบ›, เป€เบŠเบฑเปˆเบ™: เบเบฒเบ™เบ‚เบฒเบ”เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเบฅเบฐเบซเบฑเบ”เบ‚เบญเบ‡เบ–เบฑเบ‡เป€เบเบฑเบšเบ‚เปเป‰เบกเบนเบ™เบซเบผเบทเบšเปเปˆเบกเบตเบเบฒเบ™เบ›เป‰เบญเบ‡เบเบฑเบ™, เป€เบ›เบตเบ”เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบˆเบฒเบเบญเบดเบ™เป€เบ•เบตเป€เบ™เบฑเบ”เป„เบ›เบซเบฒเป€เบ„เบทเปˆเบญเบ‡ virtual.
  • เบเบงเบ”โ€‹เบเบฒโ€‹เบเบฒเบ™โ€‹เบ›เบฐโ€‹เบ•เบดโ€‹เบšเบฑเบ”โ€‹เบเบฒเบ™โ€‹เบˆเบฑเบ”โ€‹เบซเบฒโ€‹เบžเบทเป‰เบ™โ€‹เบ–เบฒเบ™โ€‹เป‚เบ„เบ‡โ€‹เบฅเปˆเบฒเบ‡.
  • เบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™เบ—เบปเบ”เบชเบญเบš runtime เบ‚เบญเบ‡เป€เบซเบ”เบœเบปเบ™เบ‚เบญเบ‡เปเบญเบฑเบšเบžเบฅเบดเป€เบ„เบŠเบฑเบ™เบ—เบตเปˆเป€เบฎเบฑเบ”เบงเบฝเบเบขเบนเปˆเปƒเบ™เป‚เบ„เบ‡เบชเป‰เบฒเบ‡เบžเบทเป‰เบ™เบ–เบฒเบ™ "เป‚เบ„เบ‡เบเบฒเบ™" เบ‚เบญเบ‡เบ—เปˆเบฒเบ™เป€เบžเบทเปˆเบญเบเบงเบ”เป€เบšเบดเปˆเบ‡เบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเบซเบผเบฑเบ‡เบˆเบฒเบเบเบฒเบ™เบชเบฐเบซเบ™เบญเบ‡.
  • เบ”เบฑเปˆเบ‡เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบชเบฒเบกเบฒเบ”เป€เบซเบฑเบ™เป„เบ”เป‰, เบกเบตเบ—เบฒเบ‡เป€เบฅเบทเบญเบเปƒเบ™เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเป‚เบ„เบ‡เบชเป‰เบฒเบ‡เบžเบทเป‰เบ™เบ–เบฒเบ™เบ—เบตเปˆเบเบงเป‰เบฒเบ‡เบ‚เบงเบฒเบ‡. Polumi เบกเบตเบเบปเบ™เป„เบเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเปƒเบ™เบ—เบธเบเบˆเบธเบ”เบเปˆเบฝเบงเบเบฑเบš spectrum เบ™เบตเป‰. เปƒเบซเป‰เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เปเบฅเบฐเป€เบšเบดเปˆเบ‡เบงเปˆเบฒเบกเบฑเบ™เป€เบฎเบฑเบ”เบงเบฝเบเปเบ™เบงเปƒเบ”.

เบเบฒเบ™โ€‹เบ—เบปเบ”โ€‹เบชเบญเบšโ€‹เบซเบปเบงโ€‹เบซเบ™เปˆเบงเบโ€‹

เป‚เบ›เบฅเปเบเบฅเบก Pulumi เบ–เบทเบเบ‚เบฝเบ™เป„เบงเป‰เปƒเบ™เบžเบฒเบชเบฒเบเบฒเบ™เบ‚เบฝเบ™เป‚เบ›เบฅเปเบเบฅเบกเบ—เบปเปˆเบงเป„เบ›เป€เบŠเบฑเปˆเบ™ JavaScript, Python, TypeScript เบซเบผเบท Go. เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบžเบฐเบฅเบฑเบ‡เบ‡เบฒเบ™เบญเบฑเบ™เป€เบ•เบฑเบกเบ—เบตเปˆเบ‚เบญเบ‡เบžเบฒเบชเบฒเป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰, เบฅเบงเบกเบ—เบฑเบ‡เป€เบ„เบทเปˆเบญเบ‡เบกเบทเปเบฅเบฐเบซเป‰เบญเบ‡เบชเบฐเบซเบกเบธเบ”เบ‚เบญเบ‡เป€เบ‚เบปเบฒเป€เบˆเบปเป‰เบฒ, เบฅเบงเบกเบ—เบฑเบ‡เบเบญเบšเบเบฒเบ™เบ—เบปเบ”เบชเบญเบš, เปเบกเปˆเบ™เบกเบตเปƒเบซเป‰เป€เบ‚เบปเบฒเป€เบˆเบปเป‰เบฒ. Pulumi เปเบกเปˆเบ™เบซเบผเบฒเบเบ„เบฅเบฒเบง, เบŠเบถเปˆเบ‡เบซเบกเบฒเบเบ„เบงเบฒเบกเบงเปˆเบฒเบกเบฑเบ™เบชเบฒเบกเบฒเบ”เบ–เบทเบเบ™เปเบฒเปƒเบŠเป‰เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบˆเบฒเบเบœเบนเป‰เปƒเบซเป‰เบšเปเบฅเบดเบเบฒเบ™เบŸเบฑเบ‡เปƒเบ”เป†.

(เปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบกเบ™เบตเป‰, เป€เบ–เบดเบ‡เบงเปˆเบฒเบˆเบฐเบกเบตเบซเบผเบฒเบเบžเบฒเบชเบฒเปเบฅเบฐ multicloud, เบžเบงเบเป€เบฎเบปเบฒเปƒเบŠเป‰ JavaScript เปเบฅเบฐ Mocha เปเบฅเบฐเบชเบธเบกเปƒเบชเปˆ AWS. เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบ™เปเบฒเปƒเบŠเป‰ Python. unittest, เป„เบ›เบเบญเบšเบเบฒเบ™เบ—เบปเบ”เบชเบญเบš, เบซเบผเบทเบเบญเบšเบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบญเบทเปˆเบ™เป†เบ—เบตเปˆเบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เบเบฒเบ™. เปเบฅเบฐ, เปเบ™เปˆเบ™เบญเบ™, Pulumi เป€เบฎเบฑเบ”เบงเบฝเบเป„เบ”เป‰เบ”เบตเบเบฑเบš Azure, Google Cloud, Kubernetes.)

เบ”เบฑเปˆเบ‡เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เป€เบซเบฑเบ™, เบกเบตเบซเบผเบฒเบเป€เบซเบ”เบœเบปเบ™เบงเปˆเบฒเป€เบ›เบฑเบ™เบซเบเบฑเบ‡เบ—เปˆเบฒเบ™เบญเบฒเบ”เบˆเบฐเบ•เป‰เบญเบ‡เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบฅเบฐเบซเบฑเบ”เป‚เบ„เบ‡เบชเป‰เบฒเบ‡เบžเบทเป‰เบ™เบ–เบฒเบ™เบ‚เบญเบ‡เบ—เปˆเบฒเบ™. เบซเบ™เบถเปˆเบ‡เปƒเบ™เบ™เบฑเป‰เบ™เปเบกเปˆเบ™เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบซเบ™เปˆเบงเบเบ‡เบฒเบ™เปเบšเบšเบ”เบฑเป‰เบ‡เป€เบ”เบตเบก. เป€เบ™เบทเปˆเบญเบ‡เบˆเบฒเบเบงเปˆเบฒเบฅเบฐเบซเบฑเบ”เบ‚เบญเบ‡เบ—เปˆเบฒเบ™เบญเบฒเบ”เบกเบตเบซเบ™เป‰เบฒเบ—เบตเปˆ - เบ•เบปเบงเบขเปˆเบฒเบ‡, เป€เบžเบทเปˆเบญเบ„เบดเบ”เป„เบฅเปˆ CIDR, เบ„เบดเบ”เป„เบฅเปˆเปเบšเบšเป„เบ”เบ™เบฒเบกเบดเบเบŠเบทเปˆ, tags, เปเบฅเบฐเบญเบทเปˆเบ™เป†. - เบ—เปˆเบฒเบ™โ€‹เบญเบฒเบ”โ€‹เบˆเบฐโ€‹เบ•เป‰เบญเบ‡โ€‹เบเบฒเบ™โ€‹เบ—เบตเปˆโ€‹เบˆเบฐโ€‹เบ—เบปเบ”โ€‹เบชเบญเบšโ€‹เปƒเบซเป‰โ€‹เป€เบ‚เบปเบฒโ€‹เป€เบˆเบปเป‰เบฒโ€‹. เบ™เบตเป‰เปเบกเปˆเบ™เบ„เบทเบเบฑเบ™เบเบฑเบšเบเบฒเบ™เบ‚เบฝเบ™เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบซเบ™เปˆเบงเบเบ‡เบฒเบ™เบ›เบปเบเบเบฐเบ•เบดเบชเปเบฒเบฅเบฑเบšเบ„เปเบฒเบฎเป‰เบญเบ‡เบชเบฐเบซเบกเบฑเบเปƒเบ™เบžเบฒเบชเบฒเบเบฒเบ™เบ‚เบฝเบ™เป‚เบ›เบผเปเบเบผเบกเบ—เบตเปˆเบ—เปˆเบฒเบ™เบกเบฑเบ.
เป€เบžเบทเปˆเบญเปƒเบซเป‰เบกเบตเบ„เบงเบฒเบกเบชเบฑเบšเบชเบปเบ™เบซเบผเบฒเบ, เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบเบงเบ”เป€เบšเบดเปˆเบ‡เบงเปˆเบฒเป‚เบ„เบ‡เบเบฒเบ™เบ‚เบญเบ‡เบ—เปˆเบฒเบ™เบˆเบฑเบ”เบชเบฑเบ™เบŠเบฑเบšเบžเบฐเบเบฒเบเบญเบ™เปเบ™เบงเปƒเบ”. เป€เบžเบทเปˆเบญเบชเบฐเปเบ”เบ‡เปƒเบซเป‰เป€เบซเบฑเบ™, เปƒเบซเป‰เบˆเบดเบ™เบ•เบฐเบ™เบฒเบเบฒเบ™เบงเปˆเบฒเบžเบงเบเป€เบฎเบปเบฒเบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เบชเป‰เบฒเบ‡เป€เบ„เบทเปˆเบญเบ‡เปเบกเปˆเบ‚เปˆเบฒเบ EC2 เบ‡เปˆเบฒเบเบ”เบฒเบเปเบฅเบฐเบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เปƒเบซเป‰เปเบ™เปˆเปƒเบˆเบงเปˆเบฒเบ•เปเปˆเป„เบ›เบ™เบตเป‰:

  • เบ•เบปเบงเบขเปˆเบฒเบ‡เบกเบตเปเบ—เบฑเบ Name.
  • Instances เบšเปเปˆเบ„เบงเบ™เปƒเบŠเป‰ inline script 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 เปเบฅเบฐเบ•เบปเบงเบขเปˆเบฒเบ‡. เบขเปˆเบฒเบ‡เปƒเบ”เบเปเปˆเบ•เบฒเบก, เบกเบฑเบ™เบ„เบงเบ™เบˆเบฐเบชเบฑเบ‡เป€เบเบ”เบงเปˆเบฒเปƒเบ™เบ—เบตเปˆเบ™เบตเป‰เบžเบงเบเป€เบฎเบปเบฒเบเปเบฒเบฅเบฑเบ‡เบฅเบฐเป€เบกเบตเบ”เบ—เบฑเบ‡เบชเบฒเบกเบเบปเบ”เบฅเบฐเบšเบฝเบšเบ—เบตเปˆเป„เบ”เป‰เบเปˆเบฒเบงเบกเบฒเบ‚เป‰เบฒเบ‡เป€เบ—เบดเบ‡. เบฅเบญเบ‡เบ‚เบฝเบ™เบšเบปเบ”เบชเบญเบšเป€เบชเบฑเบ‡เบ™เบณเบเบฑเบ™!

เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบเบฒเบ™เบ‚เบฝเบ™

เป‚เบ„เบ‡เบชเป‰เบฒเบ‡เบ—เบปเปˆเบงเป„เบ›เบ‚เบญเบ‡เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบ„เป‰เบฒเบเบ„เบทเบเบฑเบšเบเบฒเบ™เบ—เบปเบ”เบชเบญเบš 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, ะพั‚ะบั€ั‹ั‚ะพะณะพ ะฒ ะ˜ะฝั‚ะตั€ะฝะตั‚.
    });
});

เบ•เบญเบ™เบ™เบตเป‰เปƒเบซเป‰เบžเบงเบเป€เบฎเบปเบฒเบ‚เบฝเบ™เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบ„เบฑเป‰เบ‡เบ—เปเบฒเบญเบดเบ”เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒ: เปƒเบซเป‰เปเบ™เปˆเปƒเบˆเบงเปˆเบฒ instances เบกเบต tag 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เป€เบžเบทเปˆเบญเบชเบปเบกเบ—เบปเบšเบžเบงเบเบกเบฑเบ™.
  • เบชเบธเบ”เบ—เป‰เบฒเบ, เบ™เบฑเบšเบ•เบฑเป‰เบ‡เปเบ•เปˆเบ„เปˆเบฒเป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เบ–เบทเบเบ„เบดเบ”เป„เบฅเปˆเปเบšเบš asynchronous, เบžเบงเบเป€เบฎเบปเบฒเบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เปƒเบŠเป‰เบ„เบธเบ™เบชเบปเบกเบšเบฑเบ”เบเบฒเบ™เป‚เบ—เบเบฑเบš async เบžเบฒเบเปƒเบ™เบ•เบปเบงเบ‚เบญเบ‡ 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 ะดะปั ะดั€ัƒะณะธั… ัะทั‹ะบะพะฒ).
    เบŠเบทเปˆเบ‚เบญเบ‡ stack เบ—เบตเปˆเบฅเบฐเบšเบธเป„เบงเป‰เปƒเบ™เบ•เบปเบงเปเบ›เบชเบฐเบžเบฒเบšเปเบงเบ”เบฅเป‰เบญเบก PULUMI_NODEJS_STACK (เบซเบผเบท, เป‚เบ”เบเบ—เบปเปˆเบงเป„เบ›เปเบฅเป‰เบง, PULUMI__ STACK).
    เบ•เบปเบงเปเบ›เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒ stack เบ‚เบญเบ‡เบ—เปˆเบฒเบ™. เบžเบงเบเป€เบ‚เบปเบฒเบชเบฒเบกเบฒเบ”เป„เบ”เป‰เบฎเบฑเบšเป‚เบ”เบเปƒเบŠเป‰เบ•เบปเบงเปเบ›เบชเบฐเบžเบฒเบšเปเบงเบ”เบฅเป‰เบญเบก PULUMI_CONFIG เปเบฅเบฐเบฎเบนเบšเปเบšเบšเบ‚เบญเบ‡เบžเบงเบเบกเบฑเบ™เปเบกเปˆเบ™เปเบœเบ™เบ—เบตเปˆ JSON เบ—เบตเปˆเบกเบตเบ„เบนเปˆเบ„เบต/เบ„เปˆเบฒ.

    เป‚เบ„เบ‡โ€‹เบเบฒเบ™โ€‹เบˆเบฐโ€‹เบญเบญเบโ€‹เบ„เปเบฒโ€‹เป€เบ•เบทเบญเบ™โ€‹เบ—เบตเปˆโ€‹เบŠเบตเป‰โ€‹เบšเบญเบโ€‹เบงเปˆเบฒโ€‹เบเบฒเบ™โ€‹เป€เบŠเบทเปˆเบญเบกโ€‹เบ•เปเปˆโ€‹เบเบฑเบš CLI / เป€เบ„เบทเปˆเบญเบ‡โ€‹เบˆเบฑเบโ€‹เปเบกเปˆเบ™โ€‹เบšเปเปˆโ€‹เบกเบตโ€‹เปƒเบ™โ€‹เบฅเบฐโ€‹เบซเบงเปˆเบฒเบ‡โ€‹เบเบฒเบ™โ€‹เบ›เบฐโ€‹เบ•เบดโ€‹เบšเบฑเบ”โ€‹. เบ™เบตเป‰เปเบกเปˆเบ™เบชเบดเปˆเบ‡เบชเปเบฒเบ„เบฑเบ™เป€เบžเบฒเบฐเบงเปˆเบฒเป‚เบ„เบ‡เบเบฒเบ™เบ‚เบญเบ‡เป€เบˆเบปเป‰เบฒเบˆเบฐเบšเปเปˆเบ–เบทเบเบ™เปเบฒเป„เบ›เปƒเบŠเป‰เบซเบเบฑเบ‡เป€เบฅเบตเบ เปเบฅเบฐเบกเบฑเบ™เบญเบฒเบ”เบˆเบฐเป€เบ›เบฑเบ™เป€เบฅเบทเปˆเบญเบ‡เปเบ›เบเบ—เบตเปˆเบ–เป‰เบฒเบงเปˆเบฒเบ™เบฑเป‰เบ™เบšเปเปˆเปเบกเปˆเบ™เบชเบดเปˆเบ‡เบ—เบตเปˆเบ—เปˆเบฒเบ™เบ•เบฑเป‰เบ‡เปƒเบˆเบˆเบฐเป€เบฎเบฑเบ”! เป€เบžเบทเปˆเบญเบšเบญเบ Pulumi เบงเปˆเบฒเบ™เบตเป‰เปเบกเปˆเบ™เบชเบดเปˆเบ‡เบ—เบตเปˆเบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เบเบฒเบ™, เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบ•เบดเบ”เบ•เบฑเป‰เบ‡เป„เบ”เป‰ PULUMI_TEST_MODE ะฒ true.

    เบˆเบดเบ™เบ•เบฐเบ™เบฒเบเบฒเบ™เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เบฅเบฐเบšเบธเบŠเบทเปˆเป‚เบ„เบ‡เบเบฒเบ™เปƒเบ™ my-ws, เบŠเบทเปˆ stack dev, เปเบฅเบฐ AWS Region 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)

    เบ—เบธเบเบขเปˆเบฒเบ‡เบœเปˆเบฒเบ™เป„เบ›เบ”เป‰เบงเบเบ”เบต... Hurray! โœ“โœ“

    เบ™เบฑเป‰เบ™เปเบกเปˆเบ™เบ—เบฑเบ‡เบซเบกเบปเบ”เบชเปเบฒเบฅเบฑเบšเบกเบทเป‰เบ™เบตเป‰, เปเบ•เปˆเบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเป€เบงเบปเป‰เบฒเบเปˆเบฝเบงเบเบฑเบšเบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เปƒเบ™เบžเบฒเบเบ—เบตเบชเบญเบ‡เบ‚เบญเบ‡เบเบฒเบ™เปเบ›เบžเบฒเบชเบฒ ๐Ÿ˜‰

เปเบซเบผเปˆเบ‡เบ‚เปเป‰เบกเบนเบ™: www.habr.com

เป€เบžเบตเปˆเบกเบ„เบงเบฒเบกเบ„เบดเบ”เป€เบซเบฑเบ™