เชธเซ‚เชšเชจเชพเช“: เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชœเชตเชพเชฌเชฆเชพเชฐ เชญเซ‚เชฎเชฟเช•เชพเช“เชจเซเช‚ เชชเชฐเซ€เช•เซเชทเชฃ เช•เชฐเชตเซเช‚ เช…เชจเซ‡ เช‰เชคเซเชชเชพเชฆเชจ เชชเชนเซ‡เชฒเชพเช‚ เชธเชฎเชธเซเชฏเชพเช“ เชตเชฟเชถเซ‡ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชถเซ‹เชงเชตเซเช‚

เชนเซ‡เชฒเซ‹ เชฆเชฐเซ‡เช•!

เชนเซเช‚ เชนเซ‹เชŸเซ‡เชฒ เชฌเซเช•เชฟเช‚เช— เชธเซ‡เชตเชพเชฎเชพเช‚ DevOps เชเชจเซเชœเชฟเชจเชฟเชฏเชฐ เชคเชฐเซ€เช•เซ‡ เช•เชพเชฎ เช•เชฐเซเช‚ เช›เซเช‚. Ostrovok.ru. เช† เชฒเซ‡เช–เชฎเชพเช‚, เชนเซเช‚ เชœเชตเชพเชฌเชฆเชพเชฐ เชญเซ‚เชฎเชฟเช•เชพเช“เชจเซเช‚ เชชเชฐเซ€เช•เซเชทเชฃ เช•เชฐเชตเชพเชจเชพ เช…เชฎเชพเชฐเชพ เช…เชจเซเชญเชต เชตเชฟเชถเซ‡ เชตเชพเชค เช•เชฐเชตเชพ เชฎเชพเช‚เช—เซ เช›เซเช‚.

Ostrovok.ru เชชเชฐ, เช…เชฎเซ‡ เชฐเซ‚เชชเชฐเซ‡เช–เชพเช‚เช•เชจ เชฎเซ‡เชจเซ‡เชœเชฐ เชคเชฐเซ€เช•เซ‡ เช…เชจเซเชธเชฟเชฌเชฒเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เช เช›เซ€เช. เชคเชพเชœเซ‡เชคเชฐเชฎเชพเช‚, เช…เชฎเซ‡ เชญเซ‚เชฎเชฟเช•เชพเช“เชจเซเช‚ เชชเชฐเซ€เช•เซเชทเชฃ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐเชฟเชฏเชพเชค เชชเชฐ เช†เชตเซเชฏเชพ, เชชเชฐเช‚เชคเซ เชคเซ‡ เชฌเชนเชพเชฐ เช†เชตเซเชฏเซเช‚ เชคเซ‡เชฎ, เช† เชฎเชพเชŸเซ‡ เช˜เชฃเชพ เชฌเชงเชพ เชธเชพเชงเชจเซ‹ เชจเชฅเซ€ - เชธเซŒเชฅเซ€ เชตเชงเซ เชฒเซ‹เช•เชชเซเชฐเชฟเชฏ, เช•เชฆเชพเชš, เชฎเซ‹เชฒเซ‡เช•เซเชฏเซเชฒ เชซเซเชฐเซ‡เชฎเชตเชฐเซเช• เช›เซ‡, เชคเซ‡เชฅเซ€ เช…เชฎเซ‡ เชคเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชจเซเช‚ เชจเช•เซเช•เซ€ เช•เชฐเซเชฏเซเช‚. เชชเชฐเช‚เชคเซ เชคเซ‡ เชฌเชนเชพเชฐ เช†เชตเซเชฏเซเช‚ เช›เซ‡ เช•เซ‡ เชคเซ‡เชจเชพ เชฆเชธเซเชคเชพเชตเซ‡เชœเซ€เช•เชฐเชฃ เช˜เชฃเชพ เชฎเซเชถเซเช•เซ‡เชฒเซ€เช“ เชตเชฟเชถเซ‡ เชฎเซŒเชจ เช›เซ‡. เช…เชฎเชจเซ‡ เชฐเชถเชฟเชฏเชจเชฎเชพเช‚ เชชเซ‚เชฐเชคเซเช‚ เชตเชฟเช—เชคเชตเชพเชฐ เชฎเซ‡เชจเซเชฏเซเช…เชฒ เชฎเชณเซ€ เชถเช•เซเชฏเซเช‚ เชจเชฅเซ€, เชคเซ‡เชฅเซ€ เช…เชฎเซ‡ เช† เชฒเซ‡เช– เชฒเช–เชตเชพเชจเซเช‚ เชจเช•เซเช•เซ€ เช•เชฐเซเชฏเซเช‚.

เชธเซ‚เชšเชจเชพเช“: เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชœเชตเชพเชฌเชฆเชพเชฐ เชญเซ‚เชฎเชฟเช•เชพเช“เชจเซเช‚ เชชเชฐเซ€เช•เซเชทเชฃ เช•เชฐเชตเซเช‚ เช…เชจเซ‡ เช‰เชคเซเชชเชพเชฆเชจ เชชเชนเซ‡เชฒเชพเช‚ เชธเชฎเชธเซเชฏเชพเช“ เชตเชฟเชถเซ‡ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชถเซ‹เชงเชตเซเช‚

เช…เชฃเซ

เชชเชฐเชฎเชพเชฃเซ - เชœเชตเชพเชฌเชฆเชพเชฐ เชญเซ‚เชฎเชฟเช•เชพเช“เชจเซเช‚ เชชเชฐเซ€เช•เซเชทเชฃ เช•เชฐเชตเชพเชฎเชพเช‚ เชฎเชฆเชฆ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡เชจเซเช‚ เชฎเชพเชณเช–เซเช‚.

เชธเชฐเชณ เชตเชฐเซเชฃเชจ: เชคเชฎเซ‡ เชธเซเชชเชทเซเชŸ เช•เชฐเซ‹ เช›เซ‹ เชคเซ‡ เชชเซเชฒเซ‡เชŸเชซเซ‹เชฐเซเชฎ เชชเชฐ เชชเชฐเชฎเชพเชฃเซ เชเช• เชฆเชพเช–เชฒเซ‹ เชฌเชจเชพเชตเซ‡ เช›เซ‡ (เช•เซเชฒเชพเช‰เชก, เชตเชฐเซเชšเซเชฏเซเช…เชฒ เชฎเชถเซ€เชจ, เช•เชจเซเชŸเซ‡เชจเชฐ; เชตเชงเซ เชตเชฟเช—เชคเซ‹ เชฎเชพเชŸเซ‡, เชตเชฟเชญเชพเช— เชœเซเช“ เชกเซเชฐเชพเชˆเชตเชฐ), เชคเซ‡เชจเชพ เชชเชฐ เชคเชฎเชพเชฐเซ€ เชญเซ‚เชฎเชฟเช•เชพ เชšเชฒเชพเชตเซ‡ เช›เซ‡, เชชเช›เซ€ เชชเชฐเซ€เช•เซเชทเชฃเซ‹ เชšเชฒเชพเชตเซ‡ เช›เซ‡ เช…เชจเซ‡ เชฆเชพเช–เชฒเชพเชจเซ‡ เช•เชพเชขเซ€ เชจเชพเช–เซ‡ เช›เซ‡. เชเช• เชชเช—เชฒเชพเชฎเชพเช‚ เชจเชฟเชทเซเชซเชณเชคเชพเชจเชพ เช•เชฟเชธเซเชธเชพเชฎเชพเช‚, เช…เชฃเซ เชคเชฎเชจเซ‡ เชคเซ‡เชจเชพ เชตเชฟเชถเซ‡ เชœเชพเชฃ เช•เชฐเชถเซ‡.

เชนเชตเซ‡ เชตเชงเซ.

เชธเชฟเชฆเซเชงเชพเช‚เชค เชเช• เชฌเซ€เชŸ

เชชเชฐเชฎเชพเชฃเซเชจเซ€ เชฌเซ‡ เชฎเซเช–เซเชฏ เชธเช‚เชธเซเชฅเชพเช“เชจเซ‹ เชตเชฟเชšเชพเชฐ เช•เชฐเซ‹: เชฆเซƒเชถเซเชฏ เช…เชจเซ‡ เชกเซเชฐเชพเช‡เชตเชฐ.

เชชเชฐเชฟเชฆเซเชฆเชถเซเชฏ

เชธเซเช•เซเชฐเชฟเชชเซเชŸเชฎเชพเช‚ เชถเซเช‚, เช•เซเชฏเชพเช‚, เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช…เชจเซ‡ เช•เชฏเชพ เช•เซเชฐเชฎเชฎเชพเช‚ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡ เชคเซ‡เชจเซเช‚ เชตเชฐเซเชฃเชจ เช›เซ‡. เชเช• เชญเซ‚เชฎเชฟเช•เชพเชฎเชพเช‚ เช˜เชฃเซ€ เชธเซเช•เซเชฐเชฟเชชเซเชŸเซ‹ เชนเซ‹เชˆ เชถเช•เซ‡ เช›เซ‡, เช…เชจเซ‡ เชฆเชฐเซ‡เช• เชชเชพเชฅ เชธเชพเชฅเซ‡เชจเซ€ เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€ เช›เซ‡ <role>/molecule/<scenario>, เชœเซ‡เชฎเชพเช‚ เชชเชฐเซ€เช•เซเชทเชฃ เชฎเชพเชŸเซ‡ เชœเชฐเซ‚เชฐเซ€ เช•เซเชฐเชฟเชฏเชพเช“เชจเซเช‚ เชตเชฐเซเชฃเชจ เช›เซ‡. เชธเซเช•เซเชฐเชฟเชชเซเชŸ เชถเชพเชฎเซ‡เชฒ เชนเซ‹เชตเซ€ เช†เชตเชถเซเชฏเช• เช›เซ‡ default, เชœเซ‡ เช†เชชเชฎเซ‡เชณเซ‡ เชฌเชจเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡ เชœเซ‹ เชคเชฎเซ‡ เชชเชฐเชฎเชพเชฃเซ เชธเชพเชฅเซ‡ เชญเซ‚เชฎเชฟเช•เชพ เชถเชฐเซ‚ เช•เชฐเซ‹ เช›เซ‹. เชจเซ€เชšเซ‡เชจเซ€ เชธเซเช•เซเชฐเชฟเชชเซเชŸเซ‹เชจเชพ เชจเชพเชฎ เชคเชฎเชพเชฐเชพ เชชเชฐ เช›เซ‡.

เชธเซเช•เซเชฐเชฟเชชเซเชŸเชฎเชพเช‚ เชชเชฐเซ€เช•เซเชทเชฃ เช•เซเชฐเชฟเชฏเชพเช“เชจเซ‹ เช•เซเชฐเชฎ เช•เชนเซ‡เชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ เชฎเซ‡เชŸเซเชฐเชฟเช•เซเชธ, เช…เชจเซ‡ เชฎเซ‚เชณเชญเซ‚เชค เชฐเซ€เชคเซ‡ เชคเซ‡ เช›เซ‡:

(เชชเช—เชฒเชพเช“ เชฒเซ‡เชฌเชฒ เช•เชฐเซ‡เชฒเชพ ?, เชœเซ‹ เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ เชฆเซเชตเชพเชฐเชพ เช‰เชฒเซเชฒเซ‡เช–เชฟเชค เชจ เชนเซ‹เชฏ เชคเซ‹ เชฎเซ‚เชณเชญเซ‚เชค เชฐเซ€เชคเซ‡ เช›เซ‹เชกเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡)

  • lint - เชšเชพเชฒเซ€ เชฐเชนเซ‡เชฒ เชฒเซ€เช‚เชŸเชฐเซเชธ. เชฎเซ‚เชณเชญเซ‚เชค เชฐเซ€เชคเซ‡ เชตเชชเชฐเชพเชฏ เช›เซ‡ yamllint ะธ flake8,
  • destroy - เชชเชฐเชฎเชพเชฃเซเชจเชพ เช›เซ‡เชฒเซเชฒเชพ เชชเซเชฐเช•เซเชทเซ‡เชชเชฃเชฎเชพเช‚เชฅเซ€ เชฆเชพเช–เชฒเชพเช“ เช•เชพเชขเซ€ เชจเชพเช–เชตเซเช‚ (เชœเซ‹ เช•เซ‹เชˆ เชนเซ‹เชฏ เชคเซ‹),
  • dependency? - เชชเชฐเซ€เช•เซเชทเชฃ เช•เชฐเซ‡เชฒ เชญเซ‚เชฎเชฟเช•เชพเชจเซ€ เชœเชตเชพเชฌเชฆเชพเชฐ เชจเชฟเชฐเซเชญเชฐเชคเชพเชจเซ€ เชธเซเชฅเชพเชชเชจเชพ,
  • syntax - เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชญเซ‚เชฎเชฟเช•เชพเชจเซ€ เชตเชพเช•เซเชฏเชฐเชšเชจเชพ เชคเชชเชพเชธเซ‹ ansible-playbook --syntax-check,
  • create - เชเช• เชฆเชพเช–เชฒเซ‹ เชฌเชจเชพเชตเชตเซ‹,
  • prepare? - เชฆเชพเช–เชฒเชพเชจเซ€ เชคเซˆเชฏเชพเชฐเซ€; เชฆเชพ.เชค. python2 เชšเซ‡เช•/เช‡เชจเซเชธเซเชŸเซ‹เชฒ เช•เชฐเซ‹
  • converge - เชชเชฐเซ€เช•เซเชทเชฃ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ€ เชฐเชนเซ‡เชฒเซ€ เชชเซเชฒเซ‡เชฌเซเช•เชจเซเช‚ เชฒเซ‹เชจเซเชšเชฟเช‚เช—,
  • idempotence - เช†เช‡เชกเชฎเซเชชเซ‹เชŸเซ‡เชจเซเชธเซ€ เชŸเซ‡เชธเซเชŸ เชฎเชพเชŸเซ‡ เชชเซเชฒเซ‡เชฌเซเช• เชซเชฐเซ€ เชถเชฐเซ‚ เช•เชฐเซ€ เชฐเชนเซเชฏเชพ เช›เซ€เช,
  • side_effect? - เช•เซเชฐเชฟเชฏเชพเช“ เชธเซ€เชงเซ€ เชญเซ‚เชฎเชฟเช•เชพ เชธเชพเชฅเซ‡ เชธเช‚เชฌเช‚เชงเชฟเชค เชจเชฅเซ€, เชชเชฐเช‚เชคเซ เชชเชฐเซ€เช•เซเชทเชฃเซ‹ เชฎเชพเชŸเซ‡ เชœเชฐเซ‚เชฐเซ€ เช›เซ‡,
  • verify - เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชชเชฐเชฟเชฃเชพเชฎเซ€ เชฐเซ‚เชชเชฐเซ‡เช–เชพเช‚เช•เชจเชจเชพ เชชเชฐเซ€เช•เซเชทเชฃเซ‹ เชšเชพเชฒเซ€ เชฐเชนเซเชฏเชพ เช›เซ‡ testinfra(เชฎเซ‚เชณเชญเซ‚เชค) /goss/inspec,
  • cleanup? - (เชจเชตเชพ เชธเช‚เชธเซเช•เชฐเชฃเซ‹เชฎเชพเช‚) - เช†เชถเชฐเซ‡ เช•เชนเซ€เช เชคเซ‹, เชชเชฐเชฎเชพเชฃเซ เชฆเซเชตเชพเชฐเชพ เช…เชธเชฐเช—เซเชฐเชธเซเชค เชฌเชพเชนเซเชฏ เชฎเชพเชณเช–เชพเชจเซ‡ "เชธเชซเชพเชˆ" เช•เชฐเชตเซ€,
  • destroy - เชเช• เชฆเชพเช–เชฒเซ‹ เช•เชพเชขเซ€ เชจเชพเช–เชตเซเช‚.

เช† เช•เซเชฐเชฎ เชฎเซ‹เชŸเชพเชญเชพเช—เชจเชพ เช•เซ‡เชธเซ‹เชจเซ‡ เช†เชตเชฐเซ€ เชฒเซ‡ เช›เซ‡, เชชเชฐเช‚เชคเซ เชœเซ‹ เชœเชฐเซ‚เชฐเซ€ เชนเซ‹เชฏ เชคเซ‹ เชฌเชฆเชฒเซ€ เชถเช•เชพเชฏ เช›เซ‡.

เช‰เชชเชฐเซ‹เช•เซเชค เชฆเชฐเซ‡เช• เชชเช—เชฒเชพเช‚ เชธเชพเชฅเซ‡ เช…เชฒเช—เชฅเซ€ เชšเชฒเชพเชตเซ€ เชถเช•เชพเชฏ เช›เซ‡ molecule <command>. เชชเชฐเช‚เชคเซ เชคเซ‡ เชธเชฎเชœเชตเซเช‚ เชœเซ‹เชˆเช เช•เซ‡ เช†เชตเชพ เชฆเชฐเซ‡เช• เช•เซเชฒเชฟ-เช•เชฎเชพเชจเซเชก เชฎเชพเชŸเซ‡ เช•เซเชฐเชฟเชฏเชพเช“เชจเซ‹ เชชเซ‹เชคเชพเชจเซ‹ เช•เซเชฐเชฎ เชนเซ‹เชˆ เชถเช•เซ‡ เช›เซ‡, เชœเซ‡ เชคเชฎเซ‡ เชเช•เซเชเซ‡เช•เซเชฏเซเชŸ เช•เชฐเซ€เชจเซ‡ เชถเซ‹เชงเซ€ เชถเช•เซ‹ เช›เซ‹. molecule matrix <command>. เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เช†เชฆเซ‡เชถ เชšเชฒเชพเชตเชคเซ€ เชตเช–เชคเซ‡ converge (เชชเชฐเซ€เช•เซเชทเชฃ เชนเซ‡เช เชณ เชชเซเชฒเซ‡เชฌเซเช• เชšเชฒเชพเชตเชตเซเช‚), เชจเซ€เชšเซ‡เชจเซ€ เช•เซเชฐเชฟเชฏเชพเช“ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡:

$ molecule matrix converge
...
โ””โ”€โ”€ default         # ะฝะฐะทะฒะฐะฝะธะต ัั†ะตะฝะฐั€ะธั
    โ”œโ”€โ”€ dependency  # ัƒัั‚ะฐะฝะพะฒะบะฐ ะทะฐะฒะธัะธะผะพัั‚ะตะน
    โ”œโ”€โ”€ create      # ัะพะทะดะฐะฝะธะต ะธะฝัั‚ะฐะฝัะฐ
    โ”œโ”€โ”€ prepare     # ะฟั€ะตะดะฝะฐัั‚ั€ะพะนะบะฐ ะธะฝัั‚ะฐะฝัะฐ
    โ””โ”€โ”€ converge    # ะฟั€ะพะณะพะฝ ะฟะปะตะนะฑัƒะบะฐ

เช† เช•เซเชฐเชฟเชฏเชพเช“เชจเซ‹ เช•เซเชฐเชฎ เชธเช‚เชชเชพเชฆเชฟเชค เช•เชฐเซ€ เชถเช•เชพเชฏ เช›เซ‡. เชœเซ‹ เชธเซ‚เชšเชฟเชฎเชพเช‚เชฅเซ€ เช•เช‚เชˆเช• เชชเชนเซ‡เชฒเซ‡เชฅเซ€ เชœ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซเช‚ เชนเซ‹เชฏ, เชคเซ‹ เชคเซ‡ เช›เซ‹เชกเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡. เชตเชฐเซเชคเชฎเชพเชจ เชธเซเชฅเชฟเชคเชฟ, เชคเซ‡เชฎเชœ เช‰เชฆเชพเชนเชฐเชฃเซ‹เชจเซ€ เชฐเซ‚เชชเชฐเซ‡เช–เชพ, เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€เชฎเชพเช‚ เชชเชฐเชฎเชพเชฃเซ เชธเซเชŸเซ‹เชฐ เช•เชฐเซ‡ เช›เซ‡ $TMPDIR/molecule/<role>/<scenario>.

เชธเชพเชฅเซ‡ เชชเช—เชฒเชพเช‚เช“ เช‰เชฎเซ‡เชฐเซ‹ ? เชคเชฎเซ‡ เชœเชตเชพเชฌเซ€-เชชเซเชฒเซ‡เชฌเซเช• เชซเซ‹เชฐเซเชฎเซ‡เชŸเชฎเชพเช‚ เช‡เชšเซเช›เชฟเชค เช•เซเชฐเชฟเชฏเชพเช“เชจเซเช‚ เชตเชฐเซเชฃเชจ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹ เช…เชจเซ‡ เชธเซเชŸเซ‡เชช เชชเซเชฐเชฎเชพเชฃเซ‡ เชซเชพเช‡เชฒเชจเซเช‚ เชจเชพเชฎ เชฌเชจเชพเชตเซ€ เชถเช•เซ‹ เช›เซ‹: prepare.yml/side_effect.yml. เช† เชซเชพเช‡เชฒเซ‹เชจเซ€ เช…เชชเซ‡เช•เซเชทเชพ เชฐเชพเช–เซ‹ เช† เชชเชฐเชฎเชพเชฃเซ เชธเซเช•เซเชฐเชฟเชชเซเชŸ เชซเซ‹เชฒเซเชกเชฐเชฎเชพเช‚ เชนเชถเซ‡.

เชกเซเชฐเชพเชˆเชตเชฐ

เชกเซเชฐเชพเช‡เชตเชฐ เช เชเช• เชเชตเซ€ เชเชจเซเชŸเชฟเชŸเซ€ เช›เซ‡ เชœเซเชฏเชพเช‚ เชชเชฐเซ€เช•เซเชทเชฃ เชฆเชพเช–เชฒเชพเช“ เชฌเชจเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡.
เชชเซเชฐเชฎเชพเชฃเชญเซ‚เชค เชกเซเชฐเชพเช‡เชตเชฐเซ‹เชจเซ€ เชธเซ‚เชšเชฟ เช•เซ‡ เชœเซ‡เชจเชพ เชฎเชพเชŸเซ‡ เชฎเซ‹เชฒเซ‡เช•เซเชฏเซเชฒ เชชเชพเชธเซ‡ เชจเชฎเซ‚เชจเชพเช“ เชคเซˆเชฏเชพเชฐ เช›เซ‡ เชคเซ‡ เชจเซ€เชšเซ‡ เชฎเซเชœเชฌ เช›เซ‡: Azure, Docker, EC2, GCE, LXC, LXD, OpenStack, Vagrant, Delegated.

เชฎเซ‹เชŸเชพ เชญเชพเช—เชจเชพ เช•เชฟเชธเซเชธเชพเช“เชฎเชพเช‚, เชจเชฎเซ‚เชจเชพเช“ เชซเชพเช‡เชฒเซ‹ เช›เซ‡ create.yml ะธ destroy.yml เชธเซเช•เซเชฐเชฟเชชเซเชŸ เชซเซ‹เชฒเซเชกเชฐเชฎเชพเช‚ เช•เซ‡ เชœเซ‡ เช…เชจเซเช•เซเชฐเชฎเซ‡ เชฆเชพเช–เชฒเชพ เชฌเชจเชพเชตเชตเชพ เช…เชจเซ‡ เช•เชพเชขเซ€ เชจเชพเช–เชตเชพเชจเซเช‚ เชตเชฐเซเชฃเชจ เช•เชฐเซ‡ เช›เซ‡.
เช…เชชเชตเชพเชฆเซ‹ เชกเซ‹เช•เชฐ เช…เชจเซ‡ เชตเซ‡เช—เซเชฐเชจเซเชŸ เช›เซ‡, เช•เชพเชฐเชฃ เช•เซ‡ เชคเซ‡เชฎเชจเชพ เชฎเซ‹เชกเซเชฏเซเชฒเซ‹ เชธเชพเชฅเซ‡เชจเซ€ เช•เซเชฐเชฟเชฏเชพเชชเซเชฐเชคเชฟเช•เซเชฐเชฟเชฏเชพเช“ เช‰เชชเชฐเซ‹เช•เซเชค เชซเชพเช‡เชฒเซ‹ เชตเชฟเชจเชพ เชฅเชˆ เชถเช•เซ‡ เช›เซ‡.

เชกเซ‡เชฒเชฟเช—เซ‡เชŸเซ‡เชก เชกเซเชฐเชพเช‡เชตเชฐเชจเซ‡ เชนเชพเช‡เชฒเชพเช‡เชŸ เช•เชฐเชตเชพ เชฏเซ‹เช—เซเชฏ เช›เซ‡, เช•เชพเชฐเชฃ เช•เซ‡ เชœเซ‹ เชคเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— เชซเชพเช‡เชฒเซ‹เชฎเชพเช‚ เชฆเชพเช–เชฒเชพ เชฌเชจเชพเชตเชตเชพ เช…เชจเซ‡ เช•เชพเชขเซ€ เชจเชพเช–เชตเชพ เชฎเชพเชŸเซ‡ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡, เชคเซ‹ เชซเช•เซเชค เชฆเชพเช–เชฒเชพเช“เชจเชพ เชฐเซ‚เชชเชฐเซ‡เช–เชพเช‚เช•เชจ เชธเชพเชฅเซ‡ เชœ เช•เชพเชฐเซเชฏ เชตเชฐเซเชฃเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡, เชฌเชพเช•เซ€เชจเซเช‚ เชเชจเซเชœเชฟเชจเชฟเชฏเชฐ เชฆเซเชตเชพเชฐเชพ เชตเชฐเซเชฃเชจ เช•เชฐเชตเซเช‚ เชœเซ‹เชˆเช.

เชฎเซ‚เชณเชญเซ‚เชค เชกเซเชฐเชพเชˆเชตเชฐ เชกเซ‹เช•เชฐ เช›เซ‡.

เชนเชตเซ‡ เชšเชพเชฒเซ‹ เชชเซเชฐเซ‡เช•เซเชŸเชฟเชธ เชคเชฐเชซ เช†เช—เชณ เชตเชงเซ€เช เช…เชจเซ‡ เชคเซเชฏเชพเช‚เชจเซ€ เชตเชงเซ เชธเซเชตเชฟเชงเชพเช“ เชงเซเชฏเชพเชจเชฎเชพเช‚ เชฒเชˆเช.

เชชเซเชฐเชพเชฐเช‚เชญ

"เชนเซ‡เชฒเซ‹ เชตเชฐเซเชฒเซเชก" เชคเชฐเซ€เช•เซ‡, เชšเชพเชฒเซ‹ เชเช• เชธเชฐเชณ nginx เช‡เชจเซเชธเซเชŸเซ‹เชฒเซ‡เชถเชจ เชฐเซ‹เชฒเชจเซเช‚ เชชเชฐเซ€เช•เซเชทเชฃ เช•เชฐเซ€เช. เชšเชพเชฒเซ‹ เชกเซ‹เช•เชฐเชจเซ‡ เชกเซเชฐเชพเชˆเชตเชฐ เชคเชฐเซ€เช•เซ‡ เชชเชธเช‚เชฆ เช•เชฐเซ€เช - เชฎเชจเซ‡ เชฒเชพเช—เซ‡ เช›เซ‡ เช•เซ‡ เชคเชฎเชพเชฐเชพเชฎเชพเช‚เชฅเซ€ เชฎเซ‹เชŸเชพเชญเชพเช—เชจเชพ เชฒเซ‹เช•เซ‹เช เชคเซ‡เชจเซ‡ เชˆเชจเซเชธเซเชŸเซ‹เชฒ เช•เชฐเซเชฏเซเช‚ เช›เซ‡ (เช…เชจเซ‡ เชฏเชพเชฆ เชฐเชพเช–เซ‹ เช•เซ‡ เชกเซ‹เช•เชฐ เช เชกเชฟเชซเซ‹เชฒเซเชŸ เชกเซเชฐเชพเชˆเชตเชฐ เช›เซ‡).

เชšเชพเชฒเซ‹ เชคเซˆเชฏเชพเชฐเซ€ เช•เชฐเซ€เช virtualenv เช…เชจเซ‡ เชคเซ‡เชฎเชพเช‚ เช‡เชจเซเชธเซเชŸเซ‹เชฒ เช•เชฐเซ‹ molecule:

> pip install virtualenv
> virtualenv -p `which python2` venv
> source venv/bin/activate
> pip install molecule docker  # molecule ัƒัั‚ะฐะฝะพะฒะธั‚ ansible ะบะฐะบ ะทะฐะฒะธัะธะผะพัั‚ัŒ; docker ะดะปั ะดั€ะฐะนะฒะตั€ะฐ

เช†เช—เชณเชจเซเช‚ เชชเช—เชฒเซเช‚ เชจเชตเซ€ เชญเซ‚เชฎเชฟเช•เชพเชจเซ€ เชถเชฐเซ‚เช†เชค เช•เชฐเชตเชพเชจเซเช‚ เช›เซ‡.
เช†เชฆเซ‡เชถเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชจเชตเซ€ เชญเซ‚เชฎเชฟเช•เชพ, เชคเซ‡เชฎเชœ เชจเชตเซ€ เชธเซเช•เซเชฐเชฟเชชเซเชŸเชจเซ€ เชถเชฐเซ‚เช†เชค เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ molecule init <params>:

> molecule init role -r nginx
--> Initializing new role nginx...
Initialized role in <path>/nginx successfully.
> cd nginx
> tree -L 1
.
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ defaults
โ”œโ”€โ”€ handlers
โ”œโ”€โ”€ meta
โ”œโ”€โ”€ molecule
โ”œโ”€โ”€ tasks
โ””โ”€โ”€ vars

6 directories, 1 file

เชคเซ‡ เชเช• เชฒเชพเช•เซเชทเชฃเชฟเช• เชœเชตเชพเชฌเซ€ เชญเซ‚เชฎเชฟเช•เชพ เชฌเชนเชพเชฐ เช†เชตเซเชฏเซเช‚. เช†เช—เชณ, CLI เช…เชฃเซเช“ เชธเชพเชฅเซ‡เชจเซ€ เชคเชฎเชพเชฎ เช•เซเชฐเชฟเชฏเชพเชชเซเชฐเชคเชฟเช•เซเชฐเชฟเชฏเชพเช“ เชญเซ‚เชฎเชฟเช•เชพเชจเชพ เชฎเซ‚เชณเชฎเชพเช‚เชฅเซ€ เชฌเชจเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡.

เชšเชพเชฒเซ‹ เชœเซ‹เชˆเช เช•เซ‡ เชฐเซ‹เชฒ เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€เชฎเชพเช‚ เชถเซเช‚ เช›เซ‡:

> tree molecule/default/
molecule/default/
โ”œโ”€โ”€ Dockerfile.j2  # Jinja-ัˆะฐะฑะปะพะฝ ะดะปั Dockerfile
โ”œโ”€โ”€ INSTALL.rst.   # ะะตะผะฝะพะณะพ ะธะฝั„ะพั€ะผะฐั†ะธะธ ะพะฑ ัƒัั‚ะฐะฝะพะฒะบะต ะทะฐะฒะธัะธะผะพัั‚ะตะน ัั†ะตะฝะฐั€ะธั
โ”œโ”€โ”€ molecule.yml   # ะคะฐะนะป ะบะพะฝั„ะธะณัƒั€ะฐั†ะธะธ
โ”œโ”€โ”€ playbook.yml   # ะŸะปะตะนะฑัƒะบ ะทะฐะฟัƒัะบะฐ ั€ะพะปะธ
โ””โ”€โ”€ tests          # ะ”ะธั€ะตะบั‚ะพั€ะธั ั ั‚ะตัั‚ะฐะผะธ ัั‚ะฐะดะธะธ verify
    โ””โ”€โ”€ test_default.py

1 directory, 6 files

เชšเชพเชฒเซ‹ เชฐเซ‚เชชเชฐเซ‡เช–เชพเชจเซเช‚ เชตเชฟเชถเซเชฒเซ‡เชทเชฃ เช•เชฐเซ€เช molecule/default/molecule.yml (เชฎเชพเชคเซเชฐ เชกเซ‹เช•เชฐ เช›เชฌเซ€ เชฌเชฆเชฒเซ‹):

---
dependency:
  name: galaxy
driver:
  name: docker
lint:
  name: yamllint
platforms:
  - name: instance
    image: centos:7
provisioner:
  name: ansible
  lint:
    name: ansible-lint
scenario:
  name: default
verifier:
  name: testinfra
  lint:
    name: flake8

เช…เชตเชฒเช‚เชฌเชจ

เช† เชตเชฟเชญเชพเช— เชจเชฟเชฐเซเชญเชฐเชคเชพเชจเชพ เชธเซเชคเซเชฐเซ‹เชคเชจเซเช‚ เชตเชฐเซเชฃเชจ เช•เชฐเซ‡ เช›เซ‡.

เชธเช‚เชญเชตเชฟเชค เชตเชฟเช•เชฒเซเชชเซ‹: เช†เช•เชพเชถเช—เช‚เช—เชพ, เชฒเชพเช—เซ เชชเชกเซ‡ เช›เซ‡, เชถเซ‡เชฒ.

เชถเซ‡เชฒ เช เชซเช•เซเชค เชเช• เช•เชฎเชพเชจเซเชก เชถเซ‡เชฒ เช›เซ‡ เชœเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช—เซ‡เชฒเซ‡เช•เซเชธเซ€ เช…เชจเซ‡ เช—เชฟเชฒเซเชŸ เชคเชฎเชพเชฐเซ€ เชœเชฐเซ‚เชฐเชฟเชฏเชพเชคเซ‹เชจเซ‡ เช†เชตเชฐเซ€ เชฒเซ‡เชคเชพ เชจเชฅเซ€ เชคเซ‡เชตเชพ เช•เชฟเชธเซเชธเชพเชฎเชพเช‚ เชฅเชพเชฏ เช›เซ‡.

เชนเซเช‚ เช…เชนเซ€เช‚ เชฒเชพเช‚เชฌเชพ เชธเชฎเชฏ เชธเซเชงเซ€ เชฐเชนเซ€เชถ เชจเชนเซ€เช‚, เชคเซ‡ เชชเซ‚เชฐเชคเซเช‚ เชตเชฐเซเชฃเชตเซ‡เชฒ เช›เซ‡ เชฆเชธเซเชคเชพเชตเซ‡เชœเซ€เช•เชฐเชฃ.

เชกเซเชฐเชพเชˆเชตเชฐ

เชกเซเชฐเชพเช‡เชตเชฐเชจเซเช‚ เชจเชพเชฎ. เช…เชฎเชพเชฐเซเช‚ เชกเซ‹เช•เชฐ เช›เซ‡.

เชฒเชฟเชจเซเชŸ

เชฒเชฟเช‚เชŸเชฐ เชเชŸเชฒเซ‡ เชฏเชฎเชฒเชฟเช‚เชŸ.

เชฐเซ‚เชชเชฐเซ‡เช–เชพเชจเชพ เช† เชญเชพเช—เชฎเชพเช‚ เช‰เชชเชฏเซ‹เช—เซ€ เชตเชฟเช•เชฒเซเชชเซ‹ yamllint เชฎเชพเชŸเซ‡ เชฐเซ‚เชชเชฐเซ‡เช–เชพเช‚เช•เชจ เชซเชพเชˆเชฒเชจเซ‹ เช‰เชฒเซเชฒเซ‡เช– เช•เชฐเชตเชพเชจเซ€ เช•เซเชทเชฎเชคเชพ เช›เซ‡, เชชเชฐเซเชฏเชพเชตเชฐเชฃ เชšเชฒเซ‹เชจเซ‡ เช†เช—เชณ เชงเชชเชพเชตเชตเชพเชจเซ€ เช…เชฅเชตเชพ linter เชจเซ‡ เชจเชฟเชทเซเช•เซเชฐเชฟเชฏ เช•เชฐเชตเชพเชจเซ€ เช•เซเชทเชฎเชคเชพ เช›เซ‡:

lint:
  name: yamllint
  options:
    config-file: foo/bar
  env:
    FOO: bar
  enabled: False

เชชเซเชฒเซ‡เชŸเชซเซ‹เชฐเซเชฎ

เชฆเชพเช–เชฒเชพเช“เชจเชพ เชฐเซ‚เชชเชฐเซ‡เช–เชพเช‚เช•เชจเชจเซเช‚ เชตเชฐเซเชฃเชจ เช•เชฐเซ‡ เช›เซ‡.
เชกเซเชฐเชพเช‡เชตเชฐ เชคเชฐเซ€เช•เซ‡ เชกเซ‹เช•เชฐเชจเชพ เช•เชฟเชธเซเชธเชพเชฎเชพเช‚, เชชเชฐเชฎเชพเชฃเซ เช† เชตเชฟเชญเชพเช— เชชเชฐ เชชเซเชจเชฐเชพเชตเชฐเซเชคเชฟเชค เชฅเชพเชฏ เช›เซ‡, เช…เชจเซ‡ เชธเซ‚เชšเชฟเชจเซเช‚ เชฆเชฐเซ‡เช• เชคเชคเซเชต เช‰เชชเชฒเชฌเซเชง เช›เซ‡ Dockerfile.j2 เชšเชฒ เชคเชฐเซ€เช•เซ‡ item.

เชกเซเชฐเชพเช‡เชตเชฐเชจเชพ เช•เชฟเชธเซเชธเชพเชฎเชพเช‚ เชœเซ‡ เชœเชฐเซ‚เชฐเซ€ เช›เซ‡ create.yml ะธ destroy.yml, เชตเชฟเชญเชพเช— เชคเซ‡เชฎเชจเชพเชฎเชพเช‚ เช‰เชชเชฒเชฌเซเชง เช›เซ‡ molecule_yml.platforms, เช…เชจเซ‡ เชคเซ‡เชจเชพ เชชเชฐ เชชเซเชจเชฐเชพเชตเซƒเชคเซเชคเชฟเช“ เชชเชนเซ‡เชฒเซ‡เชฅเซ€ เชœ เช† เชซเชพเช‡เชฒเซ‹เชฎเชพเช‚ เชตเชฐเซเชฃเชตเซ‡เชฒ เช›เซ‡.

เช•เชพเชฐเชฃ เช•เซ‡ เชชเชฐเชฎเชพเชฃเซ เชชเซเชฐเชคเชฟเชญเชพเชตเชถเซ€เชฒ เชฎเซ‹เชกเซเชฏเซเชฒเซ‹เชจเซ‡ เช‰เชฆเชพเชนเชฐเชฃเซ‹เชจเซเช‚ เชจเชฟเชฏเช‚เชคเซเชฐเชฃ เชชเซ‚เชฐเซเช‚ เชชเชพเชกเซ‡ เช›เซ‡, เชธเช‚เชญเชตเชฟเชค เชธเซ‡เชŸเชฟเช‚เช—เซเชธเชจเซ€ เชธเซ‚เชšเชฟ เชชเชฃ เชคเซเชฏเชพเช‚ เชœเซ‹เชตเซ€ เชœเซ‹เชˆเช. เชกเซ‹เช•เชฐ เชฎเชพเชŸเซ‡, เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เชฎเซ‹เชกเซเชฏเซเชฒเชจเซ‹ เช‰เชชเชฏเซ‹เช— เชฅเชพเชฏ เช›เซ‡ docker_container_module. เช…เชจเซเชฏ เชกเซเชฐเชพเช‡เชตเชฐเซ‹เชฎเชพเช‚ เช•เชฏเชพ เชฎเซ‹เชกเซเชฏเซเชฒเซ‹เชจเซ‹ เช‰เชชเชฏเซ‹เช— เชฅเชพเชฏ เช›เซ‡ เชคเซ‡ เชถเซ‹เชงเซ€ เชถเช•เชพเชฏ เช›เซ‡ เชฆเชธเซเชคเชพเชตเซ‡เชœเซ€เช•เชฐเชฃ.

เชคเซ‡เชฎเชœ เชตเชฟเชตเชฟเชง เชกเซเชฐเชพเช‡เชตเชฐเซ‹เชจเชพ เช‰เชชเชฏเซ‹เช—เชจเชพ เช‰เชฆเชพเชนเชฐเชฃเซ‹ เชฎเชณเซ€ เชถเช•เซ‡ เช›เซ‡ เชชเชฐเชฎเชพเชฃเซเชจเชพ เชœ เชชเชฐเซ€เช•เซเชทเชฃเซ‹เชฎเชพเช‚.

เช…เชนเซ€เช‚ เชฌเชฆเชฒเซ‹ centos:7 เชชเชฐ เช‰เชฌเซเชจเซเชŸเซ.

เชœเซ‹เช—เชตเชพเชˆ เช•เชฐเชจเชพเชฐ

"เชธเชชเซเชฒเชพเชฏเชฐ" - เชเช• เชเชจเซเชŸเชฟเชŸเซ€ เชœเซ‡ เชฆเชพเช–เชฒเชพเช“เชจเซเช‚ เชธเช‚เชšเชพเชฒเชจ เช•เชฐเซ‡ เช›เซ‡. เชชเชฐเชฎเชพเชฃเซเชจเชพ เช•เชฟเชธเซเชธเชพเชฎเชพเช‚, เช† เชœเชตเชพเชฌเชฆเชพเชฐ เช›เซ‡, เช…เชจเซเชฏ เชฒเซ‹เช•เซ‹ เชฎเชพเชŸเซ‡ เชธเชฎเชฐเซเชฅเชจเชจเซเช‚ เช†เชฏเซ‹เชœเชจ เชจเชฅเซ€, เชคเซ‡เชฅเซ€ เช† เชตเชฟเชญเชพเช—เชจเซ‡ เชšเซ‡เชคเชตเชฃเซ€ เชธเชพเชฅเซ‡ เชœเชตเชพเชฌเชฆเชพเชฐ เชตเชฟเชธเซเชคเซƒเชค เชฐเซ‚เชชเชฐเซ‡เช–เชพเช‚เช•เชจ เช•เชนเซ€ เชถเช•เชพเชฏ.
เช…เชนเซ€เช‚ เชคเชฎเซ‡ เช˜เชฃเซ€ เชฌเชงเซ€ เชตเชธเซเชคเซเช“เชจเซ‹ เช‰เชฒเซเชฒเซ‡เช– เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹, เชนเซเช‚ เชฎเชพเชฐเชพ เชฎเชคเซ‡ เชฎเซเช–เซเชฏ เชฎเซเชฆเซเชฆเชพเช“เชจเซ‡ เชชเซเชฐเช•เชพเชถเชฟเชค เช•เชฐเซ€เชถ:

  • เชชเซเชฒเซ‡เชฌเซเช•เซเชธ: เชคเชฎเซ‡ เชšเซ‹เช•เซเช•เชธ เชคเชฌเช•เซเช•เชพเชฎเชพเช‚ เช•เชˆ เชชเซเชฒเซ‡เชฌเซเช•เชจเซ‹ เช‰เชชเชฏเซ‹เช— เชฅเชตเซ‹ เชœเซ‹เชˆเช เชคเซ‡ เชธเซเชชเชทเซเชŸ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹.

provisioner:
  name: ansible
  playbooks:
    create: create.yml
    destroy: ../default/destroy.yml
    converge: playbook.yml
    side_effect: side_effect.yml
    cleanup: cleanup.yml

provisioner:
  name: ansible
  config_options:
    defaults:
      fact_caching: jsonfile
    ssh_connection:
      scp_if_ssh: True

provisioner:
  name: ansible  
  connection_options:
    ansible_ssh_common_args: "-o 'UserKnownHostsFile=/dev/null' -o 'ForwardAgent=yes'"

  • เชตเชฟเช•เชฒเซเชชเซ‹: เชœเชตเชพเชฌ เช†เชชเชตเชพ เชฏเซ‹เช—เซเชฏ เชตเชฟเช•เชฒเซเชชเซ‹ เช…เชจเซ‡ เชชเชฐเซเชฏเชพเชตเชฐเชฃ เชšเชฒเซ‹

provisioner:
  name: ansible  
  options:
    vvv: true
    diff: true
  env:
    FOO: BAR

เชฆเซƒเชถเซเชฏ

เชธเซเช•เซเชฐเชฟเชชเซเชŸ เชธเชฟเช•เซเชตเชจเซเชธเชจเซเช‚ เชจเชพเชฎ เช…เชจเซ‡ เชตเชฐเซเชฃเชจ.
เชคเชฎเซ‡ เช•เซ€ เช‰เชฎเซ‡เชฐเซ€เชจเซ‡ เช•เซ‹เชˆเชชเชฃ เช†เชฆเซ‡เชถเชจเชพ เชกเชฟเชซเซ‹เชฒเซเชŸ เชเช•เซเชถเชจ เชฎเซ‡เชŸเซเชฐเชฟเช•เซเชธเชจเซ‡ เชฌเชฆเชฒเซ€ เชถเช•เซ‹ เช›เซ‹ <command>_sequence เช…เชจเซ‡ เช…เชฎเชจเซ‡ เชœเชฐเซ‚เชฐเซ€ เชชเช—เชฒเชพเช‚เช“เชจเซ€ เชธเซ‚เชšเชฟเชจเซ‡ เชตเซเชฏเชพเช–เซเชฏเชพเชฏเชฟเชค เช•เชฐเซ€เชจเซ‡ เชคเซ‡เชจเชพ เชฎเซ‚เชฒเซเชฏ เชคเชฐเซ€เช•เซ‡.
เชšเชพเชฒเซ‹ เช•เชนเซ€เช เช•เซ‡ เชชเซเชฒเซ‡เชฌเซเช• เชฐเชจ เช•เชฎเชพเชจเซเชก เชšเชฒเชพเชตเชคเซ€ เชตเช–เชคเซ‡ เช†เชชเชฃเซ‡ เช•เซเชฐเชฟเชฏเชพเช“เชจเซ‹ เช•เซเชฐเชฎ เชฌเชฆเชฒเชตเชพ เชฎเชพเช‚เช—เซ€เช เช›เซ€เช: molecule converge

# ะธะทะฝะฐั‡ะฐะปัŒะฝะพ:
# - dependency
# - create
# - prepare
# - converge
scenario:
  name: default
  converge_sequence:
    - create
    - converge

เชšเช•เชพเชธเชฃเซ€ เช•เชฐเชจเชพเชฐ

เชชเชฐเซ€เช•เซเชทเชฃเซ‹ เชฎเชพเชŸเซ‡ เชเช• เชฎเชพเชณเช–เซเช‚ เช…เชจเซ‡ เชคเซ‡เชจเชพ เชฎเชพเชŸเซ‡ เชเช• เชฒเชฟเช‚เชŸเชฐ เชธเซ‡เชŸ เช•เชฐเชตเซเช‚. เชกเชฟเชซเซ‰เชฒเซเชŸ เชฒเชฟเช‚เชŸเชฐ เช›เซ‡ testinfra ะธ flake8. เชธเช‚เชญเชตเชฟเชค เชตเชฟเช•เชฒเซเชชเซ‹ เช‰เชชเชฐเซ‹เช•เซเชค เชธเชฎเชพเชจ เช›เซ‡:

verifier:
  name: testinfra
  additional_files_or_dirs:
    - ../path/to/test_1.py
    - ../path/to/test_2.py
    - ../path/to/directory/*
  options:
    n: 1
  enabled: False
  env:
    FOO: bar
  lint:
    name: flake8
    options:
      benchmark: True
    enabled: False
    env:
      FOO: bar

เชšเชพเชฒเซ‹ เช†เชชเชฃเซ€ เชญเซ‚เชฎเชฟเช•เชพ เชชเชฐ เชชเชพเช›เชพ เชซเชฐเซ€เช. เชšเชพเชฒเซ‹ เชซเชพเชˆเชฒ เชเชกเชฟเชŸ เช•เชฐเซ€เช tasks/main.yml เช† เชชเซเชฐเช•เชพเชฐ เชฎเชพเชŸเซ‡:

---
- name: Install nginx
  apt:
    name: nginx
    state: present

- name: Start nginx
  service:
    name: nginx
    state: started

เช…เชจเซ‡ เชคเซ‡เชฎเชพเช‚ เชชเชฐเซ€เช•เซเชทเชฃเซ‹ เช‰เชฎเซ‡เชฐเซ‹ molecule/default/tests/test_default.py

def test_nginx_is_installed(host):
    nginx = host.package("nginx")
    assert nginx.is_installed

def test_nginx_running_and_enabled(host):
    nginx = host.service("nginx")
    assert nginx.is_running
    assert nginx.is_enabled

def test_nginx_config(host):
    host.run("nginx -t")

เชฅเชˆ เช—เชฏเซเช‚, เชคเซ‡ เชฎเชพเชคเซเชฐ เชšเชฒเชพเชตเชตเชพ เชฎเชพเชŸเซ‡ เชœ เชฐเชนเซ‡ เช›เซ‡ (เชญเซ‚เชฎเชฟเช•เชพเชจเชพ เชฎเซ‚เชณเชฎเชพเช‚เชฅเซ€, เชนเซเช‚ เชคเชฎเชจเซ‡ เชฏเชพเชฆ เช•เชฐเชพเชตเซเช‚ เช›เซเช‚):

> molecule test

เชธเซเชชเซ‹เช‡เชฒเชฐ เชนเซ‡เช เชณ เชฒเชพเช‚เชฌเซ€ เชเช•เซเชเซ‹เชธเซเชŸ:

--> Validating schema <path>/nginx/molecule/default/molecule.yml.
Validation completed successfully.
--> Test matrix

โ””โ”€โ”€ default
    โ”œโ”€โ”€ lint
    โ”œโ”€โ”€ destroy
    โ”œโ”€โ”€ dependency
    โ”œโ”€โ”€ syntax
    โ”œโ”€โ”€ create
    โ”œโ”€โ”€ prepare
    โ”œโ”€โ”€ converge
    โ”œโ”€โ”€ idempotence
    โ”œโ”€โ”€ side_effect
    โ”œโ”€โ”€ verify
    โ””โ”€โ”€ destroy

--> Scenario: 'default'
--> Action: 'lint'
--> Executing Yamllint on files found in <path>/nginx/...
Lint completed successfully.
--> Executing Flake8 on files found in <path>/nginx/molecule/default/tests/...
Lint completed successfully.
--> Executing Ansible Lint on <path>/nginx/molecule/default/playbook.yml...
Lint completed successfully.
--> Scenario: 'default'
--> Action: 'destroy'

    PLAY [Destroy] *****************************************************************

    TASK [Destroy molecule instance(s)] ********************************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Wait for instance(s) deletion to complete] *******************************
    ok: [localhost] => (item=None)
    ok: [localhost]

    TASK [Delete docker network(s)] ************************************************

    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0

--> Scenario: 'default'
--> Action: 'dependency'
Skipping, missing the requirements file.
--> Scenario: 'default'
--> Action: 'syntax'

    playbook: <path>/nginx/molecule/default/playbook.yml

--> Scenario: 'default'
--> Action: 'create'

    PLAY [Create] ******************************************************************

    TASK [Log into a Docker registry] **********************************************
    skipping: [localhost] => (item=None)

    TASK [Create Dockerfiles from image names] *************************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Discover local Docker images] ********************************************
    ok: [localhost] => (item=None)
    ok: [localhost]

    TASK [Build an Ansible compatible image] ***************************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Create docker network(s)] ************************************************

    TASK [Create molecule instance(s)] *********************************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Wait for instance(s) creation to complete] *******************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    PLAY RECAP *********************************************************************
    localhost                  : ok=5    changed=4    unreachable=0    failed=0

--> Scenario: 'default'
--> Action: 'prepare'
Skipping, prepare playbook not configured.
--> Scenario: 'default'
--> Action: 'converge'

    PLAY [Converge] ****************************************************************

    TASK [Gathering Facts] *********************************************************
    ok: [instance]

    TASK [nginx : Install nginx] ***************************************************
    changed: [instance]

    TASK [nginx : Start nginx] *****************************************************
    changed: [instance]

    PLAY RECAP *********************************************************************
    instance                   : ok=3    changed=2    unreachable=0    failed=0

--> Scenario: 'default'
--> Action: 'idempotence'
Idempotence completed successfully.
--> Scenario: 'default'
--> Action: 'side_effect'
Skipping, side effect playbook not configured.
--> Scenario: 'default'
--> Action: 'verify'
--> Executing Testinfra tests found in <path>/nginx/molecule/default/tests/...
    ============================= test session starts ==============================
    platform darwin -- Python 2.7.15, pytest-4.3.0, py-1.8.0, pluggy-0.9.0
    rootdir: <path>/nginx/molecule/default, inifile:
    plugins: testinfra-1.16.0
collected 4 items

    tests/test_default.py ....                                               [100%]

    ========================== 4 passed in 27.23 seconds ===========================
Verifier completed successfully.
--> Scenario: 'default'
--> Action: 'destroy'

    PLAY [Destroy] *****************************************************************

    TASK [Destroy molecule instance(s)] ********************************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Wait for instance(s) deletion to complete] *******************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Delete docker network(s)] ************************************************

    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=2    unreachable=0    failed=0

เช…เชฎเชพเชฐเซ€ เชธเชฐเชณ เชญเซ‚เชฎเชฟเช•เชพเชจเซเช‚ เชชเชฐเซ€เช•เซเชทเชฃ เชธเชฎเชธเซเชฏเชพเช“ เชตเชฟเชจเชพ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซเช‚ เชนเชคเซเช‚.
เชคเซ‡ เชฏเชพเชฆ เชฐเชพเช–เชตเซเช‚ เชฏเซ‹เช—เซเชฏ เช›เซ‡ เช•เซ‡ เชœเซ‹ เช•เชพเชฎ เชฆเชฐเชฎเชฟเชฏเชพเชจ เชธเชฎเชธเซเชฏเชพเช“ เชนเซ‹เชฏ molecule test, เชชเช›เซ€ เชœเซ‹ เชคเชฎเซ‡ เชกเชฟเชซเซ‰เชฒเซเชŸ เช•เซเชฐเชฎ เชฌเชฆเชฒเซเชฏเซ‹ เชจเชฅเซ€, เชคเซ‹ เชฎเซ‹เชฒเซ‡เช•เซเชฏเซเชฒ เชฆเชพเช–เชฒเชพเชจเซ‡ เช•เชพเชขเซ€ เชจเชพเช–เชถเซ‡.

เชจเซ€เชšเซ‡เชจเชพ เช†เชฆเซ‡เชถเซ‹ เชกเซ€เชฌเช—เซ€เช‚เช— เชฎเชพเชŸเซ‡ เช‰เชชเชฏเซ‹เช—เซ€ เช›เซ‡:

> molecule --debug <command> # debug info. ะŸั€ะธ ะพะฑั‹ั‡ะฝะพะผ ะทะฐะฟัƒัะบะต ะœะพะปะตะบัƒะปะฐ ัะบั€ั‹ะฒะฐะตั‚ ะปะพะณะธ.
> molecule converge          # ะžัั‚ะฐะฒะปัะตั‚ ะธะฝัั‚ะฐะฝั ะฟะพัะปะต ะฟั€ะพะณะพะฝะฐ ั‚ะตัั‚ะธั€ัƒะตะผะพะน ั€ะพะปะธ.
> molecule login             # ะ—ะฐะนั‚ะธ ะฒ ัะพะทะดะฐะฝะฝั‹ะน ะธะฝัั‚ะฐะฝั.
> molecule --help            # ะŸะพะปะฝั‹ะน ัะฟะธัะพะบ ะบะพะผะฐะฝะด.

เชนเชพเชฒเชจเซ€ เชญเซ‚เชฎเชฟเช•เชพ

เชนเชพเชฒเชจเซ€ เชญเซ‚เชฎเชฟเช•เชพเชฎเชพเช‚ เชจเชตเซ€ เชธเซเช•เซเชฐเชฟเชชเซเชŸ เช‰เชฎเซ‡เชฐเชตเชพเชจเซเช‚ เช›เซ‡ เชญเซ‚เชฎเชฟเช•เชพ เชจเชฟเชฐเซเชฆเซ‡เชถเชฟเช•เชพเชฎเชพเช‚เชฅเซ€ เชจเซ€เชšเซ‡เชจเชพ เช†เชฆเซ‡เชถเซ‹ เชธเชพเชฅเซ‡:

# ะฟะพะปะฝั‹ะน ัะฟะธัะพะบ ะดะพัั‚ัƒะฟะฝั‹ั… ะฟะฐั€ะฐะผะตั‚ั€ะพะฒ
> molecule init scenarion --help
# ัะพะทะดะฐะฝะธะต ะฝะพะฒะพะณะพ ัั†ะตะฝะฐั€ะธั
> molecule init scenario -r <role_name> -s <scenario_name>

เชœเซ‹ เช† เชญเซ‚เชฎเชฟเช•เชพเชฎเชพเช‚ เชชเซเชฐเชฅเชฎ เชฆเซƒเชถเซเชฏ เช›เซ‡, เชคเซ‹ เชชเชฐเชฟเชฎเชพเชฃ -s เช…เชตเช—เชฃเซ€ เชถเช•เชพเชฏ เช›เซ‡ เช•เชพเชฐเชฃ เช•เซ‡ เชคเซ‡ เชธเซเช•เซเชฐเชฟเชชเซเชŸ เชฌเชจเชพเชตเชถเซ‡ default.

เชจเชฟเชทเซเช•เชฐเซเชท

เชœเซ‡เชฎ เชคเชฎเซ‡ เชœเซ‹เชˆ เชถเช•เซ‹ เช›เซ‹, เชชเชฐเชฎเชพเชฃเซ เชฌเชนเซ เชœเชŸเชฟเชฒ เชจเชฅเซ€, เช…เชจเซ‡ เชคเชฎเชพเชฐเชพ เชชเซ‹เชคเชพเชจเชพ เชจเชฎเซ‚เชจเชพเช“เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡, เชจเชตเซ€ เชธเซเช•เซเชฐเชฟเชชเซเชŸเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชฆเชพเช–เชฒเชพ เชฌเชจเชพเชตเชŸ เช…เชจเซ‡ เชชเซเชฒเซ‡เชฌเซเช• เช•เชพเชขเซ€ เชจเชพเช–เชตเชพเชฎเชพเช‚ เชšเชฒเซ‹เชจเซ‡ เชธเช‚เชชเชพเชฆเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เช˜เชŸเชพเชกเซ€ เชถเช•เชพเชฏ เช›เซ‡. เชชเชฐเชฎเชพเชฃเซ เชธเซ€เช†เชˆ เชธเชฟเชธเซเชŸเชฎเซเชธ เชธเชพเชฅเซ‡ เชเช•เซ€เช•เซƒเชค เชฐเซ€เชคเซ‡ เชธเช‚เช•เชฒเชฟเชค เชฅเชพเชฏ เช›เซ‡, เชœเซ‡ เชคเชฎเชจเซ‡ เชชเซเชฒเซ‡เชฌเซเช•เชจเชพ เชฎเซ‡เชจเซเชฏเซเช…เชฒ เชชเชฐเซ€เช•เซเชทเชฃ เชฎเชพเชŸเซ‡เชจเซ‹ เชธเชฎเชฏ เช˜เชŸเชพเชกเซ€เชจเซ‡ เชตเชฟเช•เชพเชธเชจเซ€ เชเชกเชช เชตเชงเชพเชฐเชตเชพ เชฎเชพเชŸเซ‡ เชชเชฐเชตเชพเชจเช—เซ€ เช†เชชเซ‡ เช›เซ‡.

เชคเชฎเชพเชฐเชพ เชงเซเชฏเชพเชจ เชฌเชฆเชฒ เช†เชญเชพเชฐ. เชœเซ‹ เชคเชฎเชจเซ‡ เชœเชตเชพเชฌเชฆเชพเชฐ เชญเซ‚เชฎเชฟเช•เชพเช“เชจเซเช‚ เชชเชฐเซ€เช•เซเชทเชฃ เช•เชฐเชตเชพเชจเซ‹ เช…เชจเซเชญเชต เชนเซ‹เชฏ, เช…เชจเซ‡ เชคเซ‡ เชชเชฐเชฎเชพเชฃเซ เชธเชพเชฅเซ‡ เชธเช‚เชฌเช‚เชงเชฟเชค เชจเชฅเซ€, เชคเซ‹ เช…เชฎเชจเซ‡ เชŸเชฟเชชเซเชชเชฃเซ€เช“เชฎเชพเช‚ เชคเซ‡เชจเชพ เชตเชฟเชถเซ‡ เชœเชฃเชพเชตเซ‹!

เชธเซ‹เชฐเซเชธ: www.habr.com

เชเช• เชŸเชฟเชชเซเชชเชฃเซ€ เช‰เชฎเซ‡เชฐเซ‹