Servera iestatīŔana Rails lietojumprogrammas izvietoŔanai, izmantojot Ansible

Pirms neilga laika man vajadzēja uzrakstÄ«t vairākas Ansible rokasgrāmatas, lai sagatavotu serveri Rails lietojumprogrammas izvietoÅ”anai. Un, pārsteidzoÅ”i, es neatradu vienkārÅ”u soli pa solim rokasgrāmatu. Es negribēju kopēt kāda cita rokasgrāmatu, nesaprotot, kas notiek, un galu galā man bija jāizlasa dokumentācija, visu savācot paÅ”am. VarbÅ«t es kādam varu palÄ«dzēt paātrināt Å”o procesu, izmantojot Å”o rakstu.

Vispirms ir jāsaprot, ka ansible nodroÅ”ina ērtu saskarni, lai veiktu iepriekÅ” noteiktu darbÄ«bu sarakstu attālajā serverÄ«, izmantojot SSH. Å eit nav nekādas burvÄ«bas, jÅ«s nevarat instalēt spraudni un iegÅ«t lietojumprogrammas izvietoÅ”anu bez dÄ«kstāves, izmantojot dokstaciju, uzraudzÄ«bu un citus jaukumus. Lai rakstÄ«tu rokasgrāmatu, jums jāzina, ko tieÅ”i vēlaties darÄ«t un kā to izdarÄ«t. Tāpēc mani neapmierina gatavas GitHub rokasgrāmatas vai raksti, piemēram: ā€œKopēt un palaist, tas darbosies.ā€

Kas mums vajadzīgs?

Kā jau teicu, lai uzrakstÄ«tu rokasgrāmatu, ir jāzina, ko un kā darÄ«t. Izlemsim, kas mums vajadzÄ«gs. Rails lietojumprogrammai mums bÅ«s nepiecieÅ”amas vairākas sistēmas pakotnes: nginx, postgresql (redis utt.). Turklāt mums ir nepiecieÅ”ama Ä«paÅ”a rubÄ«na versija. Vislabāk to instalēt caur rbenv (rvm, asdf...). To visu palaist kā root lietotājam vienmēr ir slikta ideja, tāpēc ir jāizveido atseviŔķs lietotājs un jākonfigurē viņa tiesÄ«bas. Pēc tam jums ir jāaugÅ”upielādē mÅ«su kods serverÄ«, jākopē nginx, postgres utt. konfigurācijas un jāuzsāk visi Å”ie pakalpojumi.

Rezultātā darbību secība ir Ŕāda:

  1. Piesakieties kā root
  2. instalēt sistēmas pakotnes
  3. izveidot jaunu lietotāju, konfigurēt tiesības, ssh atslēgu
  4. konfigurējiet sistēmas pakotnes (nginx utt.) un palaidiet tās
  5. Mēs izveidojam lietotāju datu bāzē (jūs varat uzreiz izveidot datu bāzi)
  6. Piesakieties kā jauns lietotājs
  7. Instalējiet rbenv un ruby
  8. Komplektētāja uzstādÄ«Å”ana
  9. Lietojumprogrammas koda augŔupielāde
  10. Puma servera palaiŔana

Turklāt pēdējos posmus var veikt, izmantojot capistrano, vismaz no kastes var kopēt kodu izlaiduma direktorijos, pārslēgt laidienu ar simbolu pēc veiksmÄ«gas izvietoÅ”anas, kopēt konfigurācijas no koplietotā direktorija, restartēt puma utt. To visu var izdarÄ«t, izmantojot Ansible, bet kāpēc?

Failu struktūra

Ansible ir stingrs failu struktÅ«ra visiem failiem, tāpēc vislabāk to visu glabāt atseviŔķā direktorijā. Turklāt nav tik svarÄ«gi, vai tas bÅ«s paŔā sliežu aplikācijā, vai atseviŔķi. Varat glabāt failus atseviŔķā git repozitorijā. Man personÄ«gi visērtāk Ŕķita izveidot iespējamu direktoriju sliedes lietojumprogrammas direktorijā /config un visu glabāt vienā repozitorijā.

VienkārŔa rokasgrāmata

Playbook ir yml fails, kas, izmantojot īpaŔu sintaksi, apraksta, kas un kā Ansible jādara. Izveidosim pirmo rokasgrāmatu, kas neko nedara:

---
- name: Simple playbook
  hosts: all

Å eit mēs vienkārÅ”i sakām, ka mÅ«su rokasgrāmata saucas Simple Playbook un ka tā saturs ir jāizpilda visiem saimniekiem. Mēs varam to saglabāt /ansible direktorijā ar nosaukumu playbook.yml un mēģini skriet:

ansible-playbook ./playbook.yml

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

Ansible saka, ka nezina nevienu saimniekdatoru, kas atbilstu visu sarakstu. Tie ir jānorāda īpaŔā sarakstā inventāra fails.

Izveidosim to tajā paŔā iespējamajā direktorijā:

123.123.123.123

Tādā veidā mēs vienkārÅ”i norādām resursdatoru (ideālā gadÄ«jumā mÅ«su VPS resursdatoru testÄ“Å”anai, vai arÄ« varat reÄ£istrēt localhost) un saglabājam to ar nosaukumu inventory.
Varat mēģināt palaist ansible, izmantojot uzskaites failu:

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

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

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

Ja jums ir ssh piekļuve norādÄ«tajam resursdatoram, ansible izveidos savienojumu un apkopos informāciju par attālo sistēmu. (noklusējuma UZDEVUMS [Faktu apkopoÅ”ana]), pēc kura tas sniegs Ä«su ziņojumu par izpildi (PLAY RECAP).

Pēc noklusējuma savienojumam tiek izmantots lietotājvārds, ar kuru esat pieteicies sistēmā. Visticamāk, tas nebÅ«s saimniekdatorā. Rokasgrāmatas failā varat norādÄ«t, kuru lietotāju izmantot, lai izveidotu savienojumu, izmantojot direktÄ«vu remote_user. ArÄ« informācija par attālo sistēmu jums bieži var bÅ«t nevajadzÄ«ga, un jums nevajadzētu tērēt laiku tās apkopoÅ”anai. Å o uzdevumu var arÄ« atspējot:

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

Mēģiniet vēlreiz palaist rokasgrāmatu un pārliecinieties, vai savienojums darbojas. (Ja norādÄ«jāt root lietotāju, tad, lai iegÅ«tu paaugstinātas tiesÄ«bas, ir jānorāda arÄ« direktÄ«va tapti: true. Kā rakstÄ«ts dokumentācijā: become set to ā€˜trueā€™/ā€™yesā€™ to activate privilege escalation. lai gan nav lÄ«dz galam skaidrs, kāpēc).

Varbūt jūs saņemsit kļūdu, ko izraisa fakts, ka ansible nevar noteikt Python tulku, tad varat to norādīt manuāli:

ansible_python_interpreter: /usr/bin/python3 

Jūs varat uzzināt, kur jums ir python, izmantojot komandu whereis python.

Sistēmas pakotņu instalÄ“Å”ana

Ansible standarta izplatÄ«Å”anā ir iekļauti daudzi moduļi darbam ar dažādām sistēmas pakotnēm, tāpēc mums nav jāraksta bash skripti jebkāda iemesla dēļ. Tagad mums ir nepiecieÅ”ams viens no Å”iem moduļiem, lai atjauninātu sistēmu un instalētu sistēmas pakotnes. Manā VPS ir Ubuntu Linux, tāpēc es izmantoju pakotņu instalÄ“Å”anai apt-get Šø modulis tam. Ja jÅ«s izmantojat citu operētājsistēmu, tad jums var bÅ«t nepiecieÅ”ams cits modulis (atcerieties, es teicu sākumā, ka mums ir iepriekÅ” jāzina, ko un kā mēs darÄ«sim). Tomēr sintakse, visticamāk, bÅ«s lÄ«dzÄ«ga.

Papildināsim mūsu rokasgrāmatu ar pirmajiem uzdevumiem:

---
- 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

Uzdevums ir tieÅ”i tas uzdevums, ko Ansible veiks attālajos serveros. Mēs pieŔķiram uzdevumam nosaukumu, lai mēs varētu izsekot tā izpildei žurnālā. Un mēs aprakstām, izmantojot konkrēta moduļa sintaksi, kas tam jādara. Å ajā gadÄ«jumā apt: update_cache=yes - saka atjaunināt sistēmas pakotnes, izmantojot apt moduli. Otrā komanda ir nedaudz sarežģītāka. Mēs nododam pakotņu sarakstu apt modulim un sakām, ka tās ir state vajadzētu kļūt present, tas ir, mēs sakām, ka instalējiet Ŕīs pakotnes. LÄ«dzÄ«gā veidā mēs varam likt viņiem tos dzēst vai atjaunināt, vienkārÅ”i mainot state. LÅ«dzu, ņemiet vērā, ka, lai sliedes darbotos ar postgresql, mums ir nepiecieÅ”ama pakotne postgresql-contrib, kuru mēs tagad instalējam. Atkal, jums tas jāzina un jādara; ansible viens pats to nedarÄ«s.

Mēģiniet vēlreiz palaist rokasgrāmatu un pārbaudiet, vai pakotnes ir instalētas.

Jaunu lietotāju izveide.

Lai strādātu ar lietotājiem, Ansible ir arī modulis - lietotājs. Pievienosim vēl vienu uzdevumu (jau zināmās rotaļu grāmatas daļas paslēpu aiz komentāriem, lai katru reizi nepārkopētu to pilnībā):

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

Mēs izveidojam jaunu lietotāju, iestatām tam shell un paroli. Un tad mēs saskaramies ar vairākām problēmām. Ko darÄ«t, ja dažādu saimniekdatoru lietotājvārdiem ir jābÅ«t atŔķirÄ«giem? Un paroles glabāŔana skaidrā tekstā rokasgrāmatā ir ļoti slikta ideja. Sākumā ievadÄ«sim lietotājvārdu un paroli mainÄ«gajos, un raksta beigās es parādÄ«Å”u, kā Å”ifrēt paroli.

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

Mainīgie lielumi tiek iestatīti rokasgrāmatās, izmantojot dubultās cirtainās figūriekavas.

Mēs norādīsim mainīgo vērtības inventarizācijas failā:

123.123.123.123

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

Lūdzu, ņemiet vērā direktīvu [all:vars] - tas saka, ka nākamais teksta bloks ir mainīgie (vari) un tie ir piemērojami visiem saimniekiem (visiem).

ArÄ« dizains ir interesants "{{ user_password | password_hash('sha512') }}". Lieta tāda, ka ansible neinstalē lietotāju caur user_add tāpat kā jÅ«s to darÄ«tu manuāli. Un tas saglabā visus datus tieÅ”i, tāpēc mums ir arÄ« iepriekÅ” jāpārvērÅ” parole par jaucējkodu, ko Ŕī komanda dara.

Pievienosim savu lietotāju sudo grupai. Tomēr pirms tam mums ir jāpārliecinās, ka Ŕāda grupa pastāv, jo neviens to mÅ«su vietā nedarÄ«s:

---
- 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"

Viss ir pavisam vienkārÅ”i, mums ir arÄ« grupu modulis grupu izveidei, kura sintaksi ļoti lÄ«dzinās apt. Tad pietiek reÄ£istrēt Å”o grupu lietotājam (groups: "sudo").
Ir arÄ« noderÄ«gi Å”im lietotājam pievienot ssh atslēgu, lai mēs varētu pieteikties, izmantojot to bez paroles:

---
- 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

Å ajā gadÄ«jumā dizains ir interesants "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" ā€” tas kopē faila id_rsa.pub saturu (jÅ«su vārds var atŔķirties), tas ir, ssh atslēgas publisko daļu un augÅ”upielādē to lietotāja autorizēto atslēgu sarakstā serverÄ«.

Lomas

Visus trÄ«s lietojuma izveides uzdevumus var viegli klasificēt vienā uzdevumu grupā, un bÅ«tu ieteicams Å”o grupu glabāt atseviŔķi no galvenās rokasgrāmatas, lai tā neizaugtu pārāk liela. Å im nolÅ«kam Ansible ir lomas.
AtbilstoÅ”i paŔā sākumā norādÄ«tajai faila struktÅ«rai lomas jāievieto atseviŔķā lomu direktorijā, katrai lomai ir atseviŔķs direktorijs ar tādu paÅ”u nosaukumu, iekŔā uzdevumu, failu, veidņu utt direktorijā
Izveidosim faila struktÅ«ru: ./ansible/roles/user/tasks/main.yml (galvenais ir galvenais fails, kas tiks ielādēts un izpildÄ«ts, kad loma ir pievienota rokasgrāmatai; tai var pievienot citus lomu failus). Tagad visus ar lietotāju saistÄ«tos uzdevumus varat pārsÅ«tÄ«t uz Å”o failu:

# 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

Galvenajā rokasgrāmatā ir jānorāda, lai izmantotu lietotāja lomu:

---
- 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

Tāpat var būt lietderīgi atjaunināt sistēmu pirms visiem citiem uzdevumiem; lai to izdarītu, varat pārdēvēt bloku tasks kurā tie ir definēti pre_tasks.

Notiek nginx iestatīŔana

Mums jau vajadzētu būt instalētam Nginx; mums tas ir jākonfigurē un jāpalaiž. Darīsim to uzreiz lomā. Izveidosim faila struktūru:

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

Tagad mums ir nepiecieÅ”ami faili un veidnes. AtŔķirÄ«ba starp tiem ir tāda, ka ansible kopē failus tieÅ”i tādus, kādi tie ir. Un veidnēm ir jābÅ«t j2 paplaÅ”inājumam, un tās var izmantot mainÄ«gas vērtÄ«bas, izmantojot tās paÅ”as dubultās krokainās figÅ«riekavas.

Iespējosim nginx main.yml failu. Šim nolūkam mums ir sistēmas modulis:

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

Šeit mēs ne tikai sakām, ka nginx ir jāsāk (tas ir, mēs to palaižam), bet mēs uzreiz sakām, ka tas ir jāiespējo.
Tagad kopēsim konfigurācijas failus:

# 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'

Mēs izveidojam galveno nginx konfigurācijas failu (varat to ņemt tieÅ”i no servera vai uzrakstÄ«t pats). Un arÄ« mÅ«su lietojumprogrammas konfigurācijas fails direktorijā sites_available (tas nav nepiecieÅ”ams, bet noderÄ«gs). Pirmajā gadÄ«jumā mēs izmantojam kopÄ“Å”anas moduli, lai kopētu failus (failam jābÅ«t iekŔā /ansible/roles/nginx/files/nginx.conf). Otrajā mēs nokopējam veidni, aizstājot mainÄ«go vērtÄ«bas. Veidnei jābÅ«t iekŔā /ansible/roles/nginx/templates/my_app.j2). Un tas varētu izskatÄ«ties apmēram Ŕādi:

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 }};
  ....
}

Pievērsiet uzmanÄ«bu ieliktņiem {{ app_name }}, {{ app_path }}, {{ server_name }}, {{ inventory_hostname }} ā€” tie ir visi mainÄ«gie, kuru vērtÄ«bas Ansible aizstās veidnē pirms kopÄ“Å”anas. Tas ir noderÄ«gi, ja izmantojat rokasgrāmatu dažādām saimnieku grupām. Piemēram, mēs varam pievienot mÅ«su inventāra failu:

[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

Ja mēs tagad palaižam savu rokasgrāmatu, tā veiks norādÄ«tos uzdevumus abiem saimniekiem. Bet tajā paŔā laikā iestudējuma saimniekam mainÄ«gie atŔķirsies no ražoÅ”anas mainÄ«gajiem, un ne tikai lomās un rotaļu grāmatās, bet arÄ« nginx konfigurācijās. {{ inventory_hostname }} nav jānorāda inventarizācijas failā - Å”is Ä«paÅ”s iespējamais mainÄ«gais un tur tiek saglabāts saimniekdators, kuram paÅ”laik darbojas rokasgrāmata.
Ja vēlaties, lai inventāra fails bÅ«tu vairākiem saimniekiem, bet tas darbotos tikai vienai grupai, to var izdarÄ«t ar Ŕādu komandu:

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

Vēl viena iespēja ir izveidot atseviŔķus inventāra failus dažādām grupām. Vai arÄ« varat apvienot abas pieejas, ja jums ir daudz dažādu saimniekdatoru.

AtgriezÄ«simies pie nginx iestatÄ«Å”anas. Pēc konfigurācijas failu kopÄ“Å”anas mums ir jāizveido saite vietnē sitest_enabled uz my_app.conf no vietnes sites_available. Un restartējiet 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

Å eit viss ir vienkārÅ”i - atkal pieejami moduļi ar diezgan standarta sintaksi. Bet ir viens punkts. Nav jēgas katru reizi restartēt nginx. Vai esat ievērojuÅ”i, ka mēs nerakstām tādas komandas kā: ā€œdari to Ŕādiā€, sintakse vairāk izskatās pēc ā€œÅ”im vajadzētu bÅ«t Å”im stāvoklimā€. Un visbiežāk tieÅ”i tā darbojas ansible. Ja grupa jau pastāv vai sistēmas pakotne jau ir instalēta, ansible to pārbaudÄ«s un izlaidÄ«s uzdevumu. ArÄ« faili netiks kopēti, ja tie pilnÄ«bā sakrÄ«t ar to, kas jau atrodas serverÄ«. Mēs varam izmantot Å”o iespēju un restartēt nginx tikai tad, ja ir mainÄ«ti konfigurācijas faili. Å im nolÅ«kam ir reÄ£istra direktÄ«va:

# 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

Ja mainās kāds no konfigurācijas failiem, tiks izveidota kopija un mainÄ«gais tiks reÄ£istrēts restart_nginx. Un tikai tad, ja Å”is mainÄ«gais ir reÄ£istrēts, pakalpojums tiks restartēts.

Un, protams, galvenajai rokasgrāmatai jāpievieno nginx loma.

Postgresql iestatīŔana

Mums ir jāiespējo postgresql, izmantojot systemd tāpat kā nginx, kā arÄ« jāizveido lietotājs, kuru izmantosim, lai piekļūtu datubāzei un paÅ”ai datubāzei.
Izveidosim lomu /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 }}"

NeaprakstÄ«Å”u, kā inventāram pievienot mainÄ«gos, tas jau ir darÄ«ts daudzas reizes, kā arÄ« postgresql_db un postgresql_user moduļu sintaksi. Vairāk informācijas var atrast dokumentācijā. Å eit ir visinteresantākā direktÄ«va become_user: postgres. Fakts ir tāds, ka pēc noklusējuma tikai postgres lietotājam ir piekļuve postgresql datubāzei un tikai lokāli. Å Ä« direktÄ«va ļauj mums izpildÄ«t komandas Ŕī lietotāja vārdā (ja mums, protams, ir piekļuve).
Tāpat, iespējams, failam pg_hba.conf būs jāpievieno rindiņa, lai ļautu jaunam lietotājam piekļūt datu bāzei. To var izdarīt tāpat kā mēs mainījām nginx konfigurāciju.

Un, protams, galvenajai rokasgrāmatai jāpievieno postgresql loma.

Rubīna instalēŔana caur rbenv

Ansible nav moduļu darbam ar rbenv, bet tas tiek instalēts, klonējot git repozitoriju. Tāpēc Ŕī problēma kļūst par visnestandarta problēmu. Izveidosim viņai lomu /ansible/roles/ruby_rbenv/main.yml un sāksim to aizpildÄ«t:

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

Mēs atkal izmantojam direktÄ«vu kļūt_lietotājs, lai strādātu zem lietotāja, ko izveidojām Å”iem nolÅ«kiem. Tā kā rbenv ir instalēts tā mājas direktorijā, nevis globāli. Un mēs arÄ« izmantojam git moduli, lai klonētu repozitoriju, norādot repo un dest.

Tālāk mums ir jāreģistrē rbenv init programmā bashrc un jāpievieno rbenv uz PATH. Šim nolūkam mums ir lineinfile modulis:

- 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 -)"'

Pēc tam jums jāinstalē ruby_build:

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

Un visbeidzot instalējiet rubÄ«nu. Tas tiek darÄ«ts, izmantojot rbenv, tas ir, vienkārÅ”i ar bash komandu:

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

Mēs sakām, kuru komandu un ar ko izpildÄ«t. Tomēr Å”eit mēs saskaramies ar faktu, ka ansible pirms komandu palaiÅ”anas nepalaiž bashrc ietverto kodu. Tas nozÄ«mē, ka rbenv bÅ«s jādefinē tieÅ”i tajā paŔā skriptā.

Nākamā problēma ir saistÄ«ta ar faktu, ka čaulas komandai nav stāvokļa no iespējamā viedokļa. Tas nozÄ«mē, ka netiks veikta automātiska pārbaude, vai Ŕī rubÄ«na versija ir instalēta vai nav. To varam izdarÄ«t paÅ”i:

- 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

Atliek tikai instalēt komplektētāju:

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

Un atkal pievienojiet mūsu lomu ruby_rbenv galvenajai rokasgrāmatai.

Koplietotie faili.

Kopumā iestatÄ«Å”anu varētu pabeigt Å”eit. Tālāk atliek tikai palaist capistrano, un tas pats nokopēs kodu, izveidos nepiecieÅ”amos direktorijus un palaiž lietojumprogrammu (ja viss ir pareizi konfigurēts). Tomēr capistrano bieži vien ir nepiecieÅ”ami papildu konfigurācijas faili, piemēram, database.yml vai .env Tos var kopēt tāpat kā nginx failus un veidnes. Ir tikai viens smalkums. Pirms failu kopÄ“Å”anas jums ir jāizveido tiem direktoriju struktÅ«ra, piemēram:

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

mēs norādām tikai vienu direktoriju, un ansible automātiski izveidos vecāku direktorijus, ja nepiecieÅ”ams.

Ansible Vault

Mēs jau esam saskāruÅ”ies ar faktu, ka mainÄ«gie var saturēt slepenus datus, piemēram, lietotāja paroli. Ja esat izveidojis .env pieteikuma fails un database.yml tad tādu kritisku datu jābÅ«t vēl vairāk. BÅ«tu labi tos paslēpt no ziņkārÄ«go acÄ«m. Å im nolÅ«kam to izmanto iespējamā velve.

Izveidosim failu mainīgajiem /ansible/vars/all.yml (Ŕeit jūs varat izveidot dažādus failus dažādām saimniekdatoru grupām, tāpat kā inventāra failā: production.yml, staging.yml utt.).
Visi mainÄ«gie, kas jāŔifrē, ir jāpārsÅ«ta uz Å”o failu, izmantojot standarta yml sintaksi:

# 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

Pēc tam Å”o failu var Å”ifrēt ar komandu:

ansible-vault encrypt ./vars/all.yml

Protams, Å”ifrējot, jums bÅ«s jāiestata parole atÅ”ifrÄ“Å”anai. Pēc Ŕīs komandas izsaukÅ”anas varat redzēt, kas bÅ«s failā.

Ar ansible-vault decrypt failu var atÅ”ifrēt, modificēt un pēc tam vēlreiz Å”ifrēt.

Lai darbotos, fails nav jāatÅ”ifrē. JÅ«s to saglabājat Å”ifrētā veidā un palaižat rokasgrāmatu ar argumentu --ask-vault-pass. Ansible pieprasÄ«s paroli, izgÅ«s mainÄ«gos un izpildÄ«s uzdevumus. Visi dati paliks Å”ifrēti.

PilnÄ«ga komanda vairākām saimniekdatoru grupām un ansible Vault izskatÄ«sies apmēram Ŕādi:

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

Bet es jums nesniegŔu pilnu grāmatu un lomu tekstu, rakstiet to pats. Jo ansible ir tā - ja tu nesaproti, kas jādara, tad tas tavā vietā to nedarīs.

Avots: www.habr.com

Pievieno komentāru