Drupal Camp Brighton 2015: Ansible Drupal Medicine show
-
Upload
george-boobyer -
Category
Technology
-
view
297 -
download
3
Transcript of Drupal Camp Brighton 2015: Ansible Drupal Medicine show
blue-bag
ANSIBLE &
DRUPALMEDICINE SHOW
DRUPAL BRIGHTON CAMP JANUARY 2015
GEORGE BOOBYER BLUE-BAG
blue-bag
BLUE-BAG
GEORGE BOOBYER DRUPAL: [email protected] TWITTER: iBLUEBAG
www.blue-bag.com
Established in 2000The year before Drupal 1.0
blue-bag
ANSIBLE & DRUPAL
Security issues
Ansible
Server security
Drupal
Take homes
Questions
blue-bag
ANSIBLE & DRUPAL: TOP 10
1. Docker 2. Kubernetes 3. Taiga 4. Apache Mesos 5. OpenStack 6. Ansible 7. ownCloud 8. Apache Hadoop 9. Drupal 10.OpenDaylight
http://opensource.com/business/14/12/top-10-open-source-projects-2014
Top 10 open source projects in 2014
blue-bag
SECURITY ISSUES: 2014 TRENDS
CVE-2014-0160CVE-2014-3566CVE-2014-8730
CVE-2014-6277CVE-2014-6278CVE-2014-7169CVE-2014-7186CVE-2014-7187
Shellshock Poodle Heartbleed
SSLv3Bash OpenSSL
Exploits get branding!
blue-bag
SECURITY ISSUES: SAFE ENOUGH?Availability of cloud servers
Ease of setup
Lack of security practices
Manual exploits
Constellations of compromised machines THAT SHOULD DO IT!
blue-bag
BASIC SECURITYPrinciple of least privilege
Limit all ports access / iptables
WAF / Appliances
Platform / Providers
Secure as soon as IP is public: First 5
blue-bag
ANSIBLE BASICS
Agentless Uses SSH YAML for configuration Modules Open source not just provisioning
“Ansible is a radically simple IT automation system. It handles configuration-management, application deployment, cloud provisioning, ad-hoc task-execution, and multinode orchestration.
blue-bag
ANSIBLE GOALS
Don’t log into servers
no need for bash scripts
Document build and configuration(in source control)
Idempotent (idem-what’s-that-again?)
Maintain configuration across inventory
Retain knowledge
blue-bag
GET THE BOOK!33% DISCOUNT FOR DCB!http://leanpub.com/ansible-for-devops/c/VbhTIPZqGvWT !
https://leanpub.com/ansible-for-devops
blue-bag
ANSIBLE DOCUMENTATION
Github - https://github.com/ansible/ansibleCode and examples
Ansible Documentation - http://docs.ansible.com/ !Ansible best practiceshttp://docs.ansible.com/playbooks_best_practices.html !Ansible Galaxy - https://galaxy.ansible.com
blue-bag
ANSIBLE BASICS
Inventory
Commands / Modules
Roles
Tasks
Templates
Facts
Vars
Host Vars
Group vars
Handlers
Tests
blue-bag
ANSIBLE BASICS: MODULES
Command
Shell
Lineinfile
File
Copy
Unarchive
Apt / Yum
apache2_module
htpasswd
Git
Cloud
Homebrew
blue-bag
ANSIBLE / VAGRANT"## demo "## Vagrantfile %## hosts
# -*- mode: ruby -*-# vi: set ft=ruby :!VAGRANTFILE_API_VERSION = "2"!Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.ssh.insert_key = false config.vm.provider :virtualbox do |vb| vb.customize ["modifyvm", :id, "--memory", "256"] end ! # Application server 1. config.vm.define "app1" do |app| app.vm.hostname = "bbdemo-app1.dev" app.vm.box = "chef/debian-7.4" app.vm.network :private_network, ip: "192.168.100.120" end! # Application server 2. config.vm.define "app2" do |app| app.vm.hostname = "bbdemo-app2.dev" app.vm.box = "chef/debian-7.4" app.vm.network :private_network, ip: "192.168.100.121" end! # Database server. config.vm.define "db" do |db| db.vm.hostname = "bbdemo-db.dev" db.vm.box = "chef/debian-7.4" db.vm.network :private_network, ip: "192.168.100.122" endend
# Application servers[app]192.168.100.120192.168.100.121!# Database server[db] 192.168.100.122!# Group 'multi' with all servers[multi:children]appdb!# Variables that will be applied to all servers"[multi:vars] ansible_ssh_user=vagrantansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key
blue-bag
ANSIBLE BASICS$ ansible multi -i hosts -a "free -m" -u vagrant
192.168.100.121 | success | rc=0 >> total used free shared buffers cachedMem: 244 74 170 0 6 34-/+ buffers/cache: 32 212Swap: 767 0 767!192.168.100.120 | success | rc=0 >> total used free shared buffers cachedMem: 244 74 170 0 6 34-/+ buffers/cache: 32 212Swap: 767 0 767!192.168.100.122 | success | rc=0 >> total used free shared buffers cachedMem: 244 74 170 0 6 34-/+ buffers/cache: 32 212Swap: 767 0 767
blue-bag
ANSIBLE BASICS"## demo "## Vagrantfile "## ansible.cfg "## hosts %## log %## ansible.log
[defaults]log_path = log/ansible.loghostfile = ./hosts
…[multi]ansible_ssh_user=vagrant…
$ansible multi -i hosts -a "free -m" -u vagrant
blue-bag
ANSIBLE BASICS
$ ansible multi -a “date"!
192.168.100.122 | success | rc=0 >>Tue Jan 13 10:14:15 UTC 2015!
192.168.100.121 | success | rc=0 >>Tue Jan 13 10:14:15 UTC 2015!
192.168.100.120 | success | rc=0 >>Tue Jan 13 10:14:15 UTC 2015
blue-bag
ANSIBLE BASICS$ansible multi -s -m apt -a "pkg=ntp state=installed_ update_cache=yes"192.168.100.121 | success >> { "changed": true, "stderr": "", "stdout": "Reading package lists...\nBuilding dependency tree...\nReading state information...\nThe following extra packages will be installed:\n libopts25\nSuggested packages:\n ntp-doc\nThe following NEW packages will be installed:\n libopts25 ntp\n0 upgraded, 2 newly installed, 0 to remove and 72 not upgraded.\nNeed to get 565 kB/638 kB of archives.\nAfter this operation, 1364 kB of additional disk space will be used.\nGet:1 http://mirrors.kernel.org/debian/ wheezy/main ntp amd64 1:4.2.6.p5+dfsg-2+deb7u1 [565 kB]\nFetched 565 kB in 13s (40.8 kB/s)\nSelecting previously unselected package libopts25.\r\n(Reading database ... \r(Reading database ... 5%\r(Reading database ... 10%\r(Reading database ... 15%\r(Reading database ... 20%\r(Reading database ... 25%\r(Reading database ... 30%\r(Reading database ... 35%\r(Reading database ... 40%\r(Reading database ... 45%\r(Reading database ... 50%\r(Reading database ... 55%\r(Reading database ... 60%\r(Reading database ... 65%\r(Reading database ... 70%\r(Reading database ... 75%\r(Reading database ... 80%\r(Reading database ... 85%\r(Reading database ... 90%\r(Reading database ... 95%\r(Reading database ... 100%\r(Reading database ... 37414 files and directories currently installed.)\r\nUnpacking libopts25 (from .../libopts25_1%3a5.12-0.1_amd64.deb) ...\r\nSelecting previously unselected package ntp.\r\nUnpacking ntp (from .../ntp_1%3a4.2.6.p5+dfsg-2+deb7u1_amd64.deb) ...\r\nProcessing triggers for man-db ...\r\nSetting up libopts25 (1:5.12-0.1) ...\r\nSetting up ntp (1:4.2.6.p5+dfsg-2+deb7u1) ...\r\nStarting NTP server: ntpd.\r\n"}
blue-bag
ANSIBLE BASICS: THE PLAYBOOK
--- - hosts: all gather_facts: true sudo: true tasks: - name: NTP | Install NTP apt: > name=ntp state=installed update_cache=yes cache_valid_time=3600
"## demo "## Vagrantfile "## ansible.cfg "## hosts %## log %## ansible.log "## playbook.yml
$ ansible-playbook playbook.yml
http://docs.ansible.com/apt_module.html
blue-bag
ANSIBLE BASICS: ROLES
$ansible-galaxy init 'myrole'
"## myrole "## README.md "## defaults & %## main.yml "## files "## handlers & %## main.yml "## meta & %## main.yml "## tasks & %## main.yml "## templates %## vars %## main.yml
Use Galaxy Init to create roles
blue-bag
ANSIBLE BASICS: PROJECT STRUCTURE
https://github.com/iAugur/ansible-playbook-template
"## LICENSE"## README.md"## ansible.cfg"## common& "## handlers& & %## main.yml& %## vars& %## main.yml"## group_vars& %## all.yml"## host_vars& %## local.yml"## hosts"## log"## playbook.yml"## roles %## base "## README.md "## defaults & %## main.yml "## files "## handlers & %## main.yml "## meta & %## main.yml "## tasks & %## main.yml "## templates %## vars %## main.yml
Use a template for Ansible projects.
Common structure
blue-bag
ANSIBLE BASICS: TESTING
Test play books$ ansible-playbook --syntax-check --list-tasks main.yml
Check mode$ansible-playbook main.yml --check $ansible-playbook main.yml --check --diff
Test against Virtual machines$ ansible-playbook main.yml -l local
blue-bag
BASIC SECURITY: FIRST 5Lock down SSH
Create users and groups
Limit SSH to RSA key: (no passwords / no root)Limit to AllowGroups
Update APT - unattended updates security
Configure hostname
Configure IPTables
Configure Fail2ban
blue-bag
BASIC SECURITY: FIRST 5Take what we know
Research
Create templates / vars
Consistent across infrastructure
Use tasks to implement
Idempotent
Version controlled
Documented
blue-bag
FIRST5: SSH - EXAMPLE"## README.md"## tasks& "## main.yml& %## ssh_config.yml"## templates& %## ssh_config.j2%## vars %## main.yml
blue-bag
FIRST5: SSH - EXAMPLE"## README.md"## tasks& "## main.yml& %## ssh_config.yml"## templates& %## ssh_config.j2%## vars %## main.yml
# Package generated configuration file# See the sshd_config(5) manpage for details!# What ports, IPs and protocols we listen forPort 22# Use these options to restrict which interfaces/protocols sshd will bind to#ListenAddress ::#ListenAddress 0.0.0.0Protocol 2# HostKeys for protocol version 2HostKey /etc/ssh/ssh_host_rsa_keyHostKey /etc/ssh/ssh_host_dsa_keyHostKey /etc/ssh/ssh_host_ecdsa_key#Privilege Separation is turned on for securityUsePrivilegeSeparation yes!# Lifetime and size of ephemeral version 1 server keyKeyRegenerationInterval 3600ServerKeyBits 768# LoggingSyslogFacility AUTHLogLevel INFO# Authentication:LoginGraceTime 120
blue-bag
FIRST5: SSH - EXAMPLE"## README.md"## tasks& "## main.yml& %## ssh_config.yml"## templates& %## ssh_config.j2%## vars %## main.yml
# {{ ansible_managed }}# See the sshd_config(5) manpage for details!# What ports, IPs and protocols we listen forPort {{ ssh_port }}# Use these options to restrict which interfaces/protocols sshd will bind to#ListenAddress ::#ListenAddress 0.0.0.0Protocol 2# HostKeys for protocol version 2HostKey /etc/ssh/ssh_host_rsa_keyHostKey /etc/ssh/ssh_host_dsa_keyHostKey /etc/ssh/ssh_host_ecdsa_key#Privilege Separation is turned on for securityUsePrivilegeSeparation yes!# Lifetime and size of ephemeral version 1 server keyKeyRegenerationInterval 3600ServerKeyBits {{ ssh_server_key_bits }}# LoggingSyslogFacility AUTHLogLevel INFO# Authentication:LoginGraceTime {{ ssh_login_grace_time }}
blue-bag
FIRST5: SSH"## README.md"## tasks& "## main.yml& %## ssh_config.yml"## templates& %## ssh_config.j2%## vars %## main.yml# SSH Settings # optionally change port ssh_port: 22034 # reduce login grace time from 120 (2 minutes) ssh_login_grace_time: 20 # increase the server key bit encryption default=768 ssh_server_key_bits: 4096 # control the parallelism ssh_max_startups: 3:50:10 # control forwarding ssh_allow_tcp_forwarding: “no” ssh_allow_x11_forwarding: “no”
blue-bag
FIRST5: SSH"## README.md"## tasks& "## main.yml& %## ssh_config.yml"## templates& %## ssh_config.j2%## vars %## main.yml
--- - name: SSH Config | add ssh config file template: > src=ssh_config.j2 dest=/etc/ssh/sshd_config backup=yes notify: restart ssh
blue-bag
BASIC SECURITY: FIRST 5---- hosts: all gather_facts: true sudo: true! pre_tasks: - name: Pretask | Update apt cache apt: update_cache=yes cache_valid_time=3600! - name: Pretask | Run apt-get upgrade apt: upgrade=dist roles: - { role: base , tags: ["base"] } - { role: ntp , tags: ["ntp"] } - { role: user, tags: ["user"] } - { role: ssh , tags: ["ssh"] } - { role: fail2ban, tags: ["fail2ban"] } - { role: logwatch , tags: ["logwatch"] } - { role: exim , tags: ["exim"] } - { role: geerlingguy.firewall, tags: ["iptables"] } handlers: - include: common/handlers/main.yml
Don’t reinvent the wheelUse Galaxy Roleswhere relevant
blue-bag
ANSIBLE BASICS: PROVISION
--- - hosts: all roles: - geerlingguy.mysql - geerlingguy.apache - geerlingguy.php
A LAMP SERVER IN SIX LINES OF YAMLJeff Geerling - Ansible for Devops
blue-bag
BASIC SECURITY: SSL POODLE
- name: Apache security | SSL Poodle update lineinfile: dest=/etc/apache2/mods-available/ssl.conf regexp="{{ item.regexp }}" line="{{ item.line }}" backup=yes with_items: - { regexp: "^# enable only secure protocols:", line: "# enable only secure protocols: TLSv1, but not SSLv2 & SSLv3" } - { regexp: "^SSLProtocol", line: "SSLProtocol all -SSLv2 -SSLv3" } notify: restart apache tags: - poodle
blue-bag
BASIC SECURITY: SSL POODLE
- name: Apache security | SSL Poodle update template: src=ssl-poodle.conf.j2 dest=/etc/apache2/conf.d/ssl.conf notify: restart apache tags: - poodle
# {{ ansible_managed }}<IfModule mod_ssl.c>!# enable only secure protocols: TLSv1, but not SSLv2 & SSLv3SSLProtocol all -SSLv2 -SSLv3!</IfModule>
SSL-POODLE.CONF.J2
blue-bag
BASIC SECURITY: DRUPAL SECURITY
Ansible role quickly address security issues such as SA-CORE-2014-005
Inventory of Drupal sites
Task to apply patch
Test for vulnerability
Re-use for future patches
blue-bag
BASIC SECURITY: DRUPAL SECURITY"## common& "## handlers& & %## main.yml& %## vars& "## debian.yml& %## os_default.yml"## group_vars& "## all"## host_vars& %## local& %## example.server.net"## hosts"## log& %## ansible.log"## patch.yml"## roles %## SA-CORE-2014-005 "## README.md "## files & "## SA-CORE-2014-005-D7.patch & %## dbtng.patch "## meta & %## main.yml %## tasks %## main.yml
SA-CORE-2014-005
blue-bag
BASIC SECURITY: DRUPAL SECURITY
%## SA-CORE-2014-005 "## README.md "## files & "## SA-CORE-2014-005-D7.patch & %## dbtng.patch "## meta & %## main.yml %## tasks %## main.yml
SA-CORE-2014-005
blue-bag
BASIC SECURITY: DRUPAL SECURITY---!ansible_ssh_host: 123.123.123.123!webroot: "/var/www"!drupal7_sites: - { drupal_docroot: "{{ webroot }}/example.d7.site/live/htdocs”, vhost_name: "example.d7.site.live" } - { drupal_docroot: "{{ webroot }}/example.d7.site/dev/htdocs", vhost_name: “example.d7.site.dev" } - { drupal_docroot: "{{ webroot }}/example.d7.site/staging/htdocs", vhost_name: "example.d7.staging" } drupal6_sites: - { drupal_docroot: "{{ webroot }}example.d6.site", vhost_name: "example.d6.site" }
host_vars: example.server.net
blue-bag
BASIC SECURITY: DRUPAL SECURITY
---# tasks file for SA-CORE-2014-005-D7!- name: Drupal7 patch | get patch | SA-CORE-2014-005-D7. get_url: url: https://www.drupal.org/files/issues/SA-CORE-2014-005-D7.patch dest: /tmp/SA-CORE-2014-005-D7.patch!- name: Drupal7 patch | Apply the patch from the drupal docroot. shell: "patch -p1 < /tmp/SA-CORE-2014-005-D7.patch chdir={{ item.drupal_docroot }}" with_items: - "{{ drupal7_sites }}"!- name: Drupal7 patch | Clear Drupal caches. command: "drush cc all chdir={{ item.drupal_docroot }}" with_items: - "{{ drupal7_sites }}"
Role: SA-CORE-2014-005-D7 - main.yml
see blog post: http://www.midwesternmac.com/blogs/jeff-geerling/fixing-drupal-fast-using
blue-bag
BASIC SECURITY: DRUPAL SECURITY
!- name: Drupal6 patch | get patch | SA-CORE-2014-005-D7. copy: src=dbtng.patch dest=/tmp/SACORE2014005D6-dbtng.patch owner=root group=root mode=0644 - name: Drupal6 patch | Apply the patch from the drupal docroot. shell: "patch -p1 < /tmp/SACORE2014005D6-dbtng.patch chdir={{ item.drupal_docroot }}" with_items: - "{{ drupal6_sites }}" tags: D6
Role: SA-CORE-2014-005-D7 - main.yml - (cont..)
blue-bag
BASIC SECURITY: DRUPAL SECURITY
Subscribe to the security bulletins
Follow key Drupal people on twitter
Harden your Drupal installations
Use version control
Leave Wednesday nights free
blue-bag
Don’t use .htaccess
Migrate all .htaccess to vhosts
Get a static IP
Use custom robots.txt
BASIC SECURITY: DRUPAL SECURITY
blue-bag
CUSTOM ROBOTS.TXT
Won’t get overwritten by Drupal update
RewriteCond %{REQUEST_URI} ^/robots\.txt$ [NC] RewriteRule robots.txt$ myrobots.txt [L]
blue-bag
DRUPAL & VHOSTS
Disallow all txt other than robots.txt
Disallow all php other than index.php
Don’t use .htaccess
Migrate all .htaccess to vhosts
Get a static IP
Use custom robots.txt
blue-bag
NO PHP FILES OTHER THAN INDEX.PHP
<FilesMatch "([^index].php|[^myrobots|robots].*\.txt)$"> AuthName "Development" AuthUserFile /etc/apache2/.htpasswds/passwd AuthType basic Require valid-user Order deny,allow Deny from all Allow from 123.123.123.123 Allow from 127.0.0.1 Satisfy Any</FilesMatch>
blue-bag
DRUPAL & VHOSTS
Restrict file permissions (640 / 440)
Don’t use .htaccess
Migrate all .htaccess to vhosts
Get a static IP
Use custom robots.txt
Disallow all txt other than robots.txt
Disallow all php other than index.php
blue-bag
TEST BEFORE RESTART
$ apachectl configtestSyntax error on line 46 of example.local.conf:
RewriteRule: bad flag delimiters
$ apachectl configtest $ apachectl graceful
RewriteRule ^ index.php [L, NC]
RewriteRule ^ index.php [L,NC]
46
# If you are on RHEL/CentOS:$ apachectl -t$ /etc/init.d/httpd restart
blue-bag
BASIC SECURITY: DRUPAL SECURITY
Review your logs
Subscribe to the security bulletins
Follow key Drupal people on twitter
Harden your Drupal installations
Use version control
Leave Wednesday nights free
blue-bag
KEEP YOUR LOGS SLIM
## flag robots.txt requests - allow these to test robot behaviour SetEnvIf Request_URI "^/robots\.txt$" robots-request=log ## flag favicon requests SetEnvIf Request_URI "^/favicon\.ico$" favicon-request=nolog ## set do_not_log if any of the above flags are set SetEnvIf robots-request nolog do_not_log SetEnvIf favicon-request nolog do_not_log ## only log if do_not_log is not set CustomLog /var/www/log/mysite-access.log vcommon env=!do_not_log
blue-bag
KEEP YOUR LOGS SLIM## flag robots.txt requests - allow these to test robot behaviour SetEnvIf Request_URI "^/robots\.txt$" robots-request=log ## flag favicon requests SetEnvIf Request_URI "^/favicon\.ico$" favicon-request=nolog ## flag image, Css and JS requests and other static assets SetEnvIf Request_URI “.(eot|js|css|woff|gif|png|jp(e)g))$” is_static_asset=nolog ## flag cron calls SetEnvIf Request_URI "^(.*)cron.php$" cron-request=nolog ## flag monitor calls BrowserMatchNoCase NewRelicPinger monitor-request=nolog ## set do_not_log if any of the above flags are set SetEnvIf robots-request nolog do_not_log SetEnvIf favicon-request nolog do_not_log SetEnvIf image-request nolog do_not_log SetEnvIf is_static_asset nolog do_not_log SetEnvIf monitor-request nolog do_not_log ## only log if do_not_log is not set CustomLog /var/www/log/mysite-access.log vcommon env=!do_not_log
blue-bag
BASIC SECURITY: GENERAL SECURITY
Mod_securityDrupal specific rules and exclusionsmanage exclusions with Ansible
Know your application ‘surface’
blue-bag
## {{ ansible_managed }}!SecRule RESPONSE_STATUS "@streq 408" "phase:5,t:none,nolog,pass, setvar:ip.slow_dos_counter=+1, expirevar:ip.slow_dos_counter=60, id:'990002'"!SecRule IP:SLOW_DOS_COUNTER "@gt 5" "phase:1,t:none,log,drop, msg:'Client Connection Dropped due to high number of slow DoS alerts', id:'990003'"!SecRule ARGS "ansibletesttoseeifmodsisworking" "phase:1,log,deny,status:503,msg:'Test Rule',id:'990004'"!# Rules to allow good bots with no request header - Don’t do this!!# SecRule REQUEST_HEADERS:User-Agent "Google|Bing|Yandex" "phase:1,t:none,allow,nolog,ctl:ruleRemoveById=960015"# Do this (use Ansible to manage IP list / User-Agents are spoofed)SecRule REMOTE_ADDR "^66.249.64.165" phase:1,nolog,allow,ctl:ruleEngine=off,id:960015!<LocationMatch "/admin/structure/[pages|views|types]"> SecRuleRemoveById 981173 SecRuleRemoveById 960024 SecRuleRemoveById 981231</LocationMatch>
BASIC SECURITY: GENERAL SECURITY./templates/modsecurity_crs_48_local_exceptions.conf.j2
blue-bag
BASIC SECURITY: GENERAL SECURITY
Mod_securityDrupal specific rule and exclusionsmanage exclusions with Ansible
Fail2BanDrupal specific actions
IPTables - Whitelists
Remove all unused services
Consider log analysis servicese.g. loggly, paper trail, sumo logic
Know your application ‘surface’
blue-bag
ANSIBLE & DRUPAL
Put all sites in maintenance mode(Note: better to use maintenance site and re-point traffic to that so you can still work on your site on your ip)
Pull latest changes
Use in harmony with Drush
Clear caches and other Drush actionssee https://github.com/jenitehan/drupal_update_check
Extend Drush / Drupal to output JSON
Automate common tasks
blue-bag
BASIC SECURITY: DRUPAL SECURITY
Consider a platform provider
Subscribe to the security bulletins
Follow key Drupal people on twitter
Harden your Drupal installations
Use version control
Review your logs
Use security best practices
blue-bag
ANSIBLE & DRUPAL: EXAMPLE 2Use Case: Commerce site
Product Image updates
Replace the image(s)
Clear the Image Cache/ styles
blue-bag
ansible_ssh_host: 123.123.123.123ansible_ssh_user: ansibledrupal_sites: - “/var/www/mysite/live/htdocs” - “/var/www/mysite/staging/htdocs" - "/var/www/mysite/dev/htdocs"
ANSIBLE & DRUPAL: EXAMPLE 2./host_vars/server.example.com
./main.yml---- hosts: all gather_facts: false sudo: true! roles: - { role: updateimages , tags: ["updateimages"] }! handlers: - include: common/handlers/main.yml
./hosts[example]server.example.com
blue-bag
---# vars file for basefiles_src_path: “/path/to/local/updated/images”files_dest_path: “/sites/default/files”files_to_update: - “fa9001.jpg" - “fa9002.jpg" image_cache_folders: - “styles/thumbnail/public/product_images" - "styles/product_gallery/public/product_images" - "styles/medium_tall/public/product_images" - "styles/product_full/public/product_images"
ANSIBLE & DRUPAL: EXAMPLE 1./roles/updateimages/vars/main
---- name: clear drupal cache command: "drush cc all chdir={{ item }}" with_items: - "{{ drupal_sites }}"
./handlers/main.yml
blue-bag
- name: Image Update | Products copy: src={{ files_src_path }}/{{ item[1] }} dest={{ item[0] }}/{{ files_dest_path }}/product_images/{{ item[1] }} owner=www-data group=www-data mode:0644 with_nested: - drupal_sites - files_to_update tags: images notify: clear drupal cache!- name: Image Update | Update Cache file: > path={{ item[0] }}/{{ files_dest_path }}/{{ item[1] }}/{{ item[2] }} state=absent with_nested: - drupal_sites - image_cache_folders - files_to_update tags: images notify: clear drupal cache
ANSIBLE & DRUPAL: EXAMPLE 2./roles/updateimages/tasks/main.yml
blue-bag
RUN UPDATE
TASK: [updateimages | Image Update | Products] ****************
ok: [server.example.com] => (item=['/var/www/mysite/live/htdocs', 'fa9001.jpg']) => {"changed": false, "checksum": "9b36d8209ee8287385b1ce6af48bb033ade468a3", "dest": "/var/www/mysite/live/htdocs/sites/default/files/product_images/fa9001.jpg", "gid": 33, "group": "www-data", "item": "fa9001.jpg", "mode": "0644", "owner": "www-data", "path": “/var/www/mysite/live/htdocs/sites/default/files/product_images/fa9001.jpg", "size": 193018, "state": "file", "uid": 33}
changed: [server.example.com] => (item=['/var/www/mysite/staging/htdocs', 'fa9001.jpg']) => {"changed": true, "checksum": "e2d70c097b6fb5900045774e710cfbc9dcadde1a", "dest": "/var/www/mysite/staging/htdocs/sites/default/files/product_images/fa9001.jpg", "gid": 33, "group": "www-data", "item": "fa9001.jpg", "md5sum": "10df9698fd4f743fd199372255b15f33", "mode": "0644", "owner": "www-data", "size": 63598, "src": "/home/georgeb/.ansible/tmp/ansible-tmp-1420799222.5-262099501965035/source", "state": "file", "uid": 33}
changed: [server.example.com] => (item=['/var/www/mysite/dev/htdocs', 'fa9001.jpg']) => {"changed": true, "checksum": "e2d70c097b6fb5900045774e710cfbc9dcadde1a", "dest": "/var/www/mysite/dev/htdocs/sites/default/files/product_images/fa9001.jpg", "gid": 33, "group": "www-data", "item": "fa9001.jpg", "md5sum": "10df9698fd4f743fd199372255b15f33", "mode": "0644", "owner": "www-data", "size": 63598, "src": "/home/georgeb/.ansible/tmp/ansible-tmp-1420799222.5-262099501965035/source", "state": "file", "uid": 33}
$ ansible-playbook main.yml -l server.example.com -u ansible -K -v --tags "updateimages"
blue-bag
RUN UPDATE IMAGES PLAYTASK: [updateimages | Image Update | Update Cache] **************************
ok: [server.example.com] => (item=['thumbnail/public/product_images', 'fa9001.jpg']) => {"changed": false, "item": ["thumbnail/public/product_images", "fa9001.jpg"], "path": "/var/www/mysite/live/htdocs/sites/default/files/styles/thumbnail/public/product_images/fa9001.jpg", "state": “absent”}
changed: [server.example.com] => (item=['product_gallery/public/product_images', 'fa9001.jpg']) => {"changed": true, "item": ["product_gallery/public/product_images", "fa9001.jpg"], "path": "/var/www/mysite/live/htdocs/sites/default/files/styles/product_gallery/public/product_images/fa9001.jpg", "state": "absent"}
changed: [server.example.com] => (item=['medium_tall/public/product_images', 'fa9001.jpg']) => {"changed": true, "item": ["medium_tall/public/product_images", "fa9001.jpg"], "path": "/var/www/mysite/live/htdocs/sites/default/files/styles/medium_tall/public/product_images/fa9001.jpg", "state": "absent"}
changed: [server.example.com] => (item=['product_full/public/product_images', 'fa9001.jpg']) => {"changed": true, "item": ["product_full/public/product_images", "fa9001.jpg"], "path": "/var/www/mysite/live/htdocs/sites/default/files/styles/product_full/public/product_images/fa9001.jpg", "state": "absent"}
PLAY RECAP ********************************************************************
server.example.com : ok=2 changed=2 unreachable=0 failed=0
blue-bag
ANSIBLE TOOLS
Automate playbook runs
Collaborate
Log
Permissions
Scheduled runs
Push button deployment
Free for < 10 nodes
blue-bag
SOME USEFUL TOOLS
Unicode Code Converter: http://rishida.net/tools/conversion/
PHP Decoder / Hex Decoder: http://ddecode.com/phpdecoder/
Permissions Calculator: http://permissions-calculator.org/
RegEx:https://regex101.com/#pcre
Network Tools: CIDR masks etchttp://pingtool.org/
blue-bag
CONCLUSION / QUESTIONS
For all local development
use VLAD
http://git.io/DCB-Vlad
For Ansible get the books
https://leanpub.com/ansible-for-devops
http://www.ansible.com/ansible-book