Насб кардани сервер барои ҷойгиркунии замимаи Rails бо истифода аз Ansible

Чанде пеш ба ман лозим омад, ки якчанд китобҳои бозикунии Ansible нависам, то серверро барои ҷойгиркунии замимаи Rails омода созам. Ва, тааҷҷубовар аст, ки ман дастури оддии қадам ба қадам наёфтам. Ман намехостам, ки китоби бозии ягон каси дигарро нафаҳмидам, ки чӣ рӯй дода истодааст, нусхабардорӣ кунам ва дар ниҳоят ман маҷбур будам, ки ҳуҷҷатҳоро хонам ва ҳама чизро худам ҷамъоварӣ кунам. Шояд ман метавонам бо ёрии ин мақола ба касе кӯмак кунам, ки ин равандро суръат бахшад.

Аввалин чизе, ки бояд дарк кард, ин аст, ки ansible ба шумо интерфейси мувофиқро барои иҷрои рӯйхати пешакии амалҳо дар сервер(ҳо)-и дурдаст тавассути SSH медиҳад. Дар ин ҷо ҷодуе вуҷуд надорад, шумо наметавонед плагинро насб кунед ва истифодаи бефосилаи барномаи худро бо докер, мониторинг ва чизҳои дигар аз қуттӣ берун кунед. Барои навиштани китоби бозӣ, шумо бояд донед, ки маҳз чӣ кор кардан мехоҳед ва чӣ тавр онро иҷро кунед. Аз ин рӯ, ман аз китобҳои омодашудаи 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 анҷом дод, аммо чаро?

Сохтори файл

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 мегӯяд, ки он ягон хостеро намедонад, ки ба ҳама рӯйхат мувофиқат кунад. Онҳо бояд дар як махсус номбар карда шаванд файли инвентаризатсия.

Биёед онро дар ҳамон директорияи 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 пайваст мешавад ва маълумот дар бораи системаи дурдаст ҷамъоварӣ мекунад. (вазифаи пешфарз [Ҷамъоварии далелҳо]), пас аз он он дар бораи иҷро гузориши кӯтоҳ медиҳад (PLAY RECAP).

Бо нобаёнӣ, пайвастшавӣ номи корбареро истифода мебарад, ки зери он шумо ба система ворид шудаед. Эҳтимолияти он дар мизбон нахоҳад буд. Дар файли китоби бозӣ, шумо метавонед муайян кунед, ки кадом корбар барои пайвастшавӣ бо истифода аз дастури remote_user истифода шавад. Инчунин, маълумот дар бораи системаи дурдаст аксар вақт барои шумо нолозим буда метавонад ва шумо набояд барои ҷамъоварии он вақтро сарф кунед. Ин вазифаро инчунин ғайрифаъол кардан мумкин аст:

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

Кӯшиш кунед, ки китоби бозиро дубора иҷро кунед ва боварӣ ҳосил кунед, ки пайвастшавӣ кор мекунад. (Агар шумо корбари решаро муайян карда бошед, пас шумо инчунин бояд дастури табдил: 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. Лутфан қайд кунед, ки барои кор кардани рельс бо 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 чунон ки шумо онро дастӣ мекунед. Ва он ҳама маълумотро мустақиман захира мекунад, бинобар ин мо бояд паролро пешакӣ ба хэш табдил диҳем, ки ин фармонро иҷро мекунад.

Биёед корбари худро ба гурӯҳи 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-ро эҷод мекунем (шумо метавонед онро мустақиман аз сервер гиред ё худатон нависед). Ва инчунин файли конфигуратсияи барномаи мо дар директорияи 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 -ро ба китоби асосии бозӣ илова кунед.

Насб кардани 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 дар феҳристи хонагии он насб шудааст, на дар саросари ҷаҳон. Ва мо инчунин модули git-ро барои клон кардани анбор истифода мебарем, ки репо ва таъинотро муайян мекунад.

Баъдан, мо бояд 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 бояд бевосита дар ҳамон скрипт муайян карда шавад.

Мушкилоти навбатӣ аз он иборат аст, ки фармони ҷабҳа аз нуқтаи назари оқилона ҳолате надорад. Яъне, санҷиши автоматӣ вуҷуд надорад, ки оё ин версияи 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 -ро ба китоби асосии бозӣ илова кунед.

Файлҳои муштарак.

Умуман, дар ин ҷо насб кардан мумкин аст. Баъдан, танҳо иҷро кардани 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/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 чунин аст - агар шумо намефаҳмед, ки чӣ кор кардан лозим аст, он барои шумо ин корро намекунад.

Манбаъ: will.com

Илова Эзоҳ