copyright 2014. all rights reserved.
Deploying Django with Ansible
Andrew Mirsky
copyright 2014. all rights reserved.
For development: ~/myproject > ./manage.py runserver Validating models... 0 errors found May 30, 2014 - 11:31:08 Django version 1.6.2, using settings 'settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C.
For produc0on: /var/www > sudo ./manage.py runserver 0.0.0.0:80 /dev/null 2>&1 & /var/www >
running a django server
copyright 2014. all rights reserved.
production setup
• One or more applica=ons (aka virtual servers) • Mul=ple applica=on processes & monitoring • Data storage & retrieval (aka databases) • Security • Maintainable, robust, scalable
copyright 2014. all rights reserved.
basic setup
copyright 2014. all rights reserved.
components • webservers
– apache – nginx – cherokee
• interpreter – mod_wsgi – uwsgi – gunicorn
• databases – postgres – mysql – [ mongodb, couchdb, cassandra ]
copyright 2014. all rights reserved.
scalable setup
copyright 2014. all rights reserved.
scalable, redundant setup
copyright 2014. all rights reserved.
ansible
copyright 2014. all rights reserved.
ansible for single commands
> pip install ansible > ansible webservers –i myinventory -a ”touch /srv/foo.txt && /sbin/reboot" -f 10
copyright 2014. all rights reserved.
anatomy of an inventory > cat inventory # file: inventory [webservers] app[0:4].mirsky.net ansible_ssh_private_key_file=~/.ssh/key1.pem [dbservers] db[0:2].mirsky.net ansible_ssh_private_key_file=~/.ssh/key2.pem [mytotalsite:children] webserver dbservers
copyright 2014. all rights reserved.
ansible playbooks
copyright 2014. all rights reserved.
building playbooks > pip install ansible-role-manager > arm help usage: /Users/andrew/env/arm/bin/arm [-h] {freeze,help,init,install,uninstall} ... positional arguments: {freeze,help,init,install,uninstall} freeze produces dependencies file for this playbook based on... help an alias for calling `-h` on any subcommand init initialize directory structure & files install install playbook role uninstall remove a role from the library of dependencies > arm init -p mydjangoplaybook ansible playbook created successfully > arm install git+https://github.com/mirskytech-ansible/role-postgres.git
copyright 2014. all rights reserved.
anatomy of a playbook > cat mydjangoplaybook/mysite.yml ## file: mysite.yml !! !! ## usage: ansible-playbook -i <inventory file> mysite.yml !! - hosts: webservers vars: webservers - project: mydjangoproject roles: - cherokee - postgres tasks: - name: install uwsgi & postgres modules sudo: yes pip: name="uwsgi psycopg2”
copyright 2014. all rights reserved.
anatomy of a role > cat roles/cherokee/tasks/main.yml --- ## file: cherokee/tasks/main.yml - name: add cherokee ppa sudo: yes command: mkdir /srv/www && chgrp www-data /srv/www - name: add cherokee ppa sudo: yes apt_repository: repo="ppa:cherokee-webserver" state="present" register: ppa_add ignore_errors: true - name: package install sudo: yes apt: pkg={{ item }} state=present update_cache=yes with_items: - cherokee - libcherokee-mod-libssl register: apt_install ignore_errors: true when: ppa_add|success
copyright 2014. all rights reserved.
anatomy of a task - name: create uwsgi config file sudo: yes template: > src=templates/uwsgi.ini.j2 dest=/srv/www/{{ project }}/uwsgi.ini group='www-data' mode=660 register: this_task_rc ignore_errors: true when: previous_task_rc|success
> cat templates/uwsgi.ini.j2 # uwsgi.ini for {{ hostname }} [uwsgi] vhost = true master = true enable-threads = true processes = 2 wsgi-file = /srv/www/{{ project }}/webapp/wsgi.py virtualenv = /srv/env/{{ project }} chdir = /srv/www/{{ project }} touch-reload = /srv/reload/{{ project }} pythonpath = /srv/www/{{ project }} daemonize = /var/log/{{ hostname }}.log post-buffering = 32768 Ansible’s Template Module Docs
copyright 2014. all rights reserved.
anatomy of a module > cat library/mymodule_command from ansible.module_utils.basic import * def main(): # module arguments module_args = dict( username = dict(required=True) ) # module instantiation module = AnsibleModule( argument_spec = module_args, supports_check_mode=True,) # module variables username = module.params[’username'] # module execution # do something # if something fails: # module.fail_json(msg=‘command failed’) module_returns = { "result":"my module’s result was blah", "changed" : False, "rc" : 4,
"ansible_facts" : {}, } module.exit_json(**module_returns) main()
copyright 2014. all rights reserved.
resources • Ansible Role Manager
hNps://pypi.python.org/pypi/ansible-‐role-‐manager
• Django Deploy & Release Playbooks hNps://github.com/mirskytech-‐ansible/playbook-‐django
• Ansible Tower • Ansible Galaxy
• Ansible Docs hNp://docs.ansible.com/quickstart.html hNp://docs.ansible.com/playbooks_best_prac=ces.html hNp://docs.ansible.com/list_of_all_modules.html hNp://docs.ansible.com/
• MirskyTech Blog hNp://mirskytech.com/overflow/
• Django Pony Logo hNp://doctormo.deviantart.com/art/Django-‐Python-‐Pony-‐449031453
contact info
questions?