Настройка сСрвСра для развСртывания Rails прилоТСния ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Ansible

НС Ρ‚Π°ΠΊ Π΄Π°Π²Π½ΠΎ ΠΌΠ½Π΅ Π±Ρ‹Π»ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ нСсколько ansible playbooks для ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠΈ сСрвСра ΠΊ дСплою rails прилоТСния. И, Π½Π° ΡƒΠ΄ΠΈΠ²Π»Π΅Π½ΠΈΠ΅, я Π½Π΅ нашСл простого пошагового ΠΌΠ°Π½ΡƒΠ°Π»Π°. ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‡ΡƒΠΆΠΎΠΉ ΠΏΠ»Π΅ΠΉΠ±ΡƒΠΊ Π±Π΅Π· понимая происходящСго я Π½Π΅ Ρ…ΠΎΡ‚Π΅Π» ΠΈ Π² ΠΈΡ‚ΠΎΠ³Π΅ ΠΏΡ€ΠΈΡˆΠ»ΠΎΡΡŒ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ, собирая всС ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ. Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΊΠΎΠΌΡƒ-Ρ‚ΠΎ я смогу ΠΏΠΎΠΌΠΎΡ‡ΡŒ этот процСсс ΡƒΡΠΊΠΎΡ€ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Π΄Π°Π½Π½ΠΎΠΉ ΡΡ‚Π°Ρ‚ΡŒΠΈ.

ΠŸΠ΅Ρ€Π²Ρ‹ΠΌ Π΄Π΅Π»ΠΎΠΌ стоит ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ansible прСдоставляСт Π²Π°ΠΌ ΡƒΠ΄ΠΎΠ±Π½Ρ‹ΠΉ интСрфСйс для выполнСния Π·Π°Ρ€Π°Π½Π΅Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ списка дСйствий Π½Π° ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠΌ сСрвСрС (сСрвСрах) Ρ‡Π΅Ρ€Π΅Π· SSH. Π’ΡƒΡ‚ Π½Π΅Ρ‚ Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ ΠΌΠ°Π³ΠΈΠΈ, нСльзя ΠΏΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΏΠ»Π°Π³ΠΈΠ½ ΠΈ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΈΠ· ΠΊΠΎΡ€ΠΎΠ±ΠΊΠΈ zero downtime Π΄Π΅ΠΏΠ»ΠΎΠΉ своСго прилоТСния с Π΄ΠΎΠΊΠ΅Ρ€ΠΎΠΌ, ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ΠΎΠΌ ΠΈ ΠΏΡ€ΠΎΡ‡ΠΈΠΌΠΈ плюшками. Для Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΏΠ»Π΅ΠΉΠ±ΡƒΠΊ Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π·Π½Π°Ρ‚ΡŒ Ρ‡Ρ‚ΠΎ ΠΈΠΌΠ΅Π½Π½ΠΎ Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΈ ΠΊΠ°ΠΊ это ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ мСня Π½Π΅ ΡƒΡΡ‚Ρ€Π°ΠΈΠ²Π°ΡŽΡ‚ Π³ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ ΠΏΠ»Π΅ΠΉΠ±ΡƒΠΊΠΈ с Π³ΠΈΡ‚Ρ…Π°Π±Π°, ΠΈΠ»ΠΈ ΡΡ‚Π°Ρ‚ΡŒΠΈ Π²ΠΈΠ΄Π°: β€œΠ‘ΠΊΠΎΠΏΠΈΡ€ΡƒΠΉΡ‚Π΅ ΠΈ запуститС, β€” Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒβ€.

Π§Ρ‚ΠΎ Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ?

Как я ΡƒΠΆΠ΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΠ», для Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΏΠ»Π΅ΠΉΠ±ΡƒΠΊ Π½Π°Π΄ΠΎ Π·Π½Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΈ ΠΊΠ°ΠΊ это ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ. Π”Π°Π²Π°ΠΉΡ‚Π΅ опрСдСлимся с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ. Для Rails прилоТСния Π½Π°ΠΌ понадобится нСсколько систСмных ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ²: nginx, postgresql (redis, e.t.c.). Помимо этого Π½Π°ΠΌ Π½ΡƒΠΆΠ΅Π½ ruby ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ вСрсии. Π‘Ρ‚Π°Π²ΠΈΡ‚ΡŒ Π΅Π³ΠΎ Π»ΡƒΡ‡ΡˆΠ΅ всСго Ρ‡Π΅Ρ€Π΅Π· rbenv (rvm, asdf…). Π—Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ всС это ΠΈΠ· ΠΏΠΎΠ΄ root ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ β€” всСгда плохая идСя, поэтому Π½Π°Π΄ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, ΠΈ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Π΅ΠΌΡƒ ΠΏΡ€Π°Π²Π°. ПослС этого Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π·Π°Π»ΠΈΡ‚ΡŒ наш ΠΊΠΎΠ΄ Π½Π° сСрвСр, ΡΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΠΈ для nginx, postgres, e.t.c. ΠΈ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ всС эти сСрвисы.

Π’ ΠΈΡ‚ΠΎΠ³Π΅ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ дСйствий такая:

  1. Логинимся ΠΏΠΎΠ΄ Ρ€ΡƒΡ‚ΠΎΠΌ
  2. устанавливаСм систСмныС ΠΏΠ°ΠΊΠ΅Ρ‚Ρ‹
  3. создаСм Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, настраиваСм ΠΏΡ€Π°Π²Π°, ssh ΠΊΠ»ΡŽΡ‡
  4. настраиваСм систСмныС ΠΏΠ°ΠΊΠ΅Ρ‚Ρ‹ (nginx e.t.c) ΠΈ запускаСм ΠΈΡ…
  5. Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π² Π‘Π” (ΠΌΠΎΠΆΠ½ΠΎ сразу ΠΈ Π±Π°Π·Ρƒ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ)
  6. Логинимся Π½ΠΎΠ²Ρ‹ΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΌ
  7. УстанавливаСм rbenv ΠΈ ruby
  8. УстанавливаСм Π±Π°Π½Π΄Π»Π΅Ρ€
  9. Π—Π°Π»ΠΈΠ²Π°Π΅ΠΌ ΠΊΠΎΠ΄ прилоТСния
  10. ЗапускаСм Puma сСрвСр

ΠŸΡ€ΠΈΡ‡Π΅ΠΌ послСдниС этапы ΠΌΠΎΠΆΠ½ΠΎ Π΄Π΅Π»Π°Ρ‚ΡŒ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ capistrano, ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅ ΠΎΠ½Π° ΠΈΠ· ΠΊΠΎΡ€ΠΎΠ±ΠΊΠΈ ΡƒΠΌΠ΅Π΅Ρ‚ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ΄ Π² Ρ€Π΅Π»ΠΈΠ·Π½Ρ‹Π΅ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ, ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ Ρ€Π΅Π»ΠΈΠ· симлинком ΠΏΡ€ΠΈ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΌ Π΄Π΅ΠΏΠ»ΠΎΠ΅, ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΠΈ ΠΈΠ· shared Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ, Ρ€Π΅ΡΡ‚Π°Ρ€Ρ‚ΠΎΠ²Π°Ρ‚ΡŒ puma ΠΈ.Ρ‚.Π΄. ВсС это ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΈ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Ansible, Π½ΠΎ Π·Π°Ρ‡Π΅ΠΌ?

Ѐайловая структура

Ansible ΠΈΠΌΠ΅Π΅Ρ‚ ΡΡ‚Ρ€ΠΎΠ³ΡƒΡŽ Ρ„Π°ΠΉΠ»ΠΎΠ²ΡƒΡŽ структуру для всСх своих Ρ„Π°ΠΉΠ»ΠΎΠ², поэтому Π»ΡƒΡ‡ΡˆΠ΅ всСго Π΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ всС это Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ. ΠŸΡ€ΠΈΡ‡Π΅ΠΌ Π½Π΅ Ρ‚Π°ΠΊ Π²Π°ΠΆΠ½ΠΎ, Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ½Π° Π² самом rails ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ, ΠΈΠ»ΠΈ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ. МоТно Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Ρ„Π°ΠΉΠ»Ρ‹ Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΌ git Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ. Π›ΠΈΡ‡Π½ΠΎ ΠΌΠ½Π΅ ΡƒΠ΄ΠΎΠ±Π½Π΅Π΅ всСго оказалось ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΡŽ ansible Π² /config Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ rails прилоТСния ΠΈ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ всС Π² ΠΎΠ΄Π½ΠΎΠΌ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ.

Simple Playbook

Playbook β€” это yml Ρ„Π°ΠΉΠ», Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ синтаксиса описано, Ρ‡Ρ‚ΠΎ ΠΈ ΠΊΠ°ΠΊ ansible Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ. Π”Π°Π²Π°ΠΉΡ‚Π΅ создадим ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠ»Π΅ΠΉΠ±ΡƒΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π΅ Π΄Π΅Π»Π°Π΅Ρ‚ Π½ΠΈΡ‡Π΅Π³ΠΎ:

---
- name: Simple playbook
  hosts: all

Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ просто Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ, Ρ‡Ρ‚ΠΎ наш playbook называСтся Simple Playbook ΠΈ Ρ‡Ρ‚ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ Π΅Π³ΠΎ содСрТимоС Π΄ΠΎΠ»ΠΆΠ½ΠΎ для всСх хостов. ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π΅Π³ΠΎ Π² /ansible Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ с ΠΈΠΌΠ΅Π½Π΅ΠΌ playbook.yml ΠΈ ΠΏΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ:

ansible-playbook ./playbook.yml

PLAY [Simple Playbook] ************************************************************************************************************************************
skipping: no hosts matched

Ansible Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ Ρ‡Ρ‚ΠΎ Π½Π΅ Π·Π½Π°Π΅Ρ‚ хостов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±Ρ‹ соотвСтсвовали списку all. Π˜Ρ… Π½Π°Π΄ΠΎ ΠΏΠ΅Ρ€Π΅Ρ‡ΠΈΡΠ»ΠΈΡ‚ΡŒ Π² ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠΌ inventory Ρ„Π°ΠΉΠ»Π΅.

Π”Π°Π²Π°ΠΉΡ‚Π΅ создадим Π΅Π³ΠΎ Π² Ρ‚ΠΎΠΉ ΠΆΠ΅ ansible Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ:

123.123.123.123

Π’ΠΎΡ‚ Ρ‚Π°ΠΊ просто ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ хост (Π² ΠΈΠ΄Π΅Π°Π»Π΅ хост своСго VPS для тСстов, ΠΈΠ»ΠΈ ΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ localhost ΠΏΡ€ΠΎΠΏΠΈΡΠ°Ρ‚ΡŒ) ΠΈ сохраняСм Π΅Π³ΠΎ ΠΏΠΎΠ΄ ΠΈΠΌΠ΅Π½Π΅ΠΌ inventory.
МоТно ΠΏΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ ansible с invetory Ρ„Π°ΠΉΠ»ΠΎΠΌ:

ansible-playbook ./playbook.yml -i inventory
PLAY [Simple Playbook] ************************************************************************************************************************************

TASK [Gathering Facts] ************************************************************************************************************************************

PLAY RECAP ************************************************************************************************************************************

Если Ρƒ вас Π΅ΡΡ‚ΡŒ доступ ΠΏΠΎ ssh ΠΊ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌΡƒ хосту Ρ‚ΠΎ ansible ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡΡ ΠΈ собСрСт ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎΠ± ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠΉ систСмС. (Π΄Π΅Ρ„ΠΎΠ»Ρ‚Π½Ρ‹ΠΉ TASK [Gathering Facts] ) послС Ρ‡Π΅Π³ΠΎ даст ΠΊΡ€Π°Ρ‚ΠΊΠΈΠΉ ΠΎΡ‚Ρ‡Π΅Ρ‚ ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ (PLAY RECAP).

По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ для соСдинСния ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ имя ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΠΏΠΎΠ΄ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Π²Ρ‹ Π·Π°Π»ΠΎΠ³ΠΈΠ½Π΅Π½Ρ‹ Π² систСмС. На хостС Π΅Π³ΠΎ, скорСС всСго, Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚. Π’ playbook Ρ„Π°ΠΉΠ»Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΊΠ°ΠΊΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²Ρ‹ remote_user. Π’Π°ΠΊ ΠΆΠ΅ информация ΠΎΠ± ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠΉ систСмС Π²Π°ΠΌ часто ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π½Π΅Π½ΡƒΠΆΠ½Π° ΠΈ Π½Π΅ стоит ΡΡ‚Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ врСмя Π½Π° Π΅Π΅ сбор. Π­Ρ‚Ρƒ Π·Π°Π΄Π°Ρ‡Ρƒ Ρ‚Π°ΠΊ ΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ:

---
- name: Simple playbook
  hosts: all
  remote_user: root
  become: true
  gather_facts: no

ΠŸΠΎΠΏΡ€ΠΎΠ±ΡƒΠΉΡ‚Π΅ Π΅Ρ‰Π΅ Ρ€Π°Π· Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ playbook ΠΈ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ Ρ‡Ρ‚ΠΎ соСдинСниС Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚. (Если Π²Ρ‹ ΡƒΠΊΠ°Π·Π°Π»ΠΈ root ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, Ρ‚ΠΎ Ρ‚Π°ΠΊ ΠΆΠ΅ Π½Π°Π΄ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²Ρƒ become: true, Ρ‡Ρ‚ΠΎ Π±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΏΠΎΠ²Ρ‹ΡˆΠ΅Π½Π½Ρ‹Π΅ ΠΏΡ€Π°Π²Π°. Как написано Π² Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ: become set to β€˜true’/’yes’ to activate privilege escalation. хотя Π½Π΅ совсСм понятно, Π·Π°Ρ‡Π΅ΠΌ).

Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ ΠΎΡˆΠΈΠ±ΠΊΡƒ Π²Ρ‹Π·Ρ‹Π²Π°Π½Π½ΡƒΡŽ Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ ansible Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€ ΠΏΠΈΡ‚ΠΎΠ½Π°, Ρ‚ΠΎΠ³Π΄Π° Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ:

ansible_python_interpreter: /usr/bin/python3 

Π³Π΄Π΅ Ρƒ вас Π»Π΅ΠΆΠΈΡ‚ python ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠ·Π½Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ whereis python.

Установка систСмных ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ²

Π’ стандартной поставкС Ansible Π²Ρ…ΠΎΠ΄ΠΈΡ‚ мноТСтсво ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ систСмными ΠΏΠ°ΠΊΠ΅Ρ‚Π°ΠΌΠΈ, благодаря Ρ‡Π΅ΠΌΡƒ Π½Π°ΠΌ Π½Π΅ приходится ΠΏΠΎ Π»ΡŽΠ±ΠΎΠΌΡƒ ΠΏΠΎΠ²ΠΎΠ΄Ρƒ ΠΏΠΈΡΠ°Ρ‚ΡŒ bash скрипты. БСйчас Π½Π°ΠΌ понадобится ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Ρ‚Π°ΠΊΠΈΡ… ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ для обновлСния систСмы ΠΈ установки систСмных ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ². Π£ мСня Π½Π° VPS стоит Ubuntu Linux соотвСтсвСнно для установки ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² я ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽ apt-get ΠΈ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ для Π½Π΅Π³ΠΎ. Если Ρƒ вас ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ другая опСрационная систСма Ρ‚ΠΎ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, понадобится Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ (ΠΏΠΎΠΌΠ½ΠΈΡ‚Π΅ я Π² Π½Π°Ρ‡Π°Π»Π΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΠ», Ρ‡Ρ‚ΠΎ Π½Π°Π΄ΠΎ Π·Π°Ρ€Π°Π½Π΅Π΅ Π·Π½Π°Ρ‚ΡŒ Ρ‡Ρ‚ΠΎ ΠΈ ΠΊΠ°ΠΊ Π±ΡƒΠ΄Π΅ΠΌ Π΄Π΅Π»Π°Ρ‚ΡŒ). Однако синтаксис, скорСС всСго Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΡ…ΠΎΠΆΠΈΠΌ.

Π”ΠΎΠΏΠΎΠ»Π½ΠΈΠΌ наш ΠΏΠ»Π΅ΠΉΠ±ΡƒΠΊ ΠΏΠ΅Ρ€Π²Ρ‹ΠΌΠΈ Π·Π°Π΄Π°Ρ‡Π°ΠΌΠΈ:

---
- name: Simple playbook
  hosts: all
  remote_user: root
  become: true
  gather_facts: no

  tasks:
    - name: Update system
      apt: update_cache=yes
    - name: Install system dependencies
      apt:
        name: git,nginx,redis,postgresql,postgresql-contrib
        state: present

Task β€” это ΠΊΠ°ΠΊ Ρ€Π°Π· Π·Π°Π΄Π°Ρ‡Π° ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ansible Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ Π½Π° ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹Ρ… сСрвСрах. ΠœΡ‹ Π΄Π°Π΅ΠΌ Π·Π°Π΄Π°Ρ‡Π΅ имя, Ρ‡Ρ‚ΠΎ Π±Ρ‹ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ Π΅Π΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π² Π»ΠΎΠ³Π΅. И описываСм, ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ синтаксиса ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ модуля, Ρ‡Ρ‚ΠΎ Π΅ΠΌΡƒ Π½ΡƒΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ. Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС apt: update_cache=yes β€” Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΏΠ°ΠΊΠ΅Ρ‚Ρ‹ систСмы ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ модуля apt. Вторая ΠΊΠΎΠΌΠ°Π½Π΄Π° нСсколько слоТнСС. ΠœΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ Π² ΠΌΠΎΠ΄ΡƒΠ»ΡŒ apt список ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ², ΠΈ Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ Ρ‡Ρ‚ΠΎ ΠΈΡ… state Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΡ‚Π°Ρ‚ΡŒ present, Ρ‚ΠΎΠ΅ΡΡ‚ΡŒ Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ эти ΠΏΠ°ΠΊΠ΅Ρ‚Ρ‹. ΠŸΠΎΡ…ΠΎΠΆΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΈΡ… ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ, ΠΈΠ»ΠΈ ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ, просто помСняв state. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ rails с postgresql Π½Π°ΠΌ Π½ΡƒΠΆΠ΅Π½ ΠΏΠ°ΠΊΠ΅Ρ‚ postgresql-contrib, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ сСйчас устанавливаСм. Об этом ΠΎΠΏΡΡ‚ΡŒ ΠΆΠ΅ Π½Π°Π΄ΠΎ Π·Π½Π°Ρ‚ΡŒ ΠΈ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ, ansible сам ΠΏΠΎ сСбС этого Π΄Π΅Π»Π°Ρ‚ΡŒ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚.

ΠŸΠΎΠΏΡ€ΠΎΠ±ΡƒΠΉΡ‚Π΅ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ playbook Π΅Ρ‰Π΅ Ρ€Π°Π· ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΏΠ°ΠΊΠ΅Ρ‚Ρ‹ установятся.

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π½ΠΎΠ²Ρ‹Ρ… ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ.

Для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌΠΈ Ρƒ Ansible Ρ‚Π°ΠΊ ΠΆΠ΅ Π΅ΡΡ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ β€” user. Π”ΠΎΠ±Π°Π²ΠΈΠΌ Π΅Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½ task (я скрыл ΡƒΠΆΠ΅ извСстныС части ΠΏΠ»Π΅ΠΉΠ±ΡƒΠΊΠ° Π·Π° коммСнтариям, Ρ‡Ρ‚ΠΎ Π±Ρ‹ Π½Π΅ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ Ρ†Π΅Π»ΠΈΠΊΠΎΠΌ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π·):

---
- name: Simple playbook
  # ...
  tasks:
    # ...
    - name: Add a new user
      user:
        name: my_user
        shell: /bin/bash
        password: "{{ 123qweasd | password_hash('sha512') }}"

ΠœΡ‹ создаСм Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, устанавливаСм Π΅ΠΌΡƒ schell ΠΈ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ. И Ρ‚ΡƒΡ‚ ΠΆΠ΅ сталкиваСмся с нСсколькими ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°ΠΌΠΈ. Π§Ρ‚ΠΎ Ссли ΠΈΠΌΠ΅Π½Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ для Ρ€Π°Π·Π½Ρ‹Ρ… хостов Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ? Π”Π° ΠΈ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ Π² ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠΌ Π²ΠΈΠ΄Π΅ Π² ΠΏΠ»Π΅ΠΉΠ±ΡƒΠΊΠ΅ ΠΎΡ‡Π΅Π½ΡŒ плохая идСя. Для Π½Π°Ρ‡Π°Π»Π° вынСсСм имя ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΠΈ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, Π° Π±Π»ΠΈΠΆΠ΅ ΠΊ ΠΊΠΎΠ½Ρ†Ρƒ ΡΡ‚Π°Ρ‚ΡŒΠΈ я ΠΏΠΎΠΊΠ°ΠΆΡƒ ΠΊΠ°ΠΊ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Ρ‚ΡŒ.

---
- name: Simple playbook
  # ...
  tasks:
    # ...
    - name: Add a new user
      user:
        name: "{{ user }}"
        shell: /bin/bash
        password: "{{ user_password | password_hash('sha512') }}"

ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Π΄Π²ΠΎΠΉΠ½Ρ‹Ρ… Ρ„ΠΈΠ³ΡƒΡ€Π½Ρ‹Ρ… скобок Π² плэйбуках ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ΡΡ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅.

ЗначСния ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΌΡ‹ ΡƒΠΊΠ°ΠΆΠ΅ΠΌ Π² inventory Ρ„Π°ΠΉΠ»Π΅:

123.123.123.123

[all:vars]
user=my_user
user_password=123qweasd

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²Ρƒ [all:vars] β€” ΠΎΠ½Π° Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π±Π»ΠΎΠΊ тСкста β€” это ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ (vars) ΠΈ ΠΎΠ½ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌΡ‹ для всСх хостов (all).

Π’Π°ΠΊ ΠΆΠ΅ интСрСсна конструкция "{{ user_password | password_hash('sha512') }}". Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ansible Π½Π΅ устанавливаСт ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Ρ‡Π΅Ρ€Π΅Π· user_add ΠΊΠ°ΠΊ Π²Ρ‹ Π±Ρ‹ Π΄Π΅Π»Π°Π»ΠΈ это Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ. А сохраняСт всС Π΄Π°Π½Π½Ρ‹Π΅ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ, ΠΈΠ·-Π·Π° Ρ‡Π΅Π³ΠΎ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ ΠΌΡ‹ Ρ‚Π°ΠΊ ΠΆΠ΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π·Π°Ρ€Π°Π½Π΅Π΅ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ Π² Ρ…ΡΡˆ, Ρ‡Ρ‚ΠΎ ΠΈ Π΄Π΅Π»Π°Π΅Ρ‚ данная ΠΊΠΎΠΌΠ°Π½Π΄Π°.

Π”Π°Π²Π°ΠΉΡ‚Π΅ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ нашСго ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π² Π³Ρ€ΡƒΠΏΠΏΡƒ sudo. Однако, ΠΏΠ΅Ρ€Π΅Π΄ этим Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ Ρ‡Ρ‚ΠΎ такая Π³Ρ€ΡƒΠΏΠΏΠ° Π΅ΡΡ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π·Π° нас этого Π½ΠΈΠΊΡ‚ΠΎ Π΄Π΅Π»Π°Ρ‚ΡŒ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚:

---
- name: Simple playbook
  # ...
  tasks:
    # ...
    - name: Ensure a 'sudo' group
      group:
        name: sudo
        state: present
    - name: Add a new user
      user:
        name: "{{ user }}"
        shell: /bin/bash
        password: "{{ user_password | password_hash('sha512') }}"
        groups: "sudo"

ВсС достаточно просто, Ρƒ нас Ρ‚Π°ΠΊ ΠΆΠ΅ Π΅ΡΡ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ group для создания Π³Ρ€ΡƒΠΏΠΏ, с синтаксисом ΠΎΡ‡Π΅Π½ΡŒ ΠΏΠΎΡ…ΠΎΠΆΠΈΠΌ Π½Π° apt. ПослС Ρ‡Π΅Π³ΠΎ достаточно ΠΏΡ€ΠΎΠΏΠΈΡΠ°Ρ‚ΡŒ эту Π³Ρ€ΡƒΠΏΠΏΡƒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ (groups: "sudo").
Π’Π°ΠΊ ΠΆΠ΅ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ этому ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ ssh ΠΊΠ»ΡŽΡ‡, Ρ‡Ρ‚ΠΎ Π±Ρ‹ ΠΌΡ‹ ΠΌΠΎΠ³Π»ΠΈ Π»ΠΎΠ³ΠΈΠ½ΠΈΡ‚ΡŒΡΡ ΠΏΠΎΠ΄ Π½ΠΈΠΌ Π±Π΅Π· пароля:

---
- name: Simple playbook
  # ...
  tasks:
    # ...
    - name: Ensure a 'sudo' group
      group:
      name: sudo
        state: present
    - name: Add a new user
      user:
        name: "{{ user }}"
        shell: /bin/bash
        password: "{{ user_password | password_hash('sha512') }}"
        groups: "sudo"
    - name: Deploy SSH Key
      authorized_key:
        user: "{{ user }}"
        key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
        state: present

Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС интСрСсна конструкция "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" β€” ΠΎΠ½Π° ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ содСрТимоС Ρ„Π°ΠΉΠ»Π° id_rsa.pub (Ρƒ вас Π½Π°Π·Π²Π°Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈ ΠΎΡ‚Π»ΠΈΡ‡Π°Ρ‚ΡŒΡΡ), Ρ‚ΠΎΠ΅ΡΡ‚ΡŒ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½ΡƒΡŽ Ρ‡Π°ΡΡ‚ΡŒ ssh ΠΊΠ»ΡŽΡ‡Π° ΠΈ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ Π΅Π³ΠΎ Π² список Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΊΠ»ΡŽΡ‡Π΅ΠΉ для ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π½Π° сСрвСр.

Π ΠΎΠ»ΠΈ

ВсС Ρ‚Ρ€ΠΈ Π·Π°Π΄Π°Ρ‡ΠΈ для создания ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΌΠΎΠΆΠ½ΠΎ Π»Π΅Π³ΠΊΠΎ отнСсти ΠΊ ΠΎΠ΄Π½ΠΎΠΉ Π³Ρ€ΡƒΠΏΠΏΠ΅ Π·Π°Π΄Π°Ρ‡, ΠΈ Π½Π΅ΠΏΠ»ΠΎΡ…ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ эту Π³Ρ€ΡƒΠΏΠΏΡƒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ ΠΎΡ‚ основного ΠΏΠ»Π΅ΠΉΠ±ΡƒΠΊΠ°, Ρ‡Ρ‚ΠΎ Π±Ρ‹ ΠΎΠ½ слишком Π½Π΅ разрастался. Для этого Π² ansible ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ Ρ€ΠΎΠ»ΠΈ.
Богласно ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ Π² самом Π½Π°Ρ‡Π°Π»Π΅ Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ структурС, Ρ€ΠΎΠ»ΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚ΡŒ Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΡŽ roles, для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Ρ€ΠΎΠ»ΠΈ β€” ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Π°Ρ дирСктория с Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Ρ‹ΠΌ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ, Π²Π½ΡƒΡ‚Ρ€ΠΈ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ tasks, files, templates, e.t.c.
CΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Ρ„Π°ΠΉΠ»ΠΎΠ²ΡƒΡŽ структуру: ./ansible/roles/user/tasks/main.yml (main β€” это основной Ρ„Π°ΠΉΠ» ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ΄Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒΡΡ ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ ΠΏΡ€ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ Ρ€ΠΎΠ»ΠΈ ΠΊ ΠΏΠ»Π΅ΠΉΠ±ΡƒΠΊΡƒ, Π² Π½Π΅ΠΌ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Ρ„Π°ΠΉΠ»Ρ‹ Ρ€ΠΎΠ»ΠΈ). Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΠΎΠΆΠ½ΠΎ пСрСнСсти Π² этот Ρ„Π°ΠΉΠ» всС Π·Π°Π΄Π°Ρ‡ΠΈ относящиСся ΠΊ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ:

# Create user and add him to groups
- name: Ensure a 'sudo' group
  group:
    name: sudo
    state: present

- name: Add a new user
  user:
    name: "{{ user }}"
    shell: /bin/bash
    password: "{{ user_password | password_hash('sha512') }}"
    groups: "sudo"

- name: Deploy SSH Key
  authorized_key:
    user: "{{ user }}"
    key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
    state: present

Π’ основном ΠΆΠ΅ ΠΏΠ»Π΅ΠΉΠ±ΡƒΠΊΠ΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ€ΠΎΠ»ΡŒ user:

---
- name: Simple playbook
  hosts: all
  remote_user: root
  gather_facts: no

  tasks:
    - name: Update system
      apt: update_cache=yes
    - name: Install system dependencies
      apt:
        name: git,nginx,redis,postgresql,postgresql-contrib
        state: present

  roles:
    - user

Π’Π°ΠΊ ΠΆΠ΅, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠΌΠ΅Π΅Ρ‚ смысл Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ систСмы Ρ€Π°Π½ΡŒΡˆΠ΅ всСх ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… Π·Π°Π΄Π°Ρ‡, для этого ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Ρ‚ΡŒ Π±Π»ΠΎΠΊ tasks Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΎΠ½ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ Π² pre_tasks.

Настройка nginx

Nginx Ρƒ нас Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΡƒΠΆΠ΅ установлСн, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΅Π³ΠΎ ΡΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ. Π”Π°Π²Π°ΠΉΡ‚Π΅ Π΄Π΅Π»Π°Ρ‚ΡŒ это сразу Π² Ρ€ΠΎΠ»ΠΈ. Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Ρ„Π°ΠΉΠ»ΠΎΠ²ΡƒΡŽ структуру:

- ansible
  - roles
    - nginx
      - files
      - tasks
        - main.yml
      - templates

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π½Π°ΠΌ понадобятся Ρ„Π°ΠΉΠ»Ρ‹ ΠΈ ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹. Π Π°Π·Π½ΠΈΡ†Π° ΠΌΠ΅ΠΆΠ΄Ρƒ Π½ΠΈΠΌΠΈ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Ρ„Π°ΠΉΠ»Ρ‹ ansible ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ, ΠΊΠ°ΠΊ Π΅ΡΡ‚ΡŒ. А ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΈΠΌΠ΅Ρ‚ΡŒ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ j2 ΠΈ Π² Π½ΠΈΡ… ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ значСния ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Ρ‚Π΅Ρ… ΠΆΠ΅ Π΄Π²ΠΎΠΉΠ½Ρ‹Ρ… Ρ„ΠΈΠ³ΡƒΡ€Π½Ρ‹Ρ… скобок.

Π”Π°Π²Π°ΠΉΡ‚Π΅ Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ nginx Π² main.yml Ρ„Π°ΠΉΠ»Π΅. Для этого Ρƒ нас Π΅ΡΡ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ systemd:

# Copy nginx configs and start it
- name: enable service nginx and start
  systemd:
    name: nginx
    state: started
    enabled: yes

Π’ΡƒΡ‚ ΠΌΡ‹ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ, Ρ‡Ρ‚ΠΎ nginx Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ started (Ρ‚ΠΎΠ΅ΡΡ‚ΡŒ запускаСм Π΅Π³ΠΎ), Π½ΠΎ сразу Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ Ρ‡Ρ‚ΠΎ ΠΎΠ½ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ enabled.
Π’Π΅ΠΏΠ΅Ρ€ΡŒ скопируСм ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹:

# Copy nginx configs and start it
- name: enable service nginx and start
  systemd:
    name: nginx
    state: started
    enabled: yes

- name: Copy the nginx.conf
  copy:
    src: nginx.conf
    dest: /etc/nginx/nginx.conf
    owner: root
    group: root
    mode: '0644'
    backup: yes

- name: Copy template my_app.conf
  template:
    src: my_app_conf.j2
    dest: /etc/nginx/sites-available/my_app.conf
    owner: root
    group: root
    mode: '0644'

ΠœΡ‹ создаСм основной ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» nginx (ΠΌΠΎΠΆΠ½ΠΎ Π²Π·ΡΡ‚ΡŒ Π΅Π³ΠΎ прямо с сСрвСра, ΠΈΠ»ΠΈ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ). И Ρ‚Π°ΠΊ ΠΆΠ΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» для нашСго прилоТСния Π² sites_available Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΠΎΡ€ΠΈΡŽ (это Π½Π΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ Π½ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ). Π’ ΠΏΠ΅Ρ€Π²ΠΎΠΌ случаС ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ copy для копирования Ρ„Π°ΠΉΠ»ΠΎΠ² (Ρ„Π°ΠΉΠ» Π΄ΠΎΠ»ΠΆΠ΅Π½ Π»Π΅ΠΆΠ°Ρ‚ΡŒ Π² /ansible/roles/nginx/files/nginx.conf). Π’ΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΌ β€” ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ шаблон, подставляя значСния ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…. Π¨Π°Π±Π»ΠΎΠ½ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π»Π΅ΠΆΠ°Ρ‚ΡŒ Π² /ansible/roles/nginx/templates/my_app.j2). И Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Ρ‚Π°ΠΊ:

upstream {{ app_name }} {
  server unix:{{ app_path }}/shared/tmp/sockets/puma.sock;
}

server {
  listen 80;
  server_name {{ server_name }} {{ inventory_hostname }};
  root {{ app_path }}/current/public;

  try_files $uri/index.html $uri.html $uri @{{ app_name }};
  ....
}

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° вставки {{ app_name }}, {{ app_path }}, {{ server_name }}, {{ inventory_hostname }} β€” это всС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, значСния ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ansible подставит Π² шаблон ΠΏΠ΅Ρ€Π΅Π΄ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ. Π­Ρ‚ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ, Ссли ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ»Π΅ΠΉΠ±ΡƒΠΊ для Ρ€Π°Π·Π½Ρ‹Ρ… Π³Ρ€ΡƒΠΏΠΏ хостов. НапримСр ΠΌΡ‹ ΠΌΠΎΠΆΠ΅Ρ‚ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ наш inventory Ρ„Π°ΠΉΠ»:

[production]
123.123.123.123

[staging]
231.231.231.231

[all:vars]
user=my_user
user_password=123qweasd

[production:vars]
server_name=production
app_path=/home/www/my_app
app_name=my_app

[staging:vars]
server_name=staging
app_path=/home/www/my_stage
app_name=my_stage_app

Если ΠΌΡ‹ запустим Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ наш ΠΏΠ»Π΅ΠΉΠ±ΡƒΠΊ, Ρ‚ΠΎ ΠΎΠ½ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Π΅ Π·Π°Π΄Π°Ρ‡ΠΈ для ΠΎΠ±ΠΎΠΈΡ… хостов. Но ΠΏΡ€ΠΈ этом для staging хоста ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ отличатся ΠΎΡ‚ production, ΠΈ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² ролях ΠΈ ΠΏΠ»Π΅ΠΉΠ±ΡƒΠΊΠ°Ρ…, Π½ΠΎ ΠΈ Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³Π°Ρ… nginx. {{ inventory_hostname }} Π½Π΅ Π½Π°Π΄ΠΎ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Π² inventory Ρ„Π°ΠΉΠ»Π΅ β€” это ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Π°Ρ пСрмСнная ansible ΠΈ Ρ‚Π°ΠΌ хранится хост для ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ выполняСтся ΠΏΠ»Π΅ΠΉΠ±ΡƒΠΊ Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚.
Если Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΈΠΌΠ΅Ρ‚ΡŒ inventory Ρ„Π°ΠΉΠ» для Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… хостов, Π° Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для ΠΎΠ΄Π½ΠΎΠΉ Π³Ρ€ΡƒΠΏΠΏΡ‹, это ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ:

ansible-playbook -i inventory ./playbook.yml -l "staging"

Π΄Ρ€ΡƒΠ³ΠΎΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ β€” ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ inventory Ρ„Π°ΠΉΠ»Ρ‹ для Ρ€Π°Π·Π½Ρ‹Ρ… Π³Ρ€ΡƒΠΏΠΏ. Или ΠΌΠΎΠΆΠ½ΠΎ ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π²Π° ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π°, Ссли Ρƒ вас ΠΌΠ½ΠΎΠ³ΠΎ Ρ€Π°Π·Π½Ρ‹Π· хостов.

ВСрнСмся ΠΊ настройкС nginx. ПослС копирования ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ² Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ симлинк Π² sitest_enabled Π½Π° my_app.conf ΠΈΠ· sites_available. И ΠΏΠ΅Ρ€Π΅Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ nginx.

... # old code in mail.yml

- name: Create symlink to sites-enabled
  file:
    src: /etc/nginx/sites-available/my_app.conf
    dest: /etc/nginx/sites-enabled/my_app.conf
    state: link

- name: restart nginx
  service:
    name: nginx
    state: restarted

Π’ΡƒΡ‚ всС просто β€” ΠΎΠΏΡΡ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ ansible с достаточно стандартным синтаксисом. Но Π΅ΡΡ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΌΠΎΠΌΠ΅Π½Ρ‚. ΠŸΠ΅Ρ€Π΅Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ nginx ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ смысла. Π’Ρ‹ ΠΎΠ±Ρ€Π°Ρ‚ΠΈΠ»ΠΈ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Π½Π΅ пишСм ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ Π²ΠΈΠ΄Π°: «ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π²ΠΎΡ‚ это Π²ΠΎΡ‚ Ρ‚Π°ΠΊ», синтаксис выглядит скорСС ΠΊΠ°ΠΊ «Π²ΠΎΡ‚ Ρƒ этого Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ Π²ΠΎΡ‚ Ρ‚Π°ΠΊΠΎΠ΅ состояниС». И Ρ‡Π°Ρ‰Π΅ всСго ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ‚Π°ΠΊ ansible ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚. Если Π³Ρ€ΡƒΠΏΠΏΠ° ΡƒΠΆΠ΅ сущСствуСт, ΠΈΠ»ΠΈ систСмный ΠΏΠ°ΠΊΠ΅Ρ‚ ΡƒΠΆΠ΅ установлСн, Ρ‚ΠΎ ansible ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ это ΠΈ пропустит Π·Π°Π΄Π°Ρ‡Ρƒ. Π’Π°ΠΊ ΠΆΠ΅ Ρ„Π°ΠΉΠ»Ρ‹ Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ, Ссли ΠΎΠ½ΠΈ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡŽΡ‚ с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ ΡƒΠΆΠ΅ Π΅ΡΡ‚ΡŒ Π½Π° сСрвСрС. ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ этим Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΈ ΠΏΠ΅Ρ€Π΅Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ nginx Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ссли ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹ Π±Ρ‹Π»ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Ρ‹. Для этого сущСствуСт Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²Π° register:

# Copy nginx configs and start it
- name: enable service nginx and start
  systemd:
    name: nginx
    state: started
    enabled: yes

- name: Copy the nginx.conf
  copy:
    src: nginx.conf
    dest: /etc/nginx/nginx.conf
    owner: root
    group: root
    mode: '0644'
    backup: yes
  register: restart_nginx

- name: Copy template my_app.conf
  template:
    src: my_app_conf.j2
    dest: /etc/nginx/sites-available/my_app.conf
    owner: root
    group: root
    mode: '0644'
  register: restart_nginx

- name: Create symlink to sites-enabled
  file:
    src: /etc/nginx/sites-available/my_app.conf
    dest: /etc/nginx/sites-enabled/my_app.conf
    state: link

- name: restart nginx
  service:
    name: nginx
    state: restarted
  when: restart_nginx.changed

Если ΠΎΠ΄ΠΈΠ½ ΠΈΠ· ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ² мСняСтся, Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈ зарСгСстрирована пСрСмСнная restart_nginx. И Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ссли эта пСрСмСнная Π±Ρ‹Π»Π° зарСгистрирована, выполнится пСрСзапуск сСрвиса.

Ну ΠΈ, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, Π½ΡƒΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Ρ€ΠΎΠ»ΡŒ nginx Π² основной playbook.

Настройка postgresql

Нам Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ postgresql ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ systemd Ρ‚ΠΎΡ‡Π½ΠΎ Ρ‚Π°ΠΊ ΠΆΠ΅ ΠΊΠ°ΠΊ ΠΌΡ‹ это Π΄Π΅Π»Π°Π»ΠΈ с nginx, Π° Ρ‚Π°ΠΊ ΠΆΠ΅ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΡ‹ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для доступа ΠΊ Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ саму Π±Π°Π·Ρƒ Π΄Π°Π½Π½Ρ‹Ρ….
Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Ρ€ΠΎΠ»ΡŒ /ansible/roles/postgresql/tasks/main.yml:

# Create user in postgresql
- name: enable postgresql and start
  systemd:
    name: postgresql
    state: started
    enabled: yes

- name: Create database user
  become_user: postgres
  postgresql_user:
    name: "{{ db_user }}"
    password: "{{ db_password }}"
    role_attr_flags: SUPERUSER

- name: Create database
  become_user: postgres
  postgresql_db:
    name: "{{ db_name }}"
    encoding: UTF-8
    owner: "{{ db_user }}"

Π― Π½Π΅ Π±ΡƒΠ΄Ρƒ Ρ€Π°ΡΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊ Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ Π² inventory, это ΡƒΠΆΠ΅ дСлалось ΠΌΠ½ΠΎΠ³ΠΎ Ρ€Π°Π·, Ρ‚Π°ΠΊ ΠΆΠ΅ ΠΊΠ°ΠΊ ΠΈ синтаксис ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ postgresql_db ΠΈ postgresql_user. Π‘ΠΎΠ»ΡŒΡˆΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π² Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ. Π’ΡƒΡ‚ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ интСрСсна Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²Π° become_user: postgres. Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ доступ ΠΊ postgresql Π±Π°Π·Π΅ Π΅ΡΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρƒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ postgres ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ локально. Данная Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²Π° позволяСт Π½Π°ΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ ΠΎΡ‚ ΠΈΠΌΠ΅Π½ΠΈ этого ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ (Ссли ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ Ρƒ нас Π΅ΡΡ‚ΡŒ доступ).
Π’Π°ΠΊ ΠΆΠ΅, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π²Π°ΠΌ придСтся Π΄ΠΎΠΏΠΈΡΠ°Ρ‚ΡŒ строку Π² pg_hba.conf Ρ‡Ρ‚ΠΎ Π±Ρ‹ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ доступ Π½ΠΎΠ²ΠΎΠΌΡƒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ ΠΊ Π±Π°Π·Π΅. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ ΠΌΡ‹ мСняли ΠΊΠΎΠ½Ρ„ΠΈΠ³ nginx.

Ну ΠΈ ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ Π½Π°Π΄ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Ρ€ΠΎΠ»ΡŒ postgresql Π² основной ΠΏΠ»Π΅ΠΉΠ±ΡƒΠΊ.

Установка ruby Ρ‡Π΅Ρ€Π΅Π· rbenv

Π’ ansible Π½Π΅Ρ‚ ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с rbenv, Π° устанавливаСтся ΠΎΠ½ ΠΏΡƒΡ‚Π΅ΠΌ клонирования git рСпозитория. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ эта Π·Π°Π΄Π°Ρ‡ΠΊΠ° становится самой нСстандартной. Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ для Π½Π΅Π΅ Ρ€ΠΎΠ»ΡŒ /ansible/roles/ruby_rbenv/main.yml ΠΈ Π½Π°Ρ‡Π½Π΅ΠΌ Π΅Π΅ Π·Π°ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ:

# Install rbenv and ruby
- name: Install rbenv
  become_user: "{{ user }}"
  git: repo=https://github.com/rbenv/rbenv.git dest=~/.rbenv

ΠœΡ‹ ΠΎΠΏΡΡ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²Ρƒ become_user Ρ‡Ρ‚ΠΎ Π±Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΈΠ· ΠΏΠΎΠ΄ созданного Π½Π°ΠΌΠΈ для этих Ρ†Π΅Π»Π΅ΠΉ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. Π’Π°ΠΊ ΠΊΠ°ΠΊ rbenv устанавливаСтся Π² Π΅Π³ΠΎ home Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ, Π° Π½Π΅ глобально. И Ρ‚Π°ΠΊ ΠΆΠ΅ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ git для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Π±Ρ‹ ΡΠΊΠ»ΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ, указывя repo ΠΈ dest.

Π”Π°Π»Π΅Π΅ Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡ€ΠΎΠΏΠΈΡΠ°Ρ‚ΡŒ rbenv init Π² bashrc ΠΈ Ρ‚Π°ΠΌ ΠΆΠ΅ Π΄ΠΎΠ±Π°Π²ΠΈΡŒΡ‚ rbenv Π² PATH. Для этого Ρƒ нас Π΅ΡΡ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ lineinfile:

- name: Add rbenv to PATH
  become_user: "{{ user }}"
  lineinfile:
    path: ~/.bashrc
    state: present
    line: 'export PATH="${HOME}/.rbenv/bin:${PATH}"'

- name: Add rbenv init to bashrc
  become_user: "{{ user }}"
  lineinfile:
    path: ~/.bashrc
    state: present
    line: 'eval "$(rbenv init -)"'

ПослС Ρ‡Π΅Π³ΠΎ Π½Π°Π΄ΠΎ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ruby_build:

- name: Install ruby-build
  become_user: "{{ user }}"
  git: repo=https://github.com/rbenv/ruby-build.git dest=~/.rbenv/plugins/ruby-build

И, Π½Π°ΠΊΠΎΠ½Π΅Ρ†, ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ruby. Π­Ρ‚ΠΎ дСлаСтся Ρ‡Π΅Ρ€Π΅Π· rbenv, Ρ‚ΠΎΠ΅ΡΡ‚ΡŒ просто bash ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ:

- name: Install ruby
  become_user: "{{ user }}"
  shell: |
    export PATH="${HOME}/.rbenv/bin:${PATH}"
    eval "$(rbenv init -)"
    rbenv install {{ ruby_version }}
  args:
    executable: /bin/bash

ΠœΡ‹ Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ, ΠΊΠ°ΠΊΡƒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΈ Ρ‡Π΅ΠΌ. Однако Ρ‚ΡƒΡ‚ ΠΌΡ‹ наткнСмся Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ansible Π½Π΅ запускаСт ΠΊΠΎΠ΄, содСрТащийся Π² bashrc ΠΏΠ΅Ρ€Π΅Π΄ запуском ΠΊΠΎΠΌΠ°Π½Π΄. А Π·Π½Π°Ρ‡ΠΈΡ‚, rbenv придСтся ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ прямо Π² этом ΠΆΠ΅ скриптС.

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° связана с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ shell ΠΊΠΎΠΌΠ°Π½Π΄Π° Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ состояния с Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния ansible. Π’ΠΎΠ΅ΡΡ‚ΡŒ автоматичСской ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ, установлСна эта вСрсия ruby ΠΈΠ»ΠΈ Π½Π΅Ρ‚ β€” Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚. ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ это ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ:

- name: Install ruby
  become_user: "{{ user }}"
  shell: |
    export PATH="${HOME}/.rbenv/bin:${PATH}"
    eval "$(rbenv init -)"
    if ! rbenv versions | grep -q {{ ruby_version }}
      then rbenv install {{ ruby_version }} && rbenv global {{ ruby_version }}
    fi
  args:
    executable: /bin/bash

И остаСтся ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ bundler:

- name: Install bundler
  become_user: "{{ user }}"
  shell: |
    export PATH="${HOME}/.rbenv/bin:${PATH}"
    eval "$(rbenv init -)"
    gem install bundler

И ΠΎΠΏΡΡ‚ΡŒ ΠΆΠ΅ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π½Π°ΡˆΡƒ Ρ€ΠΎΠ»ΡŒ ruby_rbenv Π² основной ΠΏΠ»Π΅ΠΉΠ±ΡƒΠΊ.

Shared files.

Π’ Ρ†Π΅Π»ΠΎΠΌ Π½Π° этом настройку ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ Π·Π°ΠΊΠΎΠ½Ρ‡ΠΈΡ‚ΡŒ. Π”Π°Π»Π΅Π΅ остаСтся Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ capistrano ΠΈ ΠΎΠ½ΠΎ само скопируСт ΠΊΠΎΠ΄, создаст Π½ΡƒΠΆΠ½Ρ‹Π΅ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΈ ΠΈ запустит ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ (Ссли настроСно всС Π²Π΅Ρ€Π½ΠΎ). Однако Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ capistrano Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ database.yml ΠΈΠ»ΠΈ .env Π˜Ρ… ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΡ‡Π½ΠΎ Ρ‚Π°ΠΊ ΠΆΠ΅ ΠΊΠ°ΠΊ Ρ„Π°ΠΉΠ»Ρ‹ ΠΈ ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹ для nginx. Π•ΡΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½Π° Ρ‚ΠΎΠ½ΠΊΠΎΡΡ‚ΡŒ. ΠŸΠ΅Ρ€Π΅Π΄ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ Ρ„Π°ΠΉΠ»ΠΎΠ² Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ для Π½ΠΈΡ… структуру ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΎΠ², Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π²Ρ€ΠΎΠ΄Π΅ Ρ‚Π°ΠΊΠΎΠ³ΠΎ:

# Copy shared files for deploy
- name: Ensure shared dir
  become_user: "{{ user }}"
  file:
    path: "{{ app_path }}/shared/config"
    state: directory

ΠΌΡ‹ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½Ρƒ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΡŽ ΠΈ ansible автоматичСски создаст Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅, Ссли Π½ΡƒΠΆΠ½ΠΎ.

Ansible Vault

ΠœΡ‹ ΡƒΠΆΠ΅ Π½Π°Ρ‚Ρ‹ΠΊΠ°Π»ΠΈΡΡŒ Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΌΠΎΠ³ΡƒΡ‚ ΠΎΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒΡΡ сСкрСтныС Π΄Π°Π½Π½Ρ‹Π΅ Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. Если Π²Ρ‹ создали .env Ρ„Π°ΠΉΠ» для прилоТСния, ΠΈ database.yml Ρ‚ΠΎ Ρ‚Π°ΠΌ, Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ Π΅Ρ‰Π΅ большС Ρ‚Π°ΠΊΠΈΡ… ΠΊΡ€ΠΈΡ‚ΠΈΡ‡Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…. Π˜Ρ… Ρ…ΠΎΡ€ΠΎΡˆΠΎ Π±Ρ‹ ΡΠΊΡ€Ρ‹Ρ‚ΡŒ ΠΎΡ‚ посторонних Π³Π»Π°Π·. Для этого ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ansible vault.

Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Ρ„Π°ΠΉΠ» для ΠΏΠ΅Ρ€ΠΌΠ΅Π½Π½Ρ‹Ρ… /ansible/vars/all.yml (Ρ‚ΡƒΡ‚ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Ρ€Π°Π·Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹ для Ρ€Π°Π·Π½Ρ‹Ρ… Π³Ρ€ΡƒΠΏΠΏ хостов, Ρ‚ΠΎΡ‡Π½ΠΎ Ρ‚Π°ΠΊ ΠΆΠ΅ ΠΊΠ°ΠΊ Π² inventory Ρ„Π°ΠΉΠ»Π΅: production.yml, staging.yml, e.t.c).
Π’ этот Ρ„Π°ΠΉΠ» Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ пСрСнСсти всС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½Ρ‹, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ стандартный yml синтаксис:

# System vars
user_password: 123qweasd
db_password: 123qweasd

# ENV vars
aws_access_key_id: xxxxx
aws_secret_access_key: xxxxxx
aws_bucket: bucket_name
rails_secret_key_base: very_secret_key_base

ПослС Ρ‡Π΅Π³ΠΎ этот Ρ„Π°ΠΉΠ» ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ:

ansible-vault encrypt ./vars/all.yml

ЕстСствСнно, ΠΏΡ€ΠΈ ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ для Π΄Π΅ΡˆΠΈΡ„Ρ€ΠΎΠ²ΠΊΠΈ. ΠœΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ окаТСтся Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ„Π°ΠΉΠ»Π° послС Π²Ρ‹Π·ΠΎΠ²Π° этой ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹.

ΠŸΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ ansible-vault decrypt Ρ„Π°ΠΉΠ» ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°ΡΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Ρ‚ΡŒ, ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΈ ΠΏΠΎΡ‚ΠΎΠΌ Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Ρ‚ΡŒ снова.

Для Ρ€Π°Π±ΠΎΡ‚Ρ‹ Ρ€Π°ΡΡˆΠΈΡ„Ρ€ΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ» Π½Π΅ Π½Π°Π΄ΠΎ. Π’Ρ‹ Ρ…Ρ€Π°Π½ΠΈΡ‚Π΅ Π΅Π³ΠΎ Π² Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½Π½ΠΎΠΌ Π²ΠΈΠ΄Π΅ ΠΈ запускаСтС playbook с Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ --ask-vault-pass. Ansible спросит ΠΏΠ°Ρ€ΠΎΠ»ΡŒ, достанСт ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ Π·Π°Π΄Π°Ρ‡ΠΈ. ВсС Π΄Π°Π½Π½Ρ‹Π΅ останутся Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌΠΈ.

ΠŸΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Π° для Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Π³Ρ€ΡƒΠΏΠΏ хостов ΠΈ ansible vault Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Ρ‚Π°ΠΊ:

ansible-playbook -i inventory ./playbook.yml -l "staging" --ask-vault-pass

А ΠΏΠΎΠ»Π½Ρ‹ΠΉ тСкст ΠΏΠ»Π΅ΠΉΠ±ΡƒΠΊΠΎΠ² ΠΈ Ρ€ΠΎΠ»Π΅ΠΉ я Π²Π°ΠΌ Π½Π΅ Π΄Π°ΠΌ, ΠΏΠΈΡˆΠΈΡ‚Π΅ сами. ΠŸΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ansible ΡˆΡ‚ΡƒΠΊΠ° такая β€” Ссли Π½Π΅ понимаСшь Ρ‡Ρ‚ΠΎ Π½Π°Π΄ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ, Ρ‚ΠΎ ΠΈ ΠΎΠ½ Ρ‚Π΅Π±Π΅ Π½Π΅ сдСлаСт.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com