Configuration Management

Jak drzewiej bywało?

  • ktoś instalował system na maszynie ręcznie
  • ktoś instalował wszystkie paczki ręcznie
  • ktoś pisał wszystkie pliki konfiguracyjne ręcznie
  • wyglądało na działające, więc poszło na produkcję
  • ktoś np. zapominał zablokować logowanie hasłem na roota

Jak możemy to poprawić?

  • możemy zrobić to skryptem w bashu
  • możemy napisać sobie todolistę
  • możemy użyć oprogramowania
    do zarządzania konfiguracją
  • zarządzanie konfiguracją

  • infrastruktura jako kod

Czym to się różni
od pisania skryptów
w bashu?

  • opisujemy, jakiego stanu oczekujemy
  • opisujemy czynności, którymi można go osiągnąć
  • używamy do tego pojęć na wysokim poziomie
    NIE: wykonaj `apt install nano` i sprawdź,
             czy kod wyjścia był 0
    TAK: zapewnij, że aptowa paczka nano
             jest zainstalowana

O Ansiblu
słów
kilka

Mało techniczne

  • pierwsza wersja w 2012 roku
  • przejęcie firmy przez Red Hata w 2015 roku
  • licencja GPLv3

Bardziej techniczne

  • 30 MB kodu w Pythonie, który
  • łyka konfiguracje w YAMLu, z których
  • generuje masywne skrypty w Pythonie, które
  • przerzuca np. przez SSH na hosty, które konfiguruje
  • łatwo rozszerzalne: zamiast ssh może być Docker,
    konsola szeregowa, Windows PowerShell, jail na FreeBSD;
    zamiast apta może być rpm;
    zamiast zwykłej maszyny może być instancja na AWSie

This article is about a fictional communication device. For other uses, see Ansible (disambiguation).

An ansible is a category of fictional device or technology capable of near-instantaneous or superluminal communication. It can send and receive messages to and from a corresponding device over any distance or obstacle whatsoever with no delay, even between star systems.

z Wikipedii

Główne
zalety
raz
jeszcze

większy bus factor

kolega z pracy pisał
bardzo fajne skrypty shellowe

nagle wyjechał na Erasmusa
do Szwecji na pół roku

okazało się, że ma
tygodniowy okres wypowiedzenia

diff mode

szybkie sprawdzenie,
czym różni się stan faktyczny
od stanu opisanego

nie musimy ponownie rozwiązywać rozwiązanych problemów

ansible galaxy,
czyli gotowe kawałki
konfiguracji z recyklingu

Case study:
SIO2

  • hosts
  • site.yml
  • roles/
    • nginx/
      • handlers/main.yml
      • tasks/main.yml
      • templates/
        • nginx.conf
        • ...
    • ...
  • hosts – opis serwerów, które chcemy konfigurować; jak się do nich połączyć, do jakich grup należą, jakie parametry przekazać do ich konfiguracji
  • playbooki (np. site.yml) czyli opis kolejnych czynności, które chcemy wykonać
  • roles – reużywalne kawałki konfiguracji; zawierają przede wszystkim tasks (czynności) i templates (szablony plików konfiguracyjnych)
# hosts
all:
  hosts:
    ld0:
      networking:
        ipv4_address: 172.31.0.75
      nginx:
        sites:
          - dasie.mimuw.edu.pl
          - oi.edu.pl
          - szkopul.edu.pl
          - main2.edu.pl
    fox:
      nginx:
        sites:
          - fox_internal
          - OI25lecie
          - CEOI2018
    chell:
    glados:
    spr3g[1:13]:
      auth:
        ldap: no
  vars:
    ansible_user: ansible
  children:
    hosts_nginx:
      hosts:
        ld0:
        fox:
        chell:
        glados:
# site.yml
- hosts: all
  roles:
  - role: ssh
    tags: ['auth']
  - role: bash
    tags: ['base']
  - role: icinga_client
    tags: ['monit']
    when: monitoring.enabled
  - role: syslog
    when: syslog is defined
    tags: ['logs', 'monit']
  # …

- hosts:
  - stargate
  roles:
  - role: openvpn
    tags: ['vpn']
    
- hosts: hosts_nginx
  roles:
  - role: nginx
    when: nginx is defined
    tags: ['web']
# roles/nginx/tasks/main.yml
- name: install dependencies
  apt:
    name: nginx
# roles/nginx/tasks/main.yml
- name: create configuration files
  template:
    src: "{{ item }}"
    dest: "/etc/nginx"
    backup: "yes"
    mode: 0644
  with_items:
    - nginx.conf
    - ssl_params
    - proxy_params
  notify:
    - reload nginx
# roles/nginx/tasks/main.yml
- name: create diffie-hellman parameters file
  shell: |
    openssl dhparam -out /etc/nginx/dhparams.pem 2048
 args:
    creates: /etc/nginx/dhparams.pem
# roles/nginx/tasks/main.yml
- name: copy available site configuration files
  template:
    src: "nginx_sites/{{ item }}"
    dest: "/etc/nginx/sites-available/{{ item }}"
    backup: "yes"
    mode: 0644
  with_items: "{{ nginx.sites | default([]) }}"
  notify:
    - reload nginx
# dygresja:
# roles/nginx/handlers/main.yml
- name: restart nginx
  systemd:
    name: nginx
    state: restarted
    
- name: reload nginx
  systemd:
    name: nginx
    state: reloaded
# roles/nginx/tasks/main.yml
- name: gather enabled sites
  shell: |
    ls /etc/nginx/sites-enabled | cat
 register: nginx_sites_enabled_discovery
  check_mode: no
  changed_when: false

- set_fact:
    nginx_sites_enabled: |
      {{ nginx_sites_enabled_discovery.stdout_lines | list }}
# roles/nginx/tasks/main.yml
- name: disable disabled sites
  file:
    path: "/etc/nginx/sites-enabled/{{ item }}"
    state: absent
  with_items: |
    {{ nginx_sites_enabled | difference(nginx.sites|default([])) }}
  notify:
    - reload nginx
    
- name: enable enabled sites
  file:
    src: "/etc/nginx/sites-available/{{ item }}"
    dest: "/etc/nginx/sites-enabled/{{ item }}"
    state: link
    force: yes
  with_items: |
    {{ nginx.sites | default([]) | difference(nginx_sites_enabled) }}
  notify:
    - reload nginx
# roles/nginx/tasks/main.yml
- name: enable and start nginx service
  systemd:
    name: nginx
    enabled: yes
    state: started
# hosts
all:
  children:
    hosts_dns:
      hosts:
        ae86:
      vars:
        dns:
          zones:
            - dasie.mimuw.edu.pl
            - 31.172.in-addr.arpa
# roles/nsd/templates/nsd.conf
server:
  database: ""
  username: nsd
  ip-address: 127.0.0.1@5300
  do-ip4: yes
  do-ip6: no

{% for zone in dns.zones %}
zone:
  name: {{ zone }}
  zonefile: /etc/nsd/{[ zone ]}.zone
{% endfor %}

Wady

gdyby jeszcze
nie było
ich widać

Trudno jest napisać
konfigurację dobrze
za pierwszym razem

Poprawki zrobione
na produkcji
same się nie dopiszą

30 MB kodu w Pythonie,
który generuje
kod w Pythonie

wykona się szybko, będzie łatwe w edycji, zadziała: wybierz dwa

YAML

i jego wątpliwa
tolerancja na
białe znaki

Co do Yamla:
mogło być gorzej
(por. Puppet)

user { 'harry':
  ensure => present,
  uid    => '1000',
  shell  => '/bin/bash',
  home   => '/var/tmp'
}

Co
poza
Ansible?

pull

konfigurowany serwer regularnie sprawdza, czy nie zmieniła się ustalona konfiguracja w repozytorium

push

komputer konfigurujący wysyła nową konfigurację do konfigurowanego serwera

agentowy

na konfigurowanym serwerze działa daemon, z którym komunikuje się program konfigurujący

bezagentowy

nie wymagamy od serwera konfigurowanego specjalnego przygotowania

 

wystarczy np. działające ssh lub nawet konsola szeregowa

agentowe bezagentowe
pull ansible-pull curl … | sudo sh
push salt ansible, salt-ssh

Pytania?

Ansible

By Michał Sidor