Configurazione di un server per distribuire un'applicazione Rails utilizzando Ansible

Non molto tempo fa ho dovuto scrivere diversi playbook Ansible per preparare il server alla distribuzione di un'applicazione Rails. E, sorprendentemente, non ho trovato un semplice manuale passo passo. Non volevo copiare il playbook di qualcun altro senza capire cosa stava succedendo, e alla fine ho dovuto leggere la documentazione, raccogliendo tutto da solo. Forse posso aiutare qualcuno ad accelerare questo processo con l'aiuto di questo articolo.

La prima cosa da capire è che ansible fornisce una comoda interfaccia per eseguire un elenco predefinito di azioni su uno o più server remoti tramite SSH. Non c'è magia qui, non puoi installare un plugin e ottenere una distribuzione senza tempi di inattività della tua applicazione con docker, monitoraggio e altre funzionalità pronte all'uso. Per scrivere un playbook, devi sapere esattamente cosa vuoi fare e come farlo. Ecco perché non mi accontento dei playbook già pronti di GitHub o di articoli come: “Copia ed esegui, funzionerà”.

Ciò che ci serve?

Come ho già detto, per scrivere un playbook devi sapere cosa vuoi fare e come farlo. Decidiamo di cosa abbiamo bisogno. Per un'applicazione Rails avremo bisogno di diversi pacchetti di sistema: nginx, postgresql (redis, ecc.). Inoltre, abbiamo bisogno di una versione specifica di Ruby. È meglio installarlo tramite rbenv (rvm, asdf...). Eseguire tutto questo come utente root è sempre una cattiva idea, quindi è necessario creare un utente separato e configurare i suoi diritti. Successivamente, devi caricare il nostro codice sul server, copiare le configurazioni per nginx, postgres, ecc. e avviare tutti questi servizi.

Di conseguenza, la sequenza delle azioni è la seguente:

  1. Accedi come root
  2. installare i pacchetti di sistema
  3. crea un nuovo utente, configura i diritti, chiave ssh
  4. configurare i pacchetti di sistema (nginx ecc.) ed eseguirli
  5. Creiamo un utente nel database (puoi creare subito un database)
  6. Accedi come nuovo utente
  7. Installa rbenv e ruby
  8. Installazione del bundler
  9. Caricamento del codice dell'applicazione
  10. Avvio del server Puma

Inoltre, le ultime fasi possono essere eseguite utilizzando capistrano, almeno immediatamente può copiare il codice nelle directory di rilascio, cambiare la versione con un collegamento simbolico dopo la distribuzione riuscita, copiare le configurazioni da una directory condivisa, riavviare puma, ecc. Tutto questo può essere fatto utilizzando Ansible, ma perché?

Struttura dei file

Ansible è severo struttura dei file per tutti i tuoi file, quindi è meglio tenerli tutti in una directory separata. Inoltre, non è così importante se sarà nell'applicazione stessa o separatamente. Puoi archiviare i file in un repository git separato. Personalmente, ho trovato più conveniente creare una directory ansible nella directory /config dell'applicazione rails e archiviare tutto in un unico repository.

Manuale semplice

Playbook è un file yml che, utilizzando una sintassi speciale, descrive cosa dovrebbe fare Ansible e come. Creiamo il primo playbook che non fa nulla:

---
- name: Simple playbook
  hosts: all

Qui diciamo semplicemente che il nostro playbook si chiama Simple Playbook e che il suo contenuto dovrebbe essere eseguito per tutti gli host. Possiamo salvarlo nella directory /ansible con il nome playbook.yml e prova a eseguire:

ansible-playbook ./playbook.yml

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

Ansible afferma di non conoscere alcun host che corrisponda all'elenco completo. Devono essere elencati in uno speciale fascicolo di inventario.

Creiamolo nella stessa directory ansible:

123.123.123.123

In questo modo specifichiamo semplicemente l'host (idealmente l'host del nostro VPS per i test, oppure puoi registrare localhost) e lo salviamo con il nome inventory.
Puoi provare a eseguire ansible con un file di inventario:

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

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

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

Se hai accesso ssh all'host specificato, ansible si connetterà e raccoglierà informazioni sul sistema remoto. (TASK predefinito [Gathering Facts]) dopodiché fornirà un breve rapporto sull'esecuzione (PLAY RECAP).

Per impostazione predefinita, la connessione utilizza il nome utente con cui hai effettuato l'accesso al sistema. Molto probabilmente non sarà sull'host. Nel file del playbook è possibile specificare quale utente utilizzare per connettersi utilizzando la direttiva remote_user. Inoltre, le informazioni su un sistema remoto potrebbero spesso non essere necessarie per te e non dovresti perdere tempo a raccoglierle. Questa attività può anche essere disabilitata:

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

Prova a eseguire nuovamente il playbook e assicurati che la connessione funzioni. (Se hai specificato l'utente root, devi anche specificare la direttiva diventa: true per ottenere diritti elevati. Come scritto nella documentazione: become set to ‘true’/’yes’ to activate privilege escalation. anche se non è del tutto chiaro il motivo).

Forse riceverai un errore causato dal fatto che ansible non può determinare l'interprete Python, quindi puoi specificarlo manualmente:

ansible_python_interpreter: /usr/bin/python3 

Puoi scoprire dove hai Python con il comando whereis python.

Installazione dei pacchetti di sistema

La distribuzione standard di Ansible include molti moduli per lavorare con vari pacchetti di sistema, quindi non dobbiamo scrivere script bash per nessun motivo. Ora abbiamo bisogno di uno di questi moduli per aggiornare il sistema e installare i pacchetti di sistema. Ho Ubuntu Linux sul mio VPS, quindi per installare i pacchetti utilizzo apt-get и modulo per esso. Se utilizzi un sistema operativo diverso, potresti aver bisogno di un modulo diverso (ricorda, ho detto all'inizio che dobbiamo sapere in anticipo cosa e come faremo). Tuttavia, molto probabilmente la sintassi sarà simile.

Integriamo il nostro playbook con i primi compiti:

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

L'attività è esattamente l'attività che Ansible eseguirà sui server remoti. Diamo un nome all'attività in modo da poter tracciare la sua esecuzione nel registro. E descriviamo, utilizzando la sintassi di un modulo specifico, cosa deve fare. In questo caso apt: update_cache=yes - dice di aggiornare i pacchetti di sistema usando il modulo apt. Il secondo comando è un po’ più complicato. Passiamo un elenco di pacchetti al modulo apt e diciamo che lo sono state dovrebbe diventare present, ovvero diciamo installare questi pacchetti. In modo simile, possiamo dire loro di cancellarli o aggiornarli semplicemente modificandoli state. Tieni presente che affinché i rail funzionino con postgresql abbiamo bisogno del pacchetto postgresql-contrib, che stiamo installando ora. Ancora una volta, devi saperlo e farlo; ansible da solo non lo farà.

Prova a eseguire nuovamente il playbook e controlla che i pacchetti siano installati.

Creazione di nuovi utenti.

Per lavorare con gli utenti, Ansible ha anche un modulo: utente. Aggiungiamo un'altra attività (ho nascosto le parti già note del playbook dietro i commenti per non copiarlo interamente ogni volta):

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

Creiamo un nuovo utente, impostiamo uno schema e una password per esso. E poi ci imbattiamo in diversi problemi. Cosa succede se i nomi utente devono essere diversi per host diversi? E memorizzare la password in chiaro nel playbook è una pessima idea. Per cominciare, inseriamo nome utente e password in variabili e verso la fine dell'articolo mostrerò come crittografare la password.

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

Le variabili vengono impostate nei playbook utilizzando doppie parentesi graffe.

Indicheremo i valori delle variabili nel file di inventario:

123.123.123.123

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

Si prega di notare la direttiva [all:vars] - dice che il blocco di testo successivo è costituito da variabili (vars) e sono applicabili a tutti gli host (all).

Interessante anche il design "{{ user_password | password_hash('sha512') }}". Il fatto è che ansible non installa l'utente tramite user_add come se lo faresti manualmente. E salva direttamente tutti i dati, motivo per cui dobbiamo anche convertire preventivamente la password in un hash, cosa che fa questo comando.

Aggiungiamo il nostro utente al gruppo sudo. Tuttavia, prima dobbiamo assicurarci che tale gruppo esista perché nessuno lo farà per noi:

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

Tutto è abbastanza semplice, abbiamo anche un modulo group per creare gruppi, con una sintassi molto simile ad apt. Quindi è sufficiente registrare questo gruppo per l'utente (groups: "sudo").
È anche utile aggiungere una chiave ssh a questo utente in modo da poter accedere utilizzandolo senza password:

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

In questo caso il design è interessante "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" — copia il contenuto del file id_rsa.pub (il tuo nome potrebbe essere diverso), ovvero la parte pubblica della chiave ssh e lo carica nell'elenco delle chiavi autorizzate per l'utente sul server.

ruolo

Tutte e tre le attività per la creazione dell'utilizzo possono essere facilmente classificate in un unico gruppo di attività e sarebbe una buona idea archiviare questo gruppo separatamente dal playbook principale in modo che non diventi troppo grande. A questo scopo, Ansible ha ruolo.
Secondo la struttura dei file indicata all'inizio, i ruoli devono essere posizionati in una directory separata dei ruoli, per ogni ruolo esiste una directory separata con lo stesso nome, all'interno della directory task, files, templates, etc
Creiamo una struttura di file: ./ansible/roles/user/tasks/main.yml (main è il file principale che verrà caricato ed eseguito quando un ruolo è connesso al playbook; ad esso possono essere collegati altri file di ruolo). Ora puoi trasferire tutte le attività relative all'utente in questo file:

# 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

Nel playbook principale, devi specificare di utilizzare il ruolo utente:

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

Inoltre, potrebbe avere senso aggiornare il sistema prima di tutte le altre attività; per fare ciò è possibile rinominare il blocco tasks in cui sono definiti pre_tasks.

Configurazione di nginx

Dovremmo già avere Nginx installato; dobbiamo configurarlo ed eseguirlo. Facciamolo subito nel ruolo. Creiamo una struttura di file:

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

Ora abbiamo bisogno di file e modelli. La differenza tra loro è che ansible copia i file direttamente, così come sono. E i modelli devono avere l'estensione j2 e possono utilizzare valori variabili utilizzando le stesse doppie parentesi graffe.

Abilitiamo nginx in main.yml file. Per questo abbiamo un modulo systemd:

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

Qui non solo diciamo che nginx deve essere avviato (cioè lo lanciamo), ma diciamo subito che deve essere abilitato.
Adesso copiamo i file di configurazione:

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

Creiamo il file di configurazione principale di nginx (puoi prenderlo direttamente dal server o scriverlo tu stesso). E anche il file di configurazione per la nostra applicazione nella directory sites_available (non è necessario ma utile). Nel primo caso utilizziamo il modulo copy per copiare i file (il file deve essere in /ansible/roles/nginx/files/nginx.conf). Nella seconda copiamo il template, sostituendo i valori delle variabili. Il modello dovrebbe essere presente /ansible/roles/nginx/templates/my_app.j2). E potrebbe assomigliare a questo:

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

Prestare attenzione agli inserti {{ app_name }}, {{ app_path }}, {{ server_name }}, {{ inventory_hostname }} — queste sono tutte le variabili i cui valori Ansible sostituirà nel modello prima di copiare. Ciò è utile se utilizzi un playbook per diversi gruppi di host. Ad esempio, possiamo aggiungere il nostro file di inventario:

[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

Se ora lanciamo il nostro playbook, eseguirà le attività specificate per entrambi gli host. Ma allo stesso tempo, per un host di staging, le variabili saranno diverse da quelle di produzione, e non solo nei ruoli e nei playbook, ma anche nelle configurazioni nginx. {{ inventory_hostname }} non è necessario specificarlo nel file di inventario: questo variabile ansible speciale e l'host per il quale il playbook è attualmente in esecuzione è archiviato lì.
Se desideri avere un file di inventario per diversi host, ma eseguirlo solo per un gruppo, puoi farlo con il seguente comando:

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

Un'altra opzione è avere file di inventario separati per gruppi diversi. Oppure puoi combinare i due approcci se disponi di molti host diversi.

Torniamo alla configurazione di nginx. Dopo aver copiato i file di configurazione, dobbiamo creare un collegamento simbolico in sitest_enabled a my_app.conf da sites_available. E riavvia 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

Qui tutto è semplice: ancora una volta moduli ansible con una sintassi abbastanza standard. Ma c'è un punto. Non ha senso riavviare nginx ogni volta. Hai notato che non scriviamo comandi del tipo: “fai questo in questo modo”, la sintassi assomiglia più a “questo dovrebbe avere questo stato”. E molto spesso è proprio così che funziona Ansible. Se il gruppo esiste già o il pacchetto di sistema è già installato, ansible lo controllerà e salterà l'attività. Inoltre, i file non verranno copiati se corrispondono completamente a ciò che è già presente sul server. Possiamo approfittarne e riavviare nginx solo se i file di configurazione sono stati modificati. Esiste una direttiva di registro per questo:

# 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

Se uno dei file di configurazione cambia, verrà fatta una copia e la variabile verrà registrata restart_nginx. E solo se questa variabile è stata registrata il servizio verrà riavviato.

E, ovviamente, devi aggiungere il ruolo nginx al playbook principale.

Configurazione di postgresql

Dobbiamo abilitare postgresql usando systemd nello stesso modo in cui abbiamo fatto con nginx, e anche creare un utente che utilizzeremo per accedere al database e al database stesso.
Creiamo un ruolo /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 }}"

Non descriverò come aggiungere variabili all'inventario, questo è già stato fatto molte volte, così come la sintassi dei moduli postgresql_db e postgresql_user. Maggiori informazioni possono essere trovate nella documentazione. La direttiva più interessante qui è become_user: postgres. Il fatto è che per impostazione predefinita solo l'utente postgres ha accesso al database postgresql e solo localmente. Questa direttiva ci consente di eseguire comandi per conto di questo utente (se abbiamo accesso, ovviamente).
Inoltre, potrebbe essere necessario aggiungere una riga a pg_hba.conf per consentire a un nuovo utente di accedere al database. Questo può essere fatto nello stesso modo in cui abbiamo modificato la configurazione di nginx.

E, naturalmente, è necessario aggiungere il ruolo postgresql al playbook principale.

Installazione di Ruby tramite rbenv

Ansible non dispone di moduli per lavorare con rbenv, ma viene installato clonando un repository git. Pertanto, questo problema diventa il più non standard. Creiamo un ruolo per lei /ansible/roles/ruby_rbenv/main.yml e iniziamo a compilarlo:

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

Utilizziamo nuovamente la direttiva diventa_utente per lavorare con l'utente che abbiamo creato per questi scopi. Poiché rbenv è installato nella sua directory home e non a livello globale. E usiamo anche il modulo git per clonare il repository, specificando repo e dest.

Successivamente, dobbiamo registrare rbenv init in bashrc e aggiungere rbenv a PATH lì. Per questo abbiamo il modulo 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 -)"'

Quindi devi installare ruby_build:

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

E infine installa Ruby. Questo avviene tramite rbenv, cioè semplicemente con il comando 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

Diciamo quale comando eseguire e con cosa. Qui però ci imbattiamo nel fatto che ansible non esegue il codice contenuto in bashrc prima di eseguire i comandi. Ciò significa che rbenv dovrà essere definito direttamente nello stesso script.

Il problema successivo è dovuto al fatto che il comando della shell non ha uno stato dal punto di vista ansible. Cioè, non verrà effettuato alcun controllo automatico se questa versione di Ruby è installata o meno. Possiamo farlo noi stessi:

- 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

Non resta che installare bundler:

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

E ancora, aggiungi il nostro ruolo ruby_rbenv al playbook principale.

File condivisi.

In generale, la configurazione potrebbe essere completata qui. Successivamente non resta che eseguire capistrano che copierà il codice stesso, creerà le directory necessarie e avvierà l'applicazione (se tutto è configurato correttamente). Tuttavia, capistrano spesso richiede file di configurazione aggiuntivi, come database.yml o .env Possono essere copiati proprio come file e modelli per nginx. C'è solo una sottigliezza. Prima di copiare i file, devi creare una struttura di directory per loro, qualcosa del genere:

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

specifichiamo solo una directory e ansible creerà automaticamente quelle principali, se necessario.

Volta Ansible

Abbiamo già riscontrato che le variabili possono contenere dati segreti come la password dell’utente. Se hai creato .env file per la domanda e database.yml allora devono esserci ancora più dati critici di questo tipo. Sarebbe bene nasconderli da occhi indiscreti. A questo scopo viene utilizzato volta ansibile.

Creiamo un file per le variabili /ansible/vars/all.yml (qui puoi creare file diversi per diversi gruppi di host, proprio come nel file di inventario: production.yml, staging.yml, ecc.).
Tutte le variabili che devono essere crittografate devono essere trasferite in questo file utilizzando la sintassi yml standard:

# 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

Dopodiché questo file può essere crittografato con il comando:

ansible-vault encrypt ./vars/all.yml

Naturalmente, durante la crittografia dovrai impostare una password per la decrittografia. Puoi vedere cosa ci sarà all'interno del file dopo aver chiamato questo comando.

Per mezzo di ansible-vault decrypt il file può essere decrittografato, modificato e quindi nuovamente crittografato.

Non è necessario decrittografare il file per funzionare. Lo memorizzi crittografato ed esegui il playbook con l'argomento --ask-vault-pass. Ansible chiederà la password, recupererà le variabili ed eseguirà le attività. Tutti i dati rimarranno crittografati.

Il comando completo per diversi gruppi di host e ansible vault sarà simile al seguente:

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

Ma non ti darò il testo completo di playbook e ruoli, scrivilo tu stesso. Perché ansible è così: se non capisci cosa deve essere fatto, non lo farà per te.

Fonte: habr.com

Aggiungi un commento