$30 off During Our Annual Pro Sale. View Details »

Deploy Silverstripe with Ansible

Deploy Silverstripe with Ansible

Talk on the Silverstripe Conference 2015 in London. www.stripecon.eu

wernerkrauss

October 17, 2015
Tweet

More Decks by wernerkrauss

Other Decks in Programming

Transcript

  1. About me • Werner M. Krauß • Located in Hallstatt,

    Austria • wmk on IRC / github / stackoverflow • PHP since 1998 • Freelancer since 2006 (netwerkstatt) • SilverStripe since 2009
  2. Overview • What is this thing called ansible? • What

    is debops? • What is deployment? • How can we put this things together and deploy a SilverStripe site with it?
  3. What is Ansible • IT automation tool • Based on

    python • Free, open source • Agentless, over ssh • Batteries included (comes with many useful modules)
  4. Ansible is indempotent • Produces the same results if executed

    multiple times • Declarative tasks define the wanted state
  5. Ansible scales down • Of course you can manage tons

    of servers • Configuring a single node is also easy • "Simple things should be simple, complex things should be possbile" (Alan Kay)
  6. Requirements • Control Machine: – Python 2.6 or 2.7 –

    gcc (for installing some python packages) – Linux, OSX, any BSD…. – Windows isn‘t supported • Managed Node: – SSH – Python 2.4 or later
  7. Installation • Python 2.7, gcc on the management machine •

    Install requirements: sudo pip install paramiko PyYAML Jinja2 httplib2 six • sudo pip install ansible
  8. Ad-hoc commands • ansible <host-pattern> [options] –ansible all -m ping

    –ansible all -a "free m" –ansible webservers -m apt -a "name=tree state=latest" ansible module shell command
  9. Playbooks • Infrastructure as code • yml files • We

    SilverStripers love yml • pre_tasks, tasks, post_tasks and handlers
  10. Variables • Playbooks • Inventory (group vars, host vars) •

    Command line • Discovered vars (aka facts) • Of course defaults in a role
  11. Roles • reusable components • ~3.500 ready-to-use roles on ansible

    galaxy • create your own role: ansible-galaxy init <name> like SilverStripe modules
  12. Ansible vault • For saving sensible data encrypted – passwords

    – keys etc… • Vault files can be distributed or placed in vcs
  13. What is debops? • Your Debian-based data center in a

    box • Collection of Ansible playbooks • Scalable • 80+ highly extensible roles • Some custom scripts • Since October 2013 • Small but very helpful community
  14. Installing debops • sudo pip install debops • Create your

    DebOps project: debops-init /path/to/myproject • Download playbooks and roles: debops-update
  15. What is deployment? Deployment is a word, often used by

    the military, for sending troops into duty. A soldier could be part of a deployment to the Middle East. Deployment refers to assigning people to serve in various locations, especially soldiers and other military personnel. www.vocabulary.com/dictionary/deployment
  16. What is deployment? #2 In its IT context, deployment encompasses

    all the processes involved in getting new software or hardware up and running properly in its environment, including installation, configuration, running, testing, and making necessary changes. whatis.techtarget.com/definition/deploy
  17. Deploying SilverStripe • Check if all required packages are installed

    – nginx, mysql, memcache etc… • Set up a virtual host • Create needed directories • Create database • Create _ss_environment.php or mariaDB
  18. Deploying Silverstripe #2 • Copy files (checkout from git) •

    Install composer packages • Import database and assets • Run dev/build • Optional: setup cron tasks • …and anything you need for a happy site
  19. Basic server setup • Depops bootstrap • Setup ssh key

    on the machine • Add host to the webserver, php (and db) groups in inventory • Configure group vars
  20. Example group vars --- ntp_timezone: 'Europe/Berlin' postfix_relayhost: 'smtp.mydomain.com' postfix_default_local_alias_recipients: ['[email protected]']

    console_root: false #don't manage root account now... console_locales: ['de_DE.UTF-8', 'de_AT.UTF-8', ] important for localised dates
  21. Run first setup • debops bootstrap -k -u root -l

    demo wrapper for ansible-playbook ask for password limit hosts playbook for basic server setup
  22. Install packages • Add the host to special groups in

    inventory to install: – mySQL – nginx – PHP
  23. Run debops again • debops -l demo – downloads and

    installs a lot • e.g. mysql role also installs automysqlbackup – takes some time….
  24. Create project user - name: create project user user: name:

    '{{ silverstripe_user }}' group: '{{ silverstripe_group }}' comment: 'project user for {{ silverstripe_project }}' home : '{{ silverstripe_user_home}}' state: present append: True system: True some variables defined before
  25. Configure PHP - role: debops.php5 php5_packages: - php5-memcached - php5-memcache

    - php5-gd - php5-curl - php5-mcrypt php5_pools: ['{{ silverstripe_php5_pool }}']
  26. Install composer Command line: ansible-galaxy install loranger.debian-composer Playbook: - role:

    loranger.debian-composer downloads the role installs composer and keeps it updated when you run the playbook
  27. Configure nginx • Basically role configuration • Sets up redirect

    from e.g. from example.com to www.example.com • Setup virtual host and configure it for SilverStripe
  28. - role: debops.nginx nginx_upstreams: ['{{ nginx_upstream }}'] nginx_servers: - name:

    '{{ silverstripe_domains }}' enabled: True redirect_from: True root: '{{ silverstripe_path_wwwroot }}' owner: '{{ silverstripe_user }}' group: '{{ silverstripe_webserver_user }}' type: 'php5' php5: '{{ silverstripe_user }}' location: '/': try_files $uri @silverstripe; '@silverstripe': | fastcgi_keep_conn on; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass {{ silverstripe_user }}; fastcgi_index index.php; include fastcgi_params; fastcgi_read_timeout 120; fastcgi_connect_timeout 60; fastcgi_send_timeout 120; fastcgi_buffer_size 64k; fastcgi_buffers 4 65k; fastcgi_busy_buffers_size 128k; fastcgi_param SCRIPT_FILENAME $document_root/framework/main.php; fastcgi_param SCRIPT_NAME /framework/main.php; fastcgi_param QUERY_STRING url=$uri&$args; … redirect all domains to the first, e.g. www.demo.silverstrip.es => demo.silverstrip.es
  29. • silverstripe_db_password: '' #will be created silverstripe_db_pass: '{{ silverstripe_db_password if

    silverstripe_db_password|d() else lookup("password", secret + "/credentials/" + ansible_fqdn + "/mysql/" + silverstripe_db_user + "/password length=" + mysql_password_length) }}' • - role: debops.mysql mysql_users: - name: '{{ silverstripe_db_user }}' state: 'present' password: '{{ silverstripe_db_pass }}' priv: '{{ silverstripe_db_database }}.*:ALL' mysql_databases: - name: '{{ silverstripe_db_database }}'
  30. - name: Create silverstipe directories file: path: '{{ item }}'

    state: 'directory' owner: '{{ silverstripe_user }}' group: '{{ silverstripe_webserver_user }}' mode: '0755' with_items: [ '{{ silverstripe_path_home }}', '{{ silverstripe_path_wwwroot }}' ] - name: create error log dir file: path: '{{ silverstripe_error_log | dirname }}' state: 'directory' owner: '{{ silverstripe_user }}' group: '{{ silverstripe_webserver_user }}' mode: '0750' when: silverstripe_error_log_enabled
  31. Setup _ss_environment.php • From Jinja2 template • Using vars for

    db, domain and paths from above • … and copy it to the server
  32. - name: create _ss_environment.php template: src: '../templates/_ss_environment.j2' dest: '{{ silverstripe_path_home

    + "/_ss_environment.php" }}' owner: '{{ silverstripe_user }}' group: '{{ silverstripe_webserver_user }}'
  33. <?php // {{ ansible_managed }} define('SS_ENVIRONMENT_TYPE', '{{ silverstripe_environment_type | default("live")

    }}'); /* Database connection */ define('SS_DATABASE_CLASS', '{{ silverstripe_db_class }}'); define('SS_DATABASE_SERVER', '{{ silverstripe_db_host }}'); define('SS_DATABASE_USERNAME', '{{ silverstripe_db_user }}'); define('SS_DATABASE_PASSWORD', '{{ silverstripe_db_pass }}'); define('SS_DATABASE_NAME','{{ silverstripe_db_database }}'); {% if silverstripe_error_log_enabled %} define('SS_ERROR_LOG', '{{ silverstripe_error_log }}'); {% endif %} $_FILE_TO_URL_MAPPING['{{ silverstripe_path_wwwroot }}'] = 'http://{{ silverstripe_domains|first }}'; fallback for undefined variables
  34. - name: checkout project repository in webroot git: repo='{{ silverstripe_repo_url

    }}' dest='{{ silverstripe_path_wwwroot }}' accept_hostkey=yes tags: deploy-update - name: set file ownership file: > path={{ silverstripe_path_wwwroot }} recurse=yes owner='{{ silverstripe_user }}' group='{{ silverstripe_webserver_user }}' tags: deploy-update tags are useful if you want to run a set of tasks only
  35. Run installation scripts - name: run composer update shell: 'cd

    {{ silverstripe_path_wwwroot }} && composer install --no-dev --prefer-dist -o' tags: deploy-update - name: ensure sake is executable file: > path='{{ silverstripe_sake}}' mode='o+x' tags: deploy-update - name: run dev/build shell: '{{ silverstripe_sake + " dev/build flush" }}' tags: deploy-update -o : optimize autoloader
  36. Import data • SQL dump • Assets • Only when

    variables are defined • Best define it in command line when you really want to overwrite the database
  37. - name: copy dump to remote copy: > src='{{ silverstripe_db_dump

    }}' dest='{{ silverstripe_path_temp + "/" + silverstripe_db_dump|basename }}' owner='{{ silverstripe_user }}' group='{{ silverstripe_webserver_user }}' when: silverstripe_db_dump is defined - name: import sql dump mysql_db: > name='{{ silverstripe_db_database }}' state=import target='{{ silverstripe_path_temp + "/" + silverstripe_db_dump|basename }}' when: silverstripe_db_dump is defined - name: import assets unarchive: > src='{{ silverstripe_assets_dump }}' dest='{{ silverstripe_path_wwwroot + "/assets" }}' copy=yes owner='{{ silverstripe_user }}' group='{{ silverstripe_webserver_user }}' when: silverstripe_assets_dump is defined takes e.g. a .tgz and unpacks it in assets Jinja2 filter to get the filename
  38. Import Data #2 • Note to myself: SSPak is made

    for this https://github.com/silverstripe/sspak • But copy, mysql and unarchive modules are good examples
  39. Setup other stuff • You can define whatever you need

    for your app, e.g. – cache settings (memcached) – cron tasks – …
  40. - name: setup cron tasks to rebuild the site every

    night cron: > name='{{ "rebuild " + silverstripe_project + ", locale " + item.locale }}' job='{{ silverstripe_sake + " dev/tasks/RebuildStaticCacheTask locale=" + item.locale }}' hour='1' minute='{{ item.minute }}' user='{{ silverstripe_user }}' state=present with_items: - { locale: 'de_DE', minute: '22'} - { locale: 'en_US', minute: '24'} could also be a predefined list
  41. Is there a role for it? • Silverstripe deploy role

    is in development • Capistrano like deploy with releases: f500 project_deploy https://galaxy.ansible.com/list#/roles/732