Kohë më parë, më ishte nevojitur të shkruaja disa ansible playbooks për përgatitjen e serverit për deploy të një aplikacioni Rails. Dhe, me befasinë time, nuk gjeta një manual të thjeshtë hapi-pas-hapi. Nuk doja të kopjoja playbook-un e dikujt tjetër pa kuptuar atë që po ndodhte dhe përfundimisht, më duhej të lexoj dokumentacionin, duke mbledhur gjithçka vetë. Ndoshta do të mund të ndihmoj dikë të përshpejtojë këtë proces përmes këtij artikulli.
E para, Ă«shtĂ« e rĂ«ndĂ«sishme tĂ« kuptoni se ansible ju ofron njĂ« ndĂ«rfaqe tĂ« lehtĂ« pĂ«r tĂ« kryer njĂ« listĂ« tĂ« paracaktuar veprimesh nĂ« njĂ« server (servera) tĂ« largĂ«t pĂ«rmes SSH. Nuk ka ndonjĂ« magji kĂ«tu, nuk mund tĂ« vendosni njĂ« plugin dhe tĂ« merrni njĂ« deploy zero downtime tĂ« aplikacionit tuaj me docker, monitorim dhe gjĂ«ra tĂ« tjera. PĂ«r tĂ« shkruar njĂ« playbook duhet tĂ« dini se çfarĂ« dĂ«shironi tĂ« bĂ«ni dhe si ta bĂ«ni atĂ«. Prandaj, unĂ« nuk jam i kĂ«naqur me playbook-et e gatshme nga GitHub, ose artikuj qĂ« thonĂ«: âKopjoni dhe ekzekutoni, do tĂ« funksionojĂ«â.
ĂfarĂ« na nevojitet?
Siç e thashĂ«, pĂ«r tĂ« shkruar njĂ« playbook duhet tĂ« dini se çfarĂ« dĂ«shironi tĂ« bĂ«ni dhe si ta bĂ«ni atĂ«. Le tĂ« pĂ«rcaktojmĂ« se çfarĂ« na nevojitet. PĂ«r aplikacionin Rails, do tĂ« na duhen disa paketa ŃĐžŃŃĐ”ĐŒike: nginx, postgresql (redis, etj). PĂ«rveç kĂ«saj, na duhet ruby i njĂ« versioni tĂ« caktuar. E rekomandoj ta instaloni atĂ« pĂ«rmes rbenv (rvm, asdfâŠ). TĂ« gjitha kĂ«to nuk duhet tĂ« ekzekutohen nga pĂ«rdoruesi root â gjithmonĂ« Ă«shtĂ« njĂ« ide e keqe, prandaj duhet tĂ« krijoni njĂ« pĂ«rdorues tĂ« veçantĂ« dhe tâi konfiguroheni tĂ« drejtat. Pas kĂ«saj, Ă«shtĂ« e nevojshme tĂ« ngarkohet kodi ynĂ« nĂ« server, tĂ« kopjohen konfigurimet pĂ«r nginx, postgres, etj dhe tĂ« nisĂ«n tĂ« gjitha kĂ«to shĂ«rbime.
Në fund, sekuenca e veprimeve është kështu:
- Bëjmë login si root.
- instalojmë paketat sistemike.
- krijojmë një përdorues të ri, konfigurojmë të drejtat, çelësin ssh.
- konfigurojmë paketat sistemike (nginx etj) dhe i nisim ato.
- Krijojmë një përdorues në DB (mund ta krijojmë menjëherë edhe bazën).
- Bëjmë login me përdoruesin e ri.
- Instalojmë rbenv dhe ruby.
- Instalojmë bundler.
- Ngarkojmë kodin e aplikacionit.
- Nisim serverin Puma.
Dhe këto hapat e fundit mund të bëhen me ndihmën e Capistrano, të paktën ai di nga e drejta të kopjojë kodin në direktoritë e lëshimeve, të kalojë në lidhjen simlink kur deploy është i suksesshëm, të kopjojë konfigurimet nga direktoria e ndarë, ta rinstalojë puma dhe etj. Të gjitha këto mund të bëhen edhe me Ansible, por përse?
Struktura e skedarëve
Ansible ka një strukturë të rreptë për të gjitha skedarët e tij, prandaj është më mirë t'i mbani të gjitha në një direktore të veçantë. Nuk ka rëndësi nëse do të jetë brenda aplikacionit Rails, apo ndaras. Mund të ruani skedarët në një depo git të veçantë. Më së shumti, më është dukur më e lehtë të krijoj një direktore ansible në /config të aplikacionit Rails dhe të ruaj të gjitha në një depo.
Playbook i Thjeshtë
Playbook është një skedar yml, në të cilin me ndihmën e një sintakse të veçantë është përshkruar se çfarë dhe si duhet ta bëjë ansible. Le të krijojmë playbook-in tonë të parë, që nuk bën asgjë:
---
- name: Playbook i Thjeshtë
hosts: allKĂ«tu ne thjesht po themi se playbook-i ynĂ« quhet Playbook i ThjeshtĂ« dhe se pĂ«rmbajtja e tij duhet tĂ«æ§èĄhet pĂ«r tĂ« gjitha hostet. Mund ta ruajmĂ« atĂ« nĂ« direktoren /ansible me emrin playbook.yml dhe tĂ« provojmĂ« ta ranimojmĂ«:
ansible-playbook ./playbook.yml
PLAY [Playbook i Thjeshtë] ************************************************************************************************************************************
skipping: no hosts matchedAnsible thotë se nuk di hostet që përputhen me listën e të gjitha. Duhet t'i rendisim ato në një .
Le të krijojmë atë në të njëjtën direktore ansible:
123.123.123.123Këtu thjesht tregojmë hostin (idealisht hostin tuaj VPS për teste, ose mund të shkruani localhost) dhe e ruajmë me emrin inventory.
Mund të provoni ta ekzekutoni ansible me skedarin e inventarit:
ansible-playbook ./playbook.yml -i inventory
PLAY [Playbook i Thjeshtë] ************************************************************************************************************************************
TASK [Mblidh Fakte] ************************************************************************************************************************************
PLAY RECAP ************************************************************************************************************************************Nëse keni qasje përmes ssh në hostin e specifikuar, ansible do të lidhet dhe do të mbledhë informacion rreth sistemit të largët. (detyra standarde TASK [Mblidh Fakte]) pas së cilës do të japë një raport të shkurtër për ekzekutimin (PLAY RECAP).
Sipas të dhënave, emri i përdoruesit që përdoret për lidhjen është ai me të cilin jeni loguar në sistem. Në host, ndoshta nuk do të jetë. Në skedarin e playbook-it mund të tregoni se cilin përdorues duhet të përdorni për lidhjen me ndihmën e direktivës remote_user. Gjithashtu, informacioni rreth sistemit të largët shpesh mund të mos jetë i nevojshëm dhe nuk ia vlen të humbni kohë për ta mbledhur. Këtë detyrë gjithashtu mund ta çaktivizoni:
---
- name: Playbook i Thjeshtë
hosts: all
remote_user: root
become: true
gather_facts: noProvoni përsëri të nisni playbook dhe sigurohuni që lidhja funksionon. (Nëse keni specifikuar përdoruesin root, gjithashtu duhet të specifikoni direktivën become: true, për të fituar të drejtat e rritura. Siç shkruhet në dokumentacion: become e vendosur në 'true'/'yes' për të aktivizuar shkallëzimin e privilegjeve. ndonëse nuk është krejt e qartë se përse).
Mund të merrni një gabim të shkaktuar nga fakti që ansible nuk mund të përcaktojë interpreterin e python, atëherë mund ta specifikoni manualisht:
ansible_python_interpreter: /usr/bin/python3 ku e keni python mund ta merrni me komandën whereis python.
Instalimi i paketeve sistemore
Në instalimin standard të Ansible përfshihen shumë module për punë me paketa të ndryshme sistemore, duke na i lehtësuar kështu krijimin e skripteve bash në çdo rast. Tani do na nevojitet një nga këto module për të përditësuar sistemin dhe instaluar paketat sistemore. Unë në VPS kam Ubuntu Linux, kështu që për të instaluar paketat përdor apt-get dhe Nëse përdorni një sistem operativ tjetër, ndoshta do të nevojitet një modul tjetër (mbani mend se në fillim thashë që duhet ta dimë paraprakisht se çfarë dhe si do të bëjmë). Megjithatë, sintaksa ndoshta do të jetë e ngjashme.
Do ta plotësojmë playbook-un tonë me detyrat e para:
---
- 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: presentTask â Ă«shtĂ« pikĂ«risht detyra qĂ« ansible do tĂ« ekzekutojĂ« nĂ« serverĂ«t e largĂ«t. Ne japim emrin detyrĂ«s pĂ«r tĂ« ndjekur ekzekutimin e saj nĂ« log. Dhe e pĂ«rshkruajmĂ«, duke pĂ«rdorur sintaksĂ«n e modulit pĂ«rkatĂ«s, se çfarĂ« duhet tĂ« bĂ«jĂ«. NĂ« kĂ«tĂ« rast apt: update_cache=yes â thotĂ« tĂ« pĂ«rditĂ«sojĂ« paketat e sistemit duke pĂ«rdorur modulĂ«n apt. Komanda e dytĂ« Ă«shtĂ« disi mĂ« e komplikuar. Ne i kalojmĂ« modulit apt njĂ« listĂ« paketash dhe i themi qĂ« state duhet tĂ« bĂ«hen present, domethĂ«nĂ« i themi tĂ« instalojĂ« kĂ«to paketa. NĂ« tĂ« njĂ«jtĂ«n mĂ«nyrĂ«, mund tĂ« themi qĂ« t'i hiqni ose t'i pĂ«rditĂ«soni, thjesht duke ndryshuar state. Vini re se pĂ«r punĂ«n e rails me postgresql na nevojitet paketa postgresql-contrib, tĂ« cilĂ«n po e instalojmĂ« tani. Kjo duhet tĂ« dihet dhe tĂ« bĂ«het, ansible vetĂ« nuk do ta bĂ«jĂ« kĂ«tĂ«.
Provoni të ekzekutoni playbook-in përsëri dhe kontrolloni që paketat të instalohen.
Krijimi i përdoruesve të rinj.
PĂ«r tĂ« punuar me pĂ«rdoruesit, Ansible ka gjithashtu njĂ« modul â user. Do tĂ« shtojmĂ« njĂ« task tjetĂ«r (kam fshehur pjesĂ«t e njohura tĂ« playbook-ut me komente, qĂ« tĂ« mos e kopjoj tĂ«rĂ« çdo herĂ«):
---
- name: Playbook i thjeshtë
# ...
tasks:
# ...
- name: Shto një përdorues të ri
user:
name: my_user
shell: /bin/bash
password: "{{ 123qweasd | password_hash('sha512') }}"Ne po krijojmĂ« njĂ« pĂ«rdorues tĂ« ri, vendosim shell-in dhe fjalĂ«kalimin e tij. Dhe kĂ«tu pĂ«rballemi me disa probleme. ĂfarĂ« bĂ«jmĂ« nĂ«se emrat e pĂ«rdoruesve duhet tĂ« jenĂ« tĂ« ndryshĂ«m pĂ«r hoste tĂ« ndryshme? Po ashtu, tĂ« ruash fjalĂ«kalimin nĂ« formĂ« tĂ« hapur nĂ« playbook Ă«shtĂ« njĂ« ide shumĂ« e keqe. Fillimisht, do tĂ« nxjerrim emrin e pĂ«rdoruesit dhe fjalĂ«kalimin nĂ« variabla, dhe mĂ« afĂ«r fundin e artikullit do tĂ« tregoj se si ta enkriptojmĂ« fjalĂ«kalimin.
---
- name: Playbook i thjeshtë
# ...
tasks:
# ...
- name: Shto një përdorues të ri
user:
name: "{{ user }}"
shell: /bin/bash
password: "{{ user_password | password_hash('sha512') }}"Me anë të dyfishtë të kllapave në playbook-e vendosen variablat.
Vlerat e variablave do t'i specifikojmë në skedarin e inventarit:
123.123.123.123
[all:vars]
user=my_user
user_password=123qweasdKujdesini pĂ«r drejtpĂ«rsĂ«drejti [all:vars] â thotĂ« se blloku i ardhshĂ«m i tekstit Ă«shtĂ« variablat (vars) dhe janĂ« tĂ« aplikueshme pĂ«r tĂ« gjithĂ« hostet (all).
Po ashtu interesante Ă«shtĂ« konstrukti "{{ user_password | password_hash('sha512') }}". ĂĂ«shtja Ă«shtĂ« se ansible nuk e krijon pĂ«rdoruesin pĂ«rmes user_add siç do ta bĂ«nit manualisht. Ai ruan tĂ« dhĂ«nat drejtpĂ«rsĂ«drejti, pĂ«r kĂ«tĂ« arsye duhet ta konvertojmĂ« fjalĂ«kalimin nĂ« njĂ« hash paraprakisht, gjĂ« qĂ« e bĂ«n kjo komandĂ«.
Le të shtojmë përdoruesin tonë në grupin sudo. Megjithatë, përpara kësaj duhet të sigurohemi që një grup i tillë ekziston sepse askush tjetër nuk do ta bëjë këtë për ne:
---
- name: Playbook i thjeshtë
# ...
tasks:
# ...
- name: Siguro një grup 'sudo'
group:
name: sudo
state: present
- name: Shto një përdorues të ri
user:
name: "{{ user }}"
shell: /bin/bash
password: "{{ user_password | password_hash('sha512') }}"
groups: "sudo"Gjithçka është mjaft e thjeshtë, kemi gjithashtu modul grup për të krijuar grupe, me një sintaksë shumë të ngjashme me apt. Pas kësaj mjafton të regjistrojmë këtë grup te përdoruesi (groups: "sudo").
Po ashtu është e dobishme të shtojmë këtij përdoruesi një çelës ssh, që të mund të hyjmë nën të pa fjalëkalim:
---
- name: Playbook i thjeshtë
# ...
tasks:
# ...
- name: Siguro një grup 'sudo'
group:
name: sudo
state: present
- name: Shto një përdorues të ri
user:
name: "{{ user }}"
shell: /bin/bash
password: "{{ user_password | password_hash('sha512') }}"
groups: "sudo"
- name: Nxjerr çelësin SSH
authorized_key:
user: "{{ user }}"
key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
state: presentNĂ« kĂ«tĂ« rast Ă«shtĂ« interesante struktura "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" â ajo kopjon pĂ«rmbajtjen e skedĂ«s id_rsa.pub (emri mund tĂ« jetĂ« ndryshe), pra pjesĂ«n publike tĂ« çelĂ«sit ssh dhe e ngarkon atĂ« nĂ« listĂ«n e çelĂ«save tĂ« autorizuar pĂ«r pĂ«rdoruesin nĂ« server.
Rolet
Të tria këto detyra për krijimin e përdoruesit mund të përfshihen lehtësisht në një grup detyrash, dhe do të ishte mirë ta mbani këtë grup ndarë nga playbook-u kryesor, në mënyrë që të mos shfaqet shumë i madh. Për këtë në ansible ekzistojnë .
Sipas strukturĂ«s sĂ« skedarĂ«ve tĂ« specifikuar nĂ« fillim, rolet duhet tĂ« vendosen nĂ« njĂ« drejtorinĂ« tĂ« veçantĂ« roles, pĂ«r çdo rol â njĂ« drejtorinĂ« tĂ« veçantĂ« me emrin pĂ«rkatĂ«s, brenda drejtorisĂ« tasks, files, templates, etj.
TĂ« krijojmĂ« strukturĂ«n e skedarĂ«ve: ./ansible/roles/user/tasks/main.yml (main â ky Ă«shtĂ« skedari kryesor qĂ« do tĂ« ngarkohet dhe ekzekutohet kur lidhet roli me playbook-un, nĂ« tĂ« mund tĂ« lidhni skedarĂ« tĂ« tjerĂ« tĂ« rolit). Tani mund tĂ« transferoni nĂ« kĂ«tĂ« skedar tĂ« gjitha detyrat qĂ« lidhen me pĂ«rdoruesin:
# 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: presentNë playbook-un kryesor duhet të specifikoni të përdorni rolin user:
---
- name: Playbook i thjeshtë
hosts: all
remote_user: root
gather_facts: no
tasks:
- name: Përditëso sistemin
apt: update_cache=yes
- name: Instaloni varësitë e sistemit
apt:
name: git,nginx,redis,postgresql,postgresql-contrib
state: present
roles:
- userGjithashtu, ndoshta ka kuptim të kryeni përditësimin e sistemit para detyrave të tjera, për këtë mund të riemëroni bllokun tasks në të cilin ato janë të përcaktuara si pre_tasks.
Konfigurimi i nginx
Nginx duhet të jetë tashmë i instaluar, duhet ta konfigurojmë dhe ta nxjerrim në punë. Le të bëjmë këtë menjëherë në rol. Krijojmë strukturën e skedarëve:
- ansible
- roles
- nginx
- files
- tasks
- main.yml
- templatesTani na duhen skedarët dhe shabllonët. Diferenca midis tyre është se skedarët ansible i kopjon drejtpërdrejt, ashtu si janë. Ndërsa shabllonët duhet të kenë zgjerimin j2 dhe brenda tyre mund të përdoren vlerat e variablave duke përdorur të njëjtat dyfish figura të skëmbëve.
Le të përfshijmë nginx në main.yml skedarin. Për këtë kemi modul systemd:
# Copy nginx configs and start it
- name: enable service nginx and start
systemd:
name: nginx
state: started
enabled: yesKëtu ne jo vetëm që themi se nginx duhet të jetë started (domethënë ta nisim atë), por gjithashtu i themi se ai duhet të jetë enabled.
Tani do të kopjojmë skedarët e konfigurimit:
# 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'Krijojmë skedarin kryesor të konfigurimit për nginx (mund ta marrim direkt nga serveri ose ta shkruajmë vetë). Gjithashtu krijojmë skedarin e konfigurimit për aplikacionin tonë në drejtorinë sites_available (nuk është e detyrueshme, por është e dobishme). Në rastin e parë, ne përdorim modulin copy për të kopjuar skedarët (skedari duhet të jetë në /ansible/roles/nginx/files/nginx.conf). Në rastin e dytë, kopjojmë modelin, duke futur vlerat e variablave. Modeli duhet të jetë në /ansible/roles/nginx/templates/my_app.j2). Dhe mund të duket diçka si ky:
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 }};
....
}Vini re insertet {{ app_name }}, {{ app_path }}, {{ server_name }}, {{ inventory_hostname }} â kĂ«to janĂ« tĂ« gjitha variabla, vlerat e tĂ« cilĂ«ve ansible do t'i vendosĂ« nĂ« model para kopjimit. Kjo Ă«shtĂ« e dobishme nĂ«se pĂ«rdorim njĂ« playbook pĂ«r grupe tĂ« ndryshme hostesh. PĂ«r shembull, mund tĂ« shtojmĂ« skedarin tonĂ« tĂ« inventory:
[production]
123.123.123.123
[staging]
231.231.231.231
[all:vars]
user=my_user
user_password=123qweasd
[production:vars]
server_name=production
app_path=\/home\/www\/my_app
app_name=my_app
[staging:vars]
server_name=staging
app_path=\/home\/www\/my_stage
app_name=my_stage_appNĂ«se tani e fillojmĂ« playbook-un tonĂ«, do tĂ« ekzekutojĂ« detyrat e pĂ«rmendura pĂ«r tĂ« dy hostet. Por nĂ« kĂ«tĂ« rast, pĂ«r hostin staging variablat do tĂ« jenĂ« ndryshe nga production, dhe jo vetĂ«m nĂ« role dhe playbooks, por edhe nĂ« konfigurimet e nginx. {{ inventory_hostname }} nuk duhet tĂ« theksohet nĂ« skedarin e inventory â kjo dhe aty ruhet hosti pĂ«r tĂ« cilin ekzekutohet playbook-u nĂ« atĂ« moment.
Nëse dëshironi të keni një skedar inventory për disa hoste, por të ekzekutoni vetëm për një grup, mund ta bëni këtë me komandën e mëposhtme:
ansible-playbook -i inventory .\/playbook.yml -l "staging"njĂ« alternativĂ« tjetĂ«r â tĂ« keni skedarĂ« inventory tĂ« ndarĂ« pĂ«r grupe tĂ« ndryshme. Ose mund tĂ« kombinoni dy qasje, nĂ«se keni shumĂ« hoste tĂ« ndryshĂ«m.
Kthehemi te konfigurimi i nginx. Pas kopjimit të skedarëve të konfigurimit, na nevojitet të krijojmë një simlink në sites_enabled për my_app.conf nga sites_available. Dhe të rindiznim nginx.
... # kodi i vjetër në mail.yml
- name: Krijo simlink në sites-enabled
file:
src: \/etc\/nginx\/sites-available\/my_app.conf
dest: \/etc\/nginx\/sites-enabled\/my_app.conf
state: link
- name: rindizni nginx
service:
name: nginx
state: restartedKĂ«tu Ă«shtĂ« shumĂ« e thjeshtĂ« â pĂ«rsĂ«ri modulet ansible me sintaksĂ« mjaft standarde. Por ka njĂ« moment. Nuk ka kuptim tĂ« rinit nginx çdo herĂ«. A keni vĂ«nĂ« re se ne nuk shkruajmĂ« komanda tĂ« tipit: «bĂ«ni kĂ«tĂ« kĂ«shtu», sintaksa duket mĂ« shumĂ« si «kĂ«saj duhet tĂ« ketĂ« njĂ« gjendje tĂ« tillë». Dhe shpesh, kĂ«shtu punon ansible. NĂ«se grupi tashmĂ« ekziston, ose paketa sistemike Ă«shtĂ« instaluar, ansible do ta kontrollojĂ« kĂ«tĂ« dhe do ta kalojĂ« detyrĂ«n. Po ashtu, skedarĂ«t nuk do tĂ« kopohen nĂ«se ata pĂ«rputhen plotĂ«sisht me ato qĂ« janĂ« tashmĂ« nĂ« server. Ne mund ta pĂ«rfitojmĂ« kĂ«tĂ« dhe tĂ« rinisim nginx vetĂ«m nĂ«se skedarĂ«t e konfigurimit kanĂ« ndryshuar. PĂ«r kĂ«tĂ« ekziston direktiva register:
# Copy nginx configs and start it
- name: enable service nginx and start
systemd:
name: nginx
state: started
enabled: yes
- name: Copy the nginx.conf
copy:
src: nginx.conf
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
backup: yes
register: restart_nginx
- name: Copy template my_app.conf
template:
src: my_app_conf.j2
dest: /etc/nginx/sites-available/my_app.conf
owner: root
group: root
mode: '0644'
register: restart_nginx
- name: Create symlink to sites-enabled
file:
src: /etc/nginx/sites-available/my_app.conf
dest: /etc/nginx/sites-enabled/my_app.conf
state: link
- name: restart nginx
service:
name: nginx
state: restarted
when: restart_nginx.changedNëse ndonjë prej skedarëve të konfigurimit ndryshon, do të kryhet kopjimi dhe do të regjistrohet variabla restart_nginx. Dhe vetëm nëse kjo variablë është regjistruar, do të kryhet rinisja e shërbimit.
Natyrisht, duhet të shtoni rolin nginx në playbook-un kryesor.
Konfigurimi i postgresql
Na nevojitet të aktivizojmë postgresql me anë të systemd njësoj siç e bëmë me nginx, si dhe të krijojmë një përdorues, të cilin do ta përdorim për qasje në bazën e të dhënave dhe vetë bazën e të dhënave.
Le të krijojmë një rol /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 }}"Nuk do tĂ« pĂ«rshkruaj se si tĂ« shtoni variabla nĂ« inventory, kjo Ă«shtĂ« bĂ«rĂ« shumĂ« herĂ«, ashtu siç Ă«shtĂ« sintaksa e modulit postgresql_db dhe postgresql_user. MĂ« shumĂ« tĂ« dhĂ«na mund tĂ« gjenden nĂ« dokumentacion. KĂ«tu Ă«shtĂ« mĂ« interesant direktiva become_user: postgres. ĂĂ«shtja Ă«shtĂ« se, sipas parashikimeve, qasja nĂ« bazĂ«n e tĂ« dhĂ«nave postgresql Ă«shtĂ« vetĂ«m pĂ«r pĂ«rdoruesin postgres dhe vetĂ«m lokalisht. Kjo direktivĂ« na lejon tĂ« ekzekutojmĂ« komanda nĂ« emĂ«r tĂ« kĂ«tij pĂ«rdoruesi (nĂ«se natyrisht kemi qasje).
Po ashtu, ndoshta do t'ju duhet të shkruani një rresht në pg_hba.conf për të hapur aksesin e përdoruesit të ri në bazë. Këto mund të bëhen njësoj siç e ndryshuam konfigurimin e nginx.
Natyrisht, duhet të shtoni rolin postgresql në playbook-un kryesor.
Instalimi i ruby përmes rbenv
Në ansible nuk ka module për punën me rbenv, dhe ai instalohet duke klonuar depot git. Prandaj, kjo detyrë bëhet më e pazakontë. Le të krijojmë një rol për të /ansible/roles/ruby_rbenv/main.yml dhe të fillojmë ta mbushim:
# Install rbenv and ruby
- name: Install rbenv
become_user: "{{ user }}"
git: repo=https://github.com/rbenv/rbenv.git dest=~/.rbenvNe po përdorim përsëri direktivën become_user për të punuar si përdoruesi që kemi krijuar për këto qëllime. Duke qenë se rbenv instalohet në direktorinë e tij home dhe jo globalisht. Po ashtu, ne përdorim modulit git për të klonuar repozitorin, duke specifikuar repo dhe dest.
Më pas, na nevojitet të shkruajmë rbenv init në bashrc dhe atje të shtojmë rbenv në PATH. Për këtë, kemi modulit lineinfile:
- name: Shto rbenv në PATH
become_user: "{{ user }}"
lineinfile:
path: ~\/bashrc
state: present
line: 'export PATH="${HOME}\/\.rbenv\/bin:${PATH}"'
- name: Shto rbenv init në bashrc
become_user: "{{ user }}"
lineinfile:
path: ~\/bashrc
state: present
line: 'eval "$(rbenv init -)"'Pasi të bëhet kjo, duhet të instaloni ruby_build:
- name: Instaloni ruby-build
become_user: "{{ user }}"
git: repo=https:\/\/github.com\/rbenv\/ruby-build.git dest=~\/\.rbenv\/plugins\/ruby-buildDhe, në fund, instaloni ruby. Kjo bëhet përmes rbenv, thjesht me komandë bash:
- name: Instaloni ruby
become_user: "{{ user }}"
shell: |
export PATH="${HOME}\/\.rbenv\/bin:${PATH}"
eval "$(rbenv init -)"
rbenv install {{ ruby_version }}
args:
executable: \/bin\/bashNe tregojmë se cila komandë do të ekzekutohet dhe me çfarë. Megjithatë, këtu do të përballemi me faktin se ansible nuk ekzekuton kodin e pranishëm në bashrc përpara ekzekutimit të komandave. Kështu që, rbenv do të duhet të përcaktohet drejtpërdrejt në këtë skenar.
Problemi tjetĂ«r Ă«shtĂ« se komanda shell nuk ka gjendje nĂ« kĂ«ndvĂ«shtrimin e ansible. domethĂ«nĂ« nuk do tĂ« ketĂ« verifikim automatik nĂ«se kjo version ruby Ă«shtĂ« instaluar apo jo â kjo duhet ta bĂ«jmĂ« vetĂ«:
- name: Instaloni 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\/bashDhe mbetet të instaloni bundler:
- name: Instaloni bundler
become_user: "{{ user }}"
shell: |
export PATH="${HOME}\/\.rbenv\/bin:${PATH}"
eval "$(rbenv init -)"
gem install bundlerPo ashtu të shtoni rolin tonë ruby_rbenv në playbook-in kryesor.
Skedarët e ndarë.
Në përgjithësi, këtu mund të përfundohej konfigurimi. Më pas, mbetet të nisni capistrano dhe ajo do të kopjojë kodin vetë, do të krijojë katalogët e nevojshëm dhe do të niste aplikacionin (nëse është vendosur gjithçka saktë). Megjithatë, shpesh capistrano kërkon skedarë të tjerë konfigurohuese si database.yml ose .env Ato mund të kopjohen njëlloj si skedarët dhe shabllonët për nginx. Ka vetëm një hollësi. Para kopjimit të skedarëve, është e nevojshme të krijoni strukturën e katalogëve për ta, diçka të tillë:
# Copy shared files for deploy
- name: Ensure shared dir
become_user: "{{ user }}"
file:
path: "{{ app_path }}/shared/config"
state: directoryne specifikojmë vetëm një direktori dhe ansible do ta krijojë automatikisht ata prind, nëse është e nevojshme.
Ansible Vault
Kemi has already encountered cases where sensitive data such as user passwords can be found in variables. If you created .env a file for the application, and database.yml there should be even more critical data in it. Itâs best to hide them from prying eyes. For this purpose, we use .
Let's create a file for the variables /ansible/vars/all.yml (here you can create different files for different groups of hosts, just like in the inventory file: production.yml, staging.yml, etc.).
In this file, you need to transfer all variables that need to be encrypted, using standard yaml syntax:
# 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_baseAfter that, you can encrypt this file with the command:
ansible-vault encrypt ./vars/all.ymlNaturally, when encrypting, you will need to set a password for decryption. You can check what will be inside the file after invoking this command.
With the help of ansible-vault decrypt the file can be decrypted, modified, and then re-encrypted.
To work, you don't need to decrypt the file. You keep it encrypted and run the playbook with the argument --ask-vault-pass. Ansible will ask for the password, retrieve the variables, and execute the tasks. All data will remain encrypted.
The complete command for several groups of hosts and ansible vault will look something like this:
ansible-playbook -i inventory ./playbook.yml -l "staging" --ask-vault-passAnd I wonât provide you with the full text of the playbooks and roles, you write it yourself. Because ansible is such a thing â if you donât understand what needs to be done, it wonât do it for you either.
Burimi: habr.com
