ื”ื’ื“ืจืช ืฉืจืช ืœืคืจื™ืกืช ื™ื™ืฉื•ื Rails ื‘ืืžืฆืขื•ืช Ansible

ืœืคื ื™ ื–ืžืŸ ืœื ืจื‘ ื”ื™ื™ืชื™ ืฆืจื™ืš ืœื›ืชื•ื‘ ื›ืžื” ืกืคืจื™ ืžืฉื—ืง ืฉืœ Ansible ื›ื“ื™ ืœื”ื›ื™ืŸ ืืช ื”ืฉืจืช ืœืคืจื™ืกืช ื™ื™ืฉื•ื Rails. ื•ื‘ืื•ืคืŸ ืžืคืชื™ืข, ืœื ืžืฆืืชื™ ืžื“ืจื™ืš ืคืฉื•ื˜ ืฉืœื‘ ืื—ืจ ืฉืœื‘. ืœื ืจืฆื™ืชื™ ืœื”ืขืชื™ืง ืกืคืจ ืžืฉื—ืง ืฉืœ ืžื™ืฉื”ื• ืื—ืจ ื‘ืœื™ ืœื”ื‘ื™ืŸ ืžื” ืงื•ืจื”, ื•ื‘ืกื•ืคื• ืฉืœ ื“ื‘ืจ ื”ื™ื™ืชื™ ืฆืจื™ืš ืœืงืจื•ื ืืช ื”ืชื™ืขื•ื“, ืœืืกื•ืฃ ื”ื›ืœ ื‘ืขืฆืžื™. ืื•ืœื™ ืื ื™ ื™ื›ื•ืœ ืœืขื–ื•ืจ ืœืžื™ืฉื”ื• ืœื”ืื™ืฅ ืืช ื”ืชื”ืœื™ืš ื”ื–ื” ื‘ืขื–ืจืช ื”ืžืืžืจ ื”ื–ื”.

ื”ื“ื‘ืจ ื”ืจืืฉื•ืŸ ืฉืฆืจื™ืš ืœื”ื‘ื™ืŸ ื”ื•ื ืฉ-ansible ืžืกืคืงืช ืœืš ืžืžืฉืง ื ื•ื— ืœื‘ื™ืฆื•ืข ืจืฉื™ืžื” ืžื•ื’ื“ืจืช ืžืจืืฉ ืฉืœ ืคืขื•ืœื•ืช ื‘ืฉืจืช(ื™ื) ืžืจื•ื—ืงื™ื ื‘ืืžืฆืขื•ืช SSH. ืื™ืŸ ื›ืืŸ ืงืกื, ืืชื” ืœื ื™ื›ื•ืœ ืœื”ืชืงื™ืŸ ืชื•ืกืฃ ื•ืœืงื‘ืœ ืืคืก ืคืจื™ืกืช ื–ืžืŸ ื”ืฉื‘ืชื” ืฉืœ ื”ื™ื™ืฉื•ื ืฉืœืš ืขื docker, ื ื™ื˜ื•ืจ ื•ืขื•ื“ ื“ื‘ืจื™ื ื˜ื•ื‘ื™ื ืžื—ื•ืฅ ืœืงื•ืคืกื”. ื›ื“ื™ ืœื›ืชื•ื‘ ืกืคืจ ืžืฉื—ืง, ืขืœื™ืš ืœื“ืขืช ืžื” ื‘ื“ื™ื•ืง ืืชื” ืจื•ืฆื” ืœืขืฉื•ืช ื•ืื™ืš ืœืขืฉื•ืช ื–ืืช. ื–ื• ื”ืกื™ื‘ื” ืฉืื ื™ ืœื ืžืจื•ืฆื” ืขื ืกืคืจื™ ืžืฉื—ืง ืžื•ื›ื ื™ื ืž-GitHub, ืื• ืžืืžืจื™ื ื›ืžื•: "ื”ืขืชืง ื•ื”ืจืฅ, ื–ื” ื™ืขื‘ื•ื“."

ืžื” ืฉืื ื—ื ื• ืฆืจื™ื›ื™ื?

ื›ืคื™ ืฉื›ื‘ืจ ืืžืจืชื™, ื›ื“ื™ ืœื›ืชื•ื‘ ืกืคืจ ืžืฉื—ืง ืืชื” ืฆืจื™ืš ืœื“ืขืช ืžื” ืืชื” ืจื•ืฆื” ืœืขืฉื•ืช ื•ืื™ืš ืœืขืฉื•ืช ืืช ื–ื”. ื‘ื•ืื• ื ื—ืœื™ื˜ ืžื” ืื ื—ื ื• ืฆืจื™ื›ื™ื. ืขื‘ื•ืจ ื™ื™ืฉื•ื Rails ื ืฆื˜ืจืš ืžืกืคืจ ื—ื‘ื™ืœื•ืช ืžืขืจื›ืช: nginx, postgresql (redis ื•ื›ื•'). ื‘ื ื•ืกืฃ, ืื ื—ื ื• ืฆืจื™ื›ื™ื ื’ืจืกื” ืกืคืฆื™ืคื™ืช ืฉืœ ืื•ื“ื. ืขื“ื™ืฃ ืœื”ืชืงื™ืŸ ืื•ืชื• ื“ืจืš rbenv (rvm, asdf...). ืœื”ืคืขื™ืœ ืืช ื›ืœ ื–ื” ื›ืžืฉืชืžืฉ ืฉื•ืจืฉ ื–ื” ืชืžื™ื“ ืจืขื™ื•ืŸ ืจืข, ืื– ืืชื” ืฆืจื™ืš ืœื™ืฆื•ืจ ืžืฉืชืžืฉ ื ืคืจื“ ื•ืœื”ื’ื“ื™ืจ ืืช ื”ื–ื›ื•ื™ื•ืช ืฉืœื•. ืœืื—ืจ ืžื›ืŸ, ืขืœื™ืš ืœื”ืขืœื•ืช ืืช ื”ืงื•ื“ ืฉืœื ื• ืœืฉืจืช, ืœื”ืขืชื™ืง ืืช ื”ื”ื’ื“ืจื•ืช ืขื‘ื•ืจ nginx, postgres ื•ื›ื•' ื•ืœื”ืชื—ื™ืœ ืืช ื›ืœ ื”ืฉื™ืจื•ืชื™ื ื”ืœืœื•.

ื›ืชื•ืฆืื” ืžื›ืš, ืจืฆืฃ ื”ืคืขื•ืœื•ืช ื”ื•ื ื›ื“ืœืงืžืŸ:

  1. ื”ืชื—ื‘ืจ ื›ืฉื•ืจืฉ
  2. ืœื”ืชืงื™ืŸ ื—ื‘ื™ืœื•ืช ืžืขืจื›ืช
  3. ืœื™ืฆื•ืจ ืžืฉืชืžืฉ ื—ื“ืฉ, ืœื”ื’ื“ื™ืจ ื–ื›ื•ื™ื•ืช, ืžืคืชื— ssh
  4. ื”ื’ื“ืจ ื—ื‘ื™ืœื•ืช ืžืขืจื›ืช (nginx ื•ื›ื•') ื•ื”ืคืขืœ ืื•ืชืŸ
  5. ืื ื• ื™ื•ืฆืจื™ื ืžืฉืชืžืฉ ื‘ืžืกื“ ื”ื ืชื•ื ื™ื (ื ื™ืชืŸ ืœื™ืฆื•ืจ ืžื™ื“ ืžืกื“ ื ืชื•ื ื™ื)
  6. ื”ืชื—ื‘ืจ ื›ืžืฉืชืžืฉ ื—ื“ืฉ
  7. ื”ืชืงืŸ rbenv ื•-ruby
  8. ื”ืชืงื ืช ื”ื‘ืื ื“ืœืจ
  9. ื”ืขืœืืช ืงื•ื“ ื”ืืคืœื™ืงืฆื™ื”
  10. ื”ืคืขืœืช ืฉืจืช Puma

ื™ืชืจ ืขืœ ื›ืŸ, ื ื™ืชืŸ ืœื‘ืฆืข ืืช ื”ืฉืœื‘ื™ื ื”ืื—ืจื•ื ื™ื ื‘ืืžืฆืขื•ืช capistrano, ืœืคื—ื•ืช ืžื—ื•ืฅ ืœืงื•ืคืกื” ื”ื•ื ื™ื›ื•ืœ ืœื”ืขืชื™ืง ืงื•ื“ ืœืชื•ืš ืกืคืจื™ื•ืช ืฉื—ืจื•ืจ, ืœื”ื—ืœื™ืฃ ืืช ื”ื’ืจืกื” ืขื ืกื™ืžืœื™ื ืง ืœืื—ืจ ืคืจื™ืกื” ืžื•ืฆืœื—ืช, ืœื”ืขืชื™ืง ื”ื’ื“ืจื•ืช ืžืกืคืจื™ื™ื” ืžืฉื•ืชืคืช, ืœื”ืคืขื™ืœ ืžื—ื“ืฉ ืืช puma ื•ื›ื•'. ื›ืœ ื–ื” ื™ื›ื•ืœ ืœื”ื™ืขืฉื•ืช ื‘ืืžืฆืขื•ืช Ansible, ืื‘ืœ ืœืžื”?

ืžื‘ื ื” ื”ืงื•ื‘ืฅ

ืœืื ืกื™ื‘ืœ ื™ืฉ ืงืคื“ืŸ ืžื‘ื ื” ื”ืงื•ื‘ืฅ ืขื‘ื•ืจ ื›ืœ ื”ืงื‘ืฆื™ื ืฉืœืš, ืื– ืขื“ื™ืฃ ืœืฉืžื•ืจ ื”ื›ืœ ื‘ืกืคืจื™ื™ื” ื ืคืจื“ืช. ื™ืชืจื” ืžื›ืš, ื–ื” ืœื ื›ืœ ื›ืš ื—ืฉื•ื‘ ืื ื–ื” ื™ื”ื™ื” ื‘ื™ื™ืฉื•ื ื”ืžืกื™ืœื•ืช ืขืฆืžื•, ืื• ื‘ื ืคืจื“. ืืชื” ื™ื›ื•ืœ ืœืื—ืกืŸ ืงื‘ืฆื™ื ื‘ืžืื’ืจ git ื ืคืจื“. ื‘ืื•ืคืŸ ืื™ืฉื™, ืžืฆืืชื™ ืฉื”ื›ื™ ื ื•ื— ืœื™ืฆื•ืจ ืกืคืจื™ื™ื” ืžืชืื™ืžื” ื‘ืกืคืจื™ื™ืช /config ืฉืœ ื™ื™ืฉื•ื rails ื•ืœืื—ืกืŸ ื”ื›ืœ ื‘ืžืื’ืจ ืื—ื“.

ืกืคืจ ืžืฉื—ืง ืคืฉื•ื˜

Playbook ื”ื•ื ืงื•ื‘ืฅ yml ืฉื‘ืืžืฆืขื•ืช ืชื—ื‘ื™ืจ ืžื™ื•ื—ื“, ืžืชืืจ ืžื” Ansible ืฆืจื™ืš ืœืขืฉื•ืช ื•ื›ื™ืฆื“. ื‘ื•ืื• ื ื™ืฆื•ืจ ืืช ืกืคืจ ื”ืžืฉื—ืงื™ื ื”ืจืืฉื•ืŸ ืฉืœื ืขื•ืฉื” ื›ืœื•ื:

---
- name: Simple playbook
  hosts: all

ื›ืืŸ ืื ื—ื ื• ืคืฉื•ื˜ ืื•ืžืจื™ื ืฉืกืคืจ ื”ืžืฉื—ืงื™ื ืฉืœื ื• ื ืงืจื Simple Playbook ื•ื›ื™ ื™ืฉ ืœื”ืคืขื™ืœ ืืช ืชื•ื›ื ื• ืขื‘ื•ืจ ื›ืœ ื”ืžืืจื—ื™ื. ืื ื—ื ื• ื™ื›ื•ืœื™ื ืœืฉืžื•ืจ ืื•ืชื• ื‘ืกืคืจื™ื™ื” /ansible ืขื ื”ืฉื playbook.yml ื•ืชื ืกื” ืœื”ืจื™ืฅ:

ansible-playbook ./playbook.yml

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

Ansible ืื•ืžืจ ืฉื”ื•ื ืœื ืžื›ื™ืจ ืžืืจื—ื™ื ืฉืชื•ืืžื™ื ืœืจืฉื™ืžืช ื”ื›ืœ. ื”ื ื—ื™ื™ื‘ื™ื ืœื”ื™ื•ืช ืจืฉื•ืžื™ื ื‘ืกืคื™ื™ืฉืœ ืงื•ื‘ืฅ ืžืœืื™.

ื‘ื•ืื• ื ื™ืฆื•ืจ ืื•ืชื• ื‘ืื•ืชื” ืกืคืจื™ื™ื” ืืคืฉืจื™ืช:

123.123.123.123

ื›ืš ืื ื• ืคืฉื•ื˜ ืžืฆื™ื™ื ื™ื ืืช ื”ืžืืจื— (ื‘ืื•ืคืŸ ืื™ื“ื™ืืœื™ ื”ืžืืจื— ืฉืœ ื”-VPS ืฉืœื ื• ืœื‘ื“ื™ืงื”, ืื• ืฉืืชื” ื™ื›ื•ืœ ืœืจืฉื•ื localhost) ื•ื ืฉืžื•ืจ ืื•ืชื• ืชื—ืช ื”ืฉื inventory.
ืืชื” ื™ื›ื•ืœ ืœื ืกื•ืช ืœื”ืจื™ืฅ ืื ืกible ืขื ืงื•ื‘ืฅ ืžืฆืื™:

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

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

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

ืื ื™ืฉ ืœืš ื’ื™ืฉืช ssh ืœืžืืจื— ืฉืฆื•ื™ืŸ, ืื–ื™ ืื ืกื™ื‘ืœ ืชืชื—ื‘ืจ ื•ืชืืกื•ืฃ ืžื™ื“ืข ืขืœ ื”ืžืขืจื›ืช ื”ืžืจื•ื—ืงืช. (ื‘ืจื™ืจืช ืžื—ื“ืœ TASK [ืื™ืกื•ืฃ ืขื•ื‘ื“ื•ืช]) ืฉืœืื—ืจื™ื” ื”ื•ื ื™ื™ืชืŸ ื“ื•ื— ืงืฆืจ ืขืœ ื”ื‘ื™ืฆื•ืข (PLAY RECAP).

ื›ื‘ืจื™ืจืช ืžื—ื“ืœ, ื”ื—ื™ื‘ื•ืจ ืžืฉืชืžืฉ ื‘ืฉื ื”ืžืฉืชืžืฉ ืฉืชื—ืชื™ื• ืืชื” ืžื—ื•ื‘ืจ ืœืžืขืจื›ืช. ืกื‘ื™ืจ ืœื”ื ื™ื— ืฉื–ื” ืœื ื™ื”ื™ื” ืขืœ ื”ืžืืจื—. ื‘ืงื•ื‘ืฅ Playbook, ืืชื” ื™ื›ื•ืœ ืœืฆื™ื™ืŸ ื‘ืื™ื–ื” ืžืฉืชืžืฉ ืœื”ืฉืชืžืฉ ื›ื“ื™ ืœื”ืชื—ื‘ืจ ื‘ืืžืฆืขื•ืช ื”ื”ื ื—ื™ื” remote_user. ื›ืžื• ื›ืŸ, ืžื™ื“ืข ืขืœ ืžืขืจื›ืช ืžืจื•ื—ืงืช ืขืฉื•ื™ ืœื”ื™ื•ืช ืžื™ื•ืชืจ ืขื‘ื•ืจืš, ื•ืื™ืŸ ืœื‘ื–ื‘ื– ื–ืžืŸ ื‘ืื™ืกื•ืฃ. ื ื™ืชืŸ ืœื”ืฉื‘ื™ืช ืžืฉื™ืžื” ื–ื• ื’ื:

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

ื ืกื” ืœื”ืคืขื™ืœ ืฉื•ื‘ ืืช ืกืคืจ ื”ื”ืคืขืœื” ื•ื•ื“ื ืฉื”ื—ื™ื‘ื•ืจ ืคื•ืขืœ. (ืื ืฆื™ื™ื ืช ืืช ืžืฉืชืžืฉ ื”ืฉื•ืจืฉ, ืขืœื™ืš ืœืฆื™ื™ืŸ ื’ื ืืช ื”ื”ื ื—ื™ื” word: true ืขืœ ืžื ืช ืœื–ื›ื•ืช ื‘ื–ื›ื•ื™ื•ืช ืžื•ื’ื‘ืจื•ืช. ื›ืคื™ ืฉื›ืชื•ื‘ ื‘ืชื™ืขื•ื“: become set to โ€˜trueโ€™/โ€™yesโ€™ to activate privilege escalation. ืœืžืจื•ืช ืฉืœื ืœื’ืžืจื™ ื‘ืจื•ืจ ืœืžื”).

ืื•ืœื™ ืชืงื‘ืœ ืฉื’ื™ืื” ืฉื ื’ืจืžื” ื‘ื’ืœืœ ื”ืขื•ื‘ื“ื” ืฉ-ansible ืœื ื™ื›ื•ืœ ืœืงื‘ื•ืข ืืช ื”ืžืชื•ืจื’ืžืŸ ืฉืœ Python, ื•ืื– ืชื•ื›ืœ ืœืฆื™ื™ืŸ ื–ืืช ื‘ืื•ืคืŸ ื™ื“ื ื™:

ansible_python_interpreter: /usr/bin/python3 

ืืชื” ื™ื›ื•ืœ ืœื’ืœื•ืช ื”ื™ื›ืŸ ื™ืฉ ืœืš python ืขื ื”ืคืงื•ื“ื” whereis python.

ื”ืชืงื ืช ื—ื‘ื™ืœื•ืช ืžืขืจื›ืช

ื”ื”ืคืฆื” ื”ืกื˜ื ื“ืจื˜ื™ืช ืฉืœ Ansible ื›ื•ืœืœืช ืžื•ื“ื•ืœื™ื ืจื‘ื™ื ืœืขื‘ื•ื“ื” ืขื ื—ื‘ื™ืœื•ืช ืžืขืจื›ืช ืฉื•ื ื•ืช, ื›ืš ืฉืœื ื ืฆื˜ืจืš ืœื›ืชื•ื‘ ืกืงืจื™ืคื˜ื™ื ืฉืœ bash ืžื›ืœ ืกื™ื‘ื” ืฉื”ื™ื. ื›ืขืช ืื ื• ื–ืงื•ืงื™ื ืœืื—ื“ ืžื”ืžื•ื“ื•ืœื™ื ื”ืœืœื• ื›ื“ื™ ืœืขื“ื›ืŸ ืืช ื”ืžืขืจื›ืช ื•ืœื”ืชืงื™ืŸ ื—ื‘ื™ืœื•ืช ืžืขืจื›ืช. ื™ืฉ ืœื™ ืื•ื‘ื•ื ื˜ื• ืœื™ื ื•ืงืก ื‘-VPS ืฉืœื™, ืื– ื›ื“ื™ ืœื”ืชืงื™ืŸ ื—ื‘ื™ืœื•ืช ืื ื™ ืžืฉืชืžืฉ 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

ืžืฉื™ืžื” ื”ื™ื ื‘ื“ื™ื•ืง ื”ืžืฉื™ืžื” ืฉ-Ansible ืชื‘ืฆืข ื‘ืฉืจืชื™ื ืžืจื•ื—ืงื™ื. ืื ื• ื ื•ืชื ื™ื ืœืžืฉื™ืžื” ืฉื ื›ื“ื™ ืฉื ื•ื›ืœ ืœืขืงื•ื‘ ืื—ืจ ื‘ื™ืฆื•ืขื” ื‘ื™ื•ืžืŸ. ื•ืื ื—ื ื• ืžืชืืจื™ื, ื‘ืืžืฆืขื•ืช ื”ืชื—ื‘ื™ืจ ืฉืœ ืžื•ื“ื•ืœ ืกืคืฆื™ืคื™, ืžื” ื”ื•ื ืฆืจื™ืš ืœืขืฉื•ืช. ื‘ืžืงืจื” ื”ื–ื” apt: update_cache=yes - ืื•ืžืจ ืœืขื“ื›ืŸ ื—ื‘ื™ืœื•ืช ืžืขืจื›ืช ื‘ืืžืฆืขื•ืช ืžื•ื“ื•ืœ apt. ื”ืคืงื•ื“ื” ื”ืฉื ื™ื™ื” ืงืฆืช ื™ื•ืชืจ ืžืกื•ื‘ื›ืช. ืื ื• ืžืขื‘ื™ืจื™ื ืจืฉื™ืžื” ืฉืœ ื—ื‘ื™ืœื•ืช ืœืžื•ื“ื•ืœ apt ื•ืื•ืžืจื™ื ืฉื›ืŸ state ืฆืจื™ืš ืœื”ืคื•ืš present, ื›ืœื•ืžืจ, ืื ื• ืื•ืžืจื™ื ืœื”ืชืงื™ืŸ ืืช ื”ื—ื‘ื™ืœื•ืช ื”ืœืœื•. ื‘ืื•ืคืŸ ื“ื•ืžื”, ืื ื• ื™ื›ื•ืœื™ื ืœื•ืžืจ ืœื”ื ืœืžื—ื•ืง ืื•ืชื, ืื• ืœืขื“ื›ืŸ ืื•ืชื ืคืฉื•ื˜ ืขืœ ื™ื“ื™ ืฉื™ื ื•ื™ state. ืฉื™ืžื• ืœื‘ ืฉื›ื“ื™ ืฉ-rails ื™ืขื‘ื“ื• ืขื postgresql ืื ื—ื ื• ืฆืจื™ื›ื™ื ืืช ื—ื‘ื™ืœืช postgresql-contrib, ืื•ืชื” ืื ื• ืžืชืงื™ื ื™ื ื›ืขืช. ืฉื•ื‘, ืืชื” ืฆืจื™ืš ืœื“ืขืช ื•ืœืขืฉื•ืช ืืช ื–ื”; ืื ืกื™ื‘ืœ ื‘ืขืฆืžื• ืœื ื™ืขืฉื” ื–ืืช.

ื ืกื” ืœื”ืคืขื™ืœ ืฉื•ื‘ ืืช ืกืคืจ ื”ื”ืคืขืœื” ื•ื‘ื“ื•ืง ืฉื”ื—ื‘ื™ืœื•ืช ืžื•ืชืงื ื•ืช.

ื™ืฆื™ืจืช ืžืฉืชืžืฉื™ื ื—ื“ืฉื™ื.

ืœืขื‘ื•ื“ื” ืขื ืžืฉืชืžืฉื™ื, ืœ-Ansible ื™ืฉ ื’ื ืžื•ื“ื•ืœ - ืžืฉืชืžืฉ. ื‘ื•ืื• ื ื•ืกื™ืฃ ืขื•ื“ ืžืฉื™ืžื” ืื—ืช (ื”ื—ื‘ืืชื™ ืืช ื”ื—ืœืงื™ื ื”ื™ื“ื•ืขื™ื ื›ื‘ืจ ื‘ืกืคืจ ื”ืžืฉื—ืง ืžืื—ื•ืจื™ ื”ื”ืขืจื•ืช ื›ื“ื™ ืœื ืœื”ืขืชื™ืง ืื•ืชื” ืœื’ืžืจื™ ื‘ื›ืœ ืคืขื):

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

ืื ื• ื™ื•ืฆืจื™ื ืžืฉืชืžืฉ ื—ื“ืฉ, ืžื’ื“ื™ืจื™ื ืขื‘ื•ืจื• ืชื‘ื ื™ืช ื•ืกื™ืกืžื”. ื•ืื– ืื ื—ื ื• ื ืชืงืœื™ื ื‘ื›ืžื” ื‘ืขื™ื•ืช. ืžื” ืื ืฉืžื•ืช ื”ืžืฉืชืžืฉ ืฆืจื™ื›ื™ื ืœื”ื™ื•ืช ืฉื•ื ื™ื ืขื‘ื•ืจ ืžืืจื—ื™ื ืฉื•ื ื™ื? ื•ืื—ืกื•ืŸ ื”ืกื™ืกืžื” ื‘ื˜ืงืกื˜ ื‘ืจื•ืจ ื‘ืกืคืจ ื”ืžืฉื—ืงื™ื ื”ื•ื ืจืขื™ื•ืŸ ืจืข ืžืื•ื“. ื‘ืชื•ืจ ื”ืชื—ืœื”, ื ื›ื ื™ืก ืืช ืฉื ื”ืžืฉืชืžืฉ ื•ื”ืกื™ืกืžื” ืœืžืฉืชื ื™ื ื•ืœืงืจืืช ืกื•ืฃ ื”ืžืืžืจ ืืจืื” ื›ื™ืฆื“ ืœื”ืฆืคื™ืŸ ืืช ื”ืกื™ืกืžื”.

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

ืžืฉืชื ื™ื ืžื•ื’ื“ืจื™ื ื‘ืกืคืจื™ ืžืฉื—ืง ื‘ืืžืฆืขื•ืช ืคืœื˜ื” ืžืชื•ืœืชืœืช ื›ืคื•ืœื”.

ื ืฆื™ื™ืŸ ืืช ืขืจื›ื™ ื”ืžืฉืชื ื™ื ื‘ืงื•ื‘ืฅ ื”ืžืœืื™:

123.123.123.123

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

ืฉื™ืžื• ืœื‘ ืœื”ื ื—ื™ื” [all:vars] - ื–ื” ืื•ืžืจ ืฉื”ื’ื•ืฉ ื”ื‘ื ืฉืœ ื”ื˜ืงืกื˜ ื”ื•ื ืžืฉืชื ื™ื (vars) ื•ื”ื ื™ืฉื™ืžื™ื ืขืœ ื›ืœ ื”ืžืืจื—ื™ื (ื›ื•ืœื).

ื’ื ื”ืขื™ืฆื•ื‘ ืžืขื ื™ื™ืŸ "{{ user_password | password_hash('sha512') }}". ื”ืขื ื™ื™ืŸ ื”ื•ื ืฉ-ansible ืœื ืžืชืงื™ืŸ ืืช ื”ืžืฉืชืžืฉ ื“ืจืš user_add ื›ืžื• ืฉื”ื™ื™ืช ืขื•ืฉื” ืืช ื–ื” ื™ื“ื ื™ืช. ื•ื–ื” ืฉื•ืžืจ ืืช ื›ืœ ื”ื ืชื•ื ื™ื ื™ืฉื™ืจื•ืช, ื•ืœื›ืŸ ืื ื—ื ื• ื—ื™ื™ื‘ื™ื ื’ื ืœื”ืžื™ืจ ืืช ื”ืกื™ืกืžื” ืœ-hash ืžืจืืฉ, ื•ื–ื” ืžื” ืฉื”ืคืงื•ื“ื” ื”ื–ื• ืขื•ืฉื”.

ื‘ื•ืื• ื ื•ืกื™ืฃ ืืช ื”ืžืฉืชืžืฉ ืฉืœื ื• ืœืงื‘ื•ืฆืช 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"

ื”ื›ืœ ื“ื™ ืคืฉื•ื˜, ื™ืฉ ืœื ื• ื’ื ืžื•ื“ื•ืœ ืงื‘ื•ืฆืชื™ ืœื™ืฆื™ืจืช ืงื‘ื•ืฆื•ืช, ืขื ืชื—ื‘ื™ืจ ื“ื•ืžื” ืžืื•ื“ ืœ-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 ื™ืฉ ืชืคืงื™ื“ื™ื.
ืœืคื™ ืžื‘ื ื” ื”ืงื‘ืฆื™ื ืฉืฆื•ื™ืŸ ื‘ื”ืชื—ืœื”, ื™ืฉ ืœืžืงื ืชืคืงื™ื“ื™ื ื‘ืกืคืจื™ื™ืช ืชืคืงื™ื“ื™ื ื ืคืจื“ืช, ืœื›ืœ ืชืคืงื™ื“ ื™ืฉ ืกืคืจื™ื” ื ืคืจื“ืช ื‘ืื•ืชื• ืฉื, ื‘ืชื•ืš ืกืคืจื™ื™ืช ื”ืžืฉื™ืžื•ืช, ื”ืงื‘ืฆื™ื, ื”ืชื‘ื ื™ื•ืช ื•ื›ื•'.
ื‘ื•ืื• ื ื™ืฆื•ืจ ืžื‘ื ื” ืงื‘ืฆื™ื: ./ansible/roles/user/tasks/main.yml (main ื”ื•ื ื”ืงื•ื‘ืฅ ื”ืจืืฉื™ ืฉื™ื™ื˜ืขืŸ ื•ื™ื‘ื•ืฆืข ื›ืืฉืจ ืชืคืงื™ื“ ืžื—ื•ื‘ืจ ืœ-Playbook; ื ื™ืชืŸ ืœื—ื‘ืจ ืืœื™ื• ืงื‘ืฆื™ ืชืคืงื™ื“ื™ื ืื—ืจื™ื). ื›ืขืช ืชื•ื›ืœ ืœื”ืขื‘ื™ืจ ืืช ื›ืœ ื”ืžืฉื™ืžื•ืช ื”ืงืฉื•ืจื•ืช ืœืžืฉืชืžืฉ ืœืงื•ื‘ืฅ ื”ื–ื”:

# 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

ื‘ืกืคืจ ื”ืžืฉื—ืงื™ื ื”ืจืืฉื™, ืขืœื™ืš ืœืฆื™ื™ืŸ ืœื”ืฉืชืžืฉ ื‘ืชืคืงื™ื“ ื”ืžืฉืชืžืฉ:

---
- 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 ื—ื™ื™ื‘ ืœื”ื™ื•ืช ืžื•ืคืขืœ (ื›ืœื•ืžืจ, ืื ื—ื ื• ืžืคืขื™ืœื™ื ืื•ืชื•), ืืœื ืื ื—ื ื• ืžื™ื“ ืื•ืžืจื™ื ืฉื”ื•ื ื—ื™ื™ื‘ ืœื”ื™ื•ืช ืžื•ืคืขืœ.
ื›ืขืช ื ืขืชื™ืง ืืช ืงื‘ืฆื™ ื”ืชืฆื•ืจื”:

# 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 (ื–ื” ืœื ื”ื›ืจื—ื™ ืื‘ืœ ืฉื™ืžื•ืฉื™). ื‘ืžืงืจื” ื”ืจืืฉื•ืŸ, ืื ื• ืžืฉืชืžืฉื™ื ื‘ืžื•ื“ื•ืœ ื”ื”ืขืชืงื” ื›ื“ื™ ืœื”ืขืชื™ืง ืงื‘ืฆื™ื (ื”ืงื•ื‘ืฅ ื—ื™ื™ื‘ ืœื”ื™ื•ืช ื‘- /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 ื™ื—ืœื™ืคื• ื‘ืชื‘ื ื™ืช ืœืคื ื™ ื”ื”ืขืชืงื”. ื–ื” ืฉื™ืžื•ืฉื™ ืื ืืชื” ืžืฉืชืžืฉ ื‘ืกืคืจ ืžืฉื—ืง ืขื‘ื•ืจ ืงื‘ื•ืฆื•ืช ืฉื•ื ื•ืช ืฉืœ ืžืืจื—ื™ื. ืœื“ื•ื’ืžื”, ืื ื• ื™ื›ื•ืœื™ื ืœื”ื•ืกื™ืฃ ืืช ืงื•ื‘ืฅ ื”ืžืœืื™ ืฉืœื ื•:

[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

ืื ื ืฉื™ืง ื›ืขืช ืืช ืกืคืจ ื”ืžืฉื—ืงื™ื ืฉืœื ื•, ื”ื•ื ื™ื‘ืฆืข ืืช ื”ืžืฉื™ืžื•ืช ืฉืฆื•ื™ื ื• ืขื‘ื•ืจ ืฉื ื™ ื”ืžืืจื—ื™ื. ืืš ื™ื—ื“ ืขื ื–ืืช, ืขื‘ื•ืจ ืžืืจื— ื‘ื™ืžื•ื™, ื”ืžืฉืชื ื™ื ื™ื”ื™ื• ืฉื•ื ื™ื ืžืืœื” ืฉืœ ื”ื™ื™ืฆื•ืจ, ื•ืœื ืจืง ื‘ืชืคืงื™ื“ื™ื ื•ื‘ืกืคืจื™ ืžืฉื—ืง, ืืœื ื’ื ื‘ืชืฆื•ืจื•ืช nginx. {{ inventory_hostname }} ืื™ืŸ ืฆื•ืจืš ืœืฆื™ื™ืŸ ื‘ืงื•ื‘ืฅ ื”ืžืœืื™ - ื–ื” ืžืฉืชื ื” ืืคืฉืจื™ ืžื™ื•ื—ื“ ื•ื”ืžืืจื— ืฉืขื‘ื•ืจื• ืคื•ืขืœ ื›ืขืช ืกืคืจ ื”ื”ืคืขืœื” ืžืื•ื—ืกืŸ ืฉื.
ืื ืืชื” ืจื•ืฆื” ืฉื™ื”ื™ื” ืœืš ืงื•ื‘ืฅ ืžืœืื™ ืขื‘ื•ืจ ืžืกืคืจ ืžืืจื—ื™ื, ืื‘ืœ ืœื”ืคืขื™ืœ ืจืง ืขื‘ื•ืจ ืงื‘ื•ืฆื” ืื—ืช, ื ื™ืชืŸ ืœืขืฉื•ืช ื–ืืช ืขื ื”ืคืงื•ื“ื” ื”ื‘ืื”:

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

ืืคืฉืจื•ืช ื ื•ืกืคืช ื”ื™ื ืงื‘ืฆื™ ืžืœืื™ ื ืคืจื“ื™ื ืœืงื‘ื•ืฆื•ืช ืฉื•ื ื•ืช. ืื• ืฉืืชื” ื™ื›ื•ืœ ืœืฉืœื‘ ืืช ืฉืชื™ ื”ื’ื™ืฉื•ืช ืื ื™ืฉ ืœืš ืžืืจื—ื™ื ืจื‘ื™ื ื•ืฉื•ื ื™ื.

ื‘ื•ื ื ื—ื–ื•ืจ ืœื”ื’ื“ืจืช 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

ื”ื›ืœ ืคืฉื•ื˜ ื›ืืŸ - ืฉื•ื‘ ืžื•ื“ื•ืœื™ื ืืคืฉืจื™ื™ื ืขื ืชื—ื‘ื™ืจ ืกื˜ื ื“ืจื˜ื™ ืœืžื“ื™. ืื‘ืœ ื™ืฉ ื ืงื•ื“ื” ืื—ืช. ืื™ืŸ ื˜ืขื ืœื”ืคืขื™ืœ ืžื—ื“ืฉ ืืช nginx ื‘ื›ืœ ืคืขื. ืฉืžืชื ืœื‘ ืฉืื ื—ื ื• ืœื ื›ื•ืชื‘ื™ื ืคืงื•ื“ื•ืช ื›ืžื•: "ืขืฉื” ืืช ื–ื” ื›ื›ื”", ื”ืชื—ื‘ื™ืจ ื ืจืื” ื™ื•ืชืจ ื›ืžื• "ื–ื” ืฆืจื™ืš ืœื”ื™ื•ืช ื‘ืžืฆื‘ ื”ื–ื”". ื•ืœืจื•ื‘ ื–ื” ื‘ื“ื™ื•ืง ืื™ืš ansible ืขื•ื‘ื“. ืื ื”ืงื‘ื•ืฆื” ื›ื‘ืจ ืงื™ื™ืžืช, ืื• ืฉื—ื‘ื™ืœืช ื”ืžืขืจื›ืช ื›ื‘ืจ ืžื•ืชืงื ืช, ืื–ื™ ืื ืกื™ื‘ืœ ืชื‘ื“ื•ืง ื–ืืช ื•ืชื“ืœื’ ืขืœ ื”ืžืฉื™ืžื”. ื›ืžื• ื›ืŸ, ืงื‘ืฆื™ื ืœื ื™ื•ืขืชืงื• ืื ื”ื ืชื•ืืžื™ื ืœื—ืœื•ื˜ื™ืŸ ืœืžื” ืฉื›ื‘ืจ ื ืžืฆื ื‘ืฉืจืช. ื ื•ื›ืœ ืœื ืฆืœ ื–ืืช ื•ืœื”ืคืขื™ืœ ืžื—ื“ืฉ ืืช nginx ืจืง ืื ืงื‘ืฆื™ ื”ืชืฆื•ืจื” ืฉื•ื ื•. ื™ืฉ ื”ื ื—ื™ื™ืช ืจื™ืฉื•ื ืœื›ืš:

# 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 ืœืกืคืจ ื”ืžืฉื—ืงื™ื ื”ืจืืฉื™.

ื”ื’ื“ืจืช 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 }}"

ืœื ืืชืืจ ืื™ืš ืœื”ื•ืกื™ืฃ ืžืฉืชื ื™ื ืœืžืœืื™, ื–ื” ื›ื‘ืจ ื ืขืฉื” ื”ืจื‘ื” ืคืขืžื™ื, ื›ืžื• ื’ื ืืช ื”ืชื—ื‘ื™ืจ ืฉืœ ื”ืžื•ื“ื•ืœื™ื postgresql_db ื•-postgresql_user. ืžื™ื“ืข ื ื•ืกืฃ ื ื™ืชืŸ ืœืžืฆื•ื ื‘ืชื™ืขื•ื“. ื”ื”ื ื—ื™ื” ื”ื›ื™ ืžืขื ื™ื™ื ืช ื›ืืŸ ื”ื™ื become_user: postgres. ื”ืขื•ื‘ื“ื” ื”ื™ื ืฉื‘ื‘ืจื™ืจืช ืžื—ื“ืœ, ืจืง ืœืžืฉืชืžืฉ postgres ื™ืฉ ื’ื™ืฉื” ืœืžืกื“ ื”ื ืชื•ื ื™ื postgresql ื•ืจืง ื‘ืื•ืคืŸ ืžืงื•ืžื™. ื”ื ื—ื™ื” ื–ื• ืžืืคืฉืจืช ืœื ื• ืœื‘ืฆืข ืคืงื•ื“ื•ืช ื‘ืฉื ื”ืžืฉืชืžืฉ ื”ื–ื” (ืื ื™ืฉ ืœื ื• ื’ื™ืฉื”, ื›ืžื•ื‘ืŸ).
ื›ืžื• ื›ืŸ, ื™ื™ืชื›ืŸ ืฉื™ื”ื™ื” ืขืœื™ืš ืœื”ื•ืกื™ืฃ ืฉื•ืจื” ืœ-pg_hba.conf ื›ื“ื™ ืœืืคืฉืจ ืœืžืฉืชืžืฉ ื—ื“ืฉ ื’ื™ืฉื” ืœืžืกื“ ื”ื ืชื•ื ื™ื. ื ื™ืชืŸ ืœืขืฉื•ืช ื–ืืช ื‘ืื•ืชื• ืื•ืคืŸ ืฉื‘ื• ืฉื™ื ื™ื ื• ืืช ืชืฆื•ืจืช nginx.

ื•ื›ืžื•ื‘ืŸ, ืืชื” ืฆืจื™ืš ืœื”ื•ืกื™ืฃ ืืช ื”ืชืคืงื™ื“ postgresql ืœืกืคืจ ื”ืžืฉื—ืงื™ื ื”ืจืืฉื™.

ื”ืชืงื ืช ืจื•ื‘ื™ ื“ืจืš 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 ืžื•ืชืงืŸ ื‘ืกืคืจื™ื™ืช ื”ื‘ื™ืช ืฉืœื•, ื•ืœื ื‘ืื•ืคืŸ ื’ืœื•ื‘ืœื™. ื•ืื ื—ื ื• ื’ื ืžืฉืชืžืฉื™ื ื‘ืžื•ื“ื•ืœ git ื›ื“ื™ ืœืฉื›ืคืœ ืืช ื”ืžืื’ืจ, ืชื•ืš ืฆื™ื•ืŸ ืจื™ืคื• ื•-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

ื•ืœื‘ืกื•ืฃ ืชืชืงื™ืŸ ืื•ื“ื. ื–ื” ื ืขืฉื” ื‘ืืžืฆืขื•ืช 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 ื™ืฆื˜ืจืš ืœื”ื™ื•ืช ืžื•ื’ื“ืจ ื™ืฉื™ืจื•ืช ื‘ืื•ืชื• ืกืงืจื™ืคื˜.

ื”ื‘ืขื™ื” ื”ื‘ืื” ื ื•ื‘ืขืช ืžื”ืขื•ื‘ื“ื” ืฉืœืคืงื•ื“ื” ืžืขื˜ืคืช ืื™ืŸ ืžืฆื‘ ืžื ืงื•ื“ืช ืžื‘ื˜ ืืคืฉืจื™ืช. ื›ืœื•ืžืจ, ืœื ืชื”ื™ื” ื‘ื“ื™ืงื” ืื•ื˜ื•ืžื˜ื™ืช ืื ื’ืจืกื” ื–ื• ืฉืœ ืจื•ื‘ื™ ืžื•ืชืงื ืช ืื• ืœื. ืื ื—ื ื• ื™ื›ื•ืœื™ื ืœืขืฉื•ืช ื–ืืช ื‘ืขืฆืžื ื•:

- 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 ืฉืœื ื• ืœืกืคืจ ื”ืžืฉื—ืงื™ื ื”ืจืืฉื™.

ืงื‘ืฆื™ื ืžืฉื•ืชืคื™ื.

ื‘ืื•ืคืŸ ื›ืœืœื™, ื ื™ืชืŸ ื”ื™ื” ืœื”ืฉืœื™ื ืืช ื”ื”ื’ื“ืจื” ื›ืืŸ. ืœืื—ืจ ืžื›ืŸ, ื›ืœ ืžื” ืฉื ื•ืชืจ ื”ื•ื ืœื”ืคืขื™ืœ ืืช 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 ืชื™ืฆื•ืจ ืื•ื˜ื•ืžื˜ื™ืช ืกืคืจื™ื•ืช ืื‘ ื‘ืžื™ื“ืช ื”ืฆื•ืจืš.

ื›ืกืคืช ืื ืกื™ื‘ืœ

ื›ื‘ืจ ื ืชืงืœื ื• ื‘ืขื•ื‘ื“ื” ืฉืžืฉืชื ื™ื ื™ื›ื•ืœื™ื ืœื”ื›ื™ืœ ื ืชื•ื ื™ื ืกื•ื“ื™ื™ื ื›ืžื• ืกื™ืกืžืช ื”ืžืฉืชืžืฉ. ืื ื™ืฆืจืช .env ืงื•ื‘ืฅ ืขื‘ื•ืจ ื”ื‘ืงืฉื”, ื•ื›ืŸ database.yml ืื– ื—ื™ื™ื‘ื™ื ืœื”ื™ื•ืช ืืคื™ืœื• ื™ื•ืชืจ ื ืชื•ื ื™ื ืงืจื™ื˜ื™ื™ื ื›ืืœื”. ื–ื” ื™ื”ื™ื” ื˜ื•ื‘ ืœื”ืกืชื™ืจ ืื•ืชื ืžืขื™ื ื™ื™ื ืกืงืจื ื™ื•ืช. ืœืžื˜ืจื” ื–ื• ื”ื•ื ืžืฉืžืฉ ืงืžืจื•ืŸ ืกื‘ื™ืจ.

ื‘ื•ืื• ื ื™ืฆื•ืจ ืงื•ื‘ืฅ ืœืžืฉืชื ื™ื /ansible/vars/all.yml (ื›ืืŸ ื ื™ืชืŸ ืœื™ืฆื•ืจ ืงื‘ืฆื™ื ืฉื•ื ื™ื ืขื‘ื•ืจ ืงื‘ื•ืฆื•ืช ืฉื•ื ื•ืช ืฉืœ ืžืืจื—ื™ื, ื‘ื“ื™ื•ืง ื›ืžื• ื‘ืงื•ื‘ืฅ ื”ืžืœืื™: production.yml, staging.yml ื•ื›ื•').
ื™ืฉ ืœื”ืขื‘ื™ืจ ืืช ื›ืœ ื”ืžืฉืชื ื™ื ืฉื—ื™ื™ื‘ื™ื ืœื”ื™ื•ืช ืžื•ืฆืคื ื™ื ืœืงื•ื‘ืฅ ื–ื” ื‘ืืžืฆืขื•ืช ืชื—ื‘ื™ืจ 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 ื ื™ืชืŸ ืœืคืขื ื— ืืช ื”ืงื•ื‘ืฅ, ืœืฉื ื•ืช ื•ืœืื—ืจ ืžื›ืŸ ืœื”ืฆืคื™ืŸ ืฉื•ื‘.

ืืชื” ืœื ืฆืจื™ืš ืœืคืขื ื— ืืช ื”ืงื•ื‘ืฅ ื›ื“ื™ ืœืขื‘ื•ื“. ืืชื” ืžืื—ืกืŸ ืื•ืชื• ืžื•ืฆืคืŸ ื•ืžืคืขื™ืœ ืืช ืกืคืจ ื”ืžืฉื—ืง ืขื ื”ืืจื’ื•ืžื ื˜ --ask-vault-pass. Ansible ื™ื‘ืงืฉ ืืช ื”ืกื™ืกืžื”, ื™ืื—ื–ืจ ืืช ื”ืžืฉืชื ื™ื ื•ื™ื‘ืฆืข ืืช ื”ืžืฉื™ืžื•ืช. ื›ืœ ื”ื ืชื•ื ื™ื ื™ื™ืฉืืจื• ืžื•ืฆืคื ื™ื.

ื”ืคืงื•ื“ื” ื”ืžืœืื” ืขื‘ื•ืจ ืžืกืคืจ ืงื‘ื•ืฆื•ืช ืฉืœ ืžืืจื—ื™ื ื•ื›ืกืคืช ืืคืฉืจื™ืช ืชื™ืจืื” ื‘ืขืจืš ื›ืš:

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

ืื‘ืœ ืื ื™ ืœื ืืชืŸ ืœืš ืืช ื”ื˜ืงืกื˜ ื”ืžืœื ืฉืœ ืกืคืจื™ ืžืฉื—ืง ื•ืชืคืงื™ื“ื™ื, ื›ืชื•ื‘ ืืช ื–ื” ื‘ืขืฆืžืš. ื›ื™ ืื ืกื™ื‘ ื–ื” ื›ื›ื” - ืื ืืชื” ืœื ืžื‘ื™ืŸ ืžื” ืฆืจื™ืš ืœืขืฉื•ืช, ืื– ื–ื” ืœื ื™ืขืฉื” ืืช ื–ื” ื‘ืฉื‘ื™ืœืš.

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

ื”ื•ืกืคืช ืชื’ื•ื‘ื”