ΠΠ΄ΡΠ°Π²Π΅ΠΉΡΠ΅ Π½Π° Π²ΡΠΈΡΠΊΠΈ!
Π Π°Π±ΠΎΡΡ ΠΊΠ°ΡΠΎ DevOps ΠΈΠ½ΠΆΠ΅Π½Π΅Ρ Π² ΡΡΠ»ΡΠ³Π° Π·Π° Ρ
ΠΎΡΠ΅Π»ΡΠΊΠΈ ΡΠ΅Π·Π΅ΡΠ²Π°ΡΠΈΠΈ.
Π Ostrovok.ru ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ansible ΠΊΠ°ΡΠΎ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π΅Π½ ΠΌΠ΅Π½ΠΈΠ΄ΠΆΡΡ. ΠΠ°ΡΠΊΠΎΡΠΎ ΡΡΠΈΠ³Π½Π°Ρ ΠΌΠ΅ Π΄ΠΎ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΡΠ° Π΄Π° ΡΠ΅ΡΡΠ²Π°ΠΌΠ΅ ΡΠΎΠ»ΠΈ, Π½ΠΎ ΠΊΠ°ΠΊΡΠΎ ΡΠ΅ ΠΎΠΊΠ°Π·Π°, Π½ΡΠΌΠ° ΡΠΎΠ»ΠΊΠΎΠ²Π° ΠΌΠ½ΠΎΠ³ΠΎ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈ Π·Π° ΡΠΎΠ²Π° - Π½Π°ΠΉ-ΠΏΠΎΠΏΡΠ»ΡΡΠ½ΠΈΡΡ ΠΌΠΎΠΆΠ΅ Π±ΠΈ Π΅ Molecule framework, ΡΠ°ΠΊΠ° ΡΠ΅ ΡΠ΅ΡΠΈΡ ΠΌΠ΅ Π΄Π° Π³ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅. ΠΠΎ ΡΠ΅ ΠΎΠΊΠ°Π·Π°, ΡΠ΅ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡΡΠ° ΠΌΡ ΠΌΡΠ»ΡΠΈ Π·Π° ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ΄Π²ΠΎΠ΄Π½ΠΈ ΠΊΠ°ΠΌΡΠ½ΠΈ. ΠΠ΅ ΡΡΠΏΡΡ ΠΌΠ΅ Π΄Π° Π½Π°ΠΌΠ΅ΡΠΈΠΌ Π΄ΠΎΡΡΠ°ΡΡΡΠ½ΠΎ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎ ΡΡΠΊΠΎΠ²ΠΎΠ΄ΡΡΠ²ΠΎ Π½Π° ΡΡΡΠΊΠΈ, Π·Π°ΡΠΎΠ²Π° ΡΠ΅ΡΠΈΡ ΠΌΠ΅ Π΄Π° Π½Π°ΠΏΠΈΡΠ΅ΠΌ ΡΠ°Π·ΠΈ ΡΡΠ°ΡΠΈΡ.
ΠΌΠΎΠ»Π΅ΠΊΡΠ»Π°
ΠΠΏΡΠΎΡΡΠ΅Π½ΠΎ ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅: ΠΠΎΠ»Π΅ΠΊΡΠ»Π°ΡΠ° ΡΡΠ·Π΄Π°Π²Π° Π΅ΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ Π½Π° ΠΏΠ»Π°ΡΡΠΎΡΠΌΠ°ΡΠ°, ΠΊΠΎΡΡΠΎ ΠΏΠΎΡΠΎΡΠΈΡΠ΅ (ΠΎΠ±Π»Π°ΠΊ, Π²ΠΈΡΡΡΠ°Π»Π½Π° ΠΌΠ°ΡΠΈΠ½Π°, ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ; Π·Π° ΠΏΠΎΠ²Π΅ΡΠ΅ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎΡΡΠΈ Π²ΠΈΠΆΡΠ΅ ΡΠ°Π·Π΄Π΅Π»Π°
Π‘Π΅Π³Π° ΠΏΠΎΠ²Π΅ΡΠ΅.
ΠΠ°Π»ΠΊΠΎ ΡΠ΅ΠΎΡΠΈΡ
ΠΠΎΠΌΠΈΡΠ»Π΅ΡΠ΅ Π·Π° Π΄Π²Π΅ ΠΊΠ»ΡΡΠΎΠ²ΠΈ Π΅Π΄ΠΈΠ½ΠΈΡΠΈ Π½Π° ΠΌΠΎΠ»Π΅ΠΊΡΠ»Π°ΡΠ°: ΡΡΠ΅Π½Π°ΡΠΈΠΉ ΠΈ Π΄ΡΠ°ΠΉΠ²Π΅Ρ.
Π‘ΡΠ΅Π½Π°ΡΠΈΠΉ
Π‘ΠΊΡΠΈΠΏΡΡΡ ΡΡΠ΄ΡΡΠΆΠ° ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ ΠΊΠ°ΠΊΠ²ΠΎ, ΠΊΡΠ΄Π΅, ΠΊΠ°ΠΊ ΠΈ Π² ΠΊΠ°ΠΊΠ²Π° ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»Π½ΠΎΡΡ ΡΠ΅ ΡΠ΅ ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π°. ΠΠ΄Π½Π° ΡΠΎΠ»Ρ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠΌΠ° Π½ΡΠΊΠΎΠ»ΠΊΠΎ ΡΠΊΡΠΈΠΏΡΠ° ΠΈ Π²ΡΠ΅ΠΊΠΈ ΠΎΡ ΡΡΡ
Π΅ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ ΠΏΠΎ ΠΏΡΡΡ <role>/molecule/<scenario>
, ΠΊΠΎΠΉΡΠΎ ΡΡΠ΄ΡΡΠΆΠ° ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ Π½Π° Π΄Π΅ΠΉΡΡΠ²ΠΈΡΡΠ°, Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΈ Π·Π° ΡΠ΅ΡΡΠ°. Π‘ΠΊΡΠΈΠΏΡΡΡ ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π΅ Π²ΠΊΠ»ΡΡΠ΅Π½ default
, ΠΊΠΎΠΉΡΠΎ ΡΠ΅ Π±ΡΠ΄Π΅ ΡΡΠ·Π΄Π°Π΄Π΅Π½ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ½ΠΎ, Π°ΠΊΠΎ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠ°ΡΠ΅ ΡΠΎΠ»ΡΡΠ° Ρ Molecule. ΠΠΌΠ΅Π½Π°ΡΠ° Π½Π° ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ ΡΠΊΡΠΈΠΏΡΠΎΠ²Π΅ Π·Π°Π²ΠΈΡΡΡ ΠΎΡ Π²Π°Ρ.
ΠΠ·Π²ΠΈΠΊΠ²Π° ΡΠ΅ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»Π½ΠΎΡΡΡΠ° ΠΎΡ ΡΠ΅ΡΡΠΎΠ²ΠΈ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ Π² ΡΠΊΡΠΈΠΏΡ ΠΌΠ°ΡΡΠΈΡΠ°ΠΈ ΠΏΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅ Π΅:
(Π‘ΡΡΠΏΠΊΠΈΡΠ΅ ΡΠ° ΠΎΠ±ΠΎΠ·Π½Π°ΡΠ΅Π½ΠΈ ?
, ΠΏΡΠΎΠΏΡΡΠΊΠ° ΡΠ΅ ΠΏΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅, Π°ΠΊΠΎ Π½Π΅ Π΅ ΠΏΠΎΡΠΎΡΠ΅Π½ΠΎ ΠΎΡ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ)
lint
- ΡΠ΅ΡΠ°ΡΠΈ Π»ΠΈΠ½ΡΠ΅ΡΠΈ. ΠΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρyamllint
ΠΈflake8
,destroy
- ΠΈΠ·ΡΡΠΈΠ²Π°Π½Π΅ Π½Π° Π΅ΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΈ ΠΎΡ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΎΡΠΎ ΡΡΠ°ΡΡΠΈΡΠ°Π½Π΅ Π½Π° Molecule (Π°ΠΊΠΎ ΠΈΠΌΠ° ΡΠ°ΠΊΠΈΠ²Π°),dependency
? β ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°Π½Π΅ Π½Π° Π°Π½Π·ΠΈΠ±ΠΈΠ»Π½Π°ΡΠ° Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ Π½Π° ΡΠ΅ΡΡΠ²Π°Π½Π°ΡΠ° ΡΠΎΠ»Ρ,syntax
- ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° Π½Π° ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ° Π½Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π°ΡΠ° ΡΠΎΠ»Ρansible-playbook --syntax-check
,create
- ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ Π½Π° Π΅ΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ,prepare
? β ΠΏΠΎΠ΄Π³ΠΎΡΠΎΠ²ΠΊΠ° Π½Π° ΠΈΠ½ΡΡΠ°Π½ΡΠΈΡΡΠ°; Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ ΠΏΡΠΎΠ²Π΅ΡΠ΅ΡΠ΅/ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°ΠΉΡΠ΅ python2converge
β ΡΡΠ°ΡΡΠΈΡΠ°Π½Π΅ Π½Π° ΡΠ΅ΡΡΠ²Π°Π½Π°ΡΠ° ΠΊΠ½ΠΈΠ³Π° Π·Π° ΠΈΠ³ΡΠΈ,idempotence
- ΡΠ΅ΡΡΠ°ΡΡΠΈΡΠ°Π½Π΅ Π½Π° ΠΊΠ½ΠΈΠ³Π°ΡΠ° Π·Π° ΡΠ΅ΡΡΠ° Π·Π° ΠΈΠ΄Π΅ΠΌΠΏΠΎΡΠ΅Π½ΡΠ½ΠΎΡΡ,side_effect
? - Π΄Π΅ΠΉΡΡΠ²ΠΈΡ, ΠΊΠΎΠΈΡΠΎ Π½Π΅ ΡΠ° ΠΏΡΡΠΊΠΎ ΡΠ²ΡΡΠ·Π°Π½ΠΈ Ρ ΡΠΎΠ»ΡΡΠ°, Π½ΠΎ ΡΠ° Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΈ Π·Π° ΡΠ΅ΡΡΠΎΠ²Π΅,verify
- ΠΏΡΠΎΠ²Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° ΡΠ΅ΡΡΠΎΠ²Π΅ Π½Π° ΠΏΠΎΠ»ΡΡΠ΅Π½Π°ΡΠ° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ Ρ ΠΏΠΎΠΌΠΎΡΡΠ°testinfra
(ΠΏΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅) /goss
/inspec
,cleanup
? - (Π² Π½ΠΎΠ²ΠΈΡΠ΅ Π²Π΅ΡΡΠΈΠΈ) - Π³ΡΡΠ±ΠΎ ΠΊΠ°Π·Π°Π½ΠΎ, "ΠΏΠΎΡΠΈΡΡΠ²Π°Π½Π΅" Π½Π° Π²ΡΠ½ΡΠ½Π°ΡΠ° ΠΈΠ½ΡΡΠ°ΡΡΡΡΠΊΡΡΡΠ°, Π·Π°ΡΠ΅Π³Π½Π°ΡΠ° ΠΎΡ ΠΠΎΠ»Π΅ΠΊΡΠ»Π°ΡΠ°,destroy
- ΠΠ·ΡΡΠΈΠ²Π°Π½Π΅ Π½Π° Π΅ΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ.
Π’Π°Π·ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»Π½ΠΎΡΡ ΠΎΠ±Ρ Π²Π°ΡΠ° ΠΏΠΎΠ²Π΅ΡΠ΅ΡΠΎ ΡΠ»ΡΡΠ°ΠΈ, Π½ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ ΠΏΡΠΎΠΌΠ΅Π½Π΅Π½Π°, Π°ΠΊΠΎ Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ.
ΠΡΡΠΊΠ° ΠΎΡ Π³ΠΎΡΠ½ΠΈΡΠ΅ ΡΡΡΠΏΠΊΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π° ΠΎΡΠ΄Π΅Π»Π½ΠΎ Ρ molecule <command>
. ΠΠΎ ΡΡΡΠ±Π²Π° Π΄Π° ΡΠ΅ ΡΠ°Π·Π±Π΅ΡΠ΅, ΡΠ΅ Π·Π° Π²ΡΡΠΊΠ° ΡΠ°ΠΊΠ°Π²Π° cli-ΠΊΠΎΠΌΠ°Π½Π΄Π° ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠΌΠ° ΡΠ²ΠΎΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π° ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»Π½ΠΎΡΡ ΠΎΡ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ, ΠΊΠΎΠΈΡΠΎ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΡΠ°Π·Π±Π΅ΡΠ΅ΡΠ΅, ΠΊΠ°ΡΠΎ ΠΈΠ·ΠΏΡΠ»Π½ΠΈΡΠ΅ molecule matrix <command>
. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΊΠΎΠ³Π°ΡΠΎ ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π°ΡΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° converge
(ΠΏΡΡΠΊΠ°Π½Π΅ Π½Π° ΡΠ΅ΡΡΠ²Π°Π½Π°ΡΠ° ΠΊΠ½ΠΈΠ³Π° Π·Π° ΠΈΠ³ΡΠ°), ΡΠ΅ Π±ΡΠ΄Π°Ρ ΠΈΠ·Π²ΡΡΡΠ΅Π½ΠΈ ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ:
$ molecule matrix converge
...
βββ default # Π½Π°Π·Π²Π°Π½ΠΈΠ΅ ΡΡΠ΅Π½Π°ΡΠΈΡ
βββ dependency # ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠ° Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠ΅ΠΉ
βββ create # ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΈΠ½ΡΡΠ°Π½ΡΠ°
βββ prepare # ΠΏΡΠ΅Π΄Π½Π°ΡΡΡΠΎΠΉΠΊΠ° ΠΈΠ½ΡΡΠ°Π½ΡΠ°
βββ converge # ΠΏΡΠΎΠ³ΠΎΠ½ ΠΏΠ»Π΅ΠΉΠ±ΡΠΊΠ°
ΠΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»Π½ΠΎΡΡΡΠ° Π½Π° ΡΠ΅Π·ΠΈ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠ°. ΠΠΊΠΎ Π½Π΅ΡΠΎ ΠΎΡ ΡΠΏΠΈΡΡΠΊΠ° Π²Π΅ΡΠ΅ Π΅ Π½Π°ΠΏΡΠ°Π²Π΅Π½ΠΎ, ΡΠΎ ΡΠ΅ Π±ΡΠ΄Π΅ ΠΏΡΠΎΠΏΡΡΠ½Π°ΡΠΎ. Π’Π΅ΠΊΡΡΠΎΡΠΎ ΡΡΡΡΠΎΡΠ½ΠΈΠ΅, ΠΊΠ°ΠΊΡΠΎ ΠΈ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΡΠ° Π½Π° Π΅ΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΈΡΠ΅, Molecule ΡΡΡ
ΡΠ°Π½ΡΠ²Π° Π² Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡΡΠ° $TMPDIR/molecule/<role>/<scenario>
.
ΠΠΎΠ±Π°Π²Π΅ΡΠ΅ ΡΡΡΠΏΠΊΠΈ Ρ ?
ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΎΠΏΠΈΡΠ΅ΡΠ΅ ΠΆΠ΅Π»Π°Π½ΠΈΡΠ΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ Π²ΡΠ² ΡΠΎΡΠΌΠ°ΡΠ° Π½Π° ansible-playbook ΠΈ Π΄Π° Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ΅ ΠΈΠΌΠ΅ΡΠΎ Π½Π° ΡΠ°ΠΉΠ»Π° ΡΠΏΠΎΡΠ΅Π΄ ΡΡΡΠΏΠΊΠ°ΡΠ°: prepare.yml
/side_effect.yml
. ΠΡΠ°ΠΊΠ²Π°ΠΉΡΠ΅ ΡΠ΅Π·ΠΈ ΡΠ°ΠΉΠ»ΠΎΠ²Π΅. ΠΠΎΠ»Π΅ΠΊΡΠ»Π°ΡΠ° ΡΠ΅ Π±ΡΠ΄Π΅ Π² ΠΏΠ°ΠΏΠΊΠ°ΡΠ° Π½Π° ΡΠΊΡΠΈΠΏΡΠ°.
Π΄ΡΠ°ΠΉΠ²Π΅Ρ
ΠΡΠ°ΠΉΠ²Π΅ΡΡΡ Π΅ ΠΎΠ±Π΅ΠΊΡ, Π² ΠΊΠΎΠΉΡΠΎ ΡΠ΅ ΡΡΠ·Π΄Π°Π²Π°Ρ ΡΠ΅ΡΡΠΎΠ²ΠΈ Π΅ΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΈ.
Π‘ΠΏΠΈΡΡΠΊΡΡ ΡΡΡ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΈ Π΄ΡΠ°ΠΉΠ²Π΅ΡΠΈ, Π·Π° ΠΊΠΎΠΈΡΠΎ Molecule ΠΈΠΌΠ° Π³ΠΎΡΠΎΠ²ΠΈ ΡΠ°Π±Π»ΠΎΠ½ΠΈ, Π΅ ΠΊΠ°ΠΊΡΠΎ ΡΠ»Π΅Π΄Π²Π°: Azure, Docker, EC2, GCE, LXC, LXD, OpenStack, Vagrant, Delegated.
Π ΠΏΠΎΠ²Π΅ΡΠ΅ΡΠΎ ΡΠ»ΡΡΠ°ΠΈ ΡΠ°Π±Π»ΠΎΠ½ΠΈΡΠ΅ ΡΠ° ΡΠ°ΠΉΠ»ΠΎΠ²Π΅ create.yml
ΠΈ destroy.yml
Π² ΠΏΠ°ΠΏΠΊΠ°ΡΠ° Π½Π° ΡΠΊΡΠΈΠΏΡΠ°, ΠΊΠΎΠΈΡΠΎ ΠΎΠΏΠΈΡΠ²Π°Ρ ΡΡΠΎΡΠ²Π΅ΡΠ½ΠΎ ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ΡΠΎ ΠΈ ΠΈΠ·ΡΡΠΈΠ²Π°Π½Π΅ΡΠΎ Π½Π° Π΅ΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ.
ΠΠ·ΠΊΠ»ΡΡΠ΅Π½ΠΈΡΡΠ° ΡΠ° Docker ΠΈ Vagrant, ΡΡΠΉ ΠΊΠ°ΡΠΎ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΡΡΠ° Ρ ΡΠ΅Ρ
Π½ΠΈΡΠ΅ ΠΌΠΎΠ΄ΡΠ»ΠΈ ΠΌΠΎΠ³Π°Ρ Π΄Π° ΡΠ΅ ΠΎΡΡΡΠ΅ΡΡΠ²ΡΡ Π±Π΅Π· Π³ΠΎΡΠ΅ΡΠΏΠΎΠΌΠ΅Π½Π°ΡΠΈΡΠ΅ ΡΠ°ΠΉΠ»ΠΎΠ²Π΅.
Π‘ΡΡΡΠ²Π° ΡΠΈ Π΄Π° ΡΠ΅ ΠΏΠΎΠ΄ΡΠ΅ΡΡΠ°Π΅ Π΄Π΅Π»Π΅Π³ΠΈΡΠ°Π½ΠΈΡΡ Π΄ΡΠ°ΠΉΠ²Π΅Ρ, ΡΡΠΉ ΠΊΠ°ΡΠΎ Π°ΠΊΠΎ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π²ΡΠ² ΡΠ°ΠΉΠ»ΠΎΠ²Π΅ΡΠ΅ Π·Π° ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ ΠΈ ΠΈΠ·ΡΡΠΈΠ²Π°Π½Π΅ Π½Π° Π΅ΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ, ΡΠ΅ ΠΎΠΏΠΈΡΠ²Π° ΡΠ°ΠΌΠΎ ΡΠ°Π±ΠΎΡΠ°ΡΠ° Ρ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΡΠ° Π½Π° Π΅ΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΈΡΠ΅, ΠΎΡΡΠ°Π½Π°Π»ΠΎΡΠΎ ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π΅ ΠΎΠΏΠΈΡΠ°Π½ΠΎ ΠΎΡ ΠΈΠ½ΠΆΠ΅Π½Π΅ΡΠ°.
ΠΡΠ°ΠΉΠ²Π΅ΡΡΡ ΠΏΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅ Π΅ Docker.
Π‘Π΅Π³Π° Π½Π΅ΠΊΠ° Π΄Π° ΠΏΡΠ΅ΠΌΠΈΠ½Π΅ΠΌ ΠΊΡΠΌ ΠΏΡΠ°ΠΊΡΠΈΠΊΠ°ΡΠ° ΠΈ Π΄Π° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Π΄ΠΎΠΏΡΠ»Π½ΠΈΡΠ΅Π»Π½ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ ΡΠ°ΠΌ.
ΠΡΡΠ²ΠΈ ΡΡΡΠΏΠΊΠΈ
ΠΠ°ΡΠΎ βΠ·Π΄ΡΠ°Π²Π΅ΠΉ ΡΠ²ΡΡβ, Π½Π΅ΠΊΠ° ΡΠ΅ΡΡΠ²Π°ΠΌΠ΅ ΠΏΡΠΎΡΡΠ° ΠΈΠ½ΡΡΠ°Π»Π°ΡΠΈΠΎΠ½Π½Π° ΡΠΎΠ»Ρ Π½Π° nginx. ΠΠ΅ΠΊΠ° ΠΈΠ·Π±Π΅ΡΠ΅ΠΌ docker ΠΊΠ°ΡΠΎ Π΄ΡΠ°ΠΉΠ²Π΅Ρ - ΠΌΠΈΡΠ»Ρ, ΡΠ΅ ΠΏΠΎΠ²Π΅ΡΠ΅ΡΠΎ ΠΎΡ Π²Π°Ρ Π³ΠΎ ΠΈΠΌΠ°Ρ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°Π½ (ΠΈ Π½Π΅ Π·Π°Π±ΡΠ°Π²ΡΠΉΡΠ΅, ΡΠ΅ docker Π΅ Π΄ΡΠ°ΠΉΠ²Π΅ΡΡΡ ΠΏΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅).
ΠΏΠΎΠ΄Π³ΠΎΡΠ²ΠΈ 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
Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΡΠ°
Π’ΠΎΠ·ΠΈ ΡΠ°Π·Π΄Π΅Π» ΠΎΠΏΠΈΡΠ²Π° ΠΈΠ·ΡΠΎΡΠ½ΠΈΠΊΠ° Π½Π° Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ.
ΠΡΠ·ΠΌΠΎΠΆΠ½ΡΠ΅ Π²Π°ΡΠΈΠ°Π½ΡΠΈ:
Shell Π΅ ΠΏΡΠΎΡΡΠΎ ΠΊΠΎΠΌΠ°Π½Π΄Π½Π° ΠΎΠ±Π²ΠΈΠ²ΠΊΠ°, ΠΊΠΎΡΡΠΎ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π² ΡΠ»ΡΡΠ°ΠΉ, ΡΠ΅ galaxy ΠΈ gilt Π½Π΅ ΠΏΠΎΠΊΡΠΈΠ²Π°Ρ Π²Π°ΡΠΈΡΠ΅ Π½ΡΠΆΠ΄ΠΈ.
ΠΡΠΌΠ° Π΄Π° ΡΠ΅ ΡΠΏΠΈΡΠ°ΠΌ ΡΡΠΊ Π΄ΡΠ»Π³ΠΎ, Π΄ΠΎΡΡΠ°ΡΡΡΠ½ΠΎ Π΅ ΠΎΠΏΠΈΡΠ°Π½ΠΎ Π²
ΡΠΎΡΡΠΎΡ
ΠΠΌΠ΅ΡΠΎ Π½Π° Π²ΠΎΠ΄Π°ΡΠ°. ΠΠ°ΡΠΈΡΡ Π΅ Π΄ΠΎΠΊΠ΅Ρ.
ΠΌΠ°ΡΠ»Ρ
ΠΠΈΠ½ΡΠ΅ΡΡΡ Π΅ ΡΠΌΠ»ΠΈΠ½Ρ.
ΠΠΎΠ»Π΅Π·Π½ΠΈ ΠΎΠΏΡΠΈΠΈ Π² ΡΠ°Π·ΠΈ ΡΠ°ΡΡ ΠΎΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΡΠ° ΡΠ° Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡΠ° Π·Π° ΡΠΊΠ°Π·Π²Π°Π½Π΅ Π½Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π΅Π½ ΡΠ°ΠΉΠ» Π·Π° yamllint, ΠΏΡΠ΅ΠΏΡΠ°ΡΠ°Π½Π΅ Π½Π° ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ Π½Π° ΡΡΠ΅Π΄Π°ΡΠ° ΠΈΠ»ΠΈ Π΄Π΅Π°ΠΊΡΠΈΠ²ΠΈΡΠ°Π½Π΅ Π½Π° Π»ΠΈΠ½ΡΠ΅ΡΠ°:
lint:
name: yamllint
options:
config-file: foo/bar
env:
FOO: bar
enabled: False
ΠΏΠ»Π°ΡΡΠΎΡΠΌΠΈ
ΠΠΏΠΈΡΠ²Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΡΠ° Π½Π° Π΅ΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΈΡΠ΅.
Π ΡΠ»ΡΡΠ°ΠΉ Π½Π° Π΄ΠΎΠΊΠ΅Ρ ΠΊΠ°ΡΠΎ Π΄ΡΠ°ΠΉΠ²Π΅Ρ, Molecule ΡΠ΅ ΠΏΠΎΠ²ΡΠ°ΡΡ ΠΏΡΠ΅Π· ΡΠΎΠ·ΠΈ ΡΠ°Π·Π΄Π΅Π» ΠΈ Π²ΡΠ΅ΠΊΠΈ Π΅Π»Π΅ΠΌΠ΅Π½Ρ ΠΎΡ ΡΠΏΠΈΡΡΠΊΠ° Π΅ Π΄ΠΎΡΡΡΠΏΠ΅Π½ Π² Dockerfile.j2
ΠΊΠ°ΡΠΎ ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° item
.
Π ΡΠ»ΡΡΠ°ΠΉ Π½Π° Π΄ΡΠ°ΠΉΠ²Π΅Ρ, ΠΊΠΎΠΉΡΠΎ ΠΈΠ·ΠΈΡΠΊΠ²Π° create.yml
ΠΈ destroy.yml
, ΡΠ΅ΠΊΡΠΈΡΡΠ° Π΅ Π½Π°Π»ΠΈΡΠ½Π° Π² ΡΡΡ
ΠΊΠ°ΡΠΎ molecule_yml.platforms
ΠΈ ΠΈΡΠ΅ΡΠ°ΡΠΈΠΈΡΠ΅ Π½Π°Π΄ Π½Π΅Π³ΠΎ Π²Π΅ΡΠ΅ ΡΠ° ΠΎΠΏΠΈΡΠ°Π½ΠΈ Π² ΡΠ΅Π·ΠΈ ΡΠ°ΠΉΠ»ΠΎΠ²Π΅.
Π’ΡΠΉ ΠΊΠ°ΡΠΎ Molecule ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Ρ ΠΊΠΎΠ½ΡΡΠΎΠ» Π½Π° Π΅ΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΈ Π½Π° ansible ΠΌΠΎΠ΄ΡΠ»ΠΈ, ΡΠΏΠΈΡΡΠΊΡΡ Ρ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΈ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ ΡΡΡΠΎ ΡΡΡΠ±Π²Π° Π΄Π° ΡΠ΅ ΡΡΡΡΠΈ ΡΠ°ΠΌ. ΠΠ° Π΄ΠΎΠΊΠ΅Ρ Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΌΠΎΠ΄ΡΠ»ΡΡ
ΠΠ°ΠΊΡΠΎ ΠΈ ΠΏΡΠΈΠΌΠ΅ΡΠΈ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ Π΄ΡΠ°ΠΉΠ²Π΅ΡΠΈ ΠΌΠΎΠ³Π°Ρ Π΄Π° Π±ΡΠ΄Π°Ρ Π½Π°ΠΌΠ΅ΡΠ΅Π½ΠΈ
ΠΠ°ΠΌΠ΅Π½Π΅ΡΠ΅ ΡΡΠΊ ΡΠ΅Π½ΡΠΎ:7 Π½Π° Ubuntu.
Π΄ΠΎΡΡΠ°Π²ΡΠΈΠΊ
"ΠΠΎΡΡΠ°Π²ΡΠΈΠΊ" - ΡΡΠ±Π΅ΠΊΡ, ΠΊΠΎΠΉΡΠΎ ΡΠΏΡΠ°Π²Π»ΡΠ²Π° Π΅ΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΈ. Π ΡΠ»ΡΡΠ°Ρ Π½Π° Molecule ΡΠΎΠ²Π° Π΅ ansible, ΠΏΠΎΠ΄Π΄ΡΡΠΆΠΊΠ° Π·Π° Π΄ΡΡΠ³ΠΈ Π½Π΅ Π΅ ΠΏΠ»Π°Π½ΠΈΡΠ°Π½Π°, ΡΠ°ΠΊΠ° ΡΠ΅ ΡΠΎΠ·ΠΈ ΡΠ°Π·Π΄Π΅Π» ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π½Π°ΡΠ΅ΡΠ΅ ansible ΡΠ°Π·ΡΠΈΡΠ΅Π½Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ Ρ Π΅Π΄Π½ΠΎ ΠΏΡΠ΅Π΄ΡΠΏΡΠ΅ΠΆΠ΄Π΅Π½ΠΈΠ΅.
Π’ΡΠΊ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΏΠΎΡΠΎΡΠΈΡΠ΅ ΠΌΠ½ΠΎΠ³ΠΎ Π½Π΅ΡΠ°, Π°Π· ΡΠ΅ ΠΏΠΎΠ΄ΡΠ΅ΡΡΠ°Ρ ΠΎΡΠ½ΠΎΠ²Π½ΠΈΡΠ΅ ΠΌΠΎΠΌΠ΅Π½ΡΠΈ, ΡΠΏΠΎΡΠ΅Π΄ ΠΌΠ΅Π½:
- playbooks: ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΏΠΎΡΠΎΡΠΈΡΠ΅ ΠΊΠΎΠΈ ΠΊΠ½ΠΈΠ³ΠΈ-ΠΈΠ³ΡΠΈ Π΄Π° ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ Π½Π° ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈ Π΅ΡΠ°ΠΏΠΈ.
provisioner:
name: ansible
playbooks:
create: create.yml
destroy: ../default/destroy.yml
converge: playbook.yml
side_effect: side_effect.yml
cleanup: cleanup.yml
- config_options:
ansible config
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'"
- ΠΎΠΏΡΠΈΠΈ: Ansible ΠΎΠΏΡΠΈΠΈ ΠΈ ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ Π½Π° ΡΡΠ΅Π΄Π°ΡΠ°
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
.
ΠΠ°ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅
ΠΠ°ΠΊΡΠΎ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡΠ΅, Molecule Π½Π΅ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΡΠ»ΠΎΠΆΠ΅Π½ ΠΈ ΡΡΠ΅Π· ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° Π²Π°ΡΠΈ ΡΠΎΠ±ΡΡΠ²Π΅Π½ΠΈ ΡΠ°Π±Π»ΠΎΠ½ΠΈ Π²Π½Π΅Π΄ΡΡΠ²Π°Π½Π΅ΡΠΎ Π½Π° Π½ΠΎΠ² ΡΠΊΡΠΈΠΏΡ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΡΠ²Π΅Π΄Π΅ Π΄ΠΎ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠ°Π½Π΅ Π½Π° ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ Π² ΠΊΠ½ΠΈΠ³ΠΈΡΠ΅ Π·Π° ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ ΠΈ ΠΈΠ·ΡΡΠΈΠ²Π°Π½Π΅ Π½Π° Π΅ΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΈ. ΠΠΎΠ»Π΅ΠΊΡΠ»Π°ΡΠ° ΡΠ΅ ΠΈΠ½ΡΠ΅Π³ΡΠΈΡΠ° Π±Π΅Π·ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ½ΠΎ Ρ CI ΡΠΈΡΡΠ΅ΠΌΠΈ, ΠΊΠΎΠ΅ΡΠΎ Π²ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° Π΄Π° ΡΠ²Π΅Π»ΠΈΡΠΈΡΠ΅ ΡΠΊΠΎΡΠΎΡΡΡΠ° Π½Π° ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ° ΡΡΠ΅Π· Π½Π°ΠΌΠ°Π»ΡΠ²Π°Π½Π΅ Π½Π° Π²ΡΠ΅ΠΌΠ΅ΡΠΎ Π·Π° ΡΡΡΠ½ΠΎ ΡΠ΅ΡΡΠ²Π°Π½Π΅ Π½Π° ΠΊΠ½ΠΈΠ³ΠΈΡΠ΅ Π·Π° ΠΈΠ³ΡΠΈ.
ΠΠ»Π°Π³ΠΎΠ΄Π°ΡΡ Π·Π° Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ΡΠΎ. ΠΠΊΠΎ ΠΈΠΌΠ°ΡΠ΅ ΠΎΠΏΠΈΡ Π² ΡΠ΅ΡΡΠ²Π°Π½Π΅ΡΠΎ Π½Π° Π°Π½Π·ΠΈΠ±ΠΈΠ»Π½ΠΈ ΡΠΎΠ»ΠΈ ΠΈ ΡΠΎΠ²Π° Π½Π΅ Π΅ ΡΠ²ΡΡΠ·Π°Π½ΠΎ Ρ Molecule, ΡΠ°Π·ΠΊΠ°ΠΆΠ΅ΡΠ΅ Π½ΠΈ Π·Π° ΡΠΎΠ²Π° Π² ΠΊΠΎΠΌΠ΅Π½ΡΠ°ΡΠΈΡΠ΅!
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: www.habr.com