E Server opsetzen fir eng Rails Applikatioun mat Ansible z'installéieren

Net viru laanger Zäit brauch ech e puer Ansible Playbooks ze schreiwen fir de Server virzebereeden fir eng Rails Applikatioun z'installéieren. An, iwwerraschend, hunn ech keen einfache Schrëtt-fir-Schrëtt Handbuch fonnt. Ech wollt net eng aner Spillbuch kopéieren ouni ze verstoen wat geschitt ass, an um Enn hunn ech d'Dokumentatioun missen liesen, alles selwer sammelen. Vläicht kann ech een hëllefen dëse Prozess mat der Hëllef vun dësem Artikel ze beschleunegen.

Déi éischt Saach fir ze verstoen ass datt ansible Iech e prakteschen Interface ubitt fir eng virdefinéiert Lëscht vun Aktiounen op engem Fernserver(en) iwwer SSH auszeféieren. Et gëtt keng Magie hei, Dir kënnt net e Plugin installéieren an en Null-Downtime-Deployment vun Ärer Applikatioun mat Docker, Iwwerwaachung an aner Goodies aus der Këscht kréien. Fir e Spillbuch ze schreiwen, musst Dir wësse wat Dir genau wëllt maachen a wéi Dir et maacht. Dofir sinn ech net zefridden mat fäerdege Playbooks vu GitHub, oder Artikele wéi: "Kopieer a lafen, et funktionnéiert."

Wat brauche mir?

Wéi ech scho gesot hunn, fir e Spillbuch ze schreiwen musst Dir wësse wat Dir maache wëllt a wéi Dir et maacht. Loosst eis entscheeden wat mir brauchen. Fir eng Rails Applikatioun brauche mir verschidde Systempakete: nginx, postgresql (redis, etc). Zousätzlech brauche mir eng spezifesch Versioun vu Rubin. Et ass am beschten et iwwer rbenv (rvm, asdf ...) z'installéieren. All dëst als Root Benotzer lafen ass ëmmer eng schlecht Iddi, also musst Dir e separaten Benotzer erstellen a seng Rechter konfiguréieren. Duerno musst Dir eise Code op de Server eropluede, d'Konfiguratioun fir nginx, postgres, etc kopéieren an all dës Servicer starten.

Als Resultat ass d'Sequenz vun Aktiounen wéi follegt:

  1. Login als root
  2. System Packagen installéieren
  3. en neie Benotzer erstellen, Rechter konfiguréieren, ssh Schlëssel
  4. Konfiguréieren System Packagen (nginx etc) a lafen se
  5. Mir erstellen e Benotzer an der Datebank (Dir kënnt direkt eng Datebank erstellen)
  6. Login als neie Benotzer
  7. Installéiert rbenv an Rubin
  8. Installatioun vun der Bundle
  9. Eroplueden der Applikatioun Code
  10. De Puma Server starten

Ausserdeem kënnen déi lescht Etappe mat Capistrano gemaach ginn, op d'mannst aus der Këscht kann et Code an d'Verëffentlechungsverzeichnisser kopéieren, d'Verëffentlechung mat engem Symlink op erfollegräichen Deployment wiesselen, Konfiguratiounen aus engem gemeinsame Verzeechnes kopéieren, Puma nei starten, etc. All dëst kann mat Ansible gemaach ginn, awer firwat?

Datei Struktur

Ansible huet strikt Dateistruktur fir all Är Dateien, also ass et am beschten alles an engem getrennten Verzeichnis ze halen. Ausserdeem ass et net sou wichteg ob et an der Schinneapplikatioun selwer wäert sinn, oder separat. Dir kënnt Dateien an engem getrennten Git-Repository späicheren. Perséinlech hunn ech et am meeschte praktesch fonnt en ansible Verzeechnes am /config Verzeechnes vun der Schinneapplikatioun ze kreéieren an alles an engem Repository ze späicheren.

Einfach Playbook

Playbook ass eng yml Datei déi mat enger spezieller Syntax beschreift wat Ansible soll maachen a wéi. Loosst eis dat éischt Spillbuch erstellen dat näischt mécht:

---
- name: Simple playbook
  hosts: all

Hei soen mir einfach dass eist Spillbuch heescht Simple Playbook an datt säin Inhalt fir all Hosten ausgefouert soll ginn. Mir kënnen et am / ansible Verzeechnes mam Numm späicheren playbook.yml a probéiert ze lafen:

ansible-playbook ./playbook.yml

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

Ansible seet et kennt keng Hosten déi mat der ganzer Lëscht passen. Si mussen an engem speziellen opgezielt ginn Inventar Datei.

Loosst eis et am selwechte verstännegen Verzeechnes erstellen:

123.123.123.123

Dëst ass wéi mir einfach den Host spezifizéieren (am Idealfall den Host vun eisem VPS fir ze testen, oder Dir kënnt localhost registréieren) a späichert en ënner dem Numm inventory.
Dir kënnt probéieren ansible mat enger Inventardatei ze lafen:

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

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

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

Wann Dir ssh Zougang zum spezifizéierte Host hutt, da verbënnt ansible Informatioun iwwer de Fernsystem. (Standard TASK [Fakten sammelen]) duerno gëtt et e kuerze Bericht iwwer d'Ausféierung (PLAY RECAP).

Par défaut benotzt d'Verbindung de Benotzernumm ënner deem Dir an de System ageloggt sidd. Et wäert héchstwahrscheinlech net um Host sinn. An der Playbook-Datei kënnt Dir spezifizéieren wéi ee Benotzer benotzt fir ze verbannen mat der Remote_user Direktiv. Och Informatioun iwwer e Fernsystem kann Iech dacks onnéideg sinn an Dir sollt keng Zäit verschwenden fir se ze sammelen. Dës Aufgab kann och behënnert ginn:

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

Probéiert de Playbook nach eng Kéier ze lafen a gitt sécher datt d'Verbindung funktionnéiert. (Wann Dir de Root-Benotzer uginn hutt, da musst Dir och d'Direktiv ginn: true spezifizéieren, fir erhöhte Rechter ze kréien. Wéi an der Dokumentatioun geschriwwen: become set to ‘true’/’yes’ to activate privilege escalation. obwuel et net ganz kloer ass firwat).

Vläicht kritt Dir e Feeler verursaacht duerch d'Tatsaach datt ansible de Python Dolmetscher net bestëmmen kann, da kënnt Dir et manuell spezifizéieren:

ansible_python_interpreter: /usr/bin/python3 

Dir kënnt erausfannen wou Dir Python mam Kommando hutt whereis python.

Installéiere System Packagen

D'Standardverdeelung vum Ansible enthält vill Moduler fir mat verschiddene Systempakete ze schaffen, sou datt mir aus irgend engem Grond keng Bash-Skripte musse schreiwen. Elo brauche mir ee vun dëse Moduler fir de System ze aktualiséieren an System Packagen z'installéieren. Ech hunn Ubuntu Linux op mengem VPS, also fir Packagen ze installéieren déi ech benotzen apt-get и Modul fir et. Wann Dir en anere Betribssystem benotzt, da brauch Dir vläicht en anere Modul (erënnert, ech hunn am Ufank gesot datt mir am Viraus musse wëssen wat a wéi mir wäerte maachen). Wéi och ëmmer, d'Syntax wäert héchstwahrscheinlech ähnlech sinn.

Loosst eis eist Spillbuch mat den éischten Aufgaben ergänzen:

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

Aufgab ass genau d'Aufgab déi Ansible op Fernserveren ausféiert. Mir ginn der Aufgab en Numm fir datt mir hir Ausféierung am Logbuch verfollegen kënnen. A mir beschreiwen, mat der Syntax vun engem spezifesche Modul, wat et muss maachen. An dësem Fall apt: update_cache=yes - seet fir Systempakete mat dem apt Modul ze aktualiséieren. Déi zweet Kommando ass e bësse méi komplizéiert. Mir passéieren eng Lëscht vu Packagen un den apt Modul a soen datt se sinn state soll ginn present, dat ass, mir soen dës Packagen installéieren. Op eng ähnlech Manéier kënne mir hinnen soen se ze läschen, oder se aktualiséieren andeems se einfach änneren state. Notéiert w.e.g. datt fir Schinne mat postgresql ze schaffen brauche mir de postgresql-contrib Package, dee mir elo installéieren. Erëm, Dir musst wëssen a maachen dëst ansible eleng wäert dëst net maachen.

Probéiert d'Playbook nach eng Kéier auszeféieren a kontrolléiert datt d'Packagen installéiert sinn.

Schafen nei Benotzer.

Fir mat Benotzer ze schaffen, Ansible huet och e Modul - Benotzer. Loosst eis nach eng Aufgab derbäisetzen (ech hunn déi scho bekannt Deeler vum Spillbuch hannert de Kommentarer verstoppt fir se net all Kéier ganz ze kopéieren):

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

Mir erstellen en neie Benotzer, setzen e Schell a Passwuert dofir. An da komme mir op e puer Problemer. Wat wann Benotzernimm fir verschidden Hosten anescht musse sinn? An d'Passwuert am Kloertext am Spillbuch ze späicheren ass eng ganz schlecht Iddi. Als éischt, loosst eis de Benotzernumm a Passwuert a Variablen setzen, a géint d'Enn vum Artikel wäert ech weisen wéi d'Passwuert verschlësselt gëtt.

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

Variablen ginn a Spillbicher gesat mat duebel Curly Klameren.

Mir wäerten d'Wäerter vun de Variablen an der Inventardatei uginn:

123.123.123.123

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

Notéiert weg d'Direktiv [all:vars] - et seet datt den nächste Block vum Text Variablen (vars) ass a si sinn applicabel fir all Hosten (all).

Den Design ass och interessant "{{ user_password | password_hash('sha512') }}". D'Saach ass datt ansible de Benotzer net via user_add wéi wann Dir et manuell géif maachen. An et späichert all Donnéeën direkt, dofir musse mir och am Viraus d'Passwuert an en Hash konvertéieren, wat dëst Kommando mécht.

Loosst eis eise Benotzer an d'Sudo Grupp addéieren. Wéi och ëmmer, ier dëst musse sécher sinn datt esou e Grupp existéiert well keen dëst fir eis mécht:

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

Alles ass ganz einfach, mir hunn och e Gruppemodul fir Gruppen ze kreéieren, mat enger Syntax ganz ähnlech wéi apt. Da geet et duer fir dëse Grupp beim Benotzer unzemellen (groups: "sudo").
Et ass och nëtzlech fir dëse Benotzer en ssh-Schlëssel ze addéieren, fir datt mir ouni Passwuert aloggen kënnen:

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

An dësem Fall ass den Design interessant "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" - et kopéiert den Inhalt vun der id_rsa.pub Datei (Äre Numm kann anescht sinn), dat heescht den ëffentlechen Deel vum ssh Schlëssel an lued et op d'Lëscht vun autoriséierte Schlëssele fir de Benotzer um Server erop.

Rollen

All dräi Aufgaben fir schafen benotzen kann einfach an eng Grupp vun Aufgaben klasséiert ginn, an et wier eng gutt Iddi fir e Buttek dëser Grupp getrennt vun der Haaptrei playbook sou datt et net ze grouss wuessen. Fir dësen Zweck huet Ansible Rollen.
No der Dateistruktur, déi am Ufank uginn ass, mussen d'Rollen an engem getrennten Rollenverzeichnis gesat ginn, fir all Roll gëtt et e separaten Verzeechnes mam selwechten Numm, an den Aufgaben, Dateien, Templates, asw.
Loosst eis eng Dateistruktur erstellen: ./ansible/roles/user/tasks/main.yml (Main ass d'Haaptdatei déi gelueden an ausgefouert gëtt wann eng Roll mat dem Spillbuch verbonne gëtt; aner Rolledateien kënnen domat verbonne sinn). Elo kënnt Dir all Aufgaben am Zesummenhang mam Benotzer op dës Datei transferéieren:

# 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

Am Haaptspillbuch musst Dir spezifizéieren fir d'Benotzerroll ze benotzen:

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

Och kann et Sënn maachen de System virun all aner Aufgaben ze aktualiséieren fir dëst ze maachen, kënnt Dir de Block ëmbenennen tasks an deem se definéiert sinn pre_tasks.

nginx opsetzen

Mir sollten schonn Nginx installéiert hunn, mir mussen et konfiguréieren an ausféieren. Loosst eis et direkt an der Roll maachen. Loosst eis eng Dateistruktur erstellen:

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

Elo brauche mir Dateien a Templates. Den Ënnerscheed tëscht hinnen ass datt ansible d'Dateien direkt kopéiert, sou wéi et ass. A Template mussen d'j2 Extensioun hunn a si kënne verännerlech Wäerter benotze mat der selwechter duebel Curly Klammern.

Loosst eis nginx aktivéieren main.yml Fichier. Fir dëst hu mir e systemd Modul:

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

Hei soen mir net nëmmen datt nginx muss gestart ginn (dat ass, mir lancéieren et), mä mir soen direkt datt et muss aktivéiert ginn.
Loosst eis elo d'Konfiguratiounsdateien kopéieren:

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

Mir erstellen d'Haapt nginx Konfiguratiounsdatei (Dir kënnt se direkt vum Server huelen oder se selwer schreiwen). An och d'Konfiguratiounsdatei fir eis Applikatioun am Site_available Verzeechnes (dëst ass net néideg awer nëtzlech). Am éischte Fall benotze mir de Kopiemodul fir Dateien ze kopéieren (d'Datei muss an /ansible/roles/nginx/files/nginx.conf). An der zweeter kopéiere mir d'Schabloun, ersetzen d'Wäerter vun de Variablen. D'Schabloun soll an /ansible/roles/nginx/templates/my_app.j2). An et kéint esou ausgesinn:

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

Opgepasst op d'Inserts {{ app_name }}, {{ app_path }}, {{ server_name }}, {{ inventory_hostname }} - dëst sinn all Variabelen deenen hir Wäerter Ansible an d'Schabloun ersetzen ier Dir kopéiert. Dëst ass nëtzlech wann Dir e Spillbuch fir verschidde Gruppe vu Hosten benotzt. Zum Beispill kënne mir eisen Inventardatei derbäisetzen:

[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

Wa mir elo eise Playbook starten, wäert et déi spezifizéiert Aufgabe fir béid Hosten ausféieren. Awer gläichzäiteg, fir e Staging Host, wäerten d'Variabelen ënnerschiddlech sinn wéi d'Produktioun, an net nëmmen a Rollen a Spillbicher, awer och an nginx Konfiguratiounen. {{ inventory_hostname }} brauchen net am Inventar Fichier uginn ginn - dëst speziell ansible Variabel an den Host fir deen d'Spillbuch am Moment leeft ass do gespäichert.
Wann Dir eng Inventardatei fir e puer Hosten wëllt hunn, awer nëmme fir eng Grupp lafen, kann dat mat dem folgenden Kommando gemaach ginn:

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

Eng aner Optioun ass separat Inventardateie fir verschidde Gruppen ze hunn. Oder Dir kënnt déi zwou Approche kombinéieren wann Dir vill verschidde Hosten hutt.

Komme mer zréck fir nginx opzestellen. Nodeems Dir d'Konfiguratiounsdateien kopéiert hutt, musse mir e Symlink an sitest_enabled op my_app.conf vun sites_available erstellen. A restart 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

Alles ass einfach hei - erëm ansibel Moduler mat enger zimlech Standard Syntax. Mee et gëtt ee Punkt. Et ass kee Sënn fir nginx all Kéier nei ze starten. Hutt Dir gemierkt datt mir keng Kommandoen schreiwen wéi: "maacht dat esou", d'Syntax gesäit méi aus wéi "dëst soll dësen Zoustand hunn". An dat ass meeschtens genee wéi ansible funktionnéiert. Wann d'Grupp schonn existéiert, oder de System Package ass schonn installéiert, da wäert ansible fir dëst kontrolléieren an d'Aufgab iwwersprangen. Och Dateien ginn net kopéiert wa se komplett mat deem wat schonn um Server ass. Mir kënnen dovunner profitéieren an nginx nei starten wann d'Konfiguratiounsdateien geännert goufen. Et gëtt eng Registerdirektiv fir dëst:

# 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

Wann ee vun de Konfiguratiounsdateien ännert, gëtt eng Kopie gemaach an d'Variabel gëtt registréiert restart_nginx. A nëmmen wann dës Variabel registréiert gouf, gëtt de Service nei gestart.

An natierlech musst Dir d'nginx Roll an d'Haaptspillbuch addéieren.

Postgresql

Mir mussen postgresql aktivéieren mat Systemd op déiselwecht Manéier wéi mir mat nginx gemaach hunn, an och e Benotzer erstellen dee mir benotze fir Zougang zu der Datebank an der Datebank selwer.
Loosst eis eng Roll kreéieren /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 }}"

Ech wäert net beschreiwen wéi Variabelen op d'Inventar ze addéieren, dëst ass scho vill Mol gemaach ginn, souwéi d'Syntax vun de Postgresql_db a postgresql_user Moduler. Méi Informatioun fannt Dir an der Dokumentatioun. Déi interessantst Direktiv hei ass become_user: postgres. De Fakt ass datt par défaut nëmmen de Postgres Benotzer Zougang zu der Postgresql Datebank huet an nëmmen lokal. Dës Direktiv erlaabt eis Kommandoen am Numm vun dësem Benotzer auszeféieren (wa mir natierlech Zougang hunn).
Och musst Dir eng Zeil op pg_hba.conf addéieren fir en neie Benotzer Zougang zu der Datebank z'erméiglechen. Dëst kann op déiselwecht Manéier gemaach ginn wéi mir d'nginx Config geännert hunn.

An natierlech musst Dir d'Postgresql Roll an d'Haaptspillbuch addéieren.

Rubin installéieren iwwer rbenv

Ansible huet keng Moduler fir mat rbenv ze schaffen, awer et gëtt installéiert andeems Dir e Git-Repository klonet. Dofir gëtt dëse Problem am meeschten net-Standard. Loosst eis eng Roll fir hatt kreéieren /ansible/roles/ruby_rbenv/main.yml a loosst eis ufänken et auszefëllen:

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

Mir benotzen erëm d'Beta_User Direktiv fir ënner dem Benotzer ze schaffen, dee mir fir dës Zwecker erstallt hunn. Zënter rbenv ass a sengem Heemverzeichnis installéiert, an net global. A mir benotzen och de Git Modul fir de Repository ze klonen, repo an Dest spezifizéieren.

Als nächst musse mir rbenv init an bashrc registréieren an do rbenv op PATH addéieren. Fir dëst hu mir de lineinfile Modul:

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

Da musst Dir ruby_build installéieren:

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

An endlech Rubin installéieren. Dëst gëtt duerch rbenv gemaach, dat heescht einfach mam Bash Kommando:

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

Mir soen wat Kommando auszeféieren a mat wat. Wéi och ëmmer, hei komme mir op d'Tatsaach datt ansible net de Code am bashrc enthale leeft ier Dir d'Befehle leeft. Dëst bedeit datt rbenv direkt am selwechte Skript definéiert muss ginn.

Den nächste Problem ass wéinst der Tatsaach, datt de Shell Kommando kee Staat aus enger siichtbarer Siicht huet. Dat ass, et gëtt keng automatesch Kontroll ob dës Versioun vum Rubin installéiert ass oder net. Mir kënnen dat selwer maachen:

- 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

Alles wat bleift ass d'Bundler z'installéieren:

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

An erëm, füügt eis Roll ruby_rbenv an d'Haaptspillbuch.

Gedeelt Dateien.

Am Allgemengen kéint de Setup hei ofgeschloss ginn. Als nächst bleift alles fir Capistrano ze lafen an et kopéiert de Code selwer, erstellt déi néideg Verzeichnisser an lancéiert d'Applikatioun (wann alles richteg konfiguréiert ass). Wéi och ëmmer, Capistrano erfuerdert dacks zousätzlech Konfiguratiounsdateien, wéi z database.yml oder .env Si kënne kopéiert ginn wéi Dateien a Template fir nginx. Et gëtt nëmmen eng Subtilitéit. Ier Dir Dateien kopéiert, musst Dir eng Verzeichnisstruktur fir si erstellen, sou eppes:

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

mir spezifizéieren nëmmen een Dossier an ansible wäert automatesch Elterendeel schafen wann néideg.

Ansible Vault

Mir hu scho mat der Tatsaach begéint datt Variablen geheim Daten enthalen wéi de Passwuert vum Benotzer. Wann Dir geschaf hutt .env Fichier fir d'Applikatioun, an database.yml da muss et nach méi esou kritesch Donnéeë ginn. Et wier gutt fir se vu virwëtzeg Aen ze verstoppen. Fir dësen Zweck gëtt et benotzt ansible Vault.

Loosst eis e Fichier fir Variabelen erstellen /ansible/vars/all.yml (hei kënnt Dir verschidde Dateie fir verschidde Gruppe vu Hosten erstellen, sou wéi an der Inventardatei: production.yml, staging.yml, etc).
All Variabelen déi verschlësselte musse mat der Standard yml Syntax op dës Datei transferéiert ginn:

# 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

Duerno kann dës Datei verschlësselt ginn mam Kommando:

ansible-vault encrypt ./vars/all.yml

Natierlech, wann Dir verschlësselt, musst Dir e Passwuert fir d'Entschlësselung setzen. Dir kënnt gesinn wat an der Datei wäert sinn nodeems Dir dëse Kommando opgeruff huet.

Mat der Hëllef vun ansible-vault decrypt d'Datei kann entschlësselt, geännert an dann erëm verschlësselte ginn.

Dir musst d'Datei net entschlësselen fir ze schaffen. Dir späichert et verschlësselt a leeft d'Spillbuch mam Argument --ask-vault-pass. Ansible freet d'Passwuert, recuperéieren d'Variabelen an ausféieren d'Aufgaben. All Donnéeë bleiwen verschlësselte.

De komplette Kommando fir e puer Gruppe vu Hosten an ansible Vault wäert sou ausgesinn:

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

Awer ech ginn Iech net de ganzen Text vu Spillbicher a Rollen, schreift et selwer. Well ansible ass sou - wann Dir net versteet wat gemaach muss ginn, da wäert et et net fir Iech maachen.

Source: will.com

Setzt e Commentaire