Кои сме ние?

Генади Самоковаров

@gsamokovarov


Стан{,имир} Ангело{в,ff}

@StanAngeloff


  • Пише код.
  • Обича бяло червено вино (без мярка).
  • Не търпи глупави хора.

Какво няма да има в нашата презентация?

Няма да говорим за build tools.


Това не е презентация за:

  • make, rake, grunt
  • gulp


whatever you crazy kids use these days…

Какво ще има в нашата презентация?

Ще говорим за автоматизиране на съвръри.

Всекидневни задачи,

Дълги и досадни задачи,

…или как да си подкарам Ruby-то на съвръра.

Защо автоматизация?

Генади мрази да конфигурира сървъри.

Станимир мрази да конфигурира сървъри.

Генади и Станимир много мразят да конфигурират сървъри.

IT SUCKS BIG TIME!!!





Мит: Автоматизация само за големи проекти

Защо автоматизация? (продължение…)


Когато машината и dependencies еволюират, много по-лесно е да ги документираш.


Автоматизацията е като документация за машината… особено когато имате повече от една машина.

Защо автоматизация? (продължение…)


Reproducibility — няма разминаване в средите

Генади работи с Python3, Стан с Python2

Ама при мен работи?!

Време за демо

Ansible

5, 276 stars

9, 851 commits

  35 releases

  644 contributors

Puppet

1, 971 stars

15688 commits

  276 releases

  274 contributors

Какво автоматизирахме?

Едно “малко” Python приложение

def application(env, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [b"Hello Rogue!"]
    
  • Nginx (from PPA)
  • Python 3.2, pip
  • uWSGI (application server)
  • Upstart jobs

А преди това…

  • Ubuntu 12.04, x64
  • SSH server
  • Reasonable security
  • Date/time, locale, etc.
  • build-essential


…за три реда код.

Y U NO
INSTALL YOURSELF




Време за код

Конфигуриране на Python

- name: Install packages
  apt: >
    pkg={{ item }}
    state=present
  with_items:
    - 'python{{ python_version }}'
    - 'python{{ python_version }}-dev'
    
- name: Check if pip is installed
  command: >
    which {{ pip_executable }}
  register: pip_installed
  changed_when: false
  ignore_errors: true
  
- name: Install pip
  shell: >
    wget -qO- https://raw.github.com/pypa/pip/master/contrib/get-pip.py | {{ python_executable }}
  when: pip_installed | failed
  
package {
  [
    "python${version}",
    "python${version}-dev"
  ]:
}


-> exec { "wget -qO- https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python${version}":
  path   => ['/usr/bin', '/bin'],
  unless => "which pip 2>&1 1>/dev/null"
}

Конфигуриране на uWSGI

- name: Insall uWSGI
  pip: >
    executable={{ pip_executable }}
    name=uwsgi
    state=present
    
- name: Install Upstart script for uWSGI Emperor
  template: src=uwsgi.conf.j2 dest=/etc/init/uwsgi.conf
  
- name: Create uWSGI Emperor configuration directory
  file: >
    path=/etc/uwsgi/vassals/
    state=directory recurse=yes
    
- name: Create vassal configuration
  template: >
    src=vassal.ini.j2
    dest=/etc/uwsgi/vassals/{{ uwsgi_vassal_name }}.ini
  notify: restart uwsgi
  
- name: Start uWSGI Emperor
  service: name=uwsgi state=started enabled=yes
  
package { 'uwsgi':
  provider => 'pip',
  require  => Package['build-essential']
}


file {
  '/etc/init/uwsgi.conf':
    source => 'puppet:///modules/uwsgi/uwsgi.conf';
    
  ['/etc/uwsgi', '/etc/uwsgi/vassals']:
    ensure => directory;
    
  "/etc/uwsgi/vassals/${vassal_name}.ini":
    content => template('uwsgi/vassal.ini.erb'),
    notify  => Service['uwsgi'];
}


service { 'uwsgi':
  ensure  => running,
  enable  => true,
  require => [Package['uwsgi'], File['/etc/init/uwsgi.conf']]
}

Инсталиране на Nginx

- name: 'Add PPA for stable releases'
  apt_repository:
    repo='ppa:nginx/stable'
    update_cache=true
    
- name: 'Install packages'
  apt:
    pkg=nginx
    state=latest
    
apt::ppa { 'ppa:nginx/stable': }




-> package { 'nginx':
  ensure => latest
}

Конфигуриране на Nginx

- name: Create site configuration
  template: >
    src=site.conf.j2
    dest=/etc/nginx/sites-available/{{ nginx_site_name }}
  notify: restart nginx
  
- name: Disable default site
  file: >
    path=/etc/nginx/sites-enabled/default
    state=absent
  notify: restart nginx
  
- name: Enable custom site
  file: >
    path=/etc/nginx/sites-enabled/{{ nginx_site_name }}
    src=/etc/nginx/sites-available/{{ nginx_site_name }}
    state=link
  notify: restart nginx
  
file {
  '/etc/nginx/sites-enabled/default':
    require => Package['nginx'],
    notify  => Service['nginx'],
    ensure  => absent;
    
  "/etc/nginx/sites-enabled/${site_name}":
    require => Package['nginx'],
    notify  => Service['nginx'],
    ensure  => link,
    target  => "/etc/nginx/sites-available/${site_name}";
    
  "/etc/nginx/sites-available/${site_name}":
    require => Package['nginx'],
    notify  => Service['nginx'],
    content => template('nginx/site.conf.erb')
}

Конфигуриране на Nginx

- name: Create site configuration
  template: >
    src=site.conf.j2
    dest=/etc/nginx/sites-available/{{ nginx_site_name }}
  notify: restart nginx
  
- name: Disable default site
  file: >
    path=/etc/nginx/sites-enabled/default
    state=absent
  notify: restart nginx
  
- name: Enable custom site
  file: >
    path=/etc/nginx/sites-enabled/{{ nginx_site_name }}
    src=/etc/nginx/sites-available/{{ nginx_site_name }}
    state=link
  notify: restart nginx
  
file {
  '/etc/nginx/sites-enabled/default':
    ensure => absent;
    
  "/etc/nginx/sites-enabled/${site_name}":
    ensure => link,
    target => "/etc/nginx/sites-available/${site_name}";
    
  "/etc/nginx/sites-available/${site_name}":
    content => template('nginx/site.conf.erb')
}

File {
  require => Package['nginx'],
  notify  => Service['nginx']
}

Конфигуриране на Nginx

- name: Start nginx
  service: >
    name=nginx
    state=started
    enabled=yes
    
service { 'nginx':
  ensure  => running,
  enable  => true,
  require => Package['nginx']
}

Източници на Конфигурация

roles/nginx/defaults/main.yml
group_vars/webservers
inventory/servers.ini
Modules (Amazon, DO)
Local Facts
Playbook
Environment
Command-line
Hiera
Facts
Environment
Global Variables?

И още малко…

  • Libraries / Repositories with re-usable code

    Нож с две остриета.

  • Secure password & secret management

Оправдания
(да не автоматизираме)

Ще отнеме много време да се направи.

Не е моя работа, има си devops, да се оправят.

Ще си ползвам Heroku-то, там всичко работи.

Ресурси

Ansible


Puppet


Oще


Въпроси  &  Отговори