Yaqinda men serverni Rails ilovasini o'rnatishga tayyorlash uchun bir nechta Ansible o'yin kitoblarini yozishim kerak edi. Va ajablanarlisi shundaki, men oddiy bosqichma-bosqich qo'llanmani topa olmadim. Men nima bo'layotganini tushunmasdan, boshqa birovning o'yin kitobini nusxalashni xohlamadim va oxir-oqibat hujjatlarni o'qishga majbur bo'ldim, hamma narsani o'zim to'pladim. Ehtimol, men ushbu maqola yordamida kimgadir bu jarayonni tezlashtirishga yordam bera olaman.
Tushunish kerak bo'lgan birinchi narsa shundaki, ansible sizga SSH orqali uzoq server(lar)da oldindan belgilangan harakatlar ro'yxatini bajarish uchun qulay interfeysni taqdim etadi. Bu erda hech qanday sehr yo'q, siz plaginni o'rnatolmaysiz va docker, monitoring va boshqa foydali narsalar bilan ilovangizning nol ishlamay qolishiga erisha olmaysiz. O'yin kitobini yozish uchun siz aniq nima qilishni va qanday qilishni bilishingiz kerak. Shuning uchun men GitHub-dan tayyor o'yin kitoblari yoki "Nusxa ko'ring va ishga tushiring, u ishlaydi" kabi maqolalardan qoniqmadim.
Bizga nima kerak?
Yuqorida aytganimdek, o'yin kitobini yozish uchun siz nima qilishni va qanday qilishni bilishingiz kerak. Keling, nima kerakligini hal qilaylik. Rails ilovasi uchun bizga bir nechta tizim paketlari kerak bo'ladi: nginx, postgresql (redis va boshqalar). Bundan tashqari, bizga rubyning o'ziga xos versiyasi kerak. Uni rbenv (rvm, asdf...) orqali o'rnatish yaxshidir. Bularning barchasini root foydalanuvchi sifatida ishlatish har doim yomon fikrdir, shuning uchun siz alohida foydalanuvchi yaratishingiz va uning huquqlarini sozlashingiz kerak. Shundan so'ng siz bizning kodimizni serverga yuklashingiz, nginx, postgres va boshqalar uchun konfiguratsiyalarni nusxalashingiz va ushbu xizmatlarning barchasini ishga tushirishingiz kerak.
Natijada, harakatlar ketma-ketligi quyidagicha:
- Root sifatida tizimga kiring
- tizim paketlarini o'rnating
- yangi foydalanuvchi yaratish, huquqlarni sozlash, ssh kaliti
- tizim paketlarini (nginx va boshqalar) sozlang va ularni ishga tushiring
- Biz ma'lumotlar bazasida foydalanuvchi yaratamiz (siz darhol ma'lumotlar bazasini yaratishingiz mumkin)
- Yangi foydalanuvchi sifatida tizimga kiring
- Rbenv va ruby-ni o'rnating
- Bundlerni o'rnatish
- Ilova kodi yuklanmoqda
- Puma serverini ishga tushirish
Bundan tashqari, oxirgi bosqichlar capistrano yordamida amalga oshirilishi mumkin, hech bo'lmaganda qutidan tashqarida u kodni relizlar kataloglariga nusxalashi, muvaffaqiyatli o'rnatilgandan so'ng relizni simli havola bilan almashtirishi, umumiy katalogdan konfiguratsiyalarni nusxalashi, puma-ni qayta ishga tushirishi va hokazo. Bularning barchasi Ansible yordamida amalga oshirilishi mumkin, lekin nima uchun?
Fayl tuzilishi
Ansible qattiqqo'llikka ega
Oddiy o'yin kitobi
Playbook - bu yml fayli bo'lib, maxsus sintaksisdan foydalanib, Ansible nima qilish kerakligini va qanday qilib tasvirlaydi. Hech narsa qilmaydigan birinchi o'yin kitobini yarataylik:
---
- name: Simple playbook
hosts: all
Bu erda biz shunchaki o'yin kitobimiz chaqirilganligini aytamiz Simple Playbook
va uning mazmuni barcha xostlar uchun bajarilishi kerak. Biz uni nomi bilan /ansible katalogida saqlashimiz mumkin playbook.yml
va ishga tushirishga harakat qiling:
ansible-playbook ./playbook.yml
PLAY [Simple Playbook] ************************************************************************************************************************************
skipping: no hosts matched
Ansible barcha ro'yxatga mos keladigan hostlarni bilmasligini aytdi. Ular maxsus ro'yxatga kiritilishi kerak
Keling, uni bir xil ma'lumotli katalogda yarataylik:
123.123.123.123
Shunday qilib, biz oddiygina xostni belgilaymiz (ideal holda, sinov uchun VPS-ning xosti yoki siz localhost-ni ro'yxatdan o'tkazishingiz mumkin) va uni nom ostida saqlaymiz. inventory
.
Siz inventar fayli bilan ansible ishlashga harakat qilishingiz mumkin:
ansible-playbook ./playbook.yml -i inventory
PLAY [Simple Playbook] ************************************************************************************************************************************
TASK [Gathering Facts] ************************************************************************************************************************************
PLAY RECAP ************************************************************************************************************************************
Agar ko'rsatilgan xostga ssh ruxsatingiz bo'lsa, ansible ulanadi va masofaviy tizim haqida ma'lumot to'playdi. (standart TASK [Faktlarni yig'ish]), shundan so'ng u bajarilish haqida qisqacha hisobot beradi (RECAP PLAY).
Odatiy bo'lib, ulanish siz tizimga kirgan foydalanuvchi nomidan foydalanadi. Katta ehtimol bilan u uy egasida bo'lmaydi. Playbook faylida siz remote_user direktivasi yordamida ulanish uchun qaysi foydalanuvchidan foydalanishni belgilashingiz mumkin. Bundan tashqari, masofaviy tizim haqidagi ma'lumotlar ko'pincha siz uchun keraksiz bo'lishi mumkin va siz uni yig'ish uchun vaqt sarflamasligingiz kerak. Ushbu vazifani o'chirib qo'yish ham mumkin:
---
- name: Simple playbook
hosts: all
remote_user: root
become: true
gather_facts: no
O'yin kitobini qayta ishga tushirib ko'ring va ulanish ishlayotganiga ishonch hosil qiling. (Agar siz ildiz foydalanuvchisini ko'rsatgan bo'lsangiz, yuqori huquqlarga ega bo'lish uchun siz ham become: true direktivasini ko'rsatishingiz kerak. Hujjatlarda yozilganidek: become set to ‘true’/’yes’ to activate privilege escalation.
nima uchun to'liq aniq bo'lmasa ham).
Ehtimol, siz ansible Python tarjimonini aniqlay olmasligi sababli xatoga duch kelishingiz mumkin, keyin uni qo'lda belgilashingiz mumkin:
ansible_python_interpreter: /usr/bin/python3
Buyruq yordamida sizda python qayerda borligini bilib olishingiz mumkin whereis python
.
Tizim paketlarini o'rnatish
Ansible-ning standart taqsimoti turli xil tizim paketlari bilan ishlash uchun ko'plab modullarni o'z ichiga oladi, shuning uchun biz biron bir sababga ko'ra bash skriptlarini yozishimiz shart emas. Endi tizimni yangilash va tizim paketlarini o'rnatish uchun bizga ushbu modullardan biri kerak. Mening VPS-da Ubuntu Linux bor, shuning uchun paketlarni o'rnatish uchun men foydalanaman apt-get
и
Keling, o'yin kitobimizni birinchi vazifalar bilan to'ldiramiz:
---
- 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
Vazifa aynan Ansible uzoq serverlarda bajaradigan vazifadir. Biz vazifaga nom beramiz, shunda uning bajarilishini jurnalda kuzatishimiz mumkin. Va biz ma'lum bir modulning sintaksisidan foydalanib, nima qilish kerakligini tasvirlaymiz. Ushbu holatda apt: update_cache=yes
- apt moduli yordamida tizim paketlarini yangilashni aytadi. Ikkinchi buyruq biroz murakkabroq. Biz paketlar ro'yxatini apt moduliga o'tkazamiz va ular borligini aytamiz state
bo'lishi kerak present
, ya'ni bu paketlarni o'rnating deymiz. Xuddi shunga o'xshash tarzda, biz ularni o'chirishni yoki oddiygina o'zgartirish orqali yangilashni aytishimiz mumkin state
. E'tibor bering, relslar postgresql bilan ishlashi uchun bizga hozir o'rnatayotgan postgresql-contrib paketi kerak. Shunga qaramay, siz buni bilishingiz va qilishingiz kerak; ansible o'z-o'zidan buni qilmaydi.
O'yin kitobini qayta ishga tushirib ko'ring va paketlar o'rnatilganligini tekshiring.
Yangi foydalanuvchilarni yaratish.
Foydalanuvchilar bilan ishlash uchun Ansible-da foydalanuvchi moduli ham mavjud. Keling, yana bir vazifani qo'shamiz (har safar to'liq nusxa ko'chirmaslik uchun o'yin kitobining allaqachon ma'lum qismlarini sharhlar orqasiga yashirganman):
---
- name: Simple playbook
# ...
tasks:
# ...
- name: Add a new user
user:
name: my_user
shell: /bin/bash
password: "{{ 123qweasd | password_hash('sha512') }}"
Biz yangi foydalanuvchi yaratamiz, unga sxema va parolni o'rnatamiz. Va keyin biz bir nechta muammolarga duch kelamiz. Agar foydalanuvchi nomlari turli xostlar uchun boshqacha bo'lishi kerak bo'lsa-chi? Va parolni o'yin kitobida aniq matnda saqlash juda yomon fikr. Boshlash uchun, keling, foydalanuvchi nomi va parolni o'zgaruvchilarga kiritamiz va maqolaning oxirida men parolni qanday shifrlashni ko'rsataman.
---
- name: Simple playbook
# ...
tasks:
# ...
- name: Add a new user
user:
name: "{{ user }}"
shell: /bin/bash
password: "{{ user_password | password_hash('sha512') }}"
O'zgaruvchilar o'yin kitoblarida qo'sh jingalak qavslar yordamida o'rnatiladi.
Biz inventar faylida o'zgaruvchilarning qiymatlarini ko'rsatamiz:
123.123.123.123
[all:vars]
user=my_user
user_password=123qweasd
Iltimos, direktivaga e'tibor bering [all:vars]
- bu matnning keyingi bloki o'zgaruvchilar (vars) ekanligini va ular barcha xostlarga (barchasi) tegishli ekanligini aytadi.
Dizayn ham qiziqarli "{{ user_password | password_hash('sha512') }}"
. Gap shundaki, ansible foydalanuvchini orqali o'rnatmaydi user_add
xuddi qo'lda qilgandek. Va u barcha ma'lumotlarni to'g'ridan-to'g'ri saqlaydi, shuning uchun biz parolni oldindan xeshga aylantirishimiz kerak, bu buyruqni bajaradi.
Keling, foydalanuvchimizni sudo guruhiga qo'shamiz. Biroq, bundan oldin biz bunday guruh mavjudligiga ishonch hosil qilishimiz kerak, chunki hech kim buni biz uchun qilmaydi:
---
- 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"
Hammasi juda oddiy, bizda guruhlar yaratish uchun guruh moduli ham bor, sintaksisi apt ga juda o'xshash. Keyin ushbu guruhni foydalanuvchiga ro'yxatdan o'tkazish kifoya (groups: "sudo"
).
Shuningdek, ushbu foydalanuvchiga parolsiz kirishimiz uchun ssh kalitini qo'shish foydalidir:
---
- 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
Bunday holda, dizayn qiziqarli "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
— u id_rsa.pub faylining mazmunini (sizning ismingiz boshqacha boʻlishi mumkin), yaʼni ssh kalitining umumiy qismini nusxalaydi va uni serverdagi foydalanuvchi uchun ruxsat berilgan kalitlar roʻyxatiga yuklaydi.
Rollar
Foydalanishni yaratish bo'yicha barcha uchta vazifani osonlikcha bitta vazifalar guruhiga ajratish mumkin va bu guruhni juda katta bo'lmasligi uchun asosiy o'yin kitobidan alohida saqlash yaxshi bo'lar edi. Shu maqsadda Ansible bor
Eng boshida ko'rsatilgan fayl tuzilishiga ko'ra, rollar alohida rollar katalogiga joylashtirilishi kerak, har bir rol uchun vazifalar, fayllar, shablonlar va boshqalar katalogida bir xil nomdagi alohida katalog mavjud.
Fayl strukturasini yaratamiz: ./ansible/roles/user/tasks/main.yml
(asosiy - o'yin kitobiga rol ulanganda yuklanadigan va bajariladigan asosiy fayl; boshqa rol fayllari unga ulanishi mumkin). Endi siz foydalanuvchi bilan bog'liq barcha vazifalarni ushbu faylga o'tkazishingiz mumkin:
# 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
Asosiy o'yin kitobida siz foydalanuvchi rolidan foydalanishni belgilashingiz kerak:
---
- 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
Bundan tashqari, boshqa barcha vazifalardan oldin tizimni yangilash mantiqiy bo'lishi mumkin, buning uchun siz blokning nomini o'zgartirishingiz mumkin tasks
unda ular belgilangan pre_tasks
.
Nginx o'rnatilmoqda
Bizda Nginx allaqachon o'rnatilgan bo'lishi kerak; biz uni sozlashimiz va ishga tushirishimiz kerak. Keling, buni darhol rolda bajaramiz. Fayl strukturasini yaratamiz:
- ansible
- roles
- nginx
- files
- tasks
- main.yml
- templates
Endi bizga fayllar va shablonlar kerak. Ularning orasidagi farq shundaki, ansible fayllarni to'g'ridan-to'g'ri nusxa ko'chiradi. Shablonlar j2 kengaytmasiga ega bo'lishi kerak va ular bir xil juft jingalak qavslar yordamida o'zgaruvchan qiymatlardan foydalanishlari mumkin.
Keling, nginx-ni yoqaylik main.yml
fayl. Buning uchun bizda systemd moduli mavjud:
# Copy nginx configs and start it
- name: enable service nginx and start
systemd:
name: nginx
state: started
enabled: yes
Bu erda biz nafaqat nginxni ishga tushirish kerakligini aytamiz (ya'ni biz uni ishga tushiramiz), balki darhol uni yoqish kerakligini aytamiz.
Endi konfiguratsiya fayllarini nusxalaymiz:
# 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 asosiy nginx konfiguratsiya faylini yaratamiz (uni to'g'ridan-to'g'ri serverdan olishingiz yoki o'zingiz yozishingiz mumkin). Shuningdek, saytlar_available katalogidagi ilovamiz uchun konfiguratsiya fayli (bu kerak emas, lekin foydali). Birinchi holda, biz fayllarni nusxalash uchun nusxa ko'chirish modulidan foydalanamiz (fayl ichida bo'lishi kerak /ansible/roles/nginx/files/nginx.conf
). Ikkinchisida biz o'zgaruvchilar qiymatlarini almashtirib, shablonni nusxalaymiz. Shablon ichida bo'lishi kerak /ansible/roles/nginx/templates/my_app.j2
). Va u shunday ko'rinishi mumkin:
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 }};
....
}
Qo'shimchalarga e'tibor bering {{ app_name }}
, {{ app_path }}
, {{ server_name }}
, {{ inventory_hostname }}
— bu barcha oʻzgaruvchilar, ularning qiymatlari Ansible nusxa koʻchirishdan oldin shablonga almashtiriladi. Bu turli xostlar guruhlari uchun o'yin kitobidan foydalansangiz foydali bo'ladi. Masalan, biz inventar faylimizni qo'shishimiz mumkin:
[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
Endi biz o'yin kitobimizni ishga tushirsak, u ikkala xost uchun ham belgilangan vazifalarni bajaradi. Shu bilan birga, staging host uchun o'zgaruvchilar ishlab chiqarishdan farq qiladi va nafaqat rollar va o'yin kitoblarida, balki nginx konfiguratsiyasida ham. {{ inventory_hostname }}
inventar faylida ko'rsatilishi shart emas - bu
Agar siz bir nechta xostlar uchun inventar fayliga ega bo'lishni istasangiz, lekin faqat bitta guruh uchun ishlasangiz, buni quyidagi buyruq bilan bajarish mumkin:
ansible-playbook -i inventory ./playbook.yml -l "staging"
Yana bir variant - turli guruhlar uchun alohida inventar fayllarga ega bo'lish. Yoki sizda turli xil xostlar bo'lsa, ikkita yondashuvni birlashtira olasiz.
Nginx-ni sozlashga qaytaylik. Konfiguratsiya fayllarini nusxalashdan so'ng, biz sites_available dan my_app.conf ga sitest_enabled ilovasida simli havola yaratishimiz kerak. Va nginx-ni qayta ishga tushiring.
... # 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
Bu erda hamma narsa oddiy - yana standart sintaksisga ega bo'lgan qulay modullar. Lekin bir nuqta bor. Har safar nginx-ni qayta ishga tushirishning ma'nosi yo'q. E'tibor berganmisiz, biz "bunday qiling" kabi buyruqlarni yozmaymiz, sintaksis ko'proq "bu shunday holatga ega bo'lishi kerak" kabi ko'rinadi. Va ko'pincha bu ansible qanday ishlaydi. Agar guruh allaqachon mavjud bo'lsa yoki tizim paketi allaqachon o'rnatilgan bo'lsa, ansible buni tekshiradi va vazifani o'tkazib yuboradi. Bundan tashqari, agar ular serverda mavjud bo'lgan narsalarga to'liq mos keladigan bo'lsa, fayllar nusxalanmaydi. Biz bundan foydalanishimiz va faqat konfiguratsiya fayllari o'zgartirilgan bo'lsa, nginx-ni qayta ishga tushirishimiz mumkin. Buning uchun ro'yxatga olish direktivasi mavjud:
# 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
Agar konfiguratsiya fayllaridan biri o'zgartirilsa, nusxa ko'chiriladi va o'zgaruvchi ro'yxatga olinadi restart_nginx
. Va faqat bu o'zgaruvchi ro'yxatga olingan bo'lsa, xizmat qayta ishga tushiriladi.
Va, albatta, asosiy o'yin kitobiga nginx rolini qo'shishingiz kerak.
Postgresql-ni sozlash
Biz postgresql-ni systemd-dan foydalanib, xuddi nginx-da bo'lgani kabi yoqishimiz kerak, shuningdek, ma'lumotlar bazasi va ma'lumotlar bazasiga kirish uchun foydalanadigan foydalanuvchini yaratishimiz kerak.
Keling, rol yarataylik /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 }}"
Men o'zgaruvchilarni inventarizatsiyaga qanday qo'shishni tasvirlamayman, bu allaqachon ko'p marta qilingan, shuningdek postgresql_db va postgresql_user modullarining sintaksisi. Qo'shimcha ma'lumotni hujjatlarda topishingiz mumkin. Bu erda eng qiziqarli ko'rsatma become_user: postgres
. Gap shundaki, sukut bo'yicha faqat postgres foydalanuvchisi postgresql ma'lumotlar bazasiga va faqat mahalliy sifatida kirish huquqiga ega. Ushbu direktiv bizga ushbu foydalanuvchi nomidan buyruqlarni bajarishga imkon beradi (agar bizda kirish imkoni bo'lsa, albatta).
Shuningdek, yangi foydalanuvchining ma'lumotlar bazasiga kirishiga ruxsat berish uchun pg_hba.conf ga qator qo'shishingiz kerak bo'lishi mumkin. Bu nginx konfiguratsiyasini o'zgartirganimiz kabi amalga oshirilishi mumkin.
Va, albatta, asosiy o'yin kitobiga postgresql rolini qo'shishingiz kerak.
Rbenv orqali ruby o'rnatish
Ansible-da rbenv bilan ishlash uchun modullar yo'q, lekin u git omborini klonlash orqali o'rnatiladi. Shuning uchun bu muammo eng nostandart muammoga aylanadi. Keling, unga rol yarataylik /ansible/roles/ruby_rbenv/main.yml
va uni to'ldirishni boshlaylik:
# Install rbenv and ruby
- name: Install rbenv
become_user: "{{ user }}"
git: repo=https://github.com/rbenv/rbenv.git dest=~/.rbenv
Ushbu maqsadlar uchun yaratgan foydalanuvchi ostida ishlash uchun biz yana become_user direktivasidan foydalanamiz. Rbenv global miqyosda emas, balki uy katalogiga o'rnatilganligi sababli. Shuningdek, biz repo va maqsadni belgilab, omborni klonlash uchun git modulidan foydalanamiz.
Keyinchalik, bashrc-da rbenv init-ni ro'yxatdan o'tkazishimiz va u erda PATH-ga rbenv-ni qo'shishimiz kerak. Buning uchun bizda lineinfile moduli mavjud:
- 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 -)"'
Keyin ruby_build ni o'rnatishingiz kerak:
- name: Install ruby-build
become_user: "{{ user }}"
git: repo=https://github.com/rbenv/ruby-build.git dest=~/.rbenv/plugins/ruby-build
Va nihoyat ruby-ni o'rnating. Bu rbenv orqali, ya'ni oddiygina bash buyrug'i bilan amalga oshiriladi:
- name: Install ruby
become_user: "{{ user }}"
shell: |
export PATH="${HOME}/.rbenv/bin:${PATH}"
eval "$(rbenv init -)"
rbenv install {{ ruby_version }}
args:
executable: /bin/bash
Qaysi buyruq va nima bilan bajarilishini aytamiz. Biroq, bu erda biz ansible buyruqlarni ishga tushirishdan oldin bashrc tarkibidagi kodni ishga tushirmasligiga duch kelamiz. Bu shuni anglatadiki, rbenv to'g'ridan-to'g'ri bir xil skriptda aniqlanishi kerak.
Keyingi muammo qobiq buyrug'ining oqilona nuqtai nazardan holatiga ega emasligi bilan bog'liq. Ya'ni, Ruby-ning ushbu versiyasi o'rnatilgan yoki o'rnatilmaganligini avtomatik tekshirish bo'lmaydi. Buni o'zimiz qilishimiz mumkin:
- 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
Qolgan narsa bundlerni o'rnatishdir:
- name: Install bundler
become_user: "{{ user }}"
shell: |
export PATH="${HOME}/.rbenv/bin:${PATH}"
eval "$(rbenv init -)"
gem install bundler
Va yana, asosiy o'yin kitobiga ruby_rbenv rolimizni qo'shing.
Umumiy fayllar.
Umuman olganda, sozlash bu erda tugallanishi mumkin. Keyinchalik, faqat capistrano-ni ishga tushirish qoladi va u kodni o'zi nusxalaydi, kerakli kataloglarni yaratadi va dasturni ishga tushiradi (agar hamma narsa to'g'ri sozlangan bo'lsa). Biroq, capistrano ko'pincha qo'shimcha konfiguratsiya fayllarini talab qiladi, masalan database.yml
yoki .env
Ular xuddi nginx uchun fayllar va shablonlar kabi ko'chirilishi mumkin. Faqat bitta noziklik bor. Fayllarni nusxalashdan oldin ular uchun katalog tuzilishini yaratishingiz kerak, masalan:
# Copy shared files for deploy
- name: Ensure shared dir
become_user: "{{ user }}"
file:
path: "{{ app_path }}/shared/config"
state: directory
biz faqat bitta katalogni belgilaymiz va agar kerak bo'lsa, ansible avtomatik ravishda ota-onalarni yaratadi.
Ansible Vault
Biz allaqachon o'zgaruvchilar foydalanuvchi paroli kabi maxfiy ma'lumotlarni o'z ichiga olishi mumkinligiga duch keldik. Agar siz yaratgan bo'lsangiz .env
ilova uchun fayl va database.yml
unda bunday muhim ma'lumotlar bundan ham ko'proq bo'lishi kerak. Ularni qiziquvchan ko'zlardan yashirish yaxshi bo'lardi. Shu maqsadda u ishlatiladi
O'zgaruvchilar uchun fayl yarataylik /ansible/vars/all.yml
(bu yerda siz inventar faylidagi kabi turli xostlar guruhlari uchun turli xil fayllarni yaratishingiz mumkin: production.yml, staging.yml va boshqalar).
Shifrlanishi kerak bo'lgan barcha o'zgaruvchilar standart yml sintaksisi yordamida ushbu faylga o'tkazilishi kerak:
# 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
Shundan so'ng ushbu faylni buyruq bilan shifrlash mumkin:
ansible-vault encrypt ./vars/all.yml
Tabiiyki, shifrlashda siz parolni hal qilish uchun parol o'rnatishingiz kerak bo'ladi. Ushbu buyruqni chaqirganingizdan so'ng fayl ichida nima bo'lishini ko'rishingiz mumkin.
Yordamida ansible-vault decrypt
faylni shifrlash, o'zgartirish va keyin yana shifrlash mumkin.
Ishlash uchun faylning shifrini ochishingiz shart emas. Siz uni shifrlangan holda saqlaysiz va o'yin kitobini argument bilan boshqarasiz --ask-vault-pass
. Ansible parolni so'raydi, o'zgaruvchilarni oladi va vazifalarni bajaradi. Barcha maʼlumotlar shifrlangan boʻlib qoladi.
Bir nechta xostlar guruhlari va foydali ombor uchun to'liq buyruq quyidagicha ko'rinadi:
ansible-playbook -i inventory ./playbook.yml -l "staging" --ask-vault-pass
Lekin men sizga o'yin kitoblari va rollarning to'liq matnini bermayman, uni o'zingiz yozing. Chunki ansible shunday - agar siz nima qilish kerakligini tushunmasangiz, u siz uchun buni qilmaydi.
Manba: www.habr.com