Кои сме ние? – Защо автоматизация? – Време за демо



Кои сме ние? – Защо автоматизация? – Време за демо

0 0


roguedudes.github.io

Presentation of Automate ALL THE THINGS!!!

On Github RogueDudes / roguedudes.github.io

Кои сме ние?

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

@gsamokovarov

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

@StanAngeloff

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

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

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

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

  • make, rake, grunt
  • gulp

whatever you crazy kids use these days…

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

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

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

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

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

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

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

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

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

IT SUCKS BIG TIME!!!

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

Не, не е, нашето демо ще 3 реда код на Python. Дори малък проект носи със себе си много dependencies, от OS-ниво до софтуер...

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

Когато машината и 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 NOINSTALL 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ще

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

  • Защо не Bash скриптове?

    Голяма болка, особено когато скриптът стане 1, 000+ реда spaghetti code.

    Idempotence е важен, това в Bash е ръчна задача и трябва вие да я предвидите.

    Ако имате вече голямо library, започнете като го автоматизирате, но не оставяйте нещата до там.

  • Защо не Chef?

    Нищо лично, но нямаме опит с него, вероятно е cool.