Palvelimen määrittäminen Rails-sovelluksen käyttöönottoa varten Ansiblen avulla

Ei kauan sitten minun piti kirjoittaa useita Ansible playbookeja valmistellakseni palvelimen Rails-sovelluksen käyttöönottoa varten. Ja yllättävää kyllä, en löytänyt yksinkertaista vaiheittaista ohjetta. En halunnut kopioida jonkun muun leikkikirjaa ymmärtämättä mitä tapahtui, ja lopulta minun piti lukea dokumentaatio ja kerätä kaikki itse. Ehkä voin auttaa jotakuta nopeuttamaan tätä prosessia tämän artikkelin avulla.

Ensimmäinen asia, joka on ymmärrettävä, on, että ansible tarjoaa sinulle kätevän käyttöliittymän, jolla voit suorittaa ennalta määritetyn luettelon toiminnoista etäpalvelimissa SSH:n kautta. Tässä ei ole mitään taikuutta, et voi asentaa laajennusta ja saada sovelluksesi käyttöön ilman seisokkeja telakointiaseman, valvonnan ja muiden herkkujen avulla. Pelikirjan kirjoittamiseksi sinun on tiedettävä, mitä tarkalleen haluat tehdä ja miten se tehdään. Siksi en ole tyytyväinen GitHubin valmiisiin pelikirjoihin tai artikkeleihin, kuten "Kopioi ja suorita, se toimii."

Mitä me tarvitsemme?

Kuten jo sanoin, pelikirjan kirjoittamiseksi sinun on tiedettävä, mitä haluat tehdä ja miten se tehdään. Päätetään mitä tarvitsemme. Rails-sovellusta varten tarvitsemme useita järjestelmäpaketteja: nginx, postgresql (redis jne.). Lisäksi tarvitsemme tietyn version rubiinista. On parasta asentaa se rbenv:n kautta (rvm, asdf...). Kaiken tämän suorittaminen pääkäyttäjänä on aina huono idea, joten sinun on luotava erillinen käyttäjä ja määritettävä hänen oikeudet. Tämän jälkeen sinun on ladattava koodimme palvelimelle, kopioitava nginx:n, postgresin jne. asetukset ja käynnistettävä kaikki nämä palvelut.

Tämän seurauksena toimintojen järjestys on seuraava:

  1. Kirjaudu sisään root-käyttäjänä
  2. asentaa järjestelmäpaketit
  3. luo uusi käyttäjä, määritä oikeudet, ssh-avain
  4. määritä järjestelmäpaketit (nginx jne.) ja suorita ne
  5. Luomme käyttäjän tietokantaan (voit luoda tietokannan heti)
  6. Kirjaudu sisään uutena käyttäjänä
  7. Asenna rbenv ja ruby
  8. Bundlerin asennus
  9. Sovelluskoodin lataaminen
  10. Puma-palvelimen käynnistäminen

Lisäksi viimeiset vaiheet voidaan tehdä capistranolla, ainakin valmiina se voi kopioida koodia julkaisuhakemistoihin, vaihtaa julkaisua symlinkillä onnistuneen käyttöönoton yhteydessä, kopioida konfiguraatioita jaetusta hakemistosta, käynnistää puman uudelleen jne. Kaikki tämä voidaan tehdä Ansiblella, mutta miksi?

Tiedoston rakenne

Ansiblella on tiukka tiedostorakenne kaikille tiedostoille, joten on parasta säilyttää ne kaikki erillisessä hakemistossa. Lisäksi ei ole niin tärkeää, onko se itse kiskosovelluksessa vai erikseen. Voit tallentaa tiedostoja erilliseen git-arkistoon. Henkilökohtaisesti minusta oli kätevintä luoda mahdollinen hakemisto rails-sovelluksen /config-hakemistoon ja tallentaa kaikki yhteen arkistoon.

Yksinkertainen pelikirja

Playbook on yml-tiedosto, joka erityisellä syntaksilla kuvaa mitä Ansiblen tulee tehdä ja miten. Luodaan ensimmäinen pelikirja, joka ei tee mitään:

---
- name: Simple playbook
  hosts: all

Tässä sanomme yksinkertaisesti, että pelikirjamme on ns Simple Playbook ja että sen sisältö tulee suorittaa kaikille isännille. Voimme tallentaa sen /ansible-hakemistoon nimellä playbook.yml ja yritä juosta:

ansible-playbook ./playbook.yml

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

Ansible sanoo, ettei se tiedä yhtään isäntiä, joka vastaa kaikkien luetteloa. Ne on lueteltava erikoisluettelossa inventaariotiedosto.

Luodaan se samaan mahdolliseen hakemistoon:

123.123.123.123

Näin määritämme isäntäkoneen (mieluiten VPS:n isäntä testausta varten tai voit rekisteröidä localhost) ja tallennamme sen nimellä inventory.
Voit yrittää suorittaa ansiblen luettelotiedostolla:

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

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

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

Jos sinulla on ssh-käyttöoikeus määritettyyn isäntään, ansible muodostaa yhteyden ja kerää tietoja etäjärjestelmästä. (oletus TASK [Facts]), jonka jälkeen se antaa lyhyen raportin suorituksesta (PLAY RECAP).

Oletusarvoisesti yhteys käyttää käyttäjätunnusta, jolla olet kirjautunut järjestelmään. Se ei todennäköisesti ole isännässä. Pelikirjatiedostossa voit määrittää, ketä käyttäjää käytetään yhteyden muodostamiseen remote_user-ohjeen avulla. Lisäksi etäjärjestelmää koskevat tiedot voivat usein olla sinulle tarpeettomia, eikä niiden keräämiseen tule tuhlata aikaa. Tämä tehtävä voidaan myös poistaa käytöstä:

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

Yritä suorittaa pelikirja uudelleen ja varmista, että yhteys toimii. (Jos määritit pääkäyttäjän, sinun on myös määritettävä muuttuja: true -direktiivi saadaksesi korotetut oikeudet. Kuten dokumentaatiossa kirjoitetaan: become set to ‘true’/’yes’ to activate privilege escalation. vaikka ei ole täysin selvää miksi).

Ehkä saat virheen, joka johtuu siitä, että ansible ei voi määrittää Python-tulkkia, voit määrittää sen manuaalisesti:

ansible_python_interpreter: /usr/bin/python3 

Voit selvittää, missä sinulla on python komennolla whereis python.

Järjestelmäpakettien asennus

Ansiblen vakiojakelu sisältää monia moduuleja erilaisten järjestelmäpakettien kanssa työskentelemiseen, joten meidän ei tarvitse kirjoittaa bash-skriptejä mistään syystä. Tarvitsemme nyt yhden näistä moduuleista järjestelmän päivittämiseen ja järjestelmäpakettien asentamiseen. VPS:ssäni on Ubuntu Linux, joten käytän pakettien asentamiseen apt-get и moduuli sitä varten. Jos käytät eri käyttöjärjestelmää, saatat tarvita eri moduulin (muista, sanoin alussa, että meidän on tiedettävä etukäteen mitä ja miten teemme). Syntaksi on kuitenkin todennäköisesti samanlainen.

Täydennetään pelikirjaamme ensimmäisillä tehtävillä:

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

Tehtävä on juuri se tehtävä, jonka Ansible suorittaa etäpalvelimilla. Annamme tehtävälle nimen, jotta voimme seurata sen suorittamista lokissa. Ja kuvailemme tietyn moduulin syntaksia käyttäen, mitä sen on tehtävä. Tässä tapauksessa apt: update_cache=yes - käskee päivittää järjestelmäpaketit apt-moduulilla. Toinen komento on hieman monimutkaisempi. Välitämme luettelon paketeista apt-moduulille ja sanomme, että ne ovat state pitäisi tulla present, eli sanomme, että asenna nämä paketit. Samalla tavalla voimme kehottaa heitä poistamaan ne tai päivittämään ne yksinkertaisesti muuttamalla state. Huomaa, että kiskojen toimimiseksi postgresql:n kanssa tarvitsemme postgresql-contrib-paketin, jota asennamme nyt. Jälleen, sinun on tiedettävä ja tehtävä tämä; ansible yksinään ei tee tätä.

Yritä suorittaa pelikirja uudelleen ja tarkista, että paketit on asennettu.

Uusien käyttäjien luominen.

Käyttäjien kanssa työskentelyä varten Ansiblessa on myös moduuli - käyttäjä. Lisätään vielä yksi tehtävä (piilotin pelikirjan jo tunnetut osat kommenttien taakse, jotta en kopioisi sitä kokonaan joka kerta):

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

Luomme uuden käyttäjän, asetamme sille shellin ja salasanan. Ja sitten törmäämme useisiin ongelmiin. Entä jos eri isäntien käyttäjänimien on oltava erilaisia? Ja salasanan tallentaminen selkeänä tekstinä pelikirjaan on erittäin huono idea. Aluksi laitetaan käyttäjätunnus ja salasana muuttujiin, ja artikkelin lopussa näytän kuinka salasana salataan.

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

Muuttujat asetetaan leikkikirjoihin kaksoiskiharasulkeilla.

Ilmoitamme muuttujien arvot inventaariotiedostoon:

123.123.123.123

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

Huomioi ohje [all:vars] - se sanoo, että seuraava tekstilohko on muuttujia (muuttujia) ja niitä voidaan soveltaa kaikkiin koneisiin (kaikki).

Suunnittelu on myös mielenkiintoinen "{{ user_password | password_hash('sha512') }}". Asia on siinä, että ansible ei asenna käyttäjää kautta user_add kuin tekisit sen manuaalisesti. Ja se tallentaa kaikki tiedot suoraan, minkä vuoksi meidän on myös muutettava salasana etukäteen hashiksi, mitä tämä komento tekee.

Lisätään käyttäjämme sudo-ryhmään. Ennen tätä meidän on kuitenkin varmistettava, että tällainen ryhmä on olemassa, koska kukaan ei tee tätä puolestamme:

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

Kaikki on melko yksinkertaista, meillä on myös ryhmämoduuli ryhmien luomiseen, jonka syntaksi on hyvin samanlainen kuin apt. Sitten riittää rekisteröidä tämä ryhmä käyttäjälle (groups: "sudo").
On myös hyödyllistä lisätä ssh-avain tälle käyttäjälle, jotta voimme kirjautua sisään sillä ilman salasanaa:

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

Tässä tapauksessa suunnittelu on mielenkiintoinen "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" — se kopioi id_rsa.pub-tiedoston sisällön (nimesi voi olla eri) eli ssh-avaimen julkisen osan ja lataa sen palvelimella olevaan käyttäjän valtuutettujen avainten luetteloon.

rooli

Kaikki kolme käytön luomisen tehtävää voidaan helposti luokitella yhdeksi tehtäväryhmäksi, ja tämä ryhmä olisi hyvä säilyttää erillään pääpelikirjasta, jotta se ei kasva liian suureksi. Tätä tarkoitusta varten Ansiblella on rooli.
Heti alussa ilmoitetun tiedostorakenteen mukaan roolit tulee sijoittaa erilliseen roolihakemistoon, jokaiselle roolille on erillinen samanniminen hakemisto tehtävät, tiedostot, mallit jne. hakemistossa
Luodaan tiedostorakenne: ./ansible/roles/user/tasks/main.yml (main on päätiedosto, joka ladataan ja suoritetaan, kun rooli liitetään pelikirjaan; muut roolitiedostot voidaan liittää siihen). Nyt voit siirtää kaikki käyttäjään liittyvät tehtävät tähän tiedostoon:

# 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

Pääpelikirjassa sinun on määritettävä käyttääksesi käyttäjäroolia:

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

Lisäksi saattaa olla järkevää päivittää järjestelmä ennen muita tehtäviä; voit tehdä tämän nimeämällä lohkon uudelleen tasks jossa ne on määritelty pre_tasks.

Asetetaan nginx

Meillä pitäisi jo olla Nginx asennettuna; meidän on määritettävä se ja suoritettava se. Tehdään se heti roolissa. Luodaan tiedostorakenne:

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

Nyt tarvitsemme tiedostoja ja malleja. Niiden välinen ero on se, että ansible kopioi tiedostot suoraan sellaisenaan. Ja malleissa on oltava j2-pääte, ja ne voivat käyttää muuttuvia arvoja samoilla kaksoiskiharoilla.

Otetaan nginx käyttöön main.yml tiedosto. Tätä varten meillä on systemd-moduuli:

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

Tässä emme vain sano, että nginx on käynnistettävä (eli käynnistämme sen), vaan sanomme heti, että se on otettava käyttöön.
Kopioidaan nyt asetustiedostot:

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

Luomme pääasiallisen nginx-määritystiedoston (voit ottaa sen suoraan palvelimelta tai kirjoittaa sen itse). Ja myös sovelluksemme asetustiedosto sites_available-hakemistossa (tämä ei ole välttämätöntä, mutta hyödyllistä). Ensimmäisessä tapauksessa käytämme kopiointimoduulia tiedostojen kopioimiseen (tiedoston on oltava sisään /ansible/roles/nginx/files/nginx.conf). Toisessa kopioimme mallin korvaamalla muuttujien arvot. Mallin pitäisi olla mukana /ansible/roles/nginx/templates/my_app.j2). Ja se voi näyttää tältä:

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

Kiinnitä huomiota lisäkkeisiin {{ app_name }}, {{ app_path }}, {{ server_name }}, {{ inventory_hostname }} — nämä ovat kaikki muuttujat, joiden arvot Ansible korvaa mallin ennen kopioimista. Tämä on hyödyllistä, jos käytät pelikirjaa eri isäntäryhmille. Voimme esimerkiksi lisätä varastotiedostomme:

[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

Jos nyt käynnistämme pelikirjan, se suorittaa määritetyt tehtävät molemmille isännille. Mutta samaan aikaan lavastusisäntälle muuttujat ovat erilaisia ​​kuin tuotantomuuttujat, eivät vain rooleissa ja pelikirjoissa, vaan myös nginx-konfiguraatioissa. {{ inventory_hostname }} ei tarvitse määritellä inventaariotiedostossa - tämä erityinen mahdollinen muuttuja ja isäntä, jolle pelikirja on parhaillaan käynnissä, on tallennettu sinne.
Jos haluat inventaariotiedoston useille koneille, mutta vain yhdelle ryhmälle, voit tehdä tämän seuraavalla komennolla:

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

Toinen vaihtoehto on erilliset varastotiedostot eri ryhmille. Tai voit yhdistää nämä kaksi lähestymistapaa, jos sinulla on useita erilaisia ​​isäntiä.

Palataan nginxin asettamiseen. Kun määritystiedostot on kopioitu, meidän on luotava symbolilinkki sitest_enabled-tiedostoon my_app.conf osoitteesta sites_available. Ja käynnistä nginx uudelleen.

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

Kaikki on täällä yksinkertaista - jälleen mahdollisia moduuleja melko tavallisella syntaksilla. Mutta on yksi pointti. Ei ole mitään järkeä käynnistää nginxiä uudelleen joka kerta. Oletko huomannut, että emme kirjoita komentoja kuten: "tee tämä näin", syntaksi näyttää enemmän kuin "tässä pitäisi olla tämä tila". Ja useimmiten juuri näin ansible toimii. Jos ryhmä on jo olemassa tai järjestelmäpaketti on jo asennettu, ansible tarkistaa tämän ja ohittaa tehtävän. Tiedostoja ei myöskään kopioida, jos ne vastaavat täysin palvelimella jo olevia tiedostoja. Voimme hyödyntää tätä ja käynnistää nginxin uudelleen vain, jos asetustiedostoja on muutettu. Tätä varten on rekisteriohje:

# 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

Jos jokin asetustiedostoista muuttuu, siitä tehdään kopio ja muuttuja rekisteröidään restart_nginx. Ja vain jos tämä muuttuja on rekisteröity, palvelu käynnistetään uudelleen.

Ja tietysti sinun on lisättävä nginx-rooli pääpelikirjaan.

Postgresql:n asetukset

Meidän on otettava käyttöön postgresql käyttämällä systemdiä samalla tavalla kuin teimme nginxillä, ja myös luotava käyttäjä, jota käytämme tietokantaan ja itse tietokantaan.
Luodaan rooli /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 }}"

En kuvaile muuttujien lisäämistä varastoon, tämä on tehty jo monta kertaa, samoin kuin postgresql_db- ja postgresql_user-moduulien syntaksi. Lisätietoja löytyy dokumentaatiosta. Mielenkiintoisin ohje tässä on become_user: postgres. Tosiasia on, että oletusarvoisesti vain postgres-käyttäjällä on pääsy postgresql-tietokantaan ja vain paikallisesti. Tämä ohje antaa meille mahdollisuuden suorittaa komentoja tämän käyttäjän puolesta (jos meillä on pääsy, tietysti).
Saatat myös joutua lisäämään rivin pg_hba.conf-tiedostoon, jotta uusi käyttäjä pääsee käyttämään tietokantaa. Tämä voidaan tehdä samalla tavalla kuin muutimme nginx-asetusta.

Ja tietysti sinun on lisättävä postgresql-rooli pääpelikirjaan.

Rubyn asennus rbenv:n kautta

Ansiblella ei ole moduuleja rbenv:n kanssa työskentelemiseen, mutta se asennetaan kloonaamalla git-arkisto. Siksi tästä ongelmasta tulee kaikkein epätyypillisin. Luodaan hänelle rooli /ansible/roles/ruby_rbenv/main.yml ja aloitetaan sen täyttäminen:

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

Käytämme jälleen come_user-direktiiviä toimimaan tähän tarkoitukseen luomamme käyttäjän alaisuudessa. Koska rbenv on asennettu sen kotihakemistoon, ei maailmanlaajuisesti. Ja käytämme myös git-moduulia arkiston kloonaamiseen määrittämällä repo ja kohde.

Seuraavaksi meidän on rekisteröitävä rbenv init bashrc:iin ja lisättävä rbenv siellä PATH:iin. Tätä varten meillä on lineinfile-moduuli:

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

Sitten sinun on asennettava ruby_build:

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

Ja lopuksi asenna ruby. Tämä tehdään rbenv:n kautta, eli yksinkertaisesti bash-komennolla:

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

Sanomme, mikä komento suoritetaan ja millä. Tässä kohtaamme kuitenkin tosiasian, että ansible ei suorita bashrc:n sisältämää koodia ennen komentojen suorittamista. Tämä tarkoittaa, että rbenv on määritettävä suoraan samassa skriptissä.

Seuraava ongelma johtuu siitä, että shell-komennolla ei ole tilaa mahdollisesta näkökulmasta. Eli ei tehdä automaattista tarkistusta, onko tämä rubiiniversio asennettu vai ei. Voimme tehdä tämän itse:

- 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

Jäljelle jää vain bundlerin asentaminen:

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

Ja taas, lisää roolimme ruby_rbenv pääpelikirjaan.

Jaetut tiedostot.

Yleisesti ottaen asennus voidaan suorittaa täällä. Seuraavaksi jää vain suorittaa capistrano ja se kopioi itse koodin, luo tarvittavat hakemistot ja käynnistää sovelluksen (jos kaikki on määritetty oikein). Capistrano vaatii kuitenkin usein lisämääritystiedostoja, kuten database.yml tai .env Ne voidaan kopioida aivan kuten tiedostot ja mallit nginxille. Siinä on vain yksi hienovaraisuus. Ennen kuin kopioit tiedostoja, sinun on luotava niille hakemistorakenne, jotain tällaista:

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

määritämme vain yhden hakemiston ja ansible luo automaattisesti ylähakemistot tarvittaessa.

Ansible Holvi

Olemme jo törmänneet siihen, että muuttujat voivat sisältää salaisia ​​tietoja, kuten käyttäjän salasanan. Jos olet luonut .env tiedosto hakemusta varten ja database.yml niin kriittistä dataa täytyy olla vielä enemmän. Olisi hyvä piilottaa ne uteliailta katseilta. Tätä tarkoitusta varten sitä käytetään mahdollinen holvi.

Luodaan tiedosto muuttujille /ansible/vars/all.yml (tässä voit luoda erilaisia ​​tiedostoja eri isäntäryhmille, aivan kuten inventaariotiedostossa: production.yml, staging.yml jne.).
Kaikki muuttujat, jotka on salattava, on siirrettävä tähän tiedostoon tavallisella yml-syntaksilla:

# 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

Tämän jälkeen tämä tiedosto voidaan salata komennolla:

ansible-vault encrypt ./vars/all.yml

Luonnollisesti salauksen yhteydessä sinun on asetettava salasana salauksen purkamista varten. Voit nähdä, mitä tiedoston sisällä on tämän komennon kutsumisen jälkeen.

Keinoin ansible-vault decrypt tiedoston salaus voidaan purkaa, muokata ja sitten salata uudelleen.

Sinun ei tarvitse purkaa tiedoston salausta toimiaksesi. Tallennat sen salattuna ja käytät pelikirjaa argumentin kanssa --ask-vault-pass. Ansible pyytää salasanaa, hakee muuttujat ja suorittaa tehtävät. Kaikki tiedot pysyvät salattuina.

Täydellinen komento useille isäntäryhmille ja ansible Vaultille näyttää suunnilleen tältä:

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

Mutta en anna sinulle leikkikirjojen ja roolien koko tekstiä, kirjoita se itse. Koska ansible on sellainen - jos et ymmärrä, mitä on tehtävä, se ei tee sitä puolestasi.

Lähde: will.com

Lisää kommentti