рд╕реВрдЪрдирд╛: рдЙрддреНрддрд░рджрд╛рдпреА рднреВрдорд┐рдХрд╛рдВрдЪреА рдЪрд╛рдЪрдгреА рдХрд╢реА рдХрд░рд╛рд╡реА рдЖрдгрд┐ рдЙрддреНрдкрд╛рджрдирд╛рдкреВрд░реНрд╡реА рд╕рдорд╕реНрдпрд╛ рдХрд╢рд╛ рд╢реЛрдзрд╛рд╡реНрдпрд╛рдд

рд╣реЕрд▓реЛ рдкреНрд░рддреНрдпреЗрдХрдЬрдг!

рдореА рд╣реЙрдЯреЗрд▓ рдмреБрдХрд┐рдВрдЧ рд╕реЗрд╡реЗрд╕рд╛рдареА DevOps рдЕрднрд┐рдпрдВрддрд╛ рдореНрд╣рдгреВрди рдХрд╛рдо рдХрд░рддреЛ. Ostrovok.ru. рдпрд╛ рд▓реЗрдЦрд╛рдд рдорд▓рд╛ рдЙрддреНрддрд░рджрд╛рдпреА рднреВрдорд┐рдХрд╛ рддрдкрд╛рд╕рдгреНрдпрд╛рдЪреНрдпрд╛ рдЖрдордЪреНрдпрд╛ рдЕрдиреБрднрд╡рд╛рдмрджреНрджрд▓ рдмреЛрд▓рд╛рдпрдЪреЗ рдЖрд╣реЗ.

Ostrovok.ru рд╡рд░ рдЖрдореНрд╣реА рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рдореНрд╣рдгреВрди рдЙрддреНрддрд░рджрд╛рдпреА рд╡рд╛рдкрд░рддреЛ. рдЕрд▓реАрдХрдбреЗрдЪ рдЖрдореНрд╣рд╛рд▓рд╛ рднреВрдорд┐рдХрд╛рдВрдЪреА рдЪрд╛рдЪрдгреА рдШреЗрдгреНрдпрд╛рдЪреА рдЧрд░рдЬ рдЖрд▓реА, рдкрд░рдВрддреБ, рдЬрд╕реЗ рдХреА рд╣реЗ рджрд┐рд╕реВрди рдЖрд▓реЗ рдХреА рдпрд╛рд╕рд╛рдареА рдмрд░реАрдЪ рд╕рд╛рдзрдиреЗ рдирд╛рд╣реАрдд - рд╕рд░реНрд╡рд╛рдд рд▓реЛрдХрдкреНрд░рд┐рдп, рдХрджрд╛рдЪрд┐рдд, рд░реЗрдгреВ рдлреНрд░реЗрдорд╡рд░реНрдХ рдЖрд╣реЗ, рдореНрд╣рдгреВрди рдЖрдореНрд╣реА рддреЗ рд╡рд╛рдкрд░рдгреНрдпрд╛рдЪреЗ рдард░рд╡рд┐рд▓реЗ. рдкрд░рдВрддреБ рдЕрд╕реЗ рджрд┐рд╕реВрди рдЖрд▓реЗ рдХреА рддреНрдпрд╛рдЪреЗ рджрд╕реНрддрдРрд╡рдЬреАрдХрд░рдг рдЕрдиреЗрдХ рддреНрд░реБрдЯреАрдВрдмрджреНрджрд▓ рд╢рд╛рдВрдд рдЖрд╣реЗ. рдЖрдореНрд╣рд╛рд▓рд╛ рд░рд╢рд┐рдпрди рднрд╛рд╖реЗрдд рдкреБрд░реЗрд╕реЗ рддрдкрд╢реАрд▓рд╡рд╛рд░ рдорд╛рд░реНрдЧрджрд░реНрд╢рдХ рд╕рд╛рдкрдбрд▓реЗ рдирд╛рд╣реА, рдореНрд╣рдгреВрди рдЖрдореНрд╣реА рд╣рд╛ рд▓реЗрдЦ рд▓рд┐рд╣рд┐рдгреНрдпрд╛рдЪрд╛ рдирд┐рд░реНрдгрдп рдШреЗрддрд▓рд╛.

рд╕реВрдЪрдирд╛: рдЙрддреНрддрд░рджрд╛рдпреА рднреВрдорд┐рдХрд╛рдВрдЪреА рдЪрд╛рдЪрдгреА рдХрд╢реА рдХрд░рд╛рд╡реА рдЖрдгрд┐ рдЙрддреНрдкрд╛рджрдирд╛рдкреВрд░реНрд╡реА рд╕рдорд╕реНрдпрд╛ рдХрд╢рд╛ рд╢реЛрдзрд╛рд╡реНрдпрд╛рдд

рд░реЗрдгреВ

рд░реЗрдгреВ тАФ рдЙрддреНрддрд░рджрд╛рдпреА рднреВрдорд┐рдХрд╛рдВрдЪреА рдЪрд╛рдЪрдгреА рдШреЗрдгреНрдпрд╛рдд рдорджрдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдПрдХ рдлреНрд░реЗрдорд╡рд░реНрдХ.

рд╕рд░рд▓реАрдХреГрдд рд╡рд░реНрдгрди: рддреБрдореНрд╣реА рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХреЗрд▓реЗрд▓реНрдпрд╛ рдкреНрд▓реЕрдЯрдлреЙрд░реНрдорд╡рд░ рд░реЗрдгреВ рдПрдХ рдЙрджрд╛рд╣рд░рдг рддрдпрд╛рд░ рдХрд░рддреЛ (рдХреНрд▓рд╛рдЙрдб, рд╡реНрд╣рд░реНрдЪреНрдпреБрдЕрд▓ рдорд╢реАрди, рдХрдВрдЯреЗрдирд░; рдЕрдзрд┐рдХ рддрдкрд╢реАрд▓рд╛рдВрд╕рд╛рдареА, рд╡рд┐рднрд╛рдЧ рдкрд╣рд╛ рдбреНрд░рд╛рдЗрд╡реНрд╣рд░), рддреНрдпрд╛рд╡рд░ рддреБрдордЪреА рднреВрдорд┐рдХрд╛ рдЪрд╛рд▓рд╡рддреЗ, рдирдВрддрд░ рдЪрд╛рдЪрдгреНрдпрд╛ рдЪрд╛рд▓рд╡рддреЗ рдЖрдгрд┐ рдЙрджрд╛рд╣рд░рдг рд╣рдЯрд╡рддреЗ. рдПрдХрд╛ рдкрд╛рдпрд░реАрд╡рд░ рдмрд┐рдШрд╛рдб рдЭрд╛рд▓реНрдпрд╛рд╕, рд░реЗрдгреВ рддреБрдореНрд╣рд╛рд▓рд╛ рддреНрдпрд╛рдмрджреНрджрд▓ рд╕реВрдЪрд┐рдд рдХрд░реЗрд▓.

рдЖрддрд╛ рдЕрдзрд┐рдХ.

рд╕рд┐рджреНрдзрд╛рдВрддрд╛рдЪрд╛ рдмрд┐рдЯ

рд░реЗрдгреВрдЪреНрдпрд╛ рджреЛрди рдкреНрд░рдореБрдЦ рдШрдЯрдХрд╛рдВрдЪрд╛ рд╡рд┐рдЪрд╛рд░ рдХрд░реВрдпрд╛: рдкрд░рд┐рджреГрд╢реНрдп рдЖрдгрд┐ рдбреНрд░рд╛рдпрд╡реНрд╣рд░.

рдкрд░рд┐рджреГрд╢реНрдп

рд╕реНрдХреНрд░рд┐рдкреНрдЯрдордзреНрдпреЗ рдХрд╛рдп, рдХреБрдареЗ, рдХрд╕реЗ рдЖрдгрд┐ рдХреЛрдгрддреНрдпрд╛ рдХреНрд░рдорд╛рдиреЗ рдХреЗрд▓реЗ рдЬрд╛рдИрд▓ рдпрд╛рдЪреЗ рд╡рд░реНрдгрди рдЖрд╣реЗ. рдПрдХрд╛ рднреВрдорд┐рдХреЗрдд рдЕрдиреЗрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯреНрд╕ рдЕрд╕реВ рд╢рдХрддрд╛рдд рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ рдорд╛рд░реНрдЧрд╛рдЪреНрдпрд╛ рдмрд╛рдЬреВрдиреЗ рдПрдХ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдЖрд╣реЗ <role>/molecule/<scenario>, рдЪрд╛рдЪрдгреАрд╕рд╛рдареА рдЖрд╡рд╢реНрдпрдХ рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рдХреНрд░рд┐рдпрд╛рдВрдЪреЗ рд╡рд░реНрдгрди рдЕрд╕рд▓реЗрд▓реЗ. рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЕрд╕рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ default, рдЬреЗ рддреБрдореНрд╣реА Molecule рд╡рд╛рдкрд░реВрди рднреВрдорд┐рдХрд╛ рд╕реБрд░реВ рдХреЗрд▓реНрдпрд╛рд╕ рдЖрдкреЛрдЖрдк рддрдпрд╛рд░ рд╣реЛрдИрд▓. рдЦрд╛рд▓реАрд▓ рд╕реНрдХреНрд░рд┐рдкреНрдЯреНрд╕рдЪреА рдирд╛рд╡реЗ рдЖрдкрд▓реНрдпрд╛ рд╡рд┐рд╡реЗрдХрдмреБрджреНрдзреАрдиреБрд╕рд╛рд░ рдЖрд╣реЗрдд.

рд╕реНрдХреНрд░рд┐рдкреНрдЯрдордзреАрд▓ рдЪрд╛рдЪрдгреА рдХреНрд░рд┐рдпрд╛рдВрдЪреНрдпрд╛ рдХреНрд░рдорд╛рд▓рд╛ рдореНрд╣рдгрддрд╛рдд рдореЕрдЯреНрд░рд┐рдХреНрд╕, рдЖрдгрд┐ рдбреАрдлреЙрд▓реНрдЯрдиреБрд╕рд╛рд░ рддреЗ рдЕрд╕реЗ рдЖрд╣реЗ:

(рдЪрд░рдг рдЪрд┐рдиреНрд╣рд╛рдВрдХрд┐рдд ?, рд╡рд╛рдкрд░рдХрд░реНрддреНрдпрд╛рджреНрд╡рд╛рд░реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рди рдХреЗрд▓реНрдпрд╛рд╕ рддреЗ рдбреАрдлреЙрд▓реНрдЯрдиреБрд╕рд╛рд░ рд╡рдЧрд│рд▓реЗ рдЬрд╛рддрд╛рдд)

  • 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>. рдкрд░рдВрддреБ рддреБрдореНрд╣рд╛рд▓рд╛ рд╣реЗ рд╕рдордЬрд▓реЗ рдкрд╛рд╣рд┐рдЬреЗ рдХреА рдЕрд╢рд╛ рдкреНрд░рддреНрдпреЗрдХ cli рдХрдорд╛рдВрдбрд╕рд╛рдареА рдХреНрд░рд┐рдпрд╛рдВрдЪрд╛ рд╕реНрд╡рддрдГрдЪрд╛ рдХреНрд░рдо рдЕрд╕реВ рд╢рдХрддреЛ, рдЬреЛ рддреБрдореНрд╣реА рдЪрд╛рд▓рд╡реВрди рд╢реЛрдзреВ рд╢рдХрддрд╛. molecule matrix <command>. рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдХрдорд╛рдВрдб рдЪрд╛рд▓рд╡рддрд╛рдирд╛ converge (рдЪрд╛рдЪрдгреА рдХреЗрд▓реЗрд▓реЗ рдкреНрд▓реЗрдмреБрдХ рдЪрд╛рд▓рд╡рдгреЗ) рдЦрд╛рд▓реАрд▓ рдХреНрд░рд┐рдпрд╛ рдХреЗрд▓реНрдпрд╛ рдЬрд╛рддреАрд▓:

$ molecule matrix converge
...
тФФтФАтФА default         # ╨╜╨░╨╖╨▓╨░╨╜╨╕╨╡ ╤Б╤Ж╨╡╨╜╨░╤А╨╕╤П
    тФЬтФАтФА dependency  # ╤Г╤Б╤В╨░╨╜╨╛╨▓╨║╨░ ╨╖╨░╨▓╨╕╤Б╨╕╨╝╨╛╤Б╤В╨╡╨╣
    тФЬтФАтФА create      # ╤Б╨╛╨╖╨┤╨░╨╜╨╕╨╡ ╨╕╨╜╤Б╤В╨░╨╜╤Б╨░
    тФЬтФАтФА prepare     # ╨┐╤А╨╡╨┤╨╜╨░╤Б╤В╤А╨╛╨╣╨║╨░ ╨╕╨╜╤Б╤В╨░╨╜╤Б╨░
    тФФтФАтФА converge    # ╨┐╤А╨╛╨│╨╛╨╜ ╨┐╨╗╨╡╨╣╨▒╤Г╨║╨░

рдпрд╛ рдХреНрд░рд┐рдпрд╛рдВрдЪрд╛ рдХреНрд░рдо рд╕рдВрдкрд╛рджрд┐рдд рдХреЗрд▓рд╛ рдЬрд╛рдК рд╢рдХрддреЛ. рд╕реВрдЪреАрддреАрд▓ рдХрд╛рд╣реАрддрд░реА рдЖрдзреАрдЪ рдкреВрд░реНрдг рдХреЗрд▓реЗ рдЕрд╕рд▓реНрдпрд╛рд╕, рддреЗ рд╡рдЧрд│рд▓реЗ рдЬрд╛рдИрд▓. рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддреА, рддрд╕реЗрдЪ рдЙрджрд╛рд╣рд░рдг рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди, рд░реЗрдгреВ рдирд┐рд░реНрджреЗрд╢рд┐рдХреЗрдд рд╕рдВрдЧреНрд░рд╣рд┐рдд рдХреЗрд▓реЗ рдЬрд╛рддреЗ $TMPDIR/molecule/<role>/<scenario>.

рд╕рд╣ рдЪрд░рдг рдЬреЛрдбрд╛ ? рддреБрдореНрд╣реА рдЙрддреНрддрд░рджрд╛рдпреА рдкреНрд▓реЗрдмреБрдХ рдлреЙрд░рдореЕрдЯрдордзреНрдпреЗ рдЗрдЪреНрдЫрд┐рдд рдХреНрд░рд┐рдпрд╛рдВрдЪреЗ рд╡рд░реНрдгрди рдХрд░реВ рд╢рдХрддрд╛ рдЖрдгрд┐ рдЪрд░рдгрд╛рдиреБрд╕рд╛рд░ рдлрд╛рдЗрд▓рдЪреЗ рдирд╛рд╡ рдмрдирд╡реВ рд╢рдХрддрд╛: prepare.yml/side_effect.yml. рдпрд╛ Molecule рдлрд╛рдЗрд▓реНрд╕ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдлреЛрд▓реНрдбрд░рдордзреНрдпреЗ рдЕрд╕рдгреНрдпрд╛рдЪреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рд╛.

рдбреНрд░рд╛рдЗрд╡реНрд╣рд░

рдбреНрд░рд╛рдпрд╡реНрд╣рд░ рд╣реА рдПрдХ рд╕рдВрд╕реНрдерд╛ рдЖрд╣реЗ рдЬрд┐рдереЗ рдЪрд╛рдЪрдгреАрд╕рд╛рдареА рдЙрджрд╛рд╣рд░рдгреЗ рддрдпрд╛рд░ рдХреЗрд▓реА рдЬрд╛рддрд╛рдд.
рдорд╛рдирдХ рдбреНрд░рд╛рдпрд╡реНрд╣рд░реНрд╕рдЪреА рдпрд╛рджреА рдЬреНрдпрд╛рд╕рд╛рдареА рд░реЗрдгреВрдХрдбреЗ рддрдпрд╛рд░ рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдЖрд╣реЗрдд: 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 рд╕рд╛рдареА рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рдлрд╛рдЗрд▓ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдгреЗ, рдкрд░реНрдпрд╛рд╡рд░рдг рд╡реНрд╣реЗрд░рд┐рдПрдмрд▓реНрд╕ рдлреЙрд░рд╡рд░реНрдб рдХрд░рдгреЗ рдХрд┐рдВрд╡рд╛ рд▓рд┐рдВрдЯрд░ рдЕрдХреНрд╖рдо рдХрд░рдгреЗ:

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 рд╡рд░ рдЙрдмрдВрдЯреВ.

рддрд░рддреВрдж рдХрд░рдгрд╛рд░рд╛

"рдкреНрд░рджрд╛рддрд╛" рд╣реА рдШрдЯрдирд╛ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдгрд╛рд░реА рд╕рдВрд╕реНрдерд╛ рдЖрд╣реЗ. рд░реЗрдгреВрдЪреНрдпрд╛ рдмрд╛рдмрддреАрдд, рд╣реЗ рдЙрддреНрддрд░рджрд╛рдпреА рдЖрд╣реЗ; рдЗрддрд░рд╛рдВрд╕рд╛рдареА рд╕рдорд░реНрдерди рдирд┐рдпреЛрдЬрд┐рдд рдирд╛рд╣реА, рдореНрд╣рдгреВрди рдпрд╛ рд╡рд┐рднрд╛рдЧрд╛рд▓рд╛, рдЖрд░рдХреНрд╖рдгрд╛рд╕рд╣, рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдЙрддреНрддрд░рджрд╛рдпреА рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рдореНрд╣рдЯрд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ.
рдЖрдкрдг рдпреЗрдереЗ рдмрд░реЗрдЪ рдХрд╛рд╣реА рджрд░реНрд╢рд╡реВ рд╢рдХрддрд╛, рдкрд░рдВрддреБ рдореА рдорд╛рдЭреНрдпрд╛ рдорддреЗ рдореБрдЦреНрдп рдореБрджреНрджреЗ рд╣рд╛рдпрд▓рд╛рдЗрдЯ рдХрд░реЗрди:

  • playbooks: рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЯрдкреНрдкреНрдпрд╛рдВрд╡рд░ рдХреЛрдгрддреА рдкреНрд▓реЗрдмреБрдХ рд╡рд╛рдкрд░рд╛рд╡реАрдд рд╣реЗ рддреБрдореНрд╣реА рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реВ рд╢рдХрддрд╛.

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 рдЙрджрд╛рд╣рд░рдг рд╣рдЯрд╡реЗрд▓.

рдЦрд╛рд▓реАрд▓ рдЖрджреЗрд╢ рдбреАрдмрдЧрд┐рдВрдЧрд╕рд╛рдареА рдЙрдкрдпреБрдХреНрдд рдЖрд╣реЗрдд:

> 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.

рдирд┐рд╖реНрдХрд░реНрд╖

рдЬрд╕реЗ рддреБрдореНрд╣реА рдмрдШреВ рд╢рдХрддрд╛, рд░реЗрдгреВ рдлрд╛рд░ рдХреНрд▓рд┐рд╖реНрдЯ рдирд╛рд╣реА, рдЖрдгрд┐ рддреБрдордЪреЗ рд╕реНрд╡рддрдГрдЪреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╡рд╛рдкрд░рддрд╛рдирд╛, рддреБрдореНрд╣реА рдЙрджрд╛рд╣рд░рдгреЗ рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЖрдгрд┐ рд╣рдЯрд╡рдгреНрдпрд╛рд╕рд╛рдареА рдкреНрд▓реЗрдмреБрдХрдордзреАрд▓ рд╡реНрд╣реЗрд░рд┐рдПрдмрд▓реНрд╕рдЪреЗ рд╕рдВрдкрд╛рджрди рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдирд╡реАрди рд╕реНрдХреНрд░рд┐рдкреНрдЯрдЪреА рддреИрдирд╛рддреА рдХрдореА рдХрд░реВ рд╢рдХрддрд╛. рд░реЗрдгреВ рдЕрдЦрдВрдбрдкрдгреЗ CI рд╕рд┐рд╕реНрдЯреАрдорд╕рд╣ рд╕рдорд╛рдХрд▓рд┐рдд рд╣реЛрддреЗ, рдЬреЗ рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдкреНрд▓реЗрдмреБрдХрдЪреНрдпрд╛ рдореЕрдиреНрдпреБрдЕрд▓ рдЪрд╛рдЪрдгреАрд╕рд╛рдареА рд╡реЗрд│ рдХрдореА рдХрд░реВрди рд╡рд┐рдХрд╛рд╕рд╛рдЪреА рдЧрддреА рд╡рд╛рдврд╡рд┐рдгреНрдпрд╛рд╕ рдЕрдиреБрдорддреА рджреЗрддреЗ.

рдЖрдкрдг рд▓рдХреНрд╖ рджрд┐рд▓реНрдпрд╛рдмрджреНрджрд▓ рдзрдиреНрдпрд╡рд╛рдж. рддреБрдореНрд╣рд╛рд▓рд╛ рдЙрддреНрддрд░рджрд╛рдпреА рднреВрдорд┐рдХрд╛рдВрдЪреА рдЪрд╛рдЪрдгреА рдШреЗрдгреНрдпрд╛рдЪрд╛ рдЕрдиреБрднрд╡ рдЕрд╕рд▓реНрдпрд╛рд╕ рдЖрдгрд┐ рддреЗ рд░реЗрдгреВрд╢реА рд╕рдВрдмрдВрдзрд┐рдд рдирд╕рд▓реНрдпрд╛рд╕, рдЯрд┐рдкреНрдкрдгреНрдпрд╛рдВрдордзреНрдпреЗ рддреНрдпрд╛рдмрджреНрджрд▓ рдЖрдореНрд╣рд╛рд▓рд╛ рд╕рд╛рдВрдЧрд╛!

рд╕реНрддреНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╛