Keep Calm and Install PostGreSQL
Keep Calm and Install PostGreSQL
Keep Calm and Install PostGreSQL
PostGreSQL
i ng
Us 13 Ottobre 2017
PGDay.IT
In un futuro non molto lontano ...
● Tempi:
○ setup del server (ma lo si sarebbe dovuto comunque fare)
○ setup alla creazione di un nuovo server per via di conf
specifiche (nome host, parametri di connessione, etc)
E se devo pubblicare un aggiornamento?
● di sicurezza
● di un parametro di configurazione
● aggiungere allo slave un’estensione di PgSql
https://en.wikipedia.org/wiki/DevOps
Devops 2/3
Nel software è semplice… alla fine si tratta di software che gestisce altro software
Devops 3/3
E nell’hardware?
https://en.wikipedia.org/wiki/Infrastructure_as_Code
Infrastructure as Code 2/4
● CFEngine
○ prima release nel 1993
○ gestiva solo workstation Unix
○ proprio linguaggio (DSL)
● Puppet:
○ prima release nel 2005
○ scritto in Ruby
○ configurabile con un proprio DSL
● Chef:
○ prima release nel 2009
○ scritto in Ruby ed Erlang
○ proprio DSL
● Saltstack:
○ prima release nel 2011
○ scritto in Python
Infrastructure as Code 3/4
● Ansible:
○ prima release nel 2012
○ scritto in Python
○ file di configurazione in YAML
○ agent-less
Infrastructure as Code 4/4
CHEF
Prima release 2005 2009 2011 2012
➢ No agent:
○ Non è necessario installare agenti sui server da installare
■ Usa SSH per comunicare con l’infrastruttura
➢ No master:
○ Non c’è necessità di un server dove installare il software controllore
○ Si può lanciare da qualsiasi PC che possa raggiungere l’infrastruttura
■ requisito: linux o mac
➢ No file temporanei o di configurazione su server remoti
➢ Semplice da installare ed imparare:
○ no requisiti particolari, solo
■ ssh
■ python (2.6 e 2.7, in preview 3.0)
➢ Configurazione dichiarativa via YAML:
○ si scrive cosa fare (ad esempio “installa nodejs”)
○ non come farlo
Perché scegliere Ansible? 2/2
➢ Moduli:
○ libreria con più di 1300
○ possono essere scritti in Python
○ comandi di shell
○ ansible-galaxy
➢ Sicurezza:
○ comunicazione via ssh
○ diverse metodologie di autenticazione:
■ sudo, su
■ pbrun, pfexec, doas, dzdo, ksu
○ possibilità di criptare le password (vault)
➢ Configurazione per host o gruppi di host
➢ Gestione del cambio di stato
○ ogni task riporta dopo l’esecuzione se è cambiato o meno
PostGreSQL installation… for dummies
#!/bin/sh
EOF
cat <<EOF
---
- hosts: all
become: true
tasks:
- name: add apt postgresql repo key
apt_key: url=https://www.postgresql.org/media/keys/ACCC4CF8.asc
Inventory
Ansible Framework
SSH
Playbook ansible.cfg
Module
Le componenti di Ansible - Inventory 2/4
Inventory
Host 1
Host N
Host Group 2
Playbook
...
Host Group N
Module
Le componenti di Ansible - Module 3/4
Inventory
Playbook
http://docs.ansible.com/ansible/modules_by_category.html
Le componenti di Ansible - Playbook 4/4
Variables
Pre Tasks Task 1 Name
Tasks Task 2 Module
Module Post Tasks
Task N Arguments
Roles
Esempio di playbook - file YAML 1/3
foods:
- Apple
- Orange We assign a list (an array) of 4 items
- Strawberry to “foods”
- Mango
education: |
4 GCSEs Example of multiline string
3 A-Levels
BSc in the Internet of Things
Esempio di playbook 2/3
---
- hosts: dbservers 1
vars:
postgresql_version: 9.6 2
pre_tasks:
- name: print a message 3
msg: "I’m going to install PostGreSQL {{postgresql_version}}"
tasks:
...
- name: install postgresql
apt: name="{{ item }}" state=present Play
5
with_items:
- "postgresql-{{postgresql_version}}"
- "postgresql-contrib-{{postgresql_version}}"
post_tasks:
- name: print a message 6
msg: Yeah, PostGreSQL kicking and alive :-)
roles:
- rtp 4
- locale
...qualche altra curiosità!
---
- hosts: all Necessario: per installare pacchetti dobbiamo essere root
become: true
tasks:
- name: add apt postgresql repo key
apt_key: url=https://www.postgresql.org/media/keys/ACCC4CF8.asc
2. Facts:
○ definite per host o per gruppi mediante:
■ la sezione vars nel playbook
■ il modulo set_fact
- name: Set needed PostgreSQL version
set_fact: postgresql_version="9.5"
3. Dynamic variables
○ variabili definite come esito di un task
- stat: path="/etc/foo.conf"
register: foo_config_file
Esempio di utilizzo delle variabili 1/2
Inventory
db1 ansible_host=192.168.33.10
[db1:vars]
postgresql_version=9.5
debian=wheezy
db2 ansible_host=192.168.33.11
[db2:vars]
postgresql_version=9.6
debian=jessie
[dbservers]
db1
db2
Esempio di utilizzo delle variabili 2/2
Playbook
---
- hosts: dbservers
become: true
tasks:
- name: add apt postgresql repo key
apt_key: url=https://www.postgresql.org/media/keys/ACCC4CF8.asc
➢ postgresql_db:
○ Add or remove PostgreSQL databases from a remote host
➢ postgresql_schema:
○ Add or remove PostgreSQL schema from a remote host
➢ postgresql_ext :
○ Add or remove PostgreSQL extensions from a database
➢ postgresql_lang:
○ Adds, removes or changes procedural languages with a PostgreSQL
database
➢ postgresql_user:
○ Adds or removes a users (roles) from a PostgreSQL database.
➢ postgresql_privs:
○ Grant or revoke privileges on PostgreSQL database objects.
http://docs.ansible.com/ansible/latest/list_of_database_modules.html#postgresql
Esempio di creazione di un database e utenti
---
- hosts: dbservers
vars:
pgsql_user: my_superuser
pgsql_pwd: my_supersecret_password
tasks:
- name: create "foo_user"
postgresql_user:
login_host: "{{ansible_host}}"
login_user: "{{pgsql_user}}"
login_password: "{{pgsql_pwd}}"
name: foo_user
password: foo_pwd
- hosts: slave_dbservers
tasks:
- name: configure slave server for hot standby
ini_file:
path: "/etc/postgresql/{{version}}/{{cluster}}/postgresql.conf"
option: "{{item.param}}"
value: "{{item.value}}"
section: null
with_items:
- {param: port, value: 5433}
- {param: shared_buffers, value: 10GB}
- {param: hot_standby, value: on}
register: pgsql_conf
● Argomenti principali:
○ schema: Schema where to add/drop the table
○ name: Name of the table
○ state: The table state
○ owner: Owner of the table
○ columns: List of objects with name, type and null keys
○ primary_key: List with column names composing the primary key
- postgresql_table:
database: my_app
name: config
state: present
columns:
- { name: parameter, type: text, null: False }
- { name: value, type: text, null: False }
primary_key:
- parameter
Modulo postgresql_row
● Argomenti principali:
○ schema: Schema where to add/drop the table
○ table: Name of the table
○ state: The row state
○ row: Dictionary with the fields of the row
- postgresql_row:
database: my_app
table: config
row:
parameter: environment
value: production
state:
present
Modulo postgresql_query
● Argomenti principali:
○ query: Query to execute
○ parameters: Parameters of the query as:
■ list if positional parameters are used in query
■ dictionary if named parameters are used
# query_results contains:
{
rows: [{parameter: 'environment', value: 'production'}]
rowCount: 1
executed_query: "SELECT * FROM config WHERE parameter = 'environment'"
}
Modulo postgresql_command
● Argomenti principali:
○ command: The SQL command to execute
○ parameters: Parameters of the command as:
■ list if positional parameters are used in query
■ dictionary if named parameters are used
# Change the environment of the application from 'production' to
# 'staging'
- postgresql_command:
database: my_app
command: >
UPDATE config SET value = %(val)
WHERE parameter = %(prm)
parameters:
val: staging
prm: env
register: command_results
# command_results contains:
{executed_command: "UPDATE config SET value='staging' WHERE
parameter='environment'",
rowCount: 1}
Esempio: creazione di cronjobs inseriti in tabella
- postgresql_query:
name: "Fetch all the jobs for the sale department"
query: >
SELECT name, minute, hour, weekday, month, job, job_user
FROM job
WHERE department = %(dep)
parameters:
dep: sales
register: jobs_to_schedule
- cron:
name: "Schedule job {{name}} for sales department"
minute: "{{ item.minute }}"
hour: "{{ item.hour }}"
weekday: "{{ item.weekday }}"
month: "{{ item.month }}"
job: "{{ item.job }}"
user: "{{ item.job_user }}"
with_items: jobs_to_schedule.rows
exit(0)
Grazie!
denis@gasparin.net
@rtshome
http://www.gasparin.net