Ansible аркылуу Rails тиркемесин жайылтуу үчүн серверди орнотуу

Жакында эле мен серверди Rails тиркемесин жайылтууга даярдоо үчүн бир нече Ansible окуу китептерин жазууга туура келди. Жана, таң калыштуусу, мен жөнөкөй кадам-кадам колдонмосун таба алган жокмун. Мен эмне болуп жатканын түшүнбөй туруп, башка бирөөнүн оюн китебин көчүрүп алгым келген жок, акырында баарын өзүм чогултуп, документтерди окууга туура келди. Балким, мен кимдир бирөө бул макаланын жардамы менен бул процессти тездетүүгө жардам бере алам.

Биринчи түшүнө турган нерсе, ansible сизге SSH аркылуу алыскы серверде(лерде) алдын ала аныкталган аракеттердин тизмесин аткаруу үчүн ыңгайлуу интерфейс менен камсыз кылат. Бул жерде эч кандай сыйкыр жок, сиз плагинди орното албайсыз жана кутудан чыккан докер, мониторинг жана башка жакшы нерселер менен тиркемеңиздин нөлдүк токтоп иштөөсүн ала албайсыз. Оюн китебин жазуу үчүн, сиз так эмнени каалап жатканыңызды жана аны кантип жасоону билишиңиз керек. Ошондуктан мени GitHubдан даяр окуу китептери же: "Көчүрүп, иштетиңиз, ал иштейт" деген сыяктуу макалалар канааттандырбайт.

Бизге эмне керек?

Жогоруда айткандай, оюн китебин жазуу үчүн эмне кылгыңыз келгенин жана аны кантип жасоону билишиңиз керек. Бизге эмне керек экенин чечели. Rails тиркемеси үчүн бизге бир нече система пакеттери керек болот: nginx, postgresql (redis ж.б.). Мындан тышкары, бизге рубиндин конкреттүү версиясы керек. Аны rbenv (rvm, asdf...) аркылуу орнотуу жакшы. Мунун баарын түпкү колдонуучу катары иштетүү дайыма жаман идея, андыктан өзүнчө колдонуучуну түзүп, анын укуктарын конфигурациялашыңыз керек. Андан кийин, сиз биздин кодду серверге жүктөп, nginx, postgres ж.б. үчүн конфигурацияларды көчүрүп, ушул кызматтардын баарын башташыңыз керек.

Натыйжада, иш-аракеттердин ырааттуулугу төмөнкүдөй:

  1. Root катары кириңиз
  2. система пакеттерин орнотуу
  3. жаңы колдонуучуну түзүү, укуктарды конфигурациялоо, ssh ачкычы
  4. система пакеттерин конфигурациялаңыз (nginx ж.б.) жана аларды иштетиңиз
  5. Биз маалымат базасында колдонуучуну түзөбүз (сиз дароо маалымат базасын түзө аласыз)
  6. Жаңы колдонуучу катары кириңиз
  7. Rbenv жана ruby ​​орнотуңуз
  8. Бункерди орнотуу
  9. Колдонмонун коду жүктөлүүдө
  10. Puma серверин ишке киргизүү

Андан тышкары, акыркы этаптарды capistrano колдонуу менен жасоого болот, жок дегенде кутудан тышкары, ал кодду релиз каталогдоруна көчүрө алат, ийгиликтүү жайгаштыруудан кийин релизди символдук шилтеме менен алмаштыра алат, конфигурацияларды жалпы каталогдон көчүрүп, puma-ны өчүрүп ж.б. Мунун баары Ansible аркылуу жасалышы мүмкүн, бирок эмне үчүн?

Файл структурасы

Ansible катуу файл структурасы бардык файлдарыңыз үчүн, андыктан анын баарын өзүнчө каталогдо сактаганыңыз жакшы. Анын үстүнө, ал рельс тиркемесинде болобу, же өзүнчө болобу, анчалык деле маанилүү эмес. Сиз файлдарды өзүнчө git репозиторийинде сактай аласыз. Жеке мага rails тиркемесинин / config каталогунда ansible каталогун түзүү жана баарын бир репозиторийде сактоо ыңгайлуу деп таптым.

Жөнөкөй Playbook

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 бардык тизмеге дал келген хостторду билбейт дейт. Алар атайын тизмеде болушу керек инвентаризация файлы.

Келгиле, аны ошол эле ansible каталогунда түзөлү:

123.123.123.123

Мына ушундайча биз жөн гана хостту аныктайбыз (идеалында тестирлөө үчүн биздин VPS хосту, же сиз localhostту каттасаңыз болот) жана аны ат менен сактайбыз. inventory.
Сиз инвентаризация файлы менен ansible иштетүүгө аракет кылсаңыз болот:

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

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

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

Эгер сизде көрсөтүлгөн хостко ssh мүмкүнчүлүгү бар болсо, анда ansible туташып, алыскы тутум жөнүндө маалыматты чогултат. (демейки ТАПШЫРМА [Фактыларды чогултуу]), андан кийин ал аткарылышы жөнүндө кыскача отчет берет (RECAP PLAY).

Демейки боюнча, туташууда сиз системага кирген колдонуучу атын колдонот. Бул, балким, хостто болбойт. Оюн китебинин файлында, сиз remote_user директивасын колдонуп туташуу үчүн кайсы колдонуучуну колдоно аласыз. Ошондой эле, алыскы система жөнүндө маалымат сизге көп учурда керексиз болуп калышы мүмкүн жана сиз аны чогултууга убакытты текке кетирбешиңиз керек. Бул тапшырма да өчүрүлүшү мүмкүн:

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

Ойнотуу китебин кайра иштетип көрүңүз жана байланыш иштеп жатканын текшериңиз. (Эгер сиз түпкү колдонуучуну көрсөтсөңүз, анда жогорулатылган укуктарга ээ болуу үчүн, ошондой эле become: true директивасын көрсөтүшүңүз керек. Документте жазылгандай: become set to ‘true’/’yes’ to activate privilege escalation. эмне үчүн толук түшүнүксүз болсо да).

Балким, сиз ansible Python котормочусун аныктай албагандыктан улам ката аласыз, анда аны кол менен көрсөтсөңүз болот:

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

Тапшырма так Ansible алыскы серверлерде аткара турган тапшырма. Биз журналда анын аткарылышын көзөмөлдөө үчүн тапшырмага ат беребиз. Ал эми биз белгилүү бир модулдун синтаксисин колдонуп, ал эмне кылуу керектигин сүрөттөп беребиз. Бул учурда apt: update_cache=yes - apt модулунун жардамы менен тутум пакеттерин жаңыртуу дейт. Экинчи буйрук бир аз татаалыраак. Биз пакеттердин тизмесин apt модулуна өткөрүп беребиз жана алар бар деп айтабыз state болууга тийиш present, башкача айтканда, биз бул пакеттерди орнотуу дейбиз. Ошо сыяктуу эле, биз аларга аларды жок кылууну же жөн гана өзгөртүү менен жаңыртууну айта алабыз state. Постgresql менен иштөө үчүн рельс үчүн бизге азыр орнотуп жаткан 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 аны кол менен кылгандай. Жана ал бардык маалыматтарды түздөн-түз сактайт, ошондуктан биз паролду алдын ала хэшке айландырышыбыз керек, бул буйрук эмне кылат.

Биздин колдонуучубузду 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 (негизги файл ойноо китебине туташтырылганда жүктөлүп жана аткарыла турган негизги файл; ага башка ролдук файлдарды туташтырууга болот). Эми сиз бул файлга колдонуучуга тиешелүү бардык тапшырмаларды өткөрө аласыз:

# 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 конфигурация файлын түзөбүз (сиз аны түз серверден алып, же өзүңүз жазсаңыз болот). Жана ошондой эле сайттар_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 ичинде sites_available сайтынан my_app.conf үчүн символдук шилтеме түзүшүбүз керек. Жана 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ти кайра иштете алабыз. Бул үчүн реестр директивасы бар:

# 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 орнотуу

Биз nginx менен кылгандай эле systemd аркылуу postgresqlди иштетишибиз керек, ошондой эле маалымат базасына жана маалымат базасына кирүү үчүн колдоно турган колдонуучуну түзүшүбүз керек.
Келгиле, роль жараталы /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 аркылуу ruby ​​орнотуу

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 модулун колдонобуз, репо жана деst.

Андан кийин, bashrc ичинде rbenv initти катташыбыз керек жана ал жерде PATHге rbenv кошуубуз керек. Бул үчүн бизде 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 түз эле скриптте аныкталышы керек дегенди билдирет.

Кийинки көйгөй, кабык командасынын акылдуу көз караштан алганда абалы жок экендигине байланыштуу. Башкача айтканда, рубиндин бул версиясы орнотулган же орнотулбаганын автоматтык түрдө текшерүү болбойт. Муну өзүбүз жасай алабыз:

- 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

Бундлерди орнотуу гана калды:

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

Жана дагы, биздин ruby_rbenv ролубузду негизги оюн китебине кошуңуз.

Бөлүшүлгөн файлдар.

Жалпысынан алганда, орнотуу бул жерде аякташы мүмкүн. Андан кийин, капистранону иштетүү гана калат жана ал коддун өзүн көчүрүп, керектүү каталогдорду түзүп, тиркемени ишке киргизет (эгерде баары туура конфигурацияланган болсо). Бирок, 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/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 сактагычы үчүн толук буйрук төмөнкүдөй болот:

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

Бирок мен сизге китептердин жана ролдордун толук текстин бербейм, аны өзүңүз жазыңыз. Анткени ansible ушундай - эгер сиз эмне кылуу керектигин түшүнбөсөңүз, анда ал сиз үчүн муну жасабайт.

Source: www.habr.com

Комментарий кошуу