För inte sÄ lÀnge sedan behövde jag skriva flera Ansible-playbooks för att förbereda en server för utplacering av en Rails-applikation. Och, till min förvÄning, hittade jag ingen enkel steg-för-steg-manual. Jag ville inte bara kopiera nÄgon annans playbook utan att förstÄ vad som försiggick, och slutligen var jag tvungen att lÀsa dokumentationen och samla allt sjÀlv. Kanske kan jag hjÀlpa nÄgon att pÄskynda denna process med hjÀlp av denna artikel.
Först och frÀmst Àr det viktigt att förstÄ att Ansible ger dig ett bekvÀmt grÀnssnitt för att utföra en förutbestÀmd lista av ÄtgÀrder pÄ en avlÀgsen server (eller flera) via SSH. HÀr finns ingen magi; du kan inte bara installera ett plugin och fÄ en zero-downtime-deploy av din applikation med Docker, övervakning och andra godbitar direkt. För att skriva en playbook mÄste du veta exakt vad du vill göra och hur du ska göra det. DÀrför Àr jag inte nöjd med fÀrdiga playbooks frÄn GitHub, eller artiklar i stil med: "Kopiera och kör, det fungerar."
Vad behöver vi?
Som jag redan nĂ€mnt, för att skriva en playbook mĂ„ste du veta vad du vill göra och hur. LĂ„t oss faststĂ€lla vad vi behöver. För en Rails-applikation kommer vi att behöva nĂ„gra systempaket: nginx, postgresql (redis, osv.). Utöver detta behöver vi en specifik version av Ruby. Det Ă€r bĂ€st att installera det via rbenv (rvm, asdfâŠ). Att köra allt som root-anvĂ€ndare Ă€r alltid en dĂ„lig idĂ©, sĂ„ vi mĂ„ste skapa en separat anvĂ€ndare och stĂ€lla in rĂ€ttigheter för den. Efter det Ă€r det nödvĂ€ndigt att ladda upp vĂ„r kod till servern, kopiera konfigurationerna för nginx, postgres, osv. och starta alla dessa tjĂ€nster.
Till slut Àr sekvensen av ÄtgÀrder följande:
- Logga in som root
- installera systempaketen
- skapa en ny anvÀndare, sÀtta upp rÀttigheter och SSH-nyckel
- konfigurera systempaketen (nginx, osv.) och starta dem
- Skapa en anvÀndare i databasen (eventuellt skapa databasen samtidigt)
- Logga in som den nya anvÀndaren
- Installera rbenv och Ruby
- Installera Bundler
- Ladda upp applikationskoden
- Starta Puma-servern
Dessutom kan de sista stegen utföras med hjÀlp av Capistrano; Ätminstone kan den helt enkelt kopiera koden till releasekatalogerna, vÀxla release via symlink vid en lyckad utplacering, kopiera konfigurationer frÄn en delad katalog, starta om Puma, osv. Allt detta kan göras med Ansible, men varför?
Filstruktur
Ansible har en strikt för alla sina filer, sÄ det Àr bÀst att hÄlla allt i en separat katalog. Det spelar inte sÄ stor roll om den ligger i rails-applikationen eller separat. Man kan lagra filer i ett separat git-repo. Personligen tycker jag att det Àr mest praktiskt att skapa en katalog ansible i /config-katalogen av rails-applikationen och lagra allt i en och samma repo.
Enkel Playbook
En playbook Àr en yml-fil som med hjÀlp av ett specialsyntax beskriver vad och hur Ansible ska göra. LÄt oss skapa vÄr första playbook som inte gör nÄgot:
---
- name: Enkel playbook
hosts: allHÀr sÀger vi helt enkelt att vÄr playbook kallas Enkel Playbook och att dess innehÄll ska köras för alla vÀrdar. Vi kan spara den i /ansible-katalogen med namnet playbook.yml och försöka köra:
ansible-playbook ./playbook.yml
PLAY [Enkel Playbook] ************************************************************************************************************************************
skipping: no hosts matchedAnsible sÀger att den inte kÀnner till nÄgra vÀrdar som motsvarar listan all. De mÄste upprÀttas i en sÀrskild .
LÄt oss skapa den i samma ansible-katalog:
123.123.123.123SÄ hÀr skriver vi bara in vÀrden (idealiskt VPS-vÀrden för tester, eller sÄ kan man ange localhost) och sparar den med namnet inventory.
Vi kan prova att köra Ansible med inventory-filen:
ansible-playbook ./playbook.yml -i inventory
PLAY [Enkel Playbook] ************************************************************************************************************************************
TASK [Gathering Facts] ************************************************************************************************************************************
PLAY RECAP ************************************************************************************************************************************Om du har ssh-Ätkomst till den angivna vÀrden kommer Ansible att ansluta och samla information om det fjÀrrsystemet. (standard TASK [Gathering Facts]) varefter den ger en kort rapport om körningen (PLAY RECAP).
Som standard anvÀnds det anvÀndarnamn du Àr inloggad med i systemet för att ansluta. Det kommer troligtvis inte att finnas pÄ vÀrden. I playbook-filen kan du specificera vilket anvÀndarnamn som ska anvÀndas för anslutning med hjÀlp av direktivet remote_user. SÄdan information om det fjÀrrsystemet kan ofta vara onödig och man bör inte slösa tid pÄ att samla den. Den uppgiften kan ocksÄ stÀngas av:
---
- name: Enkel playbook
hosts: all
remote_user: root
become: true
gather_facts: noFörsök att köra playbook igen och se till att anslutningen fungerar. (Om du angav root-anvĂ€ndaren mĂ„ste du ocksĂ„ ange direktivet become: true för att fĂ„ förhöjda rĂ€ttigheter. Som anges i dokumentationen: become instĂ€llt pĂ„ âtrueâ/âyesâ för att aktivera privilegierad eskalering. Ă€ven om det inte Ă€r helt klart varför).
Du kan fÄ ett fel orsakat av att ansible inte kan bestÀmma python-tolk, dÄ kan du ange den manuellt:
ansible_python_interpreter: /usr/bin/python3 dÀr python ligger kan du ta reda pÄ med kommandot whereis python.
Installation av systempaket
Den standardinstallation som Ansible innehÄller mÄnga moduler för att arbeta med olika systempaket, vilket gör att vi inte behöver skriva bash-skript för varje Àrende. Nu behöver vi en av dessa moduler för att uppdatera systemet och installera systempaket. Jag har Ubuntu Linux pÄ min VPS, sÄ för att installera paket anvÀnder jag apt-get och . Om du anvÀnder ett annat operativsystem kan det hÀnda att en annan modul behövs (kom ihÄg att jag i början sa att man bör veta vad och hur vi ska göra). Syntaxen kommer förmodligen att vara liknande.
Vi kompletterar vÄr playbook med de första uppgifterna:
---
- name: Enkel playbook
hosts: all
remote_user: root
become: true
gather_facts: no
tasks:
- name: Uppdatera system
apt: update_cache=yes
- name: Installera systemberoenden
apt:
name: git,nginx,redis,postgresql,postgresql-contrib
state: presentTask â det Ă€r just den uppgift som ansible kommer att utföra pĂ„ de fjĂ€rrservrar. Vi ger uppgiften ett namn för att kunna följa dess utförande i loggen. Och beskriver med hjĂ€lp av syntaxen för den specifika modulen vad den behöver göra. I det hĂ€r fallet apt: update_cache=yes â sĂ€ger att systempaketen ska uppdateras med hjĂ€lp av modulen apt. Den andra kommandot Ă€r nĂ„got mer komplicerat. Vi skickar en lista med paket till modulen apt, och sĂ€ger att deras state ska bli present, vilket betyder att vi ber att installera dessa paket. PĂ„ liknande sĂ€tt kan vi be dem att ta bort eller uppdatera, helt enkelt genom att byta state. Observera att vi behöver paketet postgresql-contrib för att fĂ„ rails att fungera med postgresql, vilket vi nu installerar. Det hĂ€r behöver man ocksĂ„ veta och göra, ansible gör inte detta sjĂ€lv.
Försök att köra playbook igen och kontrollera att paketen installeras.
Skapar nya anvÀndare.
För att arbeta med anvÀndare har Ansible ocksÄ en modul - user. Vi lÀgger till Ànnu en task (jag har döljt vÀlkÀnda delar av playbooken med kommentarer för att inte kopiera den helt varje gÄng):
---
- name: Enkel playbook
# ...
tasks:
# ...
- name: LÀgg till en ny anvÀndare
user:
name: my_user
shell: /bin/bash
password: "{{ 123qweasd | password_hash('sha512') }}"Vi skapar en ny anvÀndare, stÀller in en schell och ett lösenord. Och vi stöter genast pÄ flera problem. Vad hÀnder om anvÀndarnamnen mÄste vara olika för olika vÀrdar? Att lagra lösenord i klartext i playbooken Àr verkligen en dÄlig idé. Först flyttar vi anvÀndarnamnet och lösenordet till variabler, och lÀngre fram i artikeln visar jag hur man krypterar lösenordet.
---
- name: Enkel playbook
# ...
tasks:
# ...
- name: LÀgg till en ny anvÀndare
user:
name: "{{ user }}"
shell: /bin/bash
password: "{{ user_password | password_hash('sha512') }}"Genom att anvÀnda dubbla klammerparenteser i playbooks sÀtts variabler.
VariabelvÀrdena anger vi i inventory-filen:
123.123.123.123
[all:vars]
user=my_user
user_password=123qweasdObservera direktivet [all:vars] â det indikerar att den följande textblocken Ă€r variabler (vars) och de gĂ€ller för alla vĂ€rdar (all).
Det Àr ocksÄ intressant konstruktion "{{ user_password | password_hash('sha512') }}". Det handlar om att ansible inte skapar anvÀndaren via user_add som du skulle göra manuellt. Utan lagrar all information direkt, vilket innebÀr att vi ocksÄ mÄste förvandla lösenordet till en hash i förvÀg, vilket denna kommandon gör.
LÄt oss lÀgga till vÄr anvÀndare i sudo-gruppen. Men först mÄste vi se till att en sÄdan grupp finns, för ingen annan kommer att göra detta Ät oss:
---
- name: Enkel playbook
# ...
tasks:
# ...
- name: SÀkerstÀll en 'sudo' grupp
group:
name: sudo
state: present
- name: LÀgg till en ny anvÀndare
user:
name: "{{ user }}"
shell: /bin/bash
password: "{{ user_password | password_hash('sha512') }}"
groups: "sudo"Allt Àr ganska enkelt, vi har ocksÄ en modul group för att skapa grupper, med en syntax som liknar apt. Efter det rÀcker det att ange denna grupp för anvÀndaren (groups: "sudo").
Det Àr ocksÄ bra att lÀgga till en ssh-nyckel för denna anvÀndare sÄ att vi kan logga in under denna anvÀndare utan lösenord:
---
- name: Enkel playbook
# ...
tasks:
# ...
- name: SÀkerstÀll 'sudo'-grupp
group:
name: sudo
state: present
- name: LÀgg till en ny anvÀndare
user:
name: "{{ user }}"
shell: /bin/bash
password: "{{ user_password | password_hash('sha512') }}"
groups: "sudo"
- name: Distribuera SSH-nyckel
authorized_key:
user: "{{ user }}"
key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
state: presentI det hĂ€r fallet Ă€r konstruktionen intressant "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" â den kopierar innehĂ„llet i filen id_rsa.pub (du kanske har ett annat namn), det vill sĂ€ga den offentliga delen av SSH-nyckeln och laddar upp den till listan över auktoriserade nycklar för anvĂ€ndaren pĂ„ servern.
Roller
Alla tre uppgifterna för att skapa anvÀndare kan lÀtt relateras till en grupp av uppgifter, och det skulle vara bra att lagra denna grupp separat frÄn huvudplaybooken, sÄ att den inte vÀxer för mycket. För detta finns det i Ansible .
Enligt den filstruktur som angavs i början, mÄste roller placeras i en separat katalog som heter roles, varje roll fÄr en egen katalog med ett liknande namn, inuti katalogen tasks, files, templates, etc.
LĂ„t oss skapa filstrukturen: ./ansible/roles/user/tasks/main.yml (main â detta Ă€r huvudfilen som kommer att laddas och köras nĂ€r rollen ansluts till playbooken, i den kan man ansluta andra roller). Nu kan vi flytta över alla uppgifter relaterade till anvĂ€ndare till den hĂ€r filen:
# 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: presentI den huvudsakliga playbooken mÄste vi ange att rollen user ska anvÀndas:
---
- name: Enkel playbook
hosts: all
remote_user: root
gather_facts: no
tasks:
- name: Uppdatera systemet
apt: update_cache=yes
- name: Installera systemberoenden
apt:
name: git,nginx,redis,postgresql,postgresql-contrib
state: present
roles:
- userDet kan ocksÄ vara meningsfullt att utföra systemuppdateringar tidigare Àn de andra uppgifterna, för detta kan blocket som de Àr definierade i döpas om till tasks Nginx bör redan vara installerat, vi mÄste konfigurera det och starta det. LÄt oss göra detta direkt i rollen. Vi skapar filstrukturen: pre_tasks.
Konfiguration av nginx
- ansible - roles - nginx - files - tasks - main.yml - templates
Nu behöver vi filer och mallar. Skillnaden mellan dem Àr att Ansible kopierar filer direkt, som de Àr. Mallar mÄste ha filÀndelsen j2 och kan anvÀnda vÀrdena av variabler med hjÀlp av samma dubbla klamrar.LÄt oss inkludera nginx i
main.yml filen. För detta har vi systemd-modulen: HÀr sÀger vi inte bara att nginx ska startas (dvs vi startar det), utan vi sÀger ocksÄ att det ska aktiveras.
# Copy nginx configs and start it
- name: enable service nginx and start
systemd:
name: nginx
state: started
enabled: yesSÄ hÀr anger vi att nginx ska startas (det vill sÀga vi kör det) och att det ocksÄ ska aktiveras.
Nu kopierar vi konfigurationsfilerna:
# 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'Vi skapar huvudkonfigurationsfilen för nginx (den kan tas direkt frÄn servern eller skrivas av oss sjÀlva). Och Àven konfigurationsfilen för vÄr applikation i katalogen sites_available (detta Àr inte nödvÀndigt men anvÀndbart). I det första fallet anvÀnder vi modulen copy för att kopiera filer (filen mÄste ligga i /ansible/roles/nginx/files/nginx.conf). I det andra fallet kopierar vi en mall, dÀr vi sÀtter in variabelvÀrden. Mallen mÄste ligga i /ansible/roles/nginx/templates/my_app.j2). Den kan se ut ungefÀr sÄ hÀr:
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 }};
....
}Observera insĂ€ttningarna {{ app_name }}, {{ app_path }}, {{ server_name }}, {{ inventory_hostname }} â dessa Ă€r alla variabler vars vĂ€rden ansible kommer att sĂ€tta in i mallen innan kopiering. Detta Ă€r anvĂ€ndbart om du anvĂ€nder en spelbok för olika grupper av vĂ€rdar. Till exempel kan vi komplettera vĂ„r inventory-fil:
[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_appOm vi nu kör vĂ„r spelbok, kommer den att utföra angivna uppgifter för bĂ„da vĂ€rdarna. Men för staging-vĂ€rden kommer variablerna att skilja sig frĂ„n produktion, och inte bara i roller och spelböcker, utan Ă€ven i nginx-konfigurationerna. {{ inventory_hostname }} det behöver inte anges i inventory-filen â detta Ă€r och dĂ€r lagras vĂ€rden för den vĂ€rd som spelboken för nĂ€rvarande körs mot.
Om du vill ha en inventory-fil för flera vÀrdar, men bara köra för en grupp, kan du göra detta med följande kommando:
ansible-playbook -i inventory .\/playbook.yml -l "staging"ett annat alternativ â ha separata inventory-filer för olika grupper. Eller sĂ„ kan du kombinera de tvĂ„ metoderna om du har mĂ„nga olika vĂ€rdar.
LÄt oss ÄtergÄ till nginx-instÀllningarna. Efter att ha kopierat konfigurationsfilerna mÄste vi skapa en symbolisk lÀnk i sites_enabled till my_app.conf frÄn sites_available. Och starta om nginx.
... # gammal kod i mail.yml
- name: Skapa symbolisk lÀnk till sites-enabled
file:
src: \/etc\/nginx\/sites-available\/my_app.conf
dest: \/etc\/nginx\/sites-enabled\/my_app.conf
state: link
- name: starta om nginx
service:
name: nginx
state: restartedHĂ€r Ă€r det enkelt â igen anvĂ€nds ansible-moduler med en ganska standardiserad syntax. Men det finns en punkt att tĂ€nka pĂ„. Det Ă€r meningslöst att starta om nginx varje gĂ„ng. Har du noterat att vi inte skriver kommandon av typen: "gör detta sĂ„ hĂ€r", syntaxen ser snarare ut som "detta ska ha ett sĂ„dant tillstĂ„nd". Och oftast Ă€r det just sĂ„ ansible fungerar. Om gruppen redan finns, eller systempaketet redan Ă€r installerat, sĂ„ kontrollerar ansible detta och hoppar över uppgiften. Filer kommer inte att kopieras om de Ă€r helt identiska med dem som redan finns pĂ„ servern. Vi kan utnyttja detta och starta om nginx endast om konfigurationsfilerna har Ă€ndrats. För detta finns direktivet 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.changedOm en av konfigurationsfilerna Àndras, kommer kopiering att utföras och en variabel registreras restart_nginx. Och endast om den hÀr variabeln har registrerats, kommer tjÀnsten att startas om.
Och sÄ klart, vi mÄste lÀgga till rollen nginx i huvudplaybooken.
Konfiguration av postgresql
Vi behöver aktivera postgresql med hjÀlp av systemd pÄ samma sÀtt som vi gjorde med nginx, och ocksÄ skapa en anvÀndare som vi kommer att anvÀnda för att komma Ät databasen och sjÀlva databasen.
LÄt oss skapa en roll /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 }}"Jag kommer inte att beskriva hur man lÀgger till variabler i inventory, det har redan gjorts mÄnga gÄnger, likasÄ syntaxen för modulerna postgresql_db och postgresql_user. Mer information kan hittas i dokumentationen. HÀr Àr direktivet av mest intresse become_user: postgres. Faktum Àr att som standard har endast anvÀndaren postgres Ätkomst till postgresql-databasen och endast lokalt. Detta direktiv lÄter oss köra kommandon i egenskap av denna anvÀndare (om vi sÄ klart har Ätkomst).
Det kan ocksÄ hÀnda att du mÄste lÀgga till en rad i pg_hba.conf för att öppna tillgÄngen för den nya anvÀndaren till databasen. Detta kan göras pÄ samma sÀtt som vi Àndrade nginx-konfigurationsfilen.
Och sjÀlvklart mÄste vi lÀgga till rollen postgresql i huvudplaybooken.
Installation av ruby via rbenv
Det finns inga ansible-moduler för att arbeta med rbenv, och det installeras genom att klona ett git-repository. DÀrför blir denna uppgift den mest otraditionella. LÄt oss skapa en roll för den /ansible/roles/ruby_rbenv/main.yml och börja fylla den med innehÄll:
# Install rbenv and ruby
- name: Install rbenv
become_user: "{{ user }}"
git: repo=https://github.com/rbenv/rbenv.git dest=~/.rbenvVi anvÀnder Äterigen direktivet become_user för att arbeta under den anvÀndare som vi har skapat för detta ÀndamÄl. Eftersom rbenv installeras i den anvÀndarens hemkatalog och inte globalt. Vi anvÀnder ocksÄ git-modulen för att klona förvaret genom att ange repo och dest.
DÀrefter mÄste vi ange rbenv init i bashrc och Àven lÀgga till rbenv i PATH. För detta har vi modulen lineinfile:
- name: LĂ€gg till rbenv i PATH
become_user: "{{ user }}"
lineinfile:
path: ~\/.ashrc
state: present
line: 'export PATH="${HOME}\/.
benv\/bin:${PATH}"'
- name: LĂ€gg till rbenv init i bashrc
become_user: "{{ user }}"
lineinfile:
path: ~\/.ashrc
state: present
line: 'eval "$(rbenv init -)"'Efter det mÄste vi installera ruby_build:
- name: Installera ruby-build
become_user: "{{ user }}"
git: repo=https:\/\/github.com\/rbenv\/ruby-build.git dest=~\/.
benv\/plugins\/ruby-buildOch slutligen installera ruby. Detta görs via rbenv, alltsÄ med ett enkelt bash-kommando:
- name: Installera ruby
become_user: "{{ user }}"
shell: |
export PATH="${HOME}\/.
benv\/bin:${PATH}"
eval "$(rbenv init -)"
rbenv install {{ ruby_version }}
args:
executable: \/bin\/bashVi anger vilken kommando som ska köras och hur. Men hÀr stöter vi pÄ att ansible inte kör koden som finns i bashrc innan kommandona körs. Det betyder att rbenv mÄste definieras direkt i detta skript.
NĂ€sta problem Ă€r att shell-kommandot inte har nĂ„got tillstĂ„nd ur ansibles perspektiv. Det finns ingen automatisk kontroll av om denna version av ruby Ă€r installerad eller inte â detta mĂ„ste vi göra sjĂ€lva:
- name: Installera ruby
become_user: "{{ user }}"
shell: |
export PATH="${HOME}\/.
benv\/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\/bashOch vi mÄste installera bundler:
- name: Installera bundler
become_user: "{{ user }}"
shell: |
export PATH="${HOME}\/.
benv\/bin:${PATH}"
eval "$(rbenv init -)"
gem install bundlerOch Äterigen lÀgga till vÄr roll ruby_rbenv i huvudplaybooken.
Dela filer.
Sammanfattningsvis skulle instÀllningen kunna avslutas hÀr. NÀsta steg Àr att köra capistrano och det kommer automatiskt att kopiera koden, skapa nödvÀndiga kataloger och starta applikationen (om allt Àr korrekt konfigurerat). Men ofta behöver capistrano ytterligare konfigurationsfiler, sÄsom database.yml eller .env Dessa kan kopieras precis som filer och mallar för nginx. Det finns bara en liten detalj. Innan vi kopierar filerna mÄste vi skapa katalogstrukturen för dem, nÄgot i stil med detta:
# Copy shared files for deploy
- name: Ensure shared dir
become_user: "{{ user }}"
file:
path: "{{ app_path }}/shared/config"
state: directoryVi anger bara en katalog och ansible skapar automatiskt förÀldrakatalogerna om det behövs.
Ansible Vault
Vi har redan stött pÄ att det kan finnas kÀnsliga uppgifter som anvÀndarlösenord i variabler. Om du har skapat .env en fil för applikationen, och database.yml sÄ bör det finnas Ànnu fler sÄdana kritiska uppgifter dÀr. Dessa bör du hÄlla gömda för obehöriga. För detta anvÀnds .
LÄt oss skapa en fil för variabler /ansible/vars/all.yml (hÀr kan du skapa olika filer för olika grupper av vÀrdar, precis som i inventory-filen: production.yml, staging.yml, osv.).
I denna fil mÄste du överföra alla variabler som ska krypteras, med hjÀlp av standard yml-syntax:
# 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_baseDĂ€refter kan du kryptera denna fil med kommandot:
ansible-vault encrypt .\/vars\/all.ymlNaturligtvis mÄste du ange ett lösenord för dekryptering vid kryptering. Du kan se vad som kommer att finnas i filen efter att ha kört detta kommando.
Med hjÀlp av ansible-vault decrypt filen kan dekrypteras, Àndras och sedan krypteras igen.
För att arbeta behöver du inte dekryptera filen. Du lagrar den i krypterad form och kör playbook med argumentet --ask-vault-pass. Ansible kommer att frÄga efter lösenordet, hÀmta variablerna och utföra uppgifterna. All data förblir krypterad.
Den fullstÀndiga kommandot för flera grupper av vÀrdar och ansible vault kommer att se ut ungefÀr sÄ hÀr:
ansible-playbook -i inventory .\/playbook.yml -l "staging" --ask-vault-passOch jag kommer inte att ge dig hela texten av playbooks och roller, skriv sjÀlv. För ansible Àr sÄ, om du inte förstÄr vad som behöver göras, sÄ kommer det inte att göra det.
KĂ€lla: habr.com
