ื™ื ืกื˜ืจื•ืงื˜ื™ืึธื ืก: ื•ื•ื™ ืฆื• ืคึผืจื•ื‘ื™ืจืŸ ืึทื ืกืึทื‘ืึทืœ ืจืึธืœืขืก ืื•ืŸ ื’ืขืคึฟื™ื ืขืŸ ื–ื™ืš ื•ื•ืขื’ืŸ ืคึผืจืึธื‘ืœืขืžืก ืื™ื™ื“ืขืจ ืคึผืจืึธื“ื•ืงืฆื™ืข

ื”ืขืœื ืึทืœืขืžืขืŸ!

ืื™ืš ืึทืจื‘ืขื˜ ื•ื•ื™ ืึท ื“ืขื•ื•ืึธืคึผืก ื™ื ื–ืฉืขื ื™ืจ ืื™ืŸ ืึท ื”ืึธื˜ืขืœ ื‘ื•ืงื™ื ื’ ื“ื™ื ืกื˜. Ostrovok.ru. ืื™ืŸ ื“ืขื ืึทืจื˜ื™ืงืœ, ืื™ืš ื•ื•ื™ืœืŸ ืฆื• ืจืขื“ืŸ ื•ื•ืขื’ืŸ ืื•ื ื“ื–ืขืจ ื“ืขืจืคืึทืจื•ื ื’ ืื™ืŸ ื˜ืขืกื˜ื™ื ื’ ืึทื ืกืึทื‘ืึทืœ ืจืึธืœืขืก.

ืื™ืŸ Ostrovok.ru, ืžื™ืจ ื ื•ืฆืŸ ืึทื ืกื™ื‘ืœืข ื•ื•ื™ ืึท ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทืŸ ืคืึทืจื•ื•ืึทืœื˜ืขืจ. ืœืขืฆื˜ื ืก, ืžื™ืจ ื’ืขืงื•ืžืขืŸ ืฆื• ื“ื™ ื ื•ื™ื˜ ืฆื• ืคึผืจื•ื‘ื™ืจืŸ ืจืึธืœืขืก, ืึธื‘ืขืจ ื•ื•ื™ ืขืก ืคืืจืงืขืจื˜ ืื•ื™ืก, ืขืก ื–ืขื ืขืŸ ื ื™ืฉื˜ ืึทื–ื•ื™ ืคื™ืœืข ืžื›ืฉื™ืจื™ื ืคึฟืึทืจ ื“ืขื - ื“ื™ ืžืขืจืกื˜ ืคืึธืœืงืก, ื˜ืึธืžืขืจ, ืื™ื– ื“ื™ ืžืึธืœืขืงื•ืœืข ืคืจื™ื™ืžื•ื•ืขืจืง, ืึทื–ื•ื™ ืžื™ืจ ื‘ืึทืฉืœืึธืกืŸ ืฆื• ื ื•ืฆืŸ ืขืก. ืึธื‘ืขืจ ืขืก ื”ืึธื˜ ื–ื™ืš ืึทืจื•ื™ืกื’ืขื•ื•ื™ื–ืŸ, ืึทื– ื–ืฒึทืŸ ื“ืึทืงื™ื•ืžืขื ื˜ืึทืฆื™ืข ืฉื•ื•ื™ื™ื’ื˜ ื•ื•ืขื’ืŸ ืึท ืกืš ื—ืกืจื•ื ื•ืช. ืžื™ืจ ืงืขืŸ ื ื™ืฉื˜ ื’ืขืคึฟื™ื ืขืŸ ืึท ื’ืขื ื•ื’ ื“ื™ื˜ื™ื™ืœื“ ืžืึทื ื•ืึทืœ ืื™ืŸ ืจื•ืกื™ืฉ, ืึทื–ื•ื™ ืžื™ืจ ื‘ืึทืฉืœืึธืกืŸ ืฆื• ืฉืจื™ื™ึทื‘ืŸ ื“ืขื ืึทืจื˜ื™ืงืœ.

ื™ื ืกื˜ืจื•ืงื˜ื™ืึธื ืก: ื•ื•ื™ ืฆื• ืคึผืจื•ื‘ื™ืจืŸ ืึทื ืกืึทื‘ืึทืœ ืจืึธืœืขืก ืื•ืŸ ื’ืขืคึฟื™ื ืขืŸ ื–ื™ืš ื•ื•ืขื’ืŸ ืคึผืจืึธื‘ืœืขืžืก ืื™ื™ื“ืขืจ ืคึผืจืึธื“ื•ืงืฆื™ืข

ืžืึธืœืขืงื•ืœืึทืจ

ืžืึธืœืขืงื•ืœ - ืึท ืคืจื™ื™ืžื•ื•ืขืจืง ืฆื• ื”ืขืœืคืŸ ืคึผืจื•ื‘ื™ืจืŸ ืึทื ืกืึทื‘ืึทืœ ืจืึธืœืขืก.

ืกื™ืžืคึผืœื™ืคื™ืขื“ ื‘ืึทืฉืจื™ื™ึทื‘ื•ื ื’: ื“ื™ ืžืึทืœืึทืงื™ื•ืœ ืงืจื™ื™ื™ืฅ ืึท ื‘ื™ื™ึทืฉืคึผื™ืœ ืื•ื™ืฃ ื“ืขืจ ืคึผืœืึทื˜ืคืึธืจืžืข ืื™ืจ ืกืคึผืขืฆื™ืคื™ืฆื™ืจืŸ (ื•ื•ืึธืœืงืŸ, ื•ื•ื™ืจื˜ื•ืึทืœ ืžืึทืฉื™ืŸ, ืงืึทื ื˜ื™ื™ื ืขืจ; ืคึฟืึทืจ ืžืขืจ ื“ืขื˜ืึทื™ืœืก, ื–ืขืŸ ื“ื™ ืึธืคึผื˜ื™ื™ืœื•ื ื’ ืฉืึธืคืขืจ), ืœื•ื™ืคื˜ ื“ื™ื™ืŸ ืจืึธืœืข ืื•ื™ืฃ ืขืก, ืื•ืŸ ืœื•ื™ืคื˜ ื˜ืขืกืฅ ืื•ืŸ ื“ื™ืœื™ืฅ ื“ืขื ื‘ื™ื™ึทืฉืคึผื™ืœ. ืื™ืŸ ืคืึทืœ ืคื•ืŸ ื“ื•ืจื›ืคืึทืœ ืื™ืŸ ืื™ื™ื ืขืจ ืคื•ืŸ ื“ื™ ืกื˜ืขืคึผืก, ื“ื™ ืžืึธืœืขืงื•ืœืข ื•ื•ืขื˜ ืžื™ื˜ื˜ื™ื™ืœืŸ ืื™ืจ ื•ื•ืขื’ืŸ ืื™ื.

ืื™ืฆื˜ ืžืขืจ.

ืขื˜ืœืขื›ืข ื˜ืขืึธืจื™ืข

ื‘ืึทื˜ืจืึทื›ื˜ืŸ ืฆื•ื•ื™ื™ ื”ื•ื™ืคึผื˜ ืขื ื˜ื™ื˜ื™ื– ืคื•ืŸ ื“ื™ ืžืึธืœืขืงื•ืœืึทืจ: ืกืฆืขื ืึทืจ ืื•ืŸ ื“ืจื™ื™ื•ื•ืขืจ.

Scenario

ื“ืขืจ ืฉืจื™ืคื˜ ื›ึผื•ืœืœ ืึท ื‘ืึทืฉืจื™ื™ึทื‘ื•ื ื’ ืคื•ืŸ ื•ื•ืึธืก, ื•ื•ื•, ื•ื•ื™ ืื•ืŸ ืื™ืŸ ื•ื•ืึธืก ืกื™ืงื•ื•ืึทื ืก ื•ื•ืขื˜ ื–ื™ื™ืŸ ื’ืขื˜ืืŸ. ืื™ื™ืŸ ืจืึธืœืข ืงืขื ืขืŸ ื”ืึธื‘ืŸ ืขื˜ืœืขื›ืข ืกืงืจื™ืคึผืก, ืื•ืŸ ื™ืขื“ืขืจ ืื™ื– ืึท ื•ื•ืขื’ื•ื•ื™ื™ึทื–ืขืจ ืฆื•ื–ืืžืขืŸ ื“ืขื ื“ืจืš <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 ืžืึธืœืขืงื•ืœืขืก ื–ืขื ืขืŸ ื’ืขืžืื›ื˜ ืคึฟื•ืŸ ื“ืขืจ ื•ื•ืึธืจืฆืœ ืคื•ืŸ ื“ืขืจ ืจืึธืœืข.

ื–ืืœ ืก ื–ืขืŸ ื•ื•ืึธืก ืื™ื– ืื™ืŸ ื“ื™ ืจืึธืœืข Directory:

> 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

ืึธืคืขื ื’ื™ืงื™ื™ึทื˜

ื“ืขืจ ืึธืคึผื˜ื™ื™ืœื•ื ื’ ื‘ืืฉืจื™ื™ื‘ื˜ ื“ื™ ืžืงื•ืจ ืคื•ืŸ ื“ื™ืคึผืขื ื“ืึทื ืกื™ื–.

ืžืขื’ืœืขืš ืึธืคึผืฆื™ืขืก: ื’ืึทืœืึทืงื˜ื™ืง, ืึทืคึผืœื™ื™ื–, ืฉืึธืœ.

ืฉืึธืœ ืื™ื– ื ืึธืจ ืึท ื‘ืึทืคึฟืขืœ ืฉืึธืœ ื•ื•ืึธืก ืื™ื– ื’ืขื ื™ืฆื˜ ืื™ืŸ ืคืึทืœ ื’ืึทืœืึทืงืกื™ ืื•ืŸ ื’ื™ืœื˜ ื˜ืึธืŸ ื ื™ื˜ ื“ืขืงืŸ ื“ื™ื™ืŸ ื“ืึทืจืฃ.

ืื™ืš ื•ื•ืขืœ ื ื™ืฉื˜ ื•ื•ื•ื™ื ืขืŸ ื“ืึธ ืคึฟืึทืจ ืึท ืœืึทื ื’ ืฆื™ื™ึทื˜, ืขืก ืื™ื– ื’ืขื ื•ื’ ื“ื™ืกืงืจื™ื™ื‘ื“ ืื™ืŸ ื“ืึทืงื™ื•ืžืขื ื˜ื™ื™ืฉืึทืŸ.

ืฉืึธืคืขืจ

ื“ืขืจ ื ืึธืžืขืŸ ืคื•ืŸ ื“ื™ ืฉืึธืคืขืจ. ืื•ื ื“ื–ืขืจ ืื™ื– ื“ืึธืงืงืขืจ.

ืœื™ื ื˜

ื“ื™ ืœื™ื ื˜ ืื™ื– ื™ืึทืžืœื™ืŸ.

ื ื•ืฆื™ืง ืึธืคึผืฆื™ืขืก ืื™ืŸ ื“ืขื ื˜ื™ื™ืœ ืคื•ืŸ ื“ื™ ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทืŸ ื–ืขื ืขืŸ ื“ื™ ืคื™ื™ื™ืงื™ื™ื˜ ืฆื• ืกืคึผืขืฆื™ืคื™ืฆื™ืจืŸ ืึท ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทืŸ ื˜ืขืงืข ืคึฟืึทืจ ื™ืึทืžืœืœื™ื ื˜, ืคืึธืจื•ื™ืก ื™ื ื•ื•ื™ื™ืจืึทื ืžืขื ืึทืœ ื•ื•ืขืจื™ืึทื‘ืึทืœื– ืึธื“ืขืจ ื“ื™ืกื™ื™ื‘ืึทืœ ื“ื™ ืœื™ื ื˜ืขืจ:

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. ื•ื•ืึธืก ืžืึทื“ื–ืฉื•ืœื– ื–ืขื ืขืŸ ื’ืขื ื™ืฆื˜ ืื™ืŸ ืื ื“ืขืจืข ื“ืจื™ื•ื•ืขืจืก ืงืขื ืขืŸ ื–ื™ื™ืŸ ื’ืขืคึฟื•ื ืขืŸ ืื™ืŸ ื“ืึทืงื™ื•ืžืขื ื˜ื™ื™ืฉืึทืŸ.

ื•ื•ื™ ื’ืขื–ื•ื ื˜ ื•ื•ื™ ื‘ื™ื™ืฉืคื™ืœืŸ ืคื•ืŸ ื“ื™ ื ื•ืฆืŸ ืคื•ืŸ ืคืึทืจืฉื™ื“ืŸ ื“ืจื™ื•ื•ืขืจืก ืงืขื ืขืŸ ื–ื™ื™ืŸ ื’ืขืคึฟื•ื ืขืŸ ืื™ืŸ ื“ื™ ื˜ืขืกืฅ ืคื•ืŸ ื“ื™ ืžืึธืœืขืงื•ืœืึทืจ ื–ื™ืš.

ืคืึทืจื‘ื™ื™ึทื˜ืŸ ื“ืึธ ืกืขื ื˜ืึธืก: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            # ะŸะพะปะฝั‹ะน ัะฟะธัะพะบ ะบะพะผะฐะฝะด.

ืขืงืกื™ืกื˜ื™ื ื’ ืจืึธืœืข

ืึทื“ื™ื ื’ ืึท ื ื™ื™ึทืข ืฉืจื™ืคื˜ ืฆื• ืึทืŸ ื™ื’ื–ื™ืกื˜ื™ื ื’ ืจืึธืœืข ืื™ื– ืคื•ืŸ ื“ื™ ืจืึธืœืข Directory ืžื™ื˜ ื“ื™ ืคืืœื’ืขื ื“ืข ืงืึทืžืึทื ื“ื–:

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

ืื™ืŸ ืคืึทืœ ื“ืึธืก ืื™ื– ื“ืขืจ ืขืจืฉื˜ืขืจ ืกืฆืขื ืึทืจ ืื™ืŸ ื“ืขืจ ืจืึธืœืข, ื“ืขืžืึธืœื˜ ื“ืขืจ ืคึผืึทืจืึทืžืขื˜ืขืจ -s ืงืขื ืขืŸ ื–ื™ื™ืŸ ืื™ื‘ืขืจื’ืขื”ื™ืคึผืขืจื˜ ื•ื•ื™ ืขืก ื•ื•ืขื˜ ืžืึทื›ืŸ ืึท ืฉืจื™ืคื˜ default.

ืกืึธืฃ

ื•ื•ื™ ืื™ืจ ืงืขื ืขืŸ ื–ืขืŸ, ื“ื™ ืžืึธืœืขืงื•ืœืข ืื™ื– ื ื™ืฉื˜ ื–ื™ื™ืขืจ ืงืึธืžืคึผืœื™ืฆื™ืจื˜, ืื•ืŸ ื“ื•ืจืš ื ื™ืฆืŸ ื“ื™ื™ืŸ ืื™ื™ื’ืขื ืข ื˜ืขืžืคึผืœืึทื˜ืขืก, ื“ื™ืคึผืœื•ื™ื™ื ื’ ืึท ื ื™ื™ึทืข ืฉืจื™ืคื˜ ืงืขื ืขืŸ ื–ื™ื™ืŸ ืจื™ื“ื•ืกื˜ ืฆื• ืจืขื“ืึทื’ื™ืจืŸ ื•ื•ืขืจื™ืึทื‘ืึทืœื– ืื™ืŸ ื“ืขืจ ื‘ื™ื™ืฉืคึผื™ืœ ืคื•ืŸ ืฉืึทืคื•ื ื’ ืื•ืŸ ื“ื™ืœื™ืฉืึทืŸ ืคื•ืŸ ืคึผืœื™ื™ึทื‘ืึธืึธืงืก. ื“ื™ ืžืึทืœืึทืงื™ื•ืœ ื™ื ื˜ืึทื’ืจื™ื™ืฅ ืกื™ืžืœืึทืก ืžื™ื˜ CI ืกื™ืกื˜ืขืžืขืŸ, ื•ื•ืึธืก ืึทืœืึทื•ื– ืื™ืจ ืฆื• ืคืึทืจื’ืจืขืกืขืจืŸ ื“ื™ ื’ื™ื›ืงื™ื™ึทื˜ ืคื•ืŸ ืึทื ื˜ื•ื•ื™ืงืœื•ื ื’ ื“ื•ืจืš ืจื™ื“ื•ืกื™ื ื’ ื“ื™ ืฆื™ื™ื˜ ืคึฟืึทืจ ืžืึทื ื•ืึทืœ ื˜ืขืกื˜ื™ื ื’ ืคื•ืŸ ืคึผืœื™ื™ึทื‘ืึธืึธืงืก.

ื“ืื ืง ืื™ืจ ืคึฟืึทืจ ื“ื™ื™ืŸ ื•ืคืžืขืจืงื–ืึทืžืงื™ื™ึทื˜. ืื•ื™ื‘ ืื™ืจ ื”ืึธื˜ ื“ืขืจืคืึทืจื•ื ื’ ืื™ืŸ ื˜ืขืกื˜ื™ื ื’ ืึทื ืกืึทื‘ืึทืœ ืจืึธืœืขืก, ืื•ืŸ ืขืก ืื™ื– ื ื™ืฉื˜ ืฉื™ื™ืš ืฆื• ื“ื™ ืžืึธืœืขืงื•ืœืึทืจ, ื–ืึธื’ืŸ ืื•ื ื“ื– ื•ื•ืขื’ืŸ ืื™ื ืื™ืŸ ื“ื™ ื‘ืึทืžืขืจืงื•ื ื’ืขืŸ!

ืžืงื•ืจ: www.habr.com

ืœื™ื™ื’ืŸ ืึท ื‘ืึทืžืขืจืงื•ื ื’