рдирд┐рд░реНрджреЗрд╢рдирд╣рд░реВ: рдХрд╕рд░реА рдЬрд╡рд╛рдлрджреЗрд╣реА рднреВрдорд┐рдХрд╛рд╣рд░реВ рдкрд░реАрдХреНрд╖рдг рдЧрд░реНрдиреЗ рд░ рдЙрддреНрдкрд╛рджрди рдЕрдШрд┐ рд╕рдорд╕реНрдпрд╛рд╣рд░реВрдХреЛ рдмрд╛рд░реЗрдорд╛ рдкрддреНрддрд╛ рд▓рдЧрд╛рдЙрдиреЗ

рдирдорд╕реНрдХрд╛рд░!

рдо рд╣реЛрдЯрд▓ рдмреБрдХрд┐рдЩ рд╕реЗрд╡рд╛рдорд╛ DevOps рдЗрдиреНрдЬрд┐рдирд┐рдпрд░рдХреЛ рд░реВрдкрдорд╛ рдХрд╛рдо рдЧрд░реНрдЫреБред Ostrovok.ruред рдпрд╕ рд▓реЗрдЦрдорд╛, рдо рдЬрд╡рд╛рдлрджреЗрд╣реА рднреВрдорд┐рдХрд╛рд╣рд░реВрдХреЛ рдкрд░реАрдХреНрд╖рдгрдорд╛ рд╣рд╛рдореНрд░реЛ рдЕрдиреБрднрд╡рдХреЛ рдмрд╛рд░реЗрдорд╛ рдХреБрд░рд╛ рдЧрд░реНрди рдЪрд╛рд╣рдиреНрдЫреБред

Ostrovok.ru рдорд╛, рд╣рд╛рдореА рдХрдиреНрдлрд┐рдЧрд░реЗрд╕рди рдкреНрд░рдмрдиреНрдзрдХрдХреЛ рд░реВрдкрдорд╛ рдЙрддреНрддрд░рджрд╛рдпреА рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдЫреМрдВред рднрд░реНрдЦрд░реИ, рд╣рд╛рдореА рднреВрдорд┐рдХрд╛рд╣рд░реВ рдкрд░реАрдХреНрд╖рдг рдЧрд░реНрдиреЗ рдЖрд╡рд╢реНрдпрдХрддрд╛рдорд╛ рдЖрдПрдХрд╛ рдЫреМрдВ, рддрд░ рдпреЛ рдмрд╛рд╣рд┐рд░ рдЖрдПрдХреЛ рд░реВрдкрдорд╛, рддреНрдпрд╣рд╛рдБ рдпрд╕рдХрд╛ рд▓рд╛рдЧрд┐ рдзреЗрд░реИ рдЙрдкрдХрд░рдгрд╣рд░реВ рдЫреИрдирдиреН - рд╕рдмреИрднрдиреНрджрд╛ рд▓реЛрдХрдкреНрд░рд┐рдп, рд╕рд╛рдпрдж, рдЕрдгреБ рдлреНрд░реЗрдорд╡рд░реНрдХ рд╣реЛ, рддреНрдпрд╕реИрд▓реЗ рд╣рд╛рдореАрд▓реЗ рдпрд╕рд▓рд╛рдИ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреЗ рдирд┐рд░реНрдгрдп рдЧрд░реНрдпреМрдВред рддрд░ рдпреЛ рдмрд╛рд╣рд┐рд░ рдирд┐рд╕реНрдХрд┐рдпреЛ рдХрд┐ рдЙрдирдХреЛ рдХрд╛рдЧрдЬрд╛рдд рдзреЗрд░реИ рдХрдордЬреЛрд░реАрд╣рд░реВрдХреЛ рдмрд╛рд░реЗрдорд╛ рдореМрди рдЫред рд╣рд╛рдореАрд▓реЗ рд░реВрд╕реАрдорд╛ рдкрд░реНрдпрд╛рдкреНрдд рд╡рд┐рд╕реНрддреГрдд рдореНрдпрд╛рдиреБрдЕрд▓ рдлреЗрд▓рд╛ рдкрд╛рд░реНрди рд╕рдХреЗрдиреМрдВ, рддреНрдпрд╕реИрд▓реЗ рд╣рд╛рдореАрд▓реЗ рдпреЛ рд▓реЗрдЦ рд▓реЗрдЦреНрдиреЗ рдирд┐рд░реНрдгрдп рдЧрд░реНрдпреМрдВред

рдирд┐рд░реНрджреЗрд╢рдирд╣рд░реВ: рдХрд╕рд░реА рдЬрд╡рд╛рдлрджреЗрд╣реА рднреВрдорд┐рдХрд╛рд╣рд░реВ рдкрд░реАрдХреНрд╖рдг рдЧрд░реНрдиреЗ рд░ рдЙрддреНрдкрд╛рджрди рдЕрдШрд┐ рд╕рдорд╕реНрдпрд╛рд╣рд░реВрдХреЛ рдмрд╛рд░реЗрдорд╛ рдкрддреНрддрд╛ рд▓рдЧрд╛рдЙрдиреЗ

рдЕрдгреБ

рдЕрдгреБ - рдЬрд╡рд╛рдлрджреЗрд╣реА рднреВрдорд┐рдХрд╛рд╣рд░реВ рдкрд░реАрдХреНрд╖рдг рдЧрд░реНрди рдорджреНрджрддрдХреЛ рд▓рд╛рдЧрд┐ рдПрдХ рдврд╛рдБрдЪрд╛ред

рд╕рд░рд▓реАрдХреГрдд рд╡рд┐рд╡рд░рдг: рддрдкрд╛рдИрдВрд▓реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЧрд░реНрдиреБрднрдПрдХреЛ рдкреНрд▓реЗрдЯрдлрд░реНрдордорд╛ рдЕрдгреБрд▓реЗ рдПрдЙрдЯрд╛ рдЙрджрд╛рд╣рд░рдг рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрджрдЫ (рдХреНрд▓рд╛рдЙрдб, рднрд░реНрдЪреБрдЕрд▓ рдореЗрд╕рд┐рди, рдХрдиреНрдЯреЗрдирд░; рдердк рд╡рд┐рд╡рд░рдгрд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐, рдЦрдгреНрдб рд╣реЗрд░реНрдиреБрд╣реЛрд╕реНред рдЪрд╛рд▓рдХ), рдпрд╕рдорд╛ рддрдкрд╛рдИрдВрдХреЛ рднреВрдорд┐рдХрд╛ рдЪрд▓рд╛рдЙрдБрдЫ, рддреНрдпрд╕рдкрдЫрд┐ рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рдЪрд▓рд╛рдЙрдБрдЫ рд░ рдЙрджрд╛рд╣рд░рдг рдореЗрдЯрд╛рдЙрдБрдЫред рдХреБрдиреИ рдПрдХ рдЪрд░рдгрдорд╛ рдЕрд╕рдлрд▓ рднрдПрдХреЛ рдЕрд╡рд╕реНрдерд╛рдорд╛, рдЕрдгреБрд▓реЗ рддрдкрд╛рдИрдВрд▓рд╛рдИ рдпрд╕рдХреЛ рдмрд╛рд░реЗрдорд╛ рд╕реВрдЪрд┐рдд рдЧрд░реНрдиреЗрдЫред

рдЕрдм рдердкред

рдмрд┐рдЯ рд╕рд┐рджреНрдзрд╛рдиреНрдд

рдЕрдгреБрдХрд╛ рджреБрдИ рдкреНрд░рдореБрдЦ рдирд┐рдХрд╛рдпрд╣рд░реВрд▓рд╛рдИ рд╡рд┐рдЪрд╛рд░ рдЧрд░реНрдиреБрд╣реЛрд╕реН: рдкрд░рд┐рджреГрд╢реНрдп рд░ рдЪрд╛рд▓рдХред

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

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

рд▓рд┐рдкрд┐рдорд╛ рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдпрд╣рд░реВрдХреЛ рдЕрдиреБрдХреНрд░рдо рднрдирд┐рдиреНрдЫ рдореНрдпрд╛рдЯреНрд░рд┐рдХреНрд╕, рд░ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд░реВрдкрдорд╛ рдпреЛ рд╣реЛ:

(рдЪрд░рдгрд╣рд░реВ рд▓реЗрдмрд▓ рдЧрд░рд┐рдПрдХреЛ рдЫ ?, рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд░реВрдкрдорд╛ рдЫреЛрдбрд┐рдпреЛ рдпрджрд┐ рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЧрд░рд┐рдПрдХреЛ рдЫреИрди)

  • lint - рдЪрд▓рд┐рд░рд╣реЗрдХреЛ lintersред рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд░реВрдкрдорд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдиреНрдЫ yamllint ╨╕ flake8,
  • destroy - рдЕрдгреБрдХреЛ рдЕрдиреНрддрд┐рдо рдкреНрд░рдХреНрд╖реЗрдкрдгрдмрд╛рдЯ рдЙрджрд╛рд╣рд░рдгрд╣рд░реВ рдореЗрдЯрд╛рдЙрдБрджреИ (рдпрджрд┐ рдХреБрдиреИ рд╣реЛ рднрдиреЗ),
  • dependency? - рдкрд░реАрдХреНрд╖рдг рднреВрдорд┐рдХрд╛рдХреЛ рдЙрддреНрддрд░рджрд╛рдпреА рдирд┐рд░реНрднрд░рддрд╛рдХреЛ рд╕реНрдерд╛рдкрдирд╛,
  • syntax - рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рднреВрдорд┐рдХрд╛рдХреЛ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдЬрд╛рдБрдЪ рдЧрд░реНрджреИ ansible-playbook --syntax-check,
  • create - рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╕рд┐рд░реНрдЬрдирд╛,
  • prepare? - рдЙрджрд╛рд╣рд░рдг рдХреЛ рддрдпрд╛рд░реА; рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐ python2 рдЬрд╛рдБрдЪ/рд╕реНрдерд╛рдкрдирд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН
  • converge - рдкрд░реАрдХреНрд╖рдг рднрдЗрд░рд╣реЗрдХреЛ рдкреНрд▓реЗрдмреБрдХрдХреЛ рд╕реБрд░реБрд╡рд╛рдд,
  • idempotence - idempotency рдкрд░реАрдХреНрд╖рдгрдХреЛ рд▓рд╛рдЧрд┐ рдкреНрд▓реЗрдмреБрдХ рдкреБрди: рд╕реБрд░реБ рдЧрд░реНрджреИ,
  • 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ред рдпреА рдлрд╛рдЗрд▓рд╣рд░реВ рдЕрдкреЗрдХреНрд╖рд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН рдЕрдгреБ рд▓рд┐рдкрд┐ рдлреЛрд▓реНрдбрд░рдорд╛ рд╣реБрдиреЗрдЫред

рдЪрд╛рд▓рдХ

рдЪрд╛рд▓рдХ рдПрдЙрдЯрд╛ рд╕рдВрд╕реНрдерд╛ рд╣реЛ рдЬрд╣рд╛рдБ рдкрд░реАрдХреНрд╖рдг рдЙрджрд╛рд╣рд░рдгрд╣рд░реВ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░рд┐рдиреНрдЫред
рдорд╛рдирдХ рдбреНрд░рд╛рдЗрднрд░рд╣рд░реВрдХреЛ рд╕реВрдЪреА рдЬрд╕рдХреЛ рд▓рд╛рдЧрд┐ рдЕрдгреБрд╕рдБрдЧ рдЯреЗрдореНрдкреНрд▓реЗрдЯрд╣рд░реВ рддрдпрд╛рд░ рдЫрдиреН: 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

рдирд┐рд░реНрднрд░рддрд╛

рдпреЛ рдЦрдгреНрдбрд▓реЗ рдирд┐рд░реНрднрд░рддрд╛рдХреЛ рд╕реНрд░реЛрддрдХреЛ рд╡рд░реНрдгрди рдЧрд░реНрджрдЫред

╨Т╨░╤А╨╕╨░╨╜╤В╤Л╨╡ :╤Л: рдЖрдХрд╛рд╢рдЧрдВрдЧрд╛, giltar, рдЦреЛрд▓ред

рд╢реЗрд▓ рдХреЗрд╡рд▓ рдПрдХ рдХрдорд╛рдгреНрдб рд╢реЗрд▓ рд╣реЛ рдЬреБрди рдЧреНрдпрд╛рд▓реЗрдХреНрд╕реА рд░ рдЧрд┐рд▓реНрдЯрд▓реЗ рддрдкрд╛рдИрдВрдХреЛ рдЖрд╡рд╢реНрдпрдХрддрд╛рд╣рд░реВ рдкреВрд░рд╛ рдЧрд░реНрджреИрди рднрдиреЗ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдиреНрдЫред

рдо рдпрд╣рд╛рдБ рд▓рд╛рдореЛ рд╕рдордп рдмрд╕реНрдиреЗ рдЫреИрди, рдпреЛ рдорд╛ рд╡рд░реНрдгрди рдкрд░реНрдпрд╛рдкреНрдд рдЫ рдХрд╛рдЧрдЬрд╛рдд.

рдЪрд╛рд▓рдХ

рдЪрд╛рд▓рдХрдХреЛ рдирд╛рдоред рд╣рд╛рдореНрд░реЛ рдбрдХрд░ рд╣реЛред

рд▓рд┐рдиреНрдЯ

рд▓рд┐рдиреНрдЯрд░ рдпрдорд▓реНрд▓рд┐рдиреНрдЯ рд╣реЛред

рдХрдиреНрдлрд┐рдЧрд░реЗрд╕рдирдХреЛ рдпрд╕ рднрд╛рдЧрдорд╛ рдЙрдкрдпреЛрдЧреА рд╡рд┐рдХрд▓реНрдкрд╣рд░реВ 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 рдорд╛ ubuntu.

рдкреНрд░рд╛рд╡рдзрд╛рдирдХрд░реНрддрд╛

"рдЖрдкреВрд░реНрддрд┐рдХрд░реНрддрд╛" - рдЙрджрд╛рд╣рд░рдгрд╣рд░реВ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрди рдЧрд░реНрдиреЗ рдПрдХ рд╕рдВрд╕реНрдерд╛ред рдЕрдгреБрдХреЛ рдорд╛рдорд▓рд╛рдорд╛, рдпреЛ рдЙрддреНрддрд░рджрд╛рдпреА рдЫ, рдЕрд░реВрдХреЛ рд▓рд╛рдЧрд┐ рд╕рдорд░реНрдерди рдпреЛрдЬрдирд╛рдмрджреНрдз рдЫреИрди, рддреНрдпрд╕реИрд▓реЗ рдпреЛ рдЦрдгреНрдбрд▓рд╛рдИ рдЪреЗрддрд╛рд╡рдиреАрдХреЛ рд╕рд╛рде рдЙрддреНрддрд░рджрд╛рдпреА рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрдиреНрдлрд┐рдЧрд░реЗрд╕рди рднрдиреНрди рд╕рдХрд┐рдиреНрдЫред
рдпрд╣рд╛рдБ рддрдкрд╛рдИрд▓реЗ рдзреЗрд░реИ рдЪреАрдЬрд╣рд░реВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ, рдо рдореБрдЦреНрдп рдмреБрдБрджрд╛рд╣рд░реВ рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдЧрд░реНрдиреЗрдЫреБ, рдореЗрд░реЛ рд╡рд┐рдЪрд╛рд░рдорд╛:

  • рдкреНрд▓реЗрдмреБрдХрд╣рд░реВ: рддрдкрд╛рдЗрдБ рдирд┐рд╢реНрдЪрд┐рдд рдЪрд░рдгрд╣рд░реВрдорд╛ рдХреБрди рдкреНрд▓реЗрдмреБрдХрд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдиреБ рдкрд░реНрдЫ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫред

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

рдЬрд╛рдБрдЪ

рдкрд░реАрдХреНрд╖рдгрдХреЛ рд▓рд╛рдЧрд┐ рдПрдХ рд░реВрдкрд░реЗрдЦрд╛ рд░ рдпрд╕рдорд╛ рдПрдХ рд▓рд┐рдиреНрдЯрд░ рд╕реЗрдЯ рдЕрдк рдЧрд░реНрджреИред рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд linter рдЫ 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.

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

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

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

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

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдердкреНрди