Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Scaling with Ansible

Scaling with Ansible

A quick introduction to Ansible followed up with presentation of the most interesting bits and how we use those. Presentation from Europython 2014 (Berlin)

Federico Marani

July 23, 2014
Tweet

More Decks by Federico Marani

Other Decks in Programming

Transcript

  1. Ansible - Quick to get started - Builds on Python,

    SSH and YAML… - Pushes updates (instead of pull) - Playbooks, tasks and inventories
  2. Use host groups, roles/includes Use the action with least side

    effects (e.g. prefer “copy” to “template”)
  3. - include: install_web_packages.yml - include: config_nginx.yml - include: config_supervisor.yml -

    include: database_daily_restore.yml when: BUILD_ENVIRONMENT == "staging" - include: app_deploy.yml tags=code Includes
  4. Deployments are really custom --- # ... - name: create

    virtualenv for Django web application shell: virtualenv --python=/usr/bin/python3.4 {{virtualenv_dir}} when: venv_dir.stat.isdir is not defined - name: install web application dependencies listed in requirements.txt pip: requirements={{app_code_dir}}-{{build_date.stdout}} /requirements.txt virtualenv={{virtualenv_dir}} - name: Install Bower packages shell: bower install chdir={{app_code_dir}}-{{build_date.stdout}} /assets/js/vendor/ - name: Install NPM packages npm: path={{app_code_dir}}-{{build_date.stdout}}/assets - name: Run grunt make (sass/requirejs/uglify/etc) shell: grunt make chdir={{app_code_dir}}-{{build_date.stdout}} /assets/ - name: Django collectstatic django_manage: command=collectstatic app_path={{app_code_dir}}-{{build_date.stdout}} virtualenv={{virtualenv_dir}} settings={{django_settings}} environment: django_env_vars - name: Testing if there are new migrations django_manage: command="migrate --list" app_path={{app_code_dir}}-{{build_date.stdout}} virtualenv={{virtualenv_dir}} settings={{django_settings}} environment: django_env_vars register: migration_test - name: Stopping Celery before applying migrations supervisorctl: name=trialreach_celery state=stopped when: "'( )' in migration_test.out" - name: Django migrate django_manage: command=migrate app_path={{app_code_dir}}-{{build_date.stdout}} virtualenv={{virtualenv_dir}} settings={{django_settings}} environment: django_env_vars when: "'( )' in migration_test.out" - name: Symlink release directory to new one file: src={{app_code_dir}}-{{build_date.stdout}}/ dest= {{app_code_dir}} state=link - name: Restart uwsgi supervisorctl: name="uwsgi" state=restarted - name: Send deployment notifications to Hipchat hipchat: token=X room="Notifications" msg_from="Web Warden" msg="Code deployed to {{ ansible_hostname }}"
  5. - fail: msg="Please define environment to deploy" when: app_environment is

    not defined Conditionals* * uses Jinja2 expressions
  6. - shell: git tag chdir="{{app_code_dir}}" register: git_tags - fail: msg="Please

    define a tag when deploying to production" when: app_environment == "production" and tag not in git_tags. stdout_lines register
  7. - name: ensure pip packages are installed pip: name={{ item

    }} state=present with_items: - virtualenv==1.11.4 - supervisor with_items
  8. - name: send notifications to Hipchat hipchat: room="Eng" msg="Deployed to

    {{ansible_hostname}}" changed_when: False facts
  9. Frequently used actions apt: install packages service: interface to init

    scripts pip: install pip packages git: checkout repositories file: check file state copy/template: copy files to server django_manage: run management commands supervisorctl: run supervisor commands
  10. Current state - 1000+ lines of playbooks - 4 environments

    - 10 production-type servers with Postgresql, Neo4J, Nginx, Solr. - Dev machines, branch machines. - AWS, DigitalOcean, Vagrant
  11. - Keep server stateless - Do things in the right

    place, either code-level or infrastructure-level. ...and remember