Configurazione del server per il deployment di un'applicazione Rails utilizzando Ansible

Di recente, ho avuto la necessità di scrivere alcuni playbook di Ansible per preparare il server al deploy di un'applicazione Rails. E, con mia sorpresa, non ho trovato un semplice manuale passo per passo. Non volevo copiare un playbook di qualcun altro senza comprendere ciò che stava accadendo, quindi ho finito per leggere la documentazione, raccogliendo tutto da solo. Forse, con questo articolo, posso aiutare qualcuno a velocizzare questo processo.

Innanzitutto, è importante capire che Ansible offre un'interfaccia comoda per eseguire un elenco predefinito di azioni su un server remoto (o più server) tramite SSH. Non c'è alcuna magia qui: non puoi semplicemente installare un plugin e ottenere un deploy zero downtime della tua applicazione con Docker, monitoraggio e altre funzionalità. Per scrivere un playbook, devi sapere esattamente cosa vuoi fare e come farlo. Pertanto, non mi accontento dei playbook già pronti da GitHub o articoli del tipo: “Copia e incolla, funzionerà”.

Di cosa abbiamo bisogno?

Come ho già detto, per scrivere un playbook devi sapere cosa vuoi fare e come farlo. Vediamo quindi quali sono le nostre esigenze. Per un'applicazione Rails, avremo bisogno di alcuni pacchetti di sistema: nginx, postgresql (redis, ecc.). Inoltre, abbiamo bisogno di ruby di una versione specifica. È meglio installarlo tramite rbenv (rvm, asdf…). Eseguire tutto come utente root è sempre una cattiva idea, quindi è necessario creare un utente separato e configurargli i permessi. Dopo di ciò, dobbiamo 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. Accediamo come root
  2. installiamo i pacchetti di sistema
  3. creiamo un nuovo utente, impostiamo i permessi, chiave ssh
  4. configuriamo i pacchetti di sistema (nginx, ecc.) e li avviamo
  5. creiamo un utente nel database (possibilmente creando anche il database)
  6. accediamo come nuovo utente
  7. installiamo rbenv e ruby
  8. installiamo bundler
  9. carichiamo il codice dell'applicazione
  10. avviamo il server Puma

Tra l'altro, le fasi finali possono essere eseguite utilizzando capistrano, almeno esso è in grado di copiare il codice nelle directory di rilascio, cambiare il rilascio con un symlink dopo un deploy riuscito, copiare le configurazioni dalla directory shared, riavviare puma, ecc. Tutto questo può essere fatto anche con Ansible, ma perché farlo?

Struttura dei file

Ansible ha una rigorosa struttura dei file per tutti i suoi file, quindi è meglio tenere tutto in una directory separata. Non è così importante che si trovi all'interno dell'applicazione rails o separatamente. Puoi conservare i file in un repository git separato. Personalmente, mi è sembrato più comodo creare una directory ansible nella directory /config dell'applicazione rails e tenere tutto in un unico repository.

Playbook Semplice

Il playbook è un file yml in cui viene descritto, utilizzando una sintassi speciale, cosa e come Ansible deve fare. Creiamo il nostro primo playbook che non fa nulla:

---
- name: Playbook semplice
  hosts: all

Qui stiamo semplicemente dicendo che il nostro playbook si chiama Playbook Semplice e che il suo contenuto deve essere eseguito per tutti gli host. Possiamo salvarlo nella directory /ansible con il nome playbook.yml e provare a lanciare:

ansible-playbook ./playbook.yml

PLAY [Playbook Semplice] ************************************************************************************************************************************
skipping: nessun host corrisponde

Ansible dice che non conosce gli host che corrispondono alla lista all. Devono essere elencati in un apposito file di inventory.

Creiamo quindi uno nella stessa directory ansible:

123.123.123.123

Così semplicemente specifichiamo un host (ideale sarebbe l'host del tuo VPS per test, altrimenti puoi scrivere localhost) e lo salviamo con il nome inventory.
Puoi provare a lanciare ansible con il file di inventory:

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

TASK [Raccolta Dati] ************************************************************************************************************************************

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

Se hai accesso ssh all'host specificato, Ansible si connetterà e raccoglierà informazioni sul sistema remoto. (TASK predefinito [Raccolta Dati]) dopo di che fornirà un breve rapporto sull'esecuzione (PLAY RECAP).

Per impostazione predefinita, per la connessione viene utilizzato il nome utente con cui sei autenticato nel sistema. Probabilmente non sarà presente sull'host. Nel file playbook puoi specificare quale utente utilizzare per la connessione tramite la direttiva remote_user. Inoltre, l'informazione sul sistema remoto potrebbe spesso non essere necessaria e non vale la pena perdere tempo a raccoglierla. Questo compito può anche essere disattivato:

---
- 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 indicare la direttiva become: true per ottenere privilegi elevati. Come indicato nella documentazione: become impostato a ‘true’/'yes' per attivare l'escalation dei privilegi. anche se non è del tutto chiaro il perché).

Potresti ricevere un errore causato dal fatto che ansible non riesce a determinare l'interprete Python, quindi puoi specificarlo manualmente:

ansible_python_interpreter: /usr/bin/python3 

puoi scoprire dove si trova Python con il comando whereis python.

Installazione di pacchetti di sistema

Nella distribuzione standard di Ansible sono inclusi numerosi moduli per lavorare con vari pacchetti di sistema, il che ci fa risparmiare tempo nel dover scrivere script bash per ogni cosa. Ora ci occorre uno di questi moduli per aggiornare il sistema e installare i pacchetti di sistema. Sul mio VPS è installato Ubuntu Linux, quindi utilizzo apt-get e il modulo per questo. Se utilizzi un altro sistema operativo, potrebbe essere necessario un modulo diverso (ricorda che all'inizio ho detto che bisogna sapere in anticipo cosa e come fare). Tuttavia, la sintassi sarà probabilmente simile.

Aggiungiamo al nostro playbook i primi compiti:

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

  tasks:
    - name: Aggiorna il sistema
      apt: update_cache=yes
    - name: Installa dipendenze di sistema
      apt:
        name: git,nginx,redis,postgresql,postgresql-contrib
        state: present

Il Task è proprio il compito che ansible eseguirà sui server remoti. Diamo un nome al task per tenere traccia della sua esecuzione nel log. E descriviamo, usando la sintassi del modulo specifico, cosa deve fare. In questo caso apt: update_cache=yes — indica di aggiornare i pacchetti di sistema utilizzando il modulo apt. Il secondo comando è un po' più complesso. Passiamo al modulo apt un elenco di pacchetti e diciamo che il loro state deve diventare present, cioè diciamo di installare questi pacchetti. Analogamente, possiamo dire di rimuoverli o aggiornarli, semplicemente cambiando state. Si prega di notare che per far funzionare rails con postgresql abbiamo bisogno del pacchetto postgresql-contrib, che stiamo attualmente installando. Anche questo è qualcosa di cui è necessario essere a conoscenza e fare, ansible da solo non lo farà.

Prova a eseguire nuovamente il playbook e verifica che i pacchetti vengano installati.

Creazione di nuovi utenti.

Per lavorare con gli utenti, Ansible ha anche un modulo chiamato user. Aggiungeremo un altro task (ho già nascosto le parti conosciute del playbook con dei commenti, per non doverlo copiare interamente ogni volta):

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

Stiamo creando un nuovo utente, impostandogli la shell e la password. E ci troviamo immediatamente di fronte a diversi problemi. Cosa succede se i nomi degli utenti devono essere diversi per diversi host? Inoltre, memorizzare la password in chiaro nel playbook è un'idea molto cattiva. Iniziamo a spostare il nome utente e la password in variabili, e verso la fine dell'articolo mostrerò come criptare la password.

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

Utilizzando le doppie parentesi graffe nei playbook vengono impostate le variabili.

Indicheremo i valori delle variabili nel file di inventory:

123.123.123.123

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

Nota la direttiva [all:vars] — indica che il blocco di testo successivo sono variabili (vars) e si applicano a tutti gli host (all).

È interessante anche la costruzione "{{ user_password | password_hash('sha512') }}". Il fatto è che ansible non aggiunge l'utente tramite user_add come faresti manualmente. Ma salva tutte le informazioni direttamente, motivo per cui anche la password deve essere preventivamente convertita in hash, come fa questo comando.

Aggiungiamo il nostro utente al gruppo sudo. Tuttavia, prima di tutto è necessario assicurarsi 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 a quella di apt. Dopodiché, è sufficiente assegnare questo gruppo all'utente (groups: "sudo").
È inoltre utile aggiungere a questo utente una chiave ssh, in modo da poter accedere senza password:

---
- name: Simple playbook
  # ...
  tasks:
    # ...
    - name: Assicurati di avere un gruppo 'sudo'
      group:
      name: sudo
        state: present
    - name: Aggiungi un nuovo utente
      user:
        name: "{{ user }}"
        shell: /bin/bash
        password: "{{ user_password | password_hash('sha512') }}"
        groups: "sudo"
    - name: Distribuisci chiave SSH
      authorized_key:
        user: "{{ user }}"
        key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
        state: present

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

Ruoli

Tutte e tre le attività per la creazione degli utenti possono facilmente essere raggruppate in un'unica categoria di attività, e sarebbe utile mantenere questo gruppo separato dal playbook principale, affinché non cresca troppo. A tale scopo, in ansible esistono ruoli.
Secondo la struttura dei file indicata all'inizio, i ruoli devono essere messi in una directory separata roles, con una directory separata per ogni ruolo con lo stesso nome, all'interno delle directory tasks, files, templates, ecc.
Creiamo la struttura dei file: ./ansible/roles/user/tasks/main.yml (main è il file principale che sarà caricato ed eseguito quando collegherai il ruolo al playbook, in esso si possono includere altri file del ruolo). Ora possiamo trasferire in questo file tutte le attività relative all'utente:

# 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, è necessario specificare di utilizzare il ruolo user:

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

  tasks:
    - name: Aggiorna il sistema
      apt: update_cache=yes
    - name: Installa le dipendenze di sistema
      apt:
        name: git,nginx,redis,postgresql,postgresql-contrib
        state: present

  roles:
    - user

Inoltre, potrebbe avere senso eseguire l'aggiornamento del sistema prima di tutte le altre attività, per fare ciò, puoi rinominare il blocco tasks nel quale sono definite in pre_tasks.

Configurazione di nginx

Nginx dovrebbe essere già installato, è necessario configurarlo e avviarlo. Facciamo questo subito nel ruolo. Creiamo la struttura dei file:

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

Ora abbiamo bisogno di file e modelli. La differenza tra di loro è che i file vengono copiati da Ansible così come sono. I modelli, invece, devono avere l'estensione j2 e possono utilizzare i valori delle variabili tramite le stesse parentesi graffe doppie.

Attiviamo nginx in main.yml file. Per farlo abbiamo il 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 (ossia lo lanciamo), ma diciamo subito che deve essere abilitato.
Ora 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 per nginx (può essere preso direttamente dal server o scritto da noi). Inoltre, creiamo il file di configurazione per la nostra applicazione nella directory sites_available (questo non è obbligatorio, ma utile). Nel primo caso utilizziamo il modulo copy per copiare i file (il file deve trovarsi in /ansible/roles/nginx/files/nginx.conf). Nel secondo caso, copiamo il modello sostituendo i valori delle variabili. Il modello deve trovarsi in /ansible/roles/nginx/templates/my_app.j2). E potrebbe assomigliare a qualcosa del genere:

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

Fai attenzione ai segnaposto {{ app_name }}, {{ app_path }}, {{ server_name }}, {{ inventory_hostname }} queste sono tutte variabili i cui valori Ansible sostituirà nel modello prima di copiare. Questo è utile se si utilizza un playbook per diverse gruppi di host. Ad esempio, possiamo completare il nostro file inventory:

[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 eseguiamo il nostro playbook, eseguirà i compiti specificati per entrambi gli host. Ma per l'host staging, i variabili saranno diversi da quelli di produzione, non solo nei ruoli e nei playbook, ma anche nei file di configurazione di nginx. {{ inventory_hostname }} non è necessario indicare nel file di inventory — questa è una variabile speciale di ansible e qui viene memorizzato l'host per cui viene eseguito il playbook in questo momento.
Se desideri avere un file di inventory per più host, ma eseguire solo per un gruppo, puoi farlo con il seguente comando:

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

un'altra opzione è avere file di inventory separati per gruppi diversi. O si possono combinare i due approcci, se hai molti host diversi.

Torniamo alla configurazione di nginx. Dopo aver copiato i file di configurazione, dobbiamo creare un symlink in sites_enabled a my_app.conf da sites_available. E riavviare nginx.

... # codice vecchio in mail.yml

- nome: Crea symlink a sites-enabled
  file:
    src: /etc/nginx/sites-available/my_app.conf
    dest: /etc/nginx/sites-enabled/my_app.conf
    state: link

- nome: riavvia nginx
  service:
    name: nginx
    state: restarted

Qui è tutto semplice: di nuovo i moduli ansible con una sintassi abbastanza standard. Ma c'è un aspetto da considerare. Non ha senso riavviare nginx ogni volta. Avete notato che non scriviamo comandi del tipo: "fai questo in questo modo", la sintassi sembra piuttosto come "questo deve avere questo stato". E di solito è così che funziona ansible. Se il gruppo esiste già, o il pacchetto di sistema è già installato, ansible lo verificherà e salterà il compito. Anche i file non verranno copiati se corrispondono completamente a ciò che è già presente sul server. Possiamo sfruttare questa caratteristica e riavviare nginx solo se i file di configurazione sono stati modificati. A questo scopo esiste la direttiva 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

Se uno dei file di configurazione viene modificato, verrà eseguita la copia e registrata la variabile restart_nginx. E solo se questa variabile è stata registrata, verrà eseguito il riavvio del servizio.

E naturalmente, è necessario aggiungere il ruolo nginx nel playbook principale.

Configurazione di postgresql

Dobbiamo avviare postgresql tramite systemd proprio come abbiamo fatto con nginx, e anche creare un utente che utilizzeremo per accedere al database e il 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 nell'inventory, è già stato fatto molte volte, così come la sintassi dei moduli postgresql_db e postgresql_user. Maggiori informazioni possono essere trovate nella documentazione. Qui la direttiva più interessante è become_user: postgres. Il fatto è che, per impostazione predefinita, l'accesso al database postgresql è riservato solo all'utente postgres e solo localmente. Questa direttiva ci consente di eseguire comandi a nome di questo utente (se abbiamo accesso, ovviamente).
Potrebbe anche essere necessario aggiungere una riga in pg_hba.conf per consentire l'accesso al nuovo utente al database. Questo può essere fatto proprio come abbiamo modificato la configurazione di nginx.

E naturalmente, bisogna aggiungere il ruolo postgresql nel playbook principale.

Installazione di ruby tramite rbenv

In ansible non ci sono moduli per lavorare con rbenv, e viene installato clonando un repository git. Quindi, questo compito diventa piuttosto atipico. Creeremo un ruolo per esso /ansible/roles/ruby_rbenv/main.yml e inizieremo a compilarlo:

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

Utilizziamo di nuovo la direttiva become_user per lavorare sotto l'utente che abbiamo creato per questo scopo. Poiché rbenv viene installato nella sua directory home e non globalmente. Utilizziamo anche il modulo git per clonare il repository, specificando repo e dest.

Successivamente dobbiamo aggiungere rbenv init nel bashrc e aggiungere rbenv nel PATH. Per questo abbiamo il modulo lineinfile:

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

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

Dopo di che, dobbiamo installare ruby_build:

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

E, infine, installare ruby. Questo viene fatto tramite rbenv, quindi semplicemente con un comando bash:

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

Indichiamo quale comando eseguire e con quale metodo. Tuttavia, qui ci imbatteremo nel fatto che ansible non esegue il codice contenuto in bashrc prima di eseguire i comandi. Pertanto, rbenv dovrà essere definito direttamente in questo stesso script.

Il problema successivo è che il comando shell non ha uno stato dal punto di vista di ansible. Non ci sarà una verifica automatica per vedere se questa versione di ruby è stata installata o meno. Possiamo farlo noi stessi:

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

E rimane da installare bundler:

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

E anche aggiungere il nostro ruolo ruby_rbenv al playbook principale.

File condivisi.

In generale, a questo punto si potrebbe concludere la configurazione. Rimane da avviare capistrano e copierà automaticamente il codice, creerà le directory necessarie e avvierà l'applicazione (se tutto è configurato correttamente). Tuttavia, spesso capistrano ha bisogno di file di configurazione aggiuntivi, come database.yml o .env Possono essere copiati esattamente come file e modelli per nginx. C'è solo una piccola particolarità. Prima di copiare i file, è necessario creare una struttura di directory per essi, qualcosa di simile a questo:

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

indichiamo solo una directory e ansible creerà automaticamente le directory superiori, se necessario.

Ansible Vault

Ci siamo già imbattuti nel fatto che nelle variabili possono trovarsi dati riservati come la password dell'utente. Se hai creato .env un file per l'applicazione, e database.yml quindi ci devono essere ancora più dati critici. Sarebbe opportuno nasconderli agli sguardi indiscreti. A tal fine si utilizza ansible vault.

Creeremo un file per le variabili /ansible/vars/all.yml (qui puoi creare diversi file per diversi gruppi di host, esattamente come nel file inventory: production.yml, staging.yml, ecc.).
In questo file è necessario trasferire tutte le variabili che devono essere criptate, 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

Dopo di che, questo file può essere criptato con il comando:

ansible-vault encrypt ./vars/all.yml

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

Utilizzando ansible-vault decrypt il file può essere decritto, modificato e poi criptato di nuovo.

Per lavorare, non è necessario decriptare il file. Lo conservi in forma criptata e avvii il playbook con l'argomento --ask-vault-pass. Ansible chiederà la password, recupererà le variabili e eseguirà i compiti. Tutti i dati rimarranno criptati.

L'intera comando per diversi gruppi di host e ansible vault apparirà approssimativamente in questo modo:

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

E non ti darò il testo completo dei playbook e dei ruoli, scrivili da solo. Perché ansible è così: se non capisci cosa devi fare, allora non lo farà nemmeno lui.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster