Ansible көмегімен Rails қолданбасын орналастыру үшін серверді орнату

Жақында мен серверді Rails қолданбасын орналастыруға дайындау үшін бірнеше Ansible оқулықтарын жазуым керек болды. Бір қызығы, мен қарапайым қадамдық нұсқаулықты таппадым. Мен не болып жатқанын түсінбей, басқа біреудің ойын кітабын көшіргім келмеді, соңында бәрін өзім жинап, құжаттаманы оқуға тура келді. Мүмкін мен біреуге осы мақаланың көмегімен бұл процесті тездетуге көмектесе аламын.

Түсіну керек бірінші нәрсе, ansible сізге SSH арқылы қашықтағы сервер(лер)де алдын ала анықталған әрекеттер тізімін орындау үшін ыңғайлы интерфейсті қамтамасыз етеді. Мұнда ешқандай сиқыр жоқ, сіз плагинді орната алмайсыз және қораптан тыс доккер, мониторинг және басқа да жақсылықтар арқылы қолданбаңыздың нөлдік тоқтау уақытын ала алмайсыз. Ойын кітабын жазу үшін сіз нақты не істегіңіз келетінін және оны қалай жасау керектігін білуіңіз керек. Сондықтан мені GitHub-тың дайын оқу кітаптары немесе «Көшіріңіз және іске қосыңыз, ол жұмыс істейді» сияқты мақалалар қанағаттандырмайды.

Бізге не керек?

Жоғарыда айтқанымдай, ойын кітабын жазу үшін сіз не істегіңіз келетінін және оны қалай жасау керектігін білуіңіз керек. Бізге не қажет екенін шешейік. Rails қолданбасы үшін бізге бірнеше жүйелік пакеттер қажет: nginx, postgresql (redis, т.б.). Сонымен қатар, бізге рубиннің нақты нұсқасы қажет. Оны rbenv (rvm, asdf...) арқылы орнатқан дұрыс. Мұның бәрін түбірлік пайдаланушы ретінде іске қосу әрқашан жаман идея болып табылады, сондықтан бөлек пайдаланушы жасап, оның құқықтарын конфигурациялау қажет. Осыдан кейін сіз біздің кодты серверге жүктеп, nginx, postgres және т.б. конфигурацияларды көшіріп, осы қызметтердің барлығын бастауыңыз керек.

Нәтижесінде әрекеттер тізбегі келесідей:

  1. Түбір ретінде кіріңіз
  2. жүйелік бумаларды орнату
  3. жаңа пайдаланушы жасау, құқықтарды конфигурациялау, ssh кілті
  4. жүйелік бумаларды (nginx т.б.) конфигурациялаңыз және оларды іске қосыңыз
  5. Біз дерекқорда пайдаланушы жасаймыз (сіз бірден дерекқор жасай аласыз)
  6. Жаңа пайдаланушы ретінде кіріңіз
  7. Rbenv және ruby ​​орнатыңыз
  8. Топтаманы орнату
  9. Қолданба кодын жүктеп салу
  10. Puma серверін іске қосу

Сонымен қатар, соңғы кезеңдерді capistrano көмегімен жасауға болады, кем дегенде, ол кодты шығарылым каталогтарына көшіре алады, сәтті орналастырудан кейін шығарылымды символдық сілтемемен ауыстыра алады, ортақ каталогтан конфигурацияларды көшіре алады, puma-ны қайта іске қоса алады және т.б. Мұның бәрін Ansible көмегімен жасауға болады, бірақ неге?

Файл құрылымы

Ansible қатал файл құрылымы барлық файлдарыңыз үшін, сондықтан оның барлығын бөлек каталогта сақтаған дұрыс. Оның үстіне, оның рельс қолданбасының өзінде немесе бөлек болуы маңызды емес. Сіз файлдарды бөлек git репозиторийінде сақтай аласыз. Жеке өзім rails қолданбасының /config каталогында түсінікті каталог жасауды және барлығын бір репозиторийде сақтауды ыңғайлы деп таптым.

Қарапайым ойын кітапшасы

Playbook - арнайы синтаксисті пайдаланып, Ansible не істеу керектігін және қалай істеу керектігін сипаттайтын yml файлы. Ештеңе жасамайтын бірінші ойын кітабын жасайық:

---
- name: Simple playbook
  hosts: all

Бұл жерде біз жай ғана біздің ойын дәптеріміз аталады деп айтамыз Simple Playbook және оның мазмұны барлық хосттар үшін орындалуы керек. Біз оны /ansible каталогында атымен сақтай аламыз playbook.yml және жүгіріп көріңіз:

ansible-playbook ./playbook.yml

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

Ansible барлық тізімге сәйкес келетін хосттарды білмейтінін айтады. Олар арнайы тізімде болуы керек түгендеу файлы.

Оны бірдей анықтамалық каталогта жасайық:

123.123.123.123

Осылайша біз жай ғана хостты көрсетеміз (ең дұрысы тестілеуге арналған VPS хосты немесе жергілікті хостты тіркеуге болады) және оны атаумен сақтаймыз. inventory.
Түгендеу файлымен ansible іске қосып көруге болады:

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

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

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

Көрсетілген хостқа ssh қатынасыңыз болса, ansible қашықтағы жүйе туралы ақпаратты қосып, жинайды. (әдепкі ТАПСЫРМА [Фактілерді жинау]), содан кейін ол орындалу туралы қысқаша есеп береді (RECAP PLAY).

Әдепкі бойынша, қосылым жүйеге кірген пайдаланушы атын пайдаланады. Ол хостта болмауы мүмкін. Ойын кітабы файлында remote_user директивасы арқылы қосылу үшін қай пайдаланушыны пайдалану керектігін көрсетуге болады. Сондай-ақ қашықтағы жүйе туралы ақпарат сізге қажетсіз болуы мүмкін және оны жинауға уақытты босқа кетірмеу керек. Бұл тапсырманы да өшіруге болады:

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

Ойын кітабын қайта іске қосып көріңіз және қосылым жұмыс істеп тұрғанына көз жеткізіңіз. (Егер сіз түбірлік пайдаланушыны көрсетсеңіз, жоғары құқықтарды алу үшін, сіз сондай-ақ become: true директивасын көрсетуіңіз керек. Құжаттамада жазылғандай: become set to ‘true’/’yes’ to activate privilege escalation. неге екені толық түсініксіз болса да).

Мүмкін сіз ansible Python интерпретаторын анықтай алмайтындықтан туындаған қатені аласыз, содан кейін оны қолмен көрсетуге болады:

ansible_python_interpreter: /usr/bin/python3 

Пәрмен арқылы python қай жерде бар екенін білуге ​​болады whereis python.

Жүйе пакеттерін орнату

Ansible стандартты дистрибутиві әртүрлі жүйелік пакеттермен жұмыс істеуге арналған көптеген модульдерді қамтиды, сондықтан қандай да бір себептермен bash сценарийлерін жазудың қажеті жоқ. Енді жүйені жаңарту және жүйелік пакеттерді орнату үшін осы модульдердің бірі қажет. Менің VPS жүйесінде Ubuntu Linux бар, сондықтан пакеттерді орнату үшін мен қолданамын apt-get и оған арналған модуль. Егер сіз басқа операциялық жүйені қолданып жатсаңыз, онда сізге басқа модуль қажет болуы мүмкін (есіңізде болсын, мен басында біз нені және қалай істейтінімізді алдын-ала білуіміз керек деп айтқанмын). Дегенмен, синтаксис, ең алдымен, ұқсас болады.

Ойын дәптерімізді бірінші тапсырмалармен толықтырайық:

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

  tasks:
    - name: Update system
      apt: update_cache=yes
    - name: Install system dependencies
      apt:
        name: git,nginx,redis,postgresql,postgresql-contrib
        state: present

Тапсырма - Ansible қашықтағы серверлерде орындайтын дәл тапсырма. Журналда оның орындалуын бақылай алатындай етіп тапсырмаға ат береміз. Біз белгілі бір модульдің синтаксисін пайдалана отырып, оның не істеу керектігін сипаттаймыз. Бұл жағдайда apt: update_cache=yes - apt модулінің көмегімен жүйелік пакеттерді жаңартуды айтады. Екінші команда сәл күрделірек. Біз пакеттер тізімін apt модуліне береміз және олардың бар екенін айтамыз state айналуы керек present, яғни бұл пакеттерді орнатыңыз дейміз. Сол сияқты, біз оларды жоюды немесе жай ғана өзгерту арқылы жаңартуды айта аламыз state. Рельстердің postgresql-мен жұмыс істеуі үшін бізге қазір орнатып жатқан postgresql-contrib бумасы қажет екенін ескеріңіз. Тағы да, сіз мұны білуіңіз және істеуіңіз керек; ansible өздігінен мұны істемейді.

Ойын кітабын қайта іске қосып көріңіз және бумалардың орнатылғанын тексеріңіз.

Жаңа пайдаланушыларды құру.

Пайдаланушылармен жұмыс істеу үшін Ansible-де пайдаланушы модулі де бар. Тағы бір тапсырманы қосамыз (әр кезде оны толығымен көшіріп алмас үшін мен ойын кітабының бұрыннан белгілі бөліктерін түсініктемелердің артына жасырдым):

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

Біз жаңа пайдаланушы жасаймыз, оған схема мен құпия сөзді орнатамыз. Содан кейін біз бірнеше проблемаларға тап боламыз. Әр түрлі хосттар үшін пайдаланушы аттары әртүрлі болуы керек болса ше? Ал парольді ойын кітапшасында анық мәтінде сақтау өте жаман идея. Бастау үшін пайдаланушы аты мен құпия сөзді айнымалыларға енгізейік, ал мақаланың соңында мен парольді қалай шифрлау керектігін көрсетемін.

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

Айнымалылар ойын кітаптарында қос бұйра жақшалар арқылы орнатылады.

Біз түгендеу файлында айнымалы мәндерді көрсетеміз:

123.123.123.123

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

Директиваны ескеріңіз [all:vars] - бұл мәтіннің келесі блогы айнымалылар (vars) және олар барлық хосттарға (барлығына) қолданылатынын айтады.

Дизайн да қызық "{{ user_password | password_hash('sha512') }}". Мәселе мынада, ansible пайдаланушыны арқылы орнатпайды user_add оны қолмен жасайтын сияқты. Және ол барлық деректерді тікелей сақтайды, сондықтан біз парольді алдын ала хэшке түрлендіруіміз керек, бұл команданың әрекеті.

Біздің пайдаланушыны sudo тобына қосамыз. Дегенмен, бұған дейін біз мұндай топтың бар екеніне көз жеткізуіміз керек, өйткені мұны біз үшін ешкім жасамайды:

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

Барлығы өте қарапайым, бізде топтарды құруға арналған топтық модуль бар, синтаксисі apt-қа өте ұқсас. Содан кейін бұл топты пайдаланушыға тіркеу жеткілікті (groups: "sudo").
Сондай-ақ бұл пайдаланушыға ssh кілтін қосу пайдалы, сонда біз оны құпия сөзсіз пайдалана аламыз:

---
- name: Simple playbook
  # ...
  tasks:
    # ...
    - name: Ensure a 'sudo' group
      group:
      name: sudo
        state: present
    - name: Add a new user
      user:
        name: "{{ user }}"
        shell: /bin/bash
        password: "{{ user_password | password_hash('sha512') }}"
        groups: "sudo"
    - name: Deploy SSH Key
      authorized_key:
        user: "{{ user }}"
        key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
        state: present

Бұл жағдайда дизайн қызықты "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" — ол id_rsa.pub файлының мазмұнын (атыңыз басқаша болуы мүмкін), яғни ssh кілтінің жалпыға ортақ бөлігін көшіреді және оны сервердегі пайдаланушыға рұқсат етілген кілттер тізіміне жүктейді.

Рөлдер

Пайдалануды құруға арналған барлық үш тапсырманы бір тапсырмалар тобына оңай жіктеуге болады және бұл топты тым үлкен емес етіп негізгі ойын кітапшасынан бөлек сақтаған дұрыс. Осы мақсатта Ansible бар рөлдері.
Ең басында көрсетілген файл құрылымына сәйкес рөлдер рөлдер каталогында орналастырылуы керек, әр рөл үшін тапсырмалар, файлдар, үлгілер және т.б. каталогтың ішінде аттас жеке каталог бар.
Файл құрылымын жасайық: ./ansible/roles/user/tasks/main.yml (негізгі - рөл ойнату кітабына қосылған кезде жүктелетін және орындалатын негізгі файл; оған басқа рөлдік файлдарды қосуға болады). Енді пайдаланушыға қатысты барлық тапсырмаларды осы файлға тасымалдауға болады:

# Create user and add him to groups
- name: Ensure a 'sudo' group
  group:
    name: sudo
    state: present

- name: Add a new user
  user:
    name: "{{ user }}"
    shell: /bin/bash
    password: "{{ user_password | password_hash('sha512') }}"
    groups: "sudo"

- name: Deploy SSH Key
  authorized_key:
    user: "{{ user }}"
    key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
    state: present

Негізгі ойын кітабында пайдаланушы рөлін пайдалану үшін көрсету керек:

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

  tasks:
    - name: Update system
      apt: update_cache=yes
    - name: Install system dependencies
      apt:
        name: git,nginx,redis,postgresql,postgresql-contrib
        state: present

  roles:
    - user

Сондай-ақ, барлық басқа тапсырмалар алдында жүйені жаңарту мағынасы болуы мүмкін; бұл үшін блоктың атын өзгертуге болады tasks онда олар анықталады pre_tasks.

Nginx орнату

Бізде Nginx орнатылған болуы керек; біз оны конфигурациялап, іске қосуымыз керек. Оны бірден рөлде орындайық. Файл құрылымын жасайық:

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

Енді бізге файлдар мен шаблондар қажет. Олардың арасындағы айырмашылық ansible файлдарды сол күйінде тікелей көшіреді. Үлгілерде j2 кеңейтімі болуы керек және олар бірдей қос бұйра жақшаларды пайдаланып айнымалы мәндерді пайдалана алады.

Nginx-ті қосайық main.yml файл. Ол үшін бізде жүйелік модуль бар:

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

Бұл жерде біз nginx іске қосылуы керек (яғни оны іске қосамыз) деп қана қоймай, оны қосу керек деп бірден айтамыз.
Енді конфигурация файлдарын көшірейік:

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

- name: Copy the nginx.conf
  copy:
    src: nginx.conf
    dest: /etc/nginx/nginx.conf
    owner: root
    group: root
    mode: '0644'
    backup: yes

- name: Copy template my_app.conf
  template:
    src: my_app_conf.j2
    dest: /etc/nginx/sites-available/my_app.conf
    owner: root
    group: root
    mode: '0644'

Біз негізгі nginx конфигурация файлын жасаймыз (оны тікелей серверден алуға немесе өзіңіз жазуға болады). Сондай-ақ, сайттар_available каталогындағы қолданбамыздың конфигурация файлы (бұл қажет емес, бірақ пайдалы). Бірінші жағдайда файлдарды көшіру үшін көшіру модулін қолданамыз (файл файлда болуы керек /ansible/roles/nginx/files/nginx.conf). Екіншіден, біз айнымалы мәндерді алмастыра отырып, үлгіні көшіреміз. Үлгі ішінде болуы керек /ansible/roles/nginx/templates/my_app.j2). Және ол келесідей көрінуі мүмкін:

upstream {{ app_name }} {
  server unix:{{ app_path }}/shared/tmp/sockets/puma.sock;
}

server {
  listen 80;
  server_name {{ server_name }} {{ inventory_hostname }};
  root {{ app_path }}/current/public;

  try_files $uri/index.html $uri.html $uri @{{ app_name }};
  ....
}

Кірістірулерге назар аударыңыз {{ app_name }}, {{ app_path }}, {{ server_name }}, {{ inventory_hostname }} — бұл көшіру алдында Ansible мәндері үлгіге ауыстырылатын барлық айнымалылар. Бұл әр түрлі хост топтары үшін ойын кітабын пайдалансаңыз пайдалы. Мысалы, біз түгендеу файлын қоса аламыз:

[production]
123.123.123.123

[staging]
231.231.231.231

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

[production:vars]
server_name=production
app_path=/home/www/my_app
app_name=my_app

[staging:vars]
server_name=staging
app_path=/home/www/my_stage
app_name=my_stage_app

Енді біз ойын кітапшасын іске қоссақ, ол екі хост үшін де көрсетілген тапсырмаларды орындайды. Бірақ сонымен бірге, стационарлық хост үшін айнымалы мәндер рөлдер мен ойын кітаптарында ғана емес, сонымен қатар nginx конфигурацияларында да өндірістік мәндерден өзгеше болады. {{ inventory_hostname }} түгендеу файлында көрсетудің қажеті жоқ - бұл арнайы айнымалы және қазіргі уақытта ойнату кітабы іске қосылған хост сонда сақталады.
Бірнеше хосттар үшін түгендеу файлы болғыңыз келсе, бірақ тек бір топ үшін іске қосылғыңыз келсе, мұны келесі пәрмен арқылы орындауға болады:

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

Басқа нұсқа - әртүрлі топтар үшін бөлек түгендеу файлдары болуы. Немесе сізде әртүрлі хосттар болса, екі тәсілді біріктіруге болады.

Nginx орнатуға оралайық. Конфигурация файлдарын көшіргеннен кейін, sitest_enabled ішінде sites_available ішінен my_app.conf сілтемесін жасауымыз керек. Және nginx қайта іске қосыңыз.

... # old code in mail.yml

- name: Create symlink to sites-enabled
  file:
    src: /etc/nginx/sites-available/my_app.conf
    dest: /etc/nginx/sites-enabled/my_app.conf
    state: link

- name: restart nginx
  service:
    name: nginx
    state: restarted

Мұнда бәрі қарапайым - жеткілікті стандартты синтаксисі бар қайталанатын модульдер. Бірақ бір нүкте бар. Әр жолы nginx қайта іске қосудың мағынасы жоқ. Байқадыңыз ба, біз «осылай істе» сияқты пәрмендерді жазбаймыз, синтаксис «осы күйде болуы керек» сияқты көрінеді. Көбінесе ansible дәл осылай жұмыс істейді. Егер топ бұрыннан бар болса немесе жүйелік бума әлдеқашан орнатылған болса, ansible мұны тексеріп, тапсырманы өткізіп жібереді. Сондай-ақ, файлдар серверде бұрыннан барға толығымен сәйкес келсе көшірілмейді. Біз мұны пайдалана аламыз және конфигурация файлдары өзгертілген жағдайда ғана nginx-ті қайта іске қоса аламыз. Бұл үшін тіркелу директивасы бар:

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

- name: Copy the nginx.conf
  copy:
    src: nginx.conf
    dest: /etc/nginx/nginx.conf
    owner: root
    group: root
    mode: '0644'
    backup: yes
  register: restart_nginx

- name: Copy template my_app.conf
  template:
    src: my_app_conf.j2
    dest: /etc/nginx/sites-available/my_app.conf
    owner: root
    group: root
    mode: '0644'
  register: restart_nginx

- name: Create symlink to sites-enabled
  file:
    src: /etc/nginx/sites-available/my_app.conf
    dest: /etc/nginx/sites-enabled/my_app.conf
    state: link

- name: restart nginx
  service:
    name: nginx
    state: restarted
  when: restart_nginx.changed

Конфигурация файлдарының бірі өзгерсе, көшірме жасалады және айнымалы тіркеледі restart_nginx. Бұл айнымалы мән тіркелген жағдайда ғана қызмет қайта іске қосылады.

Және, әрине, негізгі ойын кітабына nginx рөлін қосу керек.

Postgresql орнату

Біз postgresql-ді systemd арқылы nginx-пен жасағандай қосуымыз керек, сонымен қатар дерекқор мен дерекқордың өзіне қол жеткізу үшін қолданатын пайдаланушыны жасауымыз керек.
Рөл құрайық /ansible/roles/postgresql/tasks/main.yml:

# Create user in postgresql
- name: enable postgresql and start
  systemd:
    name: postgresql
    state: started
    enabled: yes

- name: Create database user
  become_user: postgres
  postgresql_user:
    name: "{{ db_user }}"
    password: "{{ db_password }}"
    role_attr_flags: SUPERUSER

- name: Create database
  become_user: postgres
  postgresql_db:
    name: "{{ db_name }}"
    encoding: UTF-8
    owner: "{{ db_user }}"

Мен айнымалыларды түгендеуге қалай қосу керектігін сипаттамаймын, бұл бірнеше рет жасалды, сондай-ақ postgresql_db және postgresql_user модульдерінің синтаксисі. Қосымша ақпаратты құжаттамадан табуға болады. Мұндағы ең қызықты директива become_user: postgres. Мәселе мынада, әдепкі бойынша тек postgres пайдаланушысы postgresql дерекқорына және тек жергілікті түрде қол жеткізе алады. Бұл директива бізге осы пайдаланушының атынан командаларды орындауға мүмкіндік береді (әрине бізде рұқсат болса).
Сондай-ақ, жаңа пайдаланушыға дерекқорға кіруге рұқсат беру үшін pg_hba.conf файлына жол қосу қажет болуы мүмкін. Мұны nginx конфигурациясын өзгерткендей жасауға болады.

Және, әрине, негізгі ойын кітабына postgresql рөлін қосу керек.

Rbenv арқылы ruby ​​орнату

Ansible-де rbenv-мен жұмыс істеуге арналған модульдер жоқ, бірақ ол git репозиторийін клондау арқылы орнатылады. Сондықтан бұл мәселе ең стандартты емес болып табылады. Оған рөл жасап берейік /ansible/roles/ruby_rbenv/main.yml және оны толтыруды бастайық:

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

Осы мақсаттар үшін жасаған пайдаланушының астында жұмыс істеу үшін біз қайтадан become_user директивасын қолданамыз. Өйткені rbenv ғаламдық деңгейде емес, оның үй каталогында орнатылған. Сондай-ақ біз репозиторийді клондау үшін git модулін қолданамыз, репо мен мақсатты көрсетеміз.

Әрі қарай, bashrc ішінде rbenv init тіркеуіміз керек және сол жерде PATH ішіне rbenv қосуымыз керек. Ол үшін бізде lineinfile модулі бар:

- name: Add rbenv to PATH
  become_user: "{{ user }}"
  lineinfile:
    path: ~/.bashrc
    state: present
    line: 'export PATH="${HOME}/.rbenv/bin:${PATH}"'

- name: Add rbenv init to bashrc
  become_user: "{{ user }}"
  lineinfile:
    path: ~/.bashrc
    state: present
    line: 'eval "$(rbenv init -)"'

Содан кейін сізге ruby_build орнату керек:

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

Соңында ruby ​​орнатыңыз. Бұл rbenv арқылы, яғни bash пәрменімен орындалады:

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

Біз қай команданы немен орындау керектігін айтамыз. Дегенмен, бұл жерде біз ansible пәрмендерді іске қоспас бұрын bashrc құрамындағы кодты іске қоспайтынын кездестіреміз. Бұл rbenv бір сценарийде тікелей анықталуы керек дегенді білдіреді.

Келесі мәселе қабық командасының ақылға қонымды көзқарасы бойынша күйінің болмауына байланысты. Яғни, ruby ​​нұсқасының орнатылғанын немесе орнатылмағанын автоматты түрде тексеру болмайды. Біз мұны өзіміз жасай аламыз:

- name: Install ruby
  become_user: "{{ user }}"
  shell: |
    export PATH="${HOME}/.rbenv/bin:${PATH}"
    eval "$(rbenv init -)"
    if ! rbenv versions | grep -q {{ ruby_version }}
      then rbenv install {{ ruby_version }} && rbenv global {{ ruby_version }}
    fi
  args:
    executable: /bin/bash

Қалғанының бәрі бундтерді орнату болып табылады:

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

Тағы да, негізгі ойын кітабына ruby_rbenv рөлімізді қосыңыз.

Ортақ файлдар.

Жалпы, орнатуды осы жерде аяқтауға болады. Әрі қарай, capistrano іске қосу ғана қалады және ол кодты өзі көшіріп, қажетті каталогтарды жасайды және қолданбаны іске қосады (егер бәрі дұрыс конфигурацияланған болса). Дегенмен, capistrano жиі қосымша конфигурация файлдарын қажет етеді, мысалы database.yml немесе .env Оларды nginx үшін файлдар мен үлгілер сияқты көшіруге болады. Бір ғана нәзіктік бар. Файлдарды көшірмес бұрын олар үшін каталог құрылымын жасау керек, мысалы:

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

біз тек бір каталогты көрсетеміз және қажет болған жағдайда ansible автоматты түрде негізгі каталогтарды жасайды.

Ansible Vault

Біз айнымалылар пайдаланушының құпия сөзі сияқты құпия деректерді қамтуы мүмкін фактісін бұрыннан кездестірдік. Егер сіз жасаған болсаңыз .env қолданбаға арналған файл және database.yml онда мұндай сыни деректер одан да көп болуы керек. Оларды бейтаныс көздерден жасыру жақсы болар еді. Осы мақсатта ол пайдаланылады сауатты қойма.

Айнымалылар үшін файл құрайық /ansible/vars/all.yml (мұнда сіз инвентарлық файлдағы сияқты хосттардың әртүрлі топтары үшін әртүрлі файлдарды жасай аласыз: production.yml, staging.yml, т.б.).
Шифрлануы қажет барлық айнымалылар стандартты yml синтаксисі арқылы осы файлға тасымалдануы керек:

# System vars
user_password: 123qweasd
db_password: 123qweasd

# ENV vars
aws_access_key_id: xxxxx
aws_secret_access_key: xxxxxx
aws_bucket: bucket_name
rails_secret_key_base: very_secret_key_base

Осыдан кейін бұл файлды пәрменмен шифрлауға болады:

ansible-vault encrypt ./vars/all.yml

Әрине, шифрлау кезінде шифрды шешу үшін құпия сөзді орнату қажет болады. Бұл пәрменді шақырғаннан кейін файлдың ішінде не болатынын көруге болады.

Көмегімен ansible-vault decrypt файл шифрын шешуге, өзгертуге, содан кейін қайтадан шифрлауға болады.

Жұмыс істеу үшін файлдың шифрын шешудің қажеті жоқ. Сіз оны шифрланған түрде сақтайсыз және ойын кітабын аргументпен іске қосасыз --ask-vault-pass. Ansible құпия сөзді сұрайды, айнымалы мәндерді шығарып, тапсырмаларды орындайды. Барлық деректер шифрланған күйде қалады.

Хосттардың бірнеше топтары мен ансибилді қоймаға арналған толық пәрмен келесідей болады:

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

Бірақ мен сізге ойын кітаптары мен рөлдердің толық мәтінін бермеймін, оны өзіңіз жазыңыз. Өйткені ansible солай - егер сіз не істеу керектігін түсінбесеңіз, ол сіз үшін мұны істемейді.

Ақпарат көзі: www.habr.com

пікір қалдыру