Bir müddət əvvəl mən serveri Rails tətbiqini yerləşdirməyə hazırlamaq üçün bir neçə Ansible kitabçası yazmalı oldum. Və təəccüblüdür ki, sadə bir addım-addım təlimat tapmadım. Nə baş verdiyini başa düşmədən başqasının oyun kitabını köçürmək istəmədim və sonda hər şeyi özüm toplayıb sənədləri oxumalı oldum. Bəlkə də bu məqalənin köməyi ilə kiməsə bu prosesi sürətləndirməyə kömək edə bilərəm.
Anlamaq lazım olan ilk şey odur ki, ansible sizə SSH vasitəsilə uzaq server(lər)də əvvəlcədən müəyyən edilmiş hərəkətlərin siyahısını yerinə yetirmək üçün rahat interfeys təqdim edir. Burada heç bir sehr yoxdur, siz plagin quraşdıra bilməzsiniz və docker, monitorinq və qutudan çıxarılan digər ləzzətlər ilə tətbiqinizin sıfır dayanıqlı yerləşdirilməsini əldə edə bilməzsiniz. Bir oyun kitabı yazmaq üçün siz tam olaraq nə etmək istədiyinizi və bunu necə edəcəyinizi bilməlisiniz. Buna görə də məni GitHub-dan hazır dərs kitabları və ya “Kopyala və işlət, işləyəcək” kimi məqalələr qane etmir.
Bizə nə lazımdır?
Artıq dediyim kimi, oyun kitabı yazmaq üçün nə etmək istədiyinizi və bunu necə edəcəyinizi bilməlisiniz. Nəyə ehtiyacımız olduğuna qərar verək. Rails tətbiqi üçün bizə bir neçə sistem paketi lazımdır: nginx, postgresql (redis və s.). Bundan əlavə, bizə ruby-nin xüsusi bir versiyası lazımdır. Ən yaxşısı onu rbenv (rvm, asdf...) vasitəsilə quraşdırmaqdır. Bütün bunları kök istifadəçi kimi işlətmək həmişə pis fikirdir, ona görə də ayrıca istifadəçi yaratmalı və onun hüquqlarını konfiqurasiya etməlisiniz. Bundan sonra kodumuzu serverə yükləməli, nginx, postgres və s. üçün konfiqurasiyaları köçürməli və bütün bu xidmətləri işə salmalısınız.
Nəticədə, hərəkətlərin ardıcıllığı aşağıdakı kimidir:
- Kök kimi daxil olun
- sistem paketlərini quraşdırın
- yeni istifadəçi yaradın, hüquqları konfiqurasiya edin, ssh açarı
- sistem paketlərini (nginx və s.) konfiqurasiya edin və onları işə salın
- Verilənlər bazasında istifadəçi yaradırıq (dərhal verilənlər bazası yarada bilərsiniz)
- Yeni istifadəçi kimi daxil olun
- Rbenv və Ruby quraşdırın
- Bundler quraşdırılması
- Tətbiq kodu yüklənir
- Puma serverinin işə salınması
Üstəlik, son mərhələlər capistrano istifadə edərək həyata keçirilə bilər, ən azı qutudan kənarda kodu buraxılış qovluqlarına köçürə bilər, müvəffəqiyyətli yerləşdirmədən sonra buraxılışı simvolik əlaqə ilə dəyişdirə, konfiqurasiyaları paylaşılan qovluqdan köçürə, pumanı yenidən başladın və s. Bütün bunlar Ansible vasitəsilə edilə bilər, bəs niyə?
Fayl strukturu
Ansible sərtdir
Sadə oyun kitabı
Playbook xüsusi sintaksisdən istifadə edərək Ansible-ın nə etməli olduğunu və necə edəcəyini təsvir edən yml faylıdır. Heç bir şey etməyən ilk oyun kitabını yaradaq:
---
- name: Simple playbook
hosts: all
Burada sadəcə olaraq oyun kitabımızın adlandığını söyləyirik Simple Playbook
və onun məzmunu bütün hostlar üçün icra edilməlidir. Biz onu /ansible qovluğunda adı ilə saxlaya bilərik playbook.yml
və qaçmağa çalışın:
ansible-playbook ./playbook.yml
PLAY [Simple Playbook] ************************************************************************************************************************************
skipping: no hosts matched
Ansible deyir ki, bütün siyahıya uyğun gələn hostları tanımır. Onlar xüsusi siyahıda göstərilməlidir
Gəlin onu eyni ansible kataloqda yaradaq:
123.123.123.123
Biz sadəcə olaraq hostu (test üçün VPS-nin aparıcısı və ya siz localhost-u qeydiyyatdan keçirə bilərsiniz) necə müəyyənləşdiririk və onu ad altında saxlayırıq. inventory
.
Siz inventar faylı ilə ansible işləməyə cəhd edə bilərsiniz:
ansible-playbook ./playbook.yml -i inventory
PLAY [Simple Playbook] ************************************************************************************************************************************
TASK [Gathering Facts] ************************************************************************************************************************************
PLAY RECAP ************************************************************************************************************************************
Göstərilən hosta ssh girişiniz varsa, o zaman ansible uzaq sistem haqqında məlumatı birləşdirəcək və toplayacaq. (standart TASK [Faktların toplanması]) bundan sonra icra haqqında qısa hesabat verəcək (RECAP PLAY).
Varsayılan olaraq, əlaqə sistemə daxil olduğunuz istifadəçi adından istifadə edir. Çox güman ki, hostda olmayacaq. Playbook faylında siz remote_user direktivindən istifadə edərək qoşulmaq üçün hansı istifadəçidən istifadə edəcəyinizi təyin edə bilərsiniz. Həmçinin, uzaq sistem haqqında məlumat çox vaxt sizin üçün lazımsız ola bilər və siz onu toplamaq üçün vaxt itirməməlisiniz. Bu tapşırıq da deaktiv edilə bilər:
---
- name: Simple playbook
hosts: all
remote_user: root
become: true
gather_facts: no
Oyun kitabını yenidən işə salın və əlaqənin işlədiyinə əmin olun. (Əgər siz kök istifadəçini qeyd etmisinizsə, yüksək hüquqlar əldə etmək üçün siz həmçinin olur: true direktivini göstərməlisiniz. Sənədlərdə yazıldığı kimi: become set to ‘true’/’yes’ to activate privilege escalation.
səbəb tam aydın olmasa da).
Ola bilsin ki, siz ansible-in Python tərcüməçisini təyin edə bilməməsi ilə əlaqədar xəta alacaqsınız, onda siz onu əl ilə təyin edə bilərsiniz:
ansible_python_interpreter: /usr/bin/python3
Komanda ilə python-un harada olduğunu öyrənə bilərsiniz whereis python
.
Sistem paketlərinin quraşdırılması
Ansible-ın standart paylanması müxtəlif sistem paketləri ilə işləmək üçün bir çox modulları ehtiva edir, ona görə də hər hansı bir səbəbdən bash skriptləri yazmaq məcburiyyətində deyilik. İndi sistemi yeniləmək və sistem paketlərini quraşdırmaq üçün bu modullardan birinə ehtiyacımız var. Mənim VPS-də Ubuntu Linux var, ona görə də istifadə etdiyim paketləri quraşdırmaq üçün apt-get
и
Oyun dəftərimizi ilk tapşırıqlarla tamamlayaq:
---
- 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
Tapşırıq, Ansible-ın uzaq serverlərdə yerinə yetirəcəyi vəzifədir. Tapşırıqa ad veririk ki, onun icrasını jurnalda izləyə bilək. Və biz konkret modulun sintaksisindən istifadə edərək onun nə etməli olduğunu təsvir edirik. Bu halda apt: update_cache=yes
- apt modulundan istifadə edərək sistem paketlərini yeniləməyi söyləyir. İkinci əmr bir az daha mürəkkəbdir. Paketlərin siyahısını apt moduluna ötürürük və onların olduğunu deyirik state
çevrilməlidir present
, yəni bu paketləri quraşdırın deyirik. Bənzər şəkildə, biz onlara onları silmələrini və ya sadəcə dəyişdirməklə yeniləmələrini söyləyə bilərik state
. Nəzərə alın ki, relslərin postgresql ilə işləməsi üçün bizə indi quraşdırdığımız postgresql-contrib paketi lazımdır. Yenə də bunu bilməli və etməlisən; ansible öz başına bunu etməyəcək.
Oyun kitabını yenidən işə salın və paketlərin quraşdırıldığını yoxlayın.
Yeni istifadəçilərin yaradılması.
İstifadəçilərlə işləmək üçün Ansible modulu da var - istifadəçi. Gəlin daha bir tapşırıq əlavə edək (hər dəfə onu tamamilə köçürməmək üçün kitabçanın artıq məlum olan hissələrini şərhlərin arxasında gizlətmişəm):
---
- name: Simple playbook
# ...
tasks:
# ...
- name: Add a new user
user:
name: my_user
shell: /bin/bash
password: "{{ 123qweasd | password_hash('sha512') }}"
Yeni istifadəçi yaradırıq, onun üçün sxem və parol təyin edirik. Və sonra bir neçə problemlə qarşılaşırıq. Fərqli hostlar üçün istifadəçi adları fərqli olmalıdırsa necə? Və parolu oyun kitabında aydın mətndə saxlamaq çox pis fikirdir. Başlamaq üçün, istifadəçi adı və parolu dəyişənlərə daxil edək və məqalənin sonunda parolun necə şifrələnəcəyini göstərəcəyəm.
---
- name: Simple playbook
# ...
tasks:
# ...
- name: Add a new user
user:
name: "{{ user }}"
shell: /bin/bash
password: "{{ user_password | password_hash('sha512') }}"
Dəyişənlər ikiqat buruq mötərizələrdən istifadə edərək oyun kitablarında təyin olunur.
İnventar faylında dəyişənlərin dəyərlərini göstərəcəyik:
123.123.123.123
[all:vars]
user=my_user
user_password=123qweasd
Direktivə diqqət yetirin [all:vars]
- növbəti mətn blokunun dəyişənlər (vars) olduğunu və onların bütün hostlara (hamısına) aid olduğunu söyləyir.
Dizaynı da maraqlıdır "{{ user_password | password_hash('sha512') }}"
. İş ondadır ki, ansible istifadəçini vasitəsilə quraşdırmır user_add
bunu əl ilə edəcəyiniz kimi. Və bütün məlumatları birbaşa saxlayır, buna görə də parolu əvvəlcədən hash-a çevirməliyik, bu əmrin etdiyi budur.
İstifadəçimizi sudo qrupuna əlavə edək. Bununla belə, bundan əvvəl belə bir qrupun mövcud olduğundan əmin olmalıyıq, çünki bunu bizim yerimizə heç kim etməyəcək:
---
- 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"
Hər şey olduqca sadədir, bizdə qruplar yaratmaq üçün bir qrup modulumuz var, sintaksisi apt ilə çox oxşardır. O zaman bu qrupu istifadəçiyə qeydiyyatdan keçirmək kifayətdir (groups: "sudo"
).
Bu istifadəçiyə ssh açarı əlavə etmək də faydalıdır ki, parol olmadan istifadə edərək daxil ola bilək:
---
- 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
Bu vəziyyətdə dizayn maraqlıdır "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
— id_rsa.pub faylının məzmununu (adınız fərqli ola bilər), yəni ssh açarının ictimai hissəsini kopyalayır və serverdə istifadəçi üçün icazə verilən açarlar siyahısına yükləyir.
Roles
İstifadə yaratmaq üçün hər üç tapşırıq asanlıqla bir qrup vəzifəyə təsnif edilə bilər və bu qrupu çox böyütməməsi üçün əsas kitabdan ayrı saxlamaq yaxşı olardı. Bu məqsədlə Ansible var
Başlanğıcda göstərilən fayl strukturuna uyğun olaraq, rollar ayrıca rollar kataloqunda yerləşdirilməlidir, hər rol üçün eyni adlı ayrıca qovluq var, tapşırıqlar, fayllar, şablonlar və s.
Fayl strukturunu yaradaq: ./ansible/roles/user/tasks/main.yml
(əsas, oyun kitabına rol qoşulduqda yüklənəcək və icra ediləcək əsas fayldır; digər rol faylları ona qoşula bilər). İndi istifadəçi ilə əlaqəli bütün tapşırıqları bu fayla köçürə bilərsiniz:
# 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
Əsas oyun kitabında istifadəçi rolundan istifadə etmək üçün qeyd etməlisiniz:
---
- 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
Həmçinin, bütün digər tapşırıqlardan əvvəl sistemi yeniləməyin mənası ola bilər, bunu etmək üçün blokun adını dəyişdirə bilərsiniz tasks
hansıda onlar müəyyən edilir pre_tasks
.
Nginx qurulması
Bizdə artıq Nginx quraşdırılıb, onu konfiqurasiya edib işə salmalıyıq. Gəlin bunu dərhal rolda edək. Fayl strukturunu yaradaq:
- ansible
- roles
- nginx
- files
- tasks
- main.yml
- templates
İndi bizə fayllar və şablonlar lazımdır. Onların arasındakı fərq odur ki, ansible faylları olduğu kimi birbaşa kopyalayır. Şablonlarda j2 uzantısı olmalıdır və onlar eyni cüt qıvrımlı mötərizələrdən istifadə edərək dəyişən dəyərlərdən istifadə edə bilərlər.
Nginx-i aktivləşdirək main.yml
fayl. Bunun üçün bir systemd modulumuz var:
# Copy nginx configs and start it
- name: enable service nginx and start
systemd:
name: nginx
state: started
enabled: yes
Burada biz təkcə nginx-in işə salınmalı olduğunu demirik (yəni onu işə salırıq), həm də dərhal onu aktivləşdirmək lazım olduğunu deyirik.
İndi konfiqurasiya fayllarını kopyalayaq:
# 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'
Biz əsas nginx konfiqurasiya faylını yaradırıq (onu birbaşa serverdən götürə və ya özünüz yaza bilərsiniz). Həmçinin sites_available qovluğunda tətbiqimiz üçün konfiqurasiya faylı (bu lazım deyil, lakin faydalıdır). Birinci halda, biz faylları kopyalamaq üçün surət modulundan istifadə edirik (fayl olmalıdır /ansible/roles/nginx/files/nginx.conf
). İkincisində, dəyişənlərin dəyərlərini əvəz edərək şablonu kopyalayırıq. Şablon daxil olmalıdır /ansible/roles/nginx/templates/my_app.j2
). Və belə bir şey görünə bilər:
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 }};
....
}
Əlavələrə diqqət yetirin {{ app_name }}
, {{ app_path }}
, {{ server_name }}
, {{ inventory_hostname }}
— bunlar kopyalamadan əvvəl Ansible-in şablonda əvəzlənəcəyi bütün dəyişənlərdir. Müxtəlif host qrupları üçün oyun kitabından istifadə etsəniz, bu faydalıdır. Məsələn, biz inventar faylımızı əlavə edə bilərik:
[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
İndi playbookumuzu işə salsaq, o, hər iki host üçün müəyyən edilmiş tapşırıqları yerinə yetirəcək. Ancaq eyni zamanda, bir quruluş sahibi üçün dəyişənlər istehsaldan fərqli olacaq və təkcə rollarda və oyun kitablarında deyil, həm də nginx konfiqurasiyalarında. {{ inventory_hostname }}
inventar faylında göstərilməsinə ehtiyac yoxdur - bu
Bir neçə host üçün inventar faylına sahib olmaq, lakin yalnız bir qrup üçün işləmək istəyirsinizsə, bu, aşağıdakı əmrlə edilə bilər:
ansible-playbook -i inventory ./playbook.yml -l "staging"
Başqa bir seçim, müxtəlif qruplar üçün ayrıca inventar fayllarının olmasıdır. Və ya bir çox fərqli hostunuz varsa, iki yanaşmanı birləşdirə bilərsiniz.
Nginx-in qurulmasına qayıdaq. Konfiqurasiya fayllarını kopyaladıqdan sonra biz sites_available saytından sitest_enabled-də my_app.conf-a simvolik əlaqə yaratmalıyıq. Və nginx-i yenidən başladın.
... # 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
Burada hər şey sadədir - kifayət qədər standart sintaksisi olan yenidən uyğun modullar. Ancaq bir məqam var. Hər dəfə nginx-i yenidən başlatmağın mənası yoxdur. Diqqət etdinizmi ki, biz “bunu belə et” kimi əmrlər yazmırıq, sintaksis daha çox “bunun bu vəziyyətə sahib olması lazımdır” kimi görünür. Və çox vaxt bu, ansible necə işləyir. Qrup artıq mövcuddursa və ya sistem paketi artıq quraşdırılıbsa, ansible bunu yoxlayacaq və tapşırığı atlayacaq. Həmçinin, serverdə olanlara tam uyğun gələn fayllar kopyalanmayacaq. Biz bundan faydalana və yalnız konfiqurasiya faylları dəyişdirildikdə nginx-i yenidən başlada bilərik. Bunun üçün reyestr direktivi var:
# 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
Konfiqurasiya fayllarından biri dəyişərsə, surəti hazırlanacaq və dəyişən qeydə alınacaq restart_nginx
. Və yalnız bu dəyişən qeydə alındıqda xidmət yenidən işə salınacaq.
Və təbii ki, əsas oyun kitabına nginx rolunu əlavə etməlisiniz.
Postgresql quraşdırma
Biz nginx ilə etdiyimiz kimi systemd istifadə edərək postgresql-i aktivləşdirməliyik, həmçinin verilənlər bazasına və verilənlər bazasına daxil olmaq üçün istifadə edəcəyimiz istifadəçi yaratmalıyıq.
Gəlin bir rol yaradaq /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 }}"
Dəyişənlərin inventara necə əlavə ediləcəyini təsvir etməyəcəyəm, bu, artıq dəfələrlə edilib, həmçinin postgresql_db və postgresql_user modullarının sintaksisi. Ətraflı məlumatı sənədlərdə tapa bilərsiniz. Burada ən maraqlı direktivdir become_user: postgres
. Fakt budur ki, standart olaraq, yalnız postgres istifadəçisi postgresql verilənlər bazasına və yalnız yerli olaraq daxil ola bilər. Bu direktiv bizə bu istifadəçinin adından əmrləri yerinə yetirməyə imkan verir (əlbəttə ki, çıxışımız varsa).
Həmçinin, yeni istifadəçinin verilənlər bazasına girişinə icazə vermək üçün pg_hba.conf-a sətir əlavə etməli ola bilərsiniz. Bu, nginx konfiqurasiyasını dəyişdirdiyimiz kimi edilə bilər.
Və əlbəttə ki, əsas oyun kitabına postgresql rolunu əlavə etməlisiniz.
Rbenv vasitəsilə ruby quraşdırılması
Ansible-da rbenv ilə işləmək üçün modullar yoxdur, lakin o, git repozitoriyasını klonlaşdırmaqla quraşdırılır. Buna görə də bu problem ən qeyri-standart problemə çevrilir. Gəlin onun üçün bir rol yaradaq /ansible/roles/ruby_rbenv/main.yml
və onu doldurmağa başlayaq:
# Install rbenv and ruby
- name: Install rbenv
become_user: "{{ user }}"
git: repo=https://github.com/rbenv/rbenv.git dest=~/.rbenv
Biz bu məqsədlər üçün yaratdığımız istifadəçinin altında işləmək üçün yenidən become_user direktivindən istifadə edirik. Rbenv qlobal olaraq deyil, ev kataloqunda quraşdırıldığından. Həm də biz repo və hədəfi təyin edərək deponu klonlaşdırmaq üçün git modulundan istifadə edirik.
Sonra, bashrc-də rbenv init-i qeydiyyatdan keçirməliyik və orada PATH-ə rbenv əlavə etməliyik. Bunun üçün lineinfile modulumuz var:
- 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 -)"'
Sonra ruby_build-i quraşdırmalısınız:
- name: Install ruby-build
become_user: "{{ user }}"
git: repo=https://github.com/rbenv/ruby-build.git dest=~/.rbenv/plugins/ruby-build
Və nəhayət, ruby quraşdırın. Bu, rbenv vasitəsilə, yəni sadəcə bash əmri ilə edilir:
- name: Install ruby
become_user: "{{ user }}"
shell: |
export PATH="${HOME}/.rbenv/bin:${PATH}"
eval "$(rbenv init -)"
rbenv install {{ ruby_version }}
args:
executable: /bin/bash
Hansı əmri və nə ilə icra edəcəyimizi deyirik. Bununla belə, burada biz ansible-nin əmrləri işə salmazdan əvvəl bashrc-də olan kodu işlətməməsi faktına rast gəlirik. Bu o deməkdir ki, rbenv birbaşa eyni skriptdə müəyyən edilməlidir.
Növbəti problem, qabıq əmrinin ansible baxımdan heç bir vəziyyətə malik olmaması ilə bağlıdır. Yəni, Ruby-nin bu versiyasının quraşdırılıb-quraşdırılmadığını avtomatik yoxlamaq olmayacaq. Bunu özümüz edə bilərik:
- 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
Qalan tək şey bundler quraşdırmaqdır:
- name: Install bundler
become_user: "{{ user }}"
shell: |
export PATH="${HOME}/.rbenv/bin:${PATH}"
eval "$(rbenv init -)"
gem install bundler
Yenə də ruby_rbenv rolumuzu əsas oyun kitabına əlavə edin.
Paylaşılan fayllar.
Ümumiyyətlə, quraşdırma burada tamamlana bilər. Bundan sonra, yalnız capistrano-nu işə salmaq qalır və o, kodu özü kopyalayacaq, lazımi qovluqları yaradacaq və proqramı işə salacaq (hər şey düzgün konfiqurasiya olunubsa). Bununla belə, capistrano tez-tez əlavə konfiqurasiya faylları tələb edir, məsələn database.yml
və ya .env
Onlar nginx üçün fayllar və şablonlar kimi kopyalana bilər. Yalnız bir incəlik var. Faylları kopyalamadan əvvəl onlar üçün qovluq strukturu yaratmalısınız, buna bənzər bir şey:
# Copy shared files for deploy
- name: Ensure shared dir
become_user: "{{ user }}"
file:
path: "{{ app_path }}/shared/config"
state: directory
biz yalnız bir qovluq təyin edirik və lazım gələrsə, ansible avtomatik olaraq ana kataloqları yaradacaq.
Ansible Vault
Dəyişənlərin istifadəçi parolu kimi gizli məlumatları ehtiva edə biləcəyi faktına artıq rast gəldik. yaratmısansa .env
ərizə üçün fayl və database.yml
onda belə kritik məlumatlar daha çox olmalıdır. Onları maraqlı gözlərdən gizlətmək yaxşı olardı. Bu məqsədlə istifadə olunur
Dəyişənlər üçün fayl yaradaq /ansible/vars/all.yml
(burada siz inventar faylında olduğu kimi müxtəlif host qrupları üçün müxtəlif fayllar yarada bilərsiniz: production.yml, staging.yml və s.).
Şifrələnməli olan bütün dəyişənlər standart yml sintaksisindən istifadə edərək bu fayla köçürülməlidir:
# 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
Bundan sonra bu fayl əmrlə şifrələnə bilər:
ansible-vault encrypt ./vars/all.yml
Təbii ki, şifrələmə zamanı şifrəni açmaq üçün parol təyin etməlisiniz. Bu əmri çağırdıqdan sonra faylın içində nə olacağını görə bilərsiniz.
Vasitəsilə ansible-vault decrypt
faylın şifrəsi açıla, dəyişdirilə və sonra yenidən şifrələnə bilər.
İşləmək üçün faylın şifrəsini açmağa ehtiyac yoxdur. Siz onu şifrələnmiş şəkildə saxlayırsınız və oyun kitabını arqumentlə işlədirsiniz --ask-vault-pass
. Ansible parol istəyəcək, dəyişənləri əldə edəcək və tapşırıqları yerinə yetirəcək. Bütün məlumatlar şifrələnmiş qalacaq.
Bir neçə host qrupu və ansible vault üçün tam əmr bu kimi görünəcək:
ansible-playbook -i inventory ./playbook.yml -l "staging" --ask-vault-pass
Amma mən sizə oyun kitablarının və rolların tam mətnini verməyəcəyəm, özünüz yazın. Çünki ansible belədir - nə etmək lazım olduğunu başa düşmürsənsə, o zaman bunu sizin üçün etməyəcək.
Mənbə: www.habr.com