αžŸαžΆαž€αž›αŸ’αž”αž„αž αŸαžŠαŸ’αž‹αžΆαžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž‡αžΆαž€αžΌαžŠαž‡αžΆαž˜αž½αž™ Pulumi αŸ” αž•αŸ’αž“αŸ‚αž€αž‘αžΈ 1

αžŸαž½αžŸαŸ’αžαžΈαž˜αž·αžαŸ’αžαž—αŸαž€αŸ’αžαž·αŸ” αž“αŸ…αž€αŸ’αž“αž»αž„αž€αžΆαžšαžšαŸ†αž–αžΉαž„αž‘αž»αž€αž“αŸƒαž€αžΆαžšαž…αžΆαž”αŸ‹αž•αŸ’αžαžΎαž˜αž“αŸƒαž›αŸ†αž αžΌαžšαžαŸ’αž˜αžΈαž˜αž½αž™αž“αŸ…αž€αŸ’αž“αž»αž„αž’αžαŸ’αžšαžΆ "αž€αžΆαžšαž’αž“αž»αžœαžαŸ’αž αž“αž·αž„αž§αž”αž€αžšαžŽαŸ DevOps" αž™αžΎαž„αž€αŸ†αž–αž»αž„αž…αŸ‚αž€αžšαŸ†αž›αŸ‚αž€αž‡αžΆαž˜αž½αž™αž’αŸ’αž“αž€αž“αžΌαžœαž€αžΆαžšαž”αž€αž”αŸ’αžšαŸ‚αžαŸ’αž˜αžΈαŸ” αž‘αŸ…αŸ”

αžŸαžΆαž€αž›αŸ’αž”αž„αž αŸαžŠαŸ’αž‹αžΆαžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž‡αžΆαž€αžΌαžŠαž‡αžΆαž˜αž½αž™ Pulumi αŸ” αž•αŸ’αž“αŸ‚αž€αž‘αžΈ 1

αž€αžΆαžšαž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹ Pulumi αž“αž·αž„αž—αžΆαžŸαžΆαžŸαžšαžŸαŸαžšαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαžŠαŸ‚αž›αž˜αžΆαž“αž‚αŸ„αž›αž”αŸ†αžŽαž„αž‘αžΌαž‘αŸ…αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΌαžŠαž αŸαžŠαŸ’αž‹αžΆαžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’ (Infrastructure as Code) αž•αŸ’αžαž›αŸ‹αž“αžΌαžœαž’αžαŸ’αžαž”αŸ’αžšαž™αŸ„αž‡αž“αŸαž‡αžΆαž…αŸ’αžšαžΎαž“αŸ– αž—αžΆαž–αž’αžΆαž…αžšαž€αž”αžΆαž“αž“αŸƒαž‡αŸ†αž“αžΆαž‰ αž“αž·αž„αž…αŸ†αžŽαŸαŸ‡αžŠαžΉαž„ αž€αžΆαžšαž›αž»αž”αž”αŸ†αž”αžΆαžαŸ‹ boilerplate αž“αŸ…αž€αŸ’αž“αž»αž„αž€αžΌαžŠαžαžΆαž˜αžšαž™αŸˆ abstraction αž§αž”αž€αžšαžŽαŸαžŠαŸ‚αž›αžŸαŸŠαžΆαŸ†αž“αžΉαž„αž€αŸ’αžšαž»αž˜αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€ αžŠαžΌαž…αž‡αžΆ IDEs αž“αž·αž„ lintersαŸ” αž§αž”αž€αžšαžŽαŸαžœαž·αžŸαŸ’αžœαž€αž˜αŸ’αž˜αžŸαžΌαž αŸ’αžœαžœαŸ‚αžšαž‘αžΆαŸ†αž„αž’αžŸαŸ‹αž“αŸαŸ‡αž˜αž·αž“αžαŸ’αžšαžΉαž˜αžαŸ‚αž’αŸ’αžœαžΎαž±αŸ’αž™αž™αžΎαž„αž€αžΆαž“αŸ‹αžαŸ‚αž˜αžΆαž“αž•αž›αž·αžαž—αžΆαž–αž”αŸ‰αž»αžŽαŸ’αžŽαŸ„αŸ‡αž‘αŸ αž”αŸ‰αž»αž“αŸ’αžαŸ‚αžαŸ‚αž˜αž‘αžΆαŸ†αž„αž’αŸ’αžœαžΎαž’αŸ„αž™αž‚αž»αžŽαž—αžΆαž–αž“αŸƒαž€αžΌαžŠαžšαž”αžŸαŸ‹αž™αžΎαž„αž€αžΆαž“αŸ‹αžαŸ‚αž”αŸ’αžšαžŸαžΎαžšαž‘αžΎαž„αž•αž„αžŠαŸ‚αžšαŸ” αžŠαžΌαž…αŸ’αž“αŸαŸ‡ αžœαžΆαž‚αŸ’αžšαžΆαž“αŸ‹αžαŸ‚αž‡αžΆαžšαžΏαž„αž’αž˜αŸ’αž˜αžαžΆαžŠαŸ‚αž›αž€αžΆαžšαž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αž—αžΆαžŸαžΆαžŸαžšαžŸαŸαžšαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαžŠαŸ‚αž›αž˜αžΆαž“αž‚αŸ„αž›αž”αŸ†αžŽαž„αž‘αžΌαž‘αŸ…αž’αž“αž»αž‰αŸ’αž‰αžΆαžαž±αŸ’αž™αž™αžΎαž„αžŽαŸ‚αž“αžΆαŸ†αž€αžΆαžšαž’αž“αž»αžœαžαŸ’αžαž€αžΆαžšαž’αž—αž·αžœαžŒαŸ’αžαž“αŸαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαžŸαŸ†αžαžΆαž“αŸ‹αž˜αž½αž™αž‘αŸ€αž - αž€αžΆαžšαž’αŸ’αžœαžΎαžαŸαžŸαŸ’αž.

αž“αŸ…αž€αŸ’αž“αž»αž„αž’αžαŸ’αžαž”αž‘αž“αŸαŸ‡ αž™αžΎαž„αž“αžΉαž„αž–αž·αž“αž·αžαŸ’αž™αž˜αžΎαž›αž–αžΈαžšαž”αŸ€αž”αžŠαŸ‚αž› Pulumi αž‡αž½αž™αž™αžΎαž„αžŸαžΆαž€αž›αŸ’αž”αž„αž αŸαžŠαŸ’αž‹αžΆαžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αžŠαžΌαž…αž€αžΌαžŠαžšαž”αžŸαŸ‹αž™αžΎαž„αŸ”

αžŸαžΆαž€αž›αŸ’αž”αž„αž αŸαžŠαŸ’αž‹αžΆαžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž‡αžΆαž€αžΌαžŠαž‡αžΆαž˜αž½αž™ Pulumi αŸ” αž•αŸ’αž“αŸ‚αž€αž‘αžΈ 1

αž αŸαžαž»αž’αŸ’αžœαžΈαžαŸ’αžšαžΌαžœαžŸαžΆαž€αž›αŸ’αž”αž„αž αŸαžŠαŸ’αž‹αžΆαžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’?

αž˜αž»αž“β€‹αž“αžΉαž„β€‹αž“αž·αž™αžΆαž™β€‹αž›αž˜αŸ’αž’αž·αž αžœαžΆβ€‹αž‚αž½αžšβ€‹αžŸαž½αžšβ€‹αžŸαŸ†αžŽαž½αžšβ€‹αžαžΆ "αž αŸαžαž»αž’αŸ’αžœαžΈβ€‹αž”αžΆαž“β€‹αž‡αžΆβ€‹αžŸαžΆαž€αž›αŸ’αž”αž„β€‹αž αŸαžŠαŸ’αž‹αžΆαžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’β€‹αž‘αžΆαŸ†αž„αž’αžŸαŸ‹?" αž˜αžΆαž“αž αŸαžαž»αž•αž›αž‡αžΆαž…αŸ’αžšαžΎαž“αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αžšαžΏαž„αž“αŸαŸ‡ αž αžΎαž™αž“αŸαŸ‡αž‚αžΊαž‡αžΆαž˜αž½αž™αž…αŸ†αž“αž½αž“αž“αŸƒαž–αž½αž€αž‚αŸαŸ–

  • αž€αžΆαžšαž’αŸ’αžœαžΎαžαŸαžŸαŸ’αžαž―αž€αžαžΆαž“αŸƒαž˜αž»αžαž„αžΆαžšαž“αžΈαž˜αž½αž™αŸ— αž¬αž”αŸ†αžŽαŸ‚αž€αž“αŸƒαžαž€αŸ’αž€αžœαž·αž‡αŸ’αž‡αžΆαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αŸ”
  • αž•αŸ’αž‘αŸ€αž„αž•αŸ’αž‘αžΆαžαŸ‹αžŸαŸ’αžαžΆαž“αž—αžΆαž–αžŠαŸ‚αž›αž…αž„αŸ‹αž”αžΆαž“αž“αŸƒαž αŸαžŠαŸ’αž‹αžΆαžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž”αŸ’αžšαž†αžΆαŸ†αž„αž“αžΉαž„αž§αž”αžŸαž‚αŸ’αž‚αž‡αžΆαž€αŸ‹αž›αžΆαž€αŸ‹αŸ”
  • αž€αžΆαžšαžšαž€αžƒαžΎαž‰αž€αŸ†αž αž»αžŸαž‘αžΌαž‘αŸ… αžŠαžΌαž…αž‡αžΆαž€αž„αŸ’αžœαŸ‡αž€αžΆαžšαž’αŸŠαž·αž“αž‚αŸ’αžšαžΈαž”αž’αž»αž„αž•αŸ’αž‘αž»αž€ αž¬αž˜αž·αž“αž˜αžΆαž“αž€αžΆαžšαž€αžΆαžšαž–αžΆαžš αž€αžΆαžšαž…αžΌαž›αž”αŸ’αžšαžΎαž–αžΈαž’αŸŠαžΈαž“αž’αžΊαžŽαž·αžαž‘αŸ…αž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αž“αž·αž˜αŸ’αž˜αž·αžαŸ”
  • αž–αž·αž“αž·αžαŸ’αž™αž€αžΆαžšαž’αž“αž»αžœαžαŸ’αžαž€αžΆαžšαž•αŸ’αžαž›αŸ‹αž αŸαžŠαŸ’αž‹αžΆαžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αŸ”
  • αž’αž“αž»αžœαžαŸ’αžαž€αžΆαžšαžŸαžΆαž€αž›αŸ’αž”αž„αž–αŸαž›αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž“αŸƒαžαž€αŸ’αž€αžœαž·αž‡αŸ’αž‡αžΆαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαžŠαŸ‚αž›αž€αŸ†αž–αž»αž„αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž“αŸ…αž€αŸ’αž“αž»αž„αž αŸαžŠαŸ’αž‹αžΆαžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’ "αž€αž˜αŸ’αž˜αžœαž·αž’αžΈ" αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€ αžŠαžΎαž˜αŸ’αž”αžΈαž–αž·αž“αž·αžαŸ’αž™αž˜αžΎαž›αž˜αž»αžαž„αžΆαžšαž”αž“αŸ’αž‘αžΆαž”αŸ‹αž–αžΈαž€αžΆαžšαž•αŸ’αžαž›αŸ‹αŸ”
  • αžŠαžΌαž…αžŠαŸ‚αž›αž™αžΎαž„αž’αžΆαž…αžƒαžΎαž‰αž˜αžΆαž“αž‡αž˜αŸ’αžšαžΎαžŸαž‡αžΆαž…αŸ’αžšαžΎαž“αž“αŸƒαž€αžΆαžšαž’αŸ’αžœαžΎαžαŸαžŸαŸ’αžαž αŸαžŠαŸ’αž‹αžΆαžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αŸ” Polumi αž˜αžΆαž“αž™αž“αŸ’αžαž€αžΆαžšαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž’αŸ’αžœαžΎαžαŸαžŸαŸ’αžαž“αŸ…αž‚αŸ’αžšαž”αŸ‹αž…αŸ†αžŽαž»αž…αž“αŸ…αž›αžΎαžœαž·αžŸαžΆαž›αž‚αž˜αž“αŸαŸ‡αŸ” αžαŸ„αŸ‡αž…αžΆαž”αŸ‹αž•αŸ’αžαžΎαž˜ αž αžΎαž™αž˜αžΎαž›αž–αžΈαžšαž”αŸ€αž”αžŠαŸ‚αž›αžœαžΆαžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαŸ”

αž€αžΆαžšαž’αŸ’αžœαžΎαžαŸαžŸαŸ’αžαž―αž€αžαžΆ

αž€αž˜αŸ’αž˜αžœαž·αž’αžΈ Pulumi αžαŸ’αžšαžΌαžœαž”αžΆαž“αžŸαžšαžŸαŸαžšαž‡αžΆαž—αžΆαžŸαžΆαžŸαžšαžŸαŸαžšαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαžŠαŸ‚αž›αž˜αžΆαž“αž‚αŸ„αž›αž”αŸ†αžŽαž„αž‘αžΌαž‘αŸ…αžŠαžΌαž…αž‡αžΆ JavaScript, Python, TypeScript ឬ Go αŸ” αžŠαžΌαž…αŸ’αž“αŸαŸ‡αž αžΎαž™ αžαžΆαž˜αž–αž›αž–αŸαž‰αž›αŸαž‰αž“αŸƒαž—αžΆαžŸαžΆαž‘αžΆαŸ†αž„αž“αŸαŸ‡ αžšαž½αž˜αž‘αžΆαŸ†αž„αž§αž”αž€αžšαžŽαŸ αž“αž·αž„αž”αžŽαŸ’αžŽαžΆαž›αŸαž™αžšαž”αžŸαŸ‹αž–αž½αž€αž‚αŸ αžšαž½αž˜αž‘αžΆαŸ†αž„αž€αŸ’αžšαž”αžαŸαžŽαŸ’αžŒαžŸαžΆαž€αž›αŸ’αž”αž„ αž˜αžΆαž“αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž–αž½αž€αž‚αŸαŸ” Pulumi αž‚αžΊαž‡αžΆαž–αž αž»αž–αž–αž€ αžŠαŸ‚αž›αž˜αžΆαž“αž“αŸαž™αžαžΆαžœαžΆαž’αžΆαž…αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αŸ’αžšαžΎαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž’αŸ’αžœαžΎαžαŸαžŸαŸ’αžαž–αžΈαž’αŸ’αž“αž€αž•αŸ’αžαž›αŸ‹αžŸαŸαžœαžΆαž–αž–αž€αžŽαžΆαž˜αž½αž™αŸ”

(αž“αŸ…αž€αŸ’αž“αž»αž„αž’αžαŸ’αžαž”αž‘αž“αŸαŸ‡ αž‘αŸ„αŸ‡αž”αžΈαž‡αžΆαž˜αžΆαž“αž–αž αž»αž—αžΆαžŸαžΆ αž“αž·αž„αž–αž αž»αž–αž–αž€αž€αŸαžŠαŸ„αž™ αž™αžΎαž„αž”αŸ’αžšαžΎ JavaScript αž“αž·αž„ Mocha αž αžΎαž™αž•αŸ’αžαŸ„αžαž›αžΎ AWS αŸ” αž’αŸ’αž“αž€αž’αžΆαž…αž”αŸ’αžšαžΎ Python 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 αž“αž·αž„αž§αž‘αžΆαž αžšαžŽαŸαž˜αž½αž™αŸ” αž‘αŸ„αŸ‡αž‡αžΆαž™αŸ‰αžΆαž„αžŽαžΆαž€αŸαžŠαŸ„αž™αž‚αž½αžšαž€αžαŸ‹αžŸαŸ†αž‚αžΆαž›αŸ‹αžαžΆαž“αŸ…αž‘αžΈαž“αŸαŸ‡αž™αžΎαž„αž€αŸ†αž–αž»αž„αž”αŸ†αž–αžΆαž“αž…αŸ’αž”αžΆαž”αŸ‹αž‘αžΆαŸ†αž„αž”αžΈαžŠαŸ‚αž›αž˜αžΆαž“αž…αŸ‚αž„αžαžΆαž„αž›αžΎαŸ” αžαŸ„αŸ‡αžŸαžΆαž€αž›αŸ’αž”αž„αžŸαžšαžŸαŸαžš!

αž€αžΆαžšαž’αŸ’αžœαžΎαžαŸαžŸαŸ’αžαžŸαžšαžŸαŸαžš

αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž‘αžΌαž‘αŸ…αž“αŸƒαž€αžΆαžšαž’αŸ’αžœαžΎαžαŸαžŸαŸ’αžαžšαž”αžŸαŸ‹αž™αžΎαž„αž“αžΉαž„αž˜αžΎαž›αž‘αŸ…αžŠαžΌαž…αž‡αžΆαž€αžΆαžšαž’αŸ’αžœαžΎαžαŸαžŸαŸ’αž 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αžŠαžΎαž˜αŸ’αž”αžΈαž•αŸ’αžŸαŸ†αž–αž½αž€αžœαžΆαŸ”
  • αž‡αžΆαž…αž»αž„αž€αŸ’αžšαŸ„αž™ αžŠαŸ„αž™αžŸαžΆαžšαžαž˜αŸ’αž›αŸƒαž‘αžΆαŸ†αž„αž“αŸαŸ‡αžαŸ’αžšαžΌαžœαž”αžΆαž“αž‚αžŽαž“αžΆαžŠαŸ„αž™αž’αžŸαž˜αž€αžΆαž› αž™αžΎαž„αžαŸ’αžšαžΌαžœαž”αŸ’αžšαžΎαž˜αž»αžαž„αžΆαžšαž αŸ…αžαŸ’αžšαž‘αž”αŸ‹αž˜αž€αžœαž·αž‰ 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 для Π΄Ρ€ΡƒΠ³ΠΈΡ… языков).
    αžˆαŸ’αž˜αŸ„αŸ‡αžšαž”αžŸαŸ‹αž‡αž„αŸ‹αžŠαŸ‚αž›αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αž‰αŸ’αž‡αžΆαž€αŸ‹αž“αŸ…αž€αŸ’αž“αž»αž„αž’αžαŸαžšαž”αžšαž·αžŸαŸ’αžαžΆαž“ 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

αž”αž“αŸ’αžαŸ‚αž˜αž˜αžαž·αž™αŸ„αž”αž›αŸ‹