Nastavení serveru pro nasazení Rails aplikace pomocí Ansible

Nedávno jsem potřeboval napsat několik ansible playbooků pro přípravu serveru k nasazení rails aplikace. A k mému překvapení jsem nenašel jednoduchý postupový manuál. Kopírovat cizí playbook bez pochopení, co se děje, jsem nechtěl, a nakonec jsem musel číst dokumentaci a všechno si poskládat sám. Snad někomu pomohu tento proces urychlit pomocí tohoto článku.

Nejdříve je třeba pochopit, že ansible vám poskytuje pohodlné rozhraní pro provádění předem definovaného seznamu akcí na vzdáleném serveru (serverech) přes SSH. Není v tom žádná magie, nelze nainstalovat plugin a získat rovnou bezproblémové nasazení své aplikace s dockerem, monitoringem a dalšími vychytávkami. Abychom napsali playbook, musíme vědět, co přesně chceme udělat a jak to udělat. Proto mě neuspokojují hotové playbooky z GitHubu, nebo články typu: „Zkopírujte a spusťte, — bude to fungovat.“

Co potřebujeme?

Jak už jsem zmínil, abychom napsali playbook, musíme vědět, co chceme udělat a jak to udělat. Pojďme si ujasnit, co potřebujeme. Pro Rails aplikaci budeme potřebovat několik systémových balíčků: nginx, postgresql (redis atd.). Kromě toho potřebujeme ruby určité verze. Je nejlepší ho nainstalovat přes rbenv (rvm, asdf…). Spouštět to všechno pod uživatelským účtem root je vždy špatný nápad, proto je třeba vytvořit nového uživatele a nastavit mu oprávnění. Po tom je nutné nahrát náš kód na server, zkopírovat konfigurace pro nginx, postgres atd. a spustit všechny tyto služby.

A tedy sekvence akcí je následující:

  1. Přihlásíme se jako root
  2. nainstalujeme systémové balíčky
  3. vytvoříme nového uživatele, nastavíme práva, ssh klíč
  4. nastavíme systémové balíčky (nginx atd.) a spustíme je
  5. Vytvoříme uživatele v databázi (můžeme rovnou vytvořit i databázi)
  6. Přihlásíme se novým uživatelem
  7. Nainstalujeme rbenv a ruby
  8. Nainstalujeme bundler
  9. Nahrajeme kód aplikace
  10. Spustíme server Puma

Poslední etapy lze provádět pomocí capistrano, protože z krabice umí kopírovat kód do vydaných adresářů, přepínat vydání pomocí symlink při úspěšném nasazení, kopírovat konfigurace z sdíleného adresáře, restartovat pumu atd. To lze udělat také pomocí Ansible, ale proč?

Struktura souborů

Ansible má přísnou strukturu souborů pro všechny své soubory, proto je nejlepší mít to všechno v samostatném adresáři. Není tak důležité, zda bude v samotné rails aplikaci, nebo odděleně. Soubory lze uchovávat v samostatném git repozitáři. Osobně mi bylo nejpohodlnější vytvořit adresář ansible v /config adresáři rails aplikace a vše uchovávat v jednom repozitáři.

Jednoduchý Playbook

Playbook je yml soubor, ve kterém je pomocí speciální syntaxe popsáno, co a jak má ansible udělat. Pojďme vytvořit náš první playbook, který nic nedělá:

---
- name: Jednoduchý playbook
  hosts: all

Zde jednoduše říkáme, že náš playbook se jmenuje Jednoduchý Playbook a že jeho obsah se má vykonávat pro všechny hostitele. Můžeme ho uložit do /ansible adresáře pod názvem playbook.yml a zkusit ho spustit:

ansible-playbook ./playbook.yml

PLAY [Jednoduchý Playbook] ************************************************************************************************************************************
skipping: no hosts matched

Ansible říká, že nezná hostitele, kteří by odpovídali seznamu all. Ty je třeba vyjmenovat ve speciálním inventory souboru.

Pojďme ho vytvořit ve stejné ansible adresáři:

123.123.123.123

Takto jednoduše uvedeme hostitele (ideálně hostitele svého VPS pro testy, nebo lze napsat localhost) a uložíme jej pod názvem inventář.
Můžete zkusit spustit ansible s inventory souborem:

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

ÚKOL [Sbírání faktů] ************************************************************************************************************************************

PŘEHLED HRY ************************************************************************************************************************************

Pokud máte přístup přes ssh k uvedenému hostiteli, ansible se připojí a shromáždí informace o vzdáleném systému. (výchozí ÚKOL [Sbírání faktů]) poté poskytne stručnou zprávu o provedení (PŘEHLED HRY).

Ve výchozím nastavení se k připojení používá uživatelské jméno, pod kterým jste přihlášeni do systému. Na hostiteli pravděpodobně nebude. V souboru playbook můžete uvést, jakého uživatele použít pro připojení pomocí direktivy remote_user. Také informace o vzdáleném systému vám často mohou být zbytečné a neměli byste plýtvat časem na jejich shromažďování. Tento úkol lze také deaktivovat:

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

Zkuste znovu spustit playbook a ujistit se, že připojení funguje. (Pokud jste uvedli uživatele root, musíte také uvést direktivu become: true, abyste získali zvýšená oprávnění. Jak je uvedeno v dokumentaci: become nastaveno na ‘true’/’yes’ pro aktivaci zvýšení oprávnění. i když není zcela jasné, proč).

Možná obdržíte chybu způsobenou tím, že ansible nemůže určit interpret Pythonu, pak ho můžete uvést ručně:

ansible_python_interpreter: /usr/bin/python3 

kde máte python, můžete zjistit příkazem whereis python.

Instalace systémových balíčků

Ve standardní distribuci Ansible je k dispozici řada modulů pro práci s různými systémovými balíčky, díky nimž nemusíme psát bash skripty kvůli každé maličkosti. Nyní budeme potřebovat jeden z těchto modulů pro aktualizaci systému a instalaci systémových balíčků. Na mém VPS běží Ubuntu Linux, proto používám apt-get a modul pro něj. Pokud používáte jiný operační systém, možná budete potřebovat jiný modul (pamatujte, že jsem na začátku říkal, že je dobré vědět předem, co a jak budeme dělat). Přesto bude syntaxe pravděpodobně podobná.

Doplníme náš playbook o první úkoly:

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

  tasks:
    - name: Aktualizovat systém
      apt: update_cache=yes
    - name: Nainstalovat systémové závislosti
      apt:
        name: git,nginx,redis,postgresql,postgresql-contrib
        state: present

Úkol — to je právě úkol, který ansible bude vykonávat na vzdálených serverech. Dáváme úkolu jméno, abychom mohli sledovat jeho provádění v logu. A popisujeme, pomocí syntaxe konkrétního modulu, co má udělat. V tomto případě apt: update_cache=yes — říká, že má aktualizovat balíčky systému pomocí modulu apt. Druhý příkaz je o něco složitější. Předáváme modulu apt seznam balíčků a říkáme, že jejich stav musí stát present, tedy říkáme nainstalovat tyto balíčky. Podobně můžeme říct je odstranit nebo aktualizovat, prostě tím, že to změníme stav. Všimněte si, že pro práci rails s postgresql potřebujeme balíček postgresql-contrib, který nyní instalujeme. O tom je také potřeba vědět a udělat, ansible to samo o sobě neudělá.

Zkuste spustit playbook znovu a zkontrolovat, že balíčky se nainstalují.

Vytváření nových uživatelů.

Pro práci s uživateli má Ansible také modul — user. Přidáme ještě jeden úkol (už známé části playbooku jsem skryl za komentáři, abych nemusel kopírovat všechnu jeho část pokaždé):

---
- name: Jednoduchý playbook
  # ...
  tasks:
    # ...
    - name: Přidat nového uživatele
      user:
        name: my_user
        shell: \/bin\/bash
        password: "{{ 123qweasd | password_hash('sha512') }}"

Vytváříme nového uživatele, nastavujeme mu shell a heslo. A hned se setkáváme s několika problémy. Co když mají mít uživatelská jména pro různé hostitele různá? A uchovávat heslo v otevřeném textu v playbooku je velmi špatný nápad. Nejdříve vyjmeme jméno uživatele a heslo do proměnných, a na konci článku ukážu, jak heslo zašifrovat.

---
- name: Jednoduchý playbook
  # ...
  tasks:
    # ...
    - name: Přidat nového uživatele
      user:
        name: "{{ user }}"
        shell: \/bin\/bash
        password: "{{ user_password | password_hash('sha512') }}"

pomocí dvojitých složených závorek se v playbooks nastavují proměnné.

Hodnoty proměnných uvedeme v souboru inventáře:

123.123.123.123

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

Všimněte si na direktivu [all:vars] — ta říká, že následující blok textu jsou proměnné (vars) a platí pro všechny hostitele (all).

Také zajímavá je konstrukce "{{ user_password | password_hash('sha512') }}". Skutečnost je taková, že ansible nenastavuje uživatele přes user_add jak byste to dělali ručně. A ukládá všechna data přímo, proto musíme také heslo předem převést na hash, což tato příkaz dělá.

Přidáme našeho uživatele do skupiny sudo. Nicméně, před tím je potřebné ujistit se, že taková skupina existuje, protože nikdo jiný to za nás neudělá:

---
- name: Jednoduchý playbook
  # ...
  tasks:
    # ...
    - name: Ujistěte se, že skupina 'sudo' existuje
      group:
        name: sudo
        state: present
    - name: Přidat nového uživatele
      user:
        name: "{{ user }}"
        shell: \/bin\/bash
        password: "{{ user_password | password_hash('sha512') }}"
        groups: "sudo"

Všechno je poměrně jednoduché, máme také modul group pro vytváření skupin s velmi podobnou syntaxí jako apt. Poté stačí přiřadit tuto skupinu uživateli (groups: "sudo").
Je také užitečné přidat tomuto uživateli ssh klíč, abychom se pod ním mohli přihlásit bez hesla:

---
- name: Jednoduchý playbook
  # ...
  tasks:
    # ...
    - name: Zajistit skupinu 'sudo'
      group:
      name: sudo
        state: present
    - name: Přidat nového uživatele
      user:
        name: "{{ user }}"
        shell: /bin/bash
        password: "{{ user_password | password_hash('sha512') }}"
        groups: "sudo"
    - name: Nasadit SSH klíč
      authorized_key:
        user: "{{ user }}"
        key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
        state: present

V tomto případě je zajímavá konstrukce "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" — ta zkopíruje obsah souboru id_rsa.pub (u vás se může jmenovat jinak), tedy veřejnou část ssh klíče a nahraje ji do seznamu autorizovaných klíčů pro uživatele na serveru.

Role

Všechny tři úkoly pro vytvoření uživatele lze snadno přiřadit k jedné skupině úkolů, a bylo by dobré tuto skupinu uchovávat odděleně od hlavního playbooku, aby příliš nepřerostla. K tomu existují v ansible role.
Podle struktury souborů uvedené na začátku je třeba role umístit do samostatného adresáře roles, pro každou roli — samostatný adresář se shodným názvem, uvnitř adresáře tasks, files, templates atd.
Vytvoříme strukturu adresářů: ./ansible/roles/user/tasks/main.yml (main — to je hlavní soubor, který bude načítán a prováděn při připojení role k playbooku, v něm lze připojit další soubory role). Nyní můžeme přesunout do tohoto souboru všechny úkoly týkající se uživatele:

# 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

V hlavním playbooku je nutné uvést použití role user:

---
- name: Jednoduchý playbook
  hosts: all
  remote_user: root
  gather_facts: no

  tasks:
    - name: Aktualizovat systém
      apt: update_cache=yes
    - name: Nainstalovat systémové závislosti
      apt:
        name: git,nginx,redis,postgresql,postgresql-contrib
        state: present

  roles:
    - user

Také, možná má smysl provést aktualizaci systému dříve než všechny ostatní úkoly, k tomu lze přejmenovat blok tasks ve kterém jsou definovány na pre_tasks.

Nastavení nginx

Nginx by měl být již nainstalován, je třeba ho nakonfigurovat a spustit. Pojďme to udělat hned v roli. Vytváříme strukturu adresářů:

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

Nyní budeme potřebovat soubory a šablony. Rozdíl mezi nimi je v tom, že Ansible kopíruje soubory přímo, jak jsou. Šablony musí mít příponu j2 a můžete v nich použít hodnoty proměnných pomocí stejných dvojitých složených závorek.

Pojďme zapnout nginx v main.yml souboru. K tomu máme modul systemd:

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

Zde neříkáme jen to, že nginx by měl být spuštěný (tím ho spouštíme), ale také hned říkáme, že by měl být povolen.
Nyní zkopírujeme konfigurační soubory:

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

Vytváříme hlavní konfigurační soubor nginx (můžete si ho vzít přímo ze serveru nebo ho napsat sami). A také konfigurační soubor pro naši aplikaci do adresáře sites_available (to není povinné, ale užitečné). V prvním případě použijeme modul copy k zkopírování souborů (soubor by měl být umístěn v /ansible/roles/nginx/files/nginx.conf). Ve druhém případě kopírujeme šablonu a doplňujeme hodnoty proměnných. Šablona by měla být umístěna v /ansible/roles/nginx/templates/my_app.j2). A její vzhled může být přibližně takto:

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

Všimněte si vložených {{ app_name }}, {{ app_path }}, {{ server_name }}, {{ inventory_hostname }} — to jsou všechny proměnné, jejichž hodnoty Ansible vloží do šablony před zkopírováním. Je to užitečné, pokud použijete playbook pro různé skupiny hostitelů. Například můžeme doplnit náš inventární soubor:

[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

Pokud nyní spustíme náš playbook, vykoná zadané úkoly pro oba hostitele. Ale pro staging hosta budou proměnné se lišit od production, a to nejen v rolích a playboocích, ale i v konfiguračních souborech nginx. {{ inventory_hostname }} nemusíte uvádět v inventárním souboru — to je speciální proměnná ansible a tam je uložen hostitel, pro který se aktuálně playbook provádí.
Pokud chcete mít inventární soubor pro více hostitelů, ale spouštět pouze pro jednu skupinu, můžete to udělat následující příkazem:

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

další možností je mít samostatné inventární soubory pro různé skupiny. Nebo můžete kombinovat oba přístupy, pokud máte mnoho různých hostitelů.

Vraťme se k nastavení nginx. Po zkopírování konfiguračních souborů je třeba vytvořit symlink v sites_enabled na my_app.conf ze sites_available. A restartovat nginx.

... # starý kód v mail.yml

- name: Vytvořit symlink do 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

Tady je to jednoduché – opět moduly ansible se poměrně standardní syntaxi. Ale je tu jeden aspekt. Nemá smysl restartovat nginx pokaždé. Všimli jste si, že nepíšeme příkazy jako: „udělat to takto“, syntakticky to spíše vypadá jako „toto by mělo mít tento stav“. A většinou ansible skutečně takto funguje. Pokud skupina již existuje nebo systémový balíček je již nainstalován, ansible to zkontroluje a úkol přeskočí. Také soubory nebudou kopírovány, pokud se plně shodují s tím, co již na serveru je. Můžeme toho využít a restartovat nginx pouze v případě, že došlo ke změnám v konfiguračních souborech. K tomu existuje direktiva register:

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

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

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

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

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

Pokud se jeden z konfiguračních souborů změní, dojde ke zkopírování a registraci proměnné restart_nginx. A pouze pokud byla tato proměnná registrována, dojde k restartu služby.

A samozřejmě je nutné přidat roli nginx do hlavního playbooku.

Nastavení postgresql

Musíme povolit postgresql pomocí systemd přesně tak, jak jsme to dělali s nginx, a také vytvořit uživatele, kterého budeme používat k přístupu k databázi, a samotnou databázi.
Vytvoříme roli /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 }}"

Nebudu uvádět, jak přidávat proměnné do inventáře, to už bylo děláno mnohokrát, stejně jako syntaxe modulů postgresql_db a postgresql_user. Další informace naleznete v dokumentaci. Zde je nejzajímavější direktiva become_user: postgres. Věc se má tak, že přístup k databázi postgresql má pouze uživatel postgres a pouze lokálně. Tato direktiva nám umožňuje vykonávat příkazy jménem tohoto uživatele (pokud máme přístup).
Také byste možná museli doplnit řádek do pg_hba.conf, abyste otevřeli přístup novému uživateli k databázi. To lze provést stejně, jako jsme měnili konfiguraci nginx.

A samozřejmě je také třeba přidat roli postgresql do hlavního playbooku.

Instalace ruby přes rbenv

V Ansible nejsou moduly pro práci s rbenv a instaluje se pomocí klonování git repozitáře. Proto se tato úloha stává nejvíce nestandardní. Vytvoříme pro ni roli /ansible/roles/ruby_rbenv/main.yml a začneme ji vyplňovat:

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

Opět používáme direktivu become_user, abychom pracovali z pohledu uživatele, kterého jsme pro tyto účely vytvořili. Protože rbenv je instalován v jeho domovském adresáři, nikoliv globálně. Také používáme modul git pro klonování repozitáře, uvádějíc repo a dest.

Pak je třeba zapsat rbenv init do bashrc a také přidat rbenv do PATH. K tomu máme modul lineinfile:

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

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

Poté je nutné nainstalovat ruby_build:

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

A nakonec nainstalovat ruby. To se provádí přes rbenv, tedy jednoduše bash příkazem:

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

Říkáme, jaký příkaz provést a čím. Nicméně zde narazíme na to, že Ansible nespouští kód obsažený v bashrc před spuštěním příkazů. To znamená, že rbenv je třeba definovat přímo v tomto skriptu.

Další problém souvisí s tím, že shell příkaz nemá stav z pohledu ansible. Tedy automatické kontroly, zda je tato verze ruby nainstalována nebo ne, nebude. Můžeme to udělat ručně:

- name: Nainstalovat 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

A zůstává nainstalovat bundler:

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

A opět přidat naši roli ruby_rbenv do hlavního playbooku.

Sdílené soubory.

Celkově by tímto byla konfigurace ukončena. Dále zbývá spustit capistrano, které samo zkopíruje kód, vytvoří potřebné adresáře a spustí aplikaci (pokud je všechno správně nastaveno). Nicméně často capistrano potřebuje další konfigurační soubory, jako například database.yml nebo .env Lze je zkopírovat přesně tak, jak soubory a šablony pro nginx. Existuje jen jeden drobný detail. Před kopírováním souborů je třeba vytvořit strukturu adresářů, něco jako je toto:

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

uvádíme pouze jeden adresář a ansible automaticky vytvoří rodičovské, pokud je to potřeba.

Ansible Vault

Už jsme narazili na situaci, kdy v proměnných mohou být tajné údaje, jako je uživatelské heslo. Pokud jste vytvořili .env soubor pro aplikaci a database.yml musí tam být ještě více takových kritických údajů. Bylo by dobré je skrýt před cizími očima. K tomu se používá ansible vault.

Vytvoříme soubor pro proměnné /ansible/vars/all.yml (zde lze vytvářet různé soubory pro různé skupiny hostitelů, přesně tak, jak v inventářovém souboru: production.yml, staging.yml atd.).
Do tohoto souboru je třeba přesunout všechny proměnné, které by měly být zašifrovány, pomocí standardní syntaxe 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

Poté lze tento soubor zašifrovat příkazem:

ansible-vault encrypt ./vars/all.yml

Samozřejmě, že při šifrování bude nutné nastavit heslo pro dešifrování. Můžete se podívat, co se uvnitř souboru objeví po zavolání tohoto příkazu.

Pomocí ansible-vault decrypt lze soubor dešifrovat, upravit a poté znovu zašifrovat.

Pro práci není nutné soubor dešifrovat. Uchováváte ho v zašifrovaném stavu a spouštíte playbook s argumentem --ask-vault-pass. Ansible se zeptá na heslo, získá proměnné a vykoná úkoly. Všechna data zůstanou zašifrovaná.

Celý příkaz pro několik skupin hostitelů a ansible vault bude vypadat přibližně takto:

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

A celý text playbooků a rolí vám nedám, napište si sami. Protože ansible je taková věc — pokud nerozumíte, co je třeba udělat, tak vám to ani on neudělá.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster