Dutch PHP Conference 2016
It's a situation many of us are familiar with: a large legacy application, limited or no tests, slow & manual release process, low velocity, no confidence.... Oh, and management wants new features, fast.
But how to proceed? Using examples and lessons learned from a real-world case, I'll show you how to strangle the legacy application with a modern service architecture and build a continuous deployment pipeline to deliver value from the first sprint. On the way, we take a look at testing strategies and various (possibly controversial!) tips and best practices.
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
The road to continuous deployment: a case study (DPC16)
1. THE ROAD TO CONTINUOUS
DEPLOYMENT - A CASE STUDY
MICHIEL ROOK
2. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
ABOUT ME
▸ Java, PHP & Scala contractor
▸ PHP since ’99
▸ Maintainer of Phing
▸ Dutch Web Alliance
▸ http://www.linkedin.com/in/
michieltcs
▸ @michieltcs
3. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
THIS TALK
▸ Background
▸ The approach
▸ Process / standards
▸ Build pipelines
▸ Results & lessons learned
4.
5. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
THE SYSTEM - SAN DIEGO
▸ ... or the Big Ball Of Mud
▸ Large legacy monolith
▸ Generates significant income
▸ Slow
▸ Complex, lots of moving parts
▸ Technical debt
6. SAN DIEGO
FRONTEND
MYSQL
DB
SAN DIEGO
BACKEND
LOAD BALANCERS / VARNISH
ITBANEN INTERMEDIAIR NATIONALEVACATUREBANK
SAN DIEGO
FRONTEND
SAN DIEGO
FRONTEND
SAN DIEGO
FRONTEND
SAN DIEGO
BACKEND
SAN DIEGO
BACKEND
SAN DIEGO
BACKEND
MEMCACHE FTP
EXT.
SERVICES
SOLR
7. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
THE SYSTEM - SAN DIEGO
▸ 2.5% code coverage
▸ Fragile tests
▸ Low velocity
▸ Frequent outages / bugs / issues
▸ Frustrated team
▸ Low confidence modifying existing code
15. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
PROXY
# Serve job detail page from new code
RewriteRule ^/vacature/.* /app.php [L,PT]
# Proxy php files to php5-fpm
ProxyPassMatch ^/(app.php(/.*)?)$ fcgi://127.0.0.1:9000/opt/webapp/web/$1
# Proxy everything else to SanDiego
ProxyPass / ${SAN_DIEGO__URL} nocanon
ProxyPassReverse / ${SAN_DIEGO__URL}
ProxyPreserveHost On
16. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
FEATURE TOGGLES, A/B TESTS
18. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
PROCESS
▸ Scrum, 1 week sprints
▸ TDD / BDD
▸ Definition of Done
▸ Team mindset / experience
▸ Focus on value
▸ Replace old features with new (legacy becomes obsolete)
31. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
DEFENSE IN DEPTH
UNIT TESTS
SCENARIOS
INTEGRATION
SMOKE / PERF.
TESTS
MANUAL
TESTING?
32. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
UNIT TESTS
public function testGetById(){
$expectedJob = $this->getJob();
$this->jobRepository->getById($expectedJob->getId())
->shouldBeCalled()
->willReturn($expectedJob);
$this->assertEquals(
$expectedJob,
$this->jobService->getById($expectedJob->getId()
);
}
33. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
SCENARIOS
Scenario: As an API user I need to be able to retrieve a job
Given there is a valid job
When I retrieve a valid job
Then I should get a valid job resource
34. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
BUILDING
<project name="JobService" default="build">
<target name="build">
<delete file="jobservice.tar" quiet="true"/>
<tar destfile="jobservice.tar">
<fileset dir="src">
<include name="*.php"/>
</fileset>
</tar>
</target>
</project>
35. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
DOCKER
FROM php:7.0-apache
ADD vhost.conf /etc/apache2/sites-available/000-default.conf
ADD jobservice.tar /opt/webapp
RUN chown -R www-data:www-data /opt/webapp
36. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
DEPLOYING
PULL IMAGE
REMOVE FROM LOAD BALANCER
STOP CONTAINER
START NEW CONTAINER
WAIT FOR PORT
SMOKE TESTS / HEALTH CHECKS
ADD TO LOAD BALANCER
37. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
DEPLOYING
- name: remove instance from load balancer
haproxy: state=disabled host={{ inventory_hostname }} backend=jobservice
delegate_to: "{{ item }}"
with_items: groups.haproxy
- name: stop & remove old container
docker:
name: jobservice
state: absent
image: jobservice
- name: start container
docker:
name: jobservice
state: present
image: jobservice:{{ BUILD_NUMBER }}
ports:
- "8080:8080"
38. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
DEPLOYING
- name: perform health check
uri:
url: http://localhost:8080/_health
status_code: 200
timeout: 30
return_content: true
changed_when: False
register: result
until: result.content is defined and result.content.find("jobservice") != -1
retries: 10
delay: 3
- name: add instance to load balancer
haproxy: state=enabled host={{ inventory_hostname }} backend=jobservice
delegate_to: "{{ item }}"
with_items: groups.haproxy
39. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
BUILD PIPELINE
node {
stage 'Run tests'
sh "phpunit"
sh "behat"
stage 'Build docker image'
sh "phing build"
sh "docker build -t jobservice:${env.BUILD_NUMBER} ."
sh "docker push jobservice:${env.BUILD_NUMBER}"
stage 'Deploy acceptance'
sh "ansible-playbook -e BUILD_NUMBER=${env.BUILD_NUMBER} -i acc deploy.yml"
stage 'Deploy production'
sh "ansible-playbook -e BUILD_NUMBER=${env.BUILD_NUMBER} -i prod deploy.yml"
}
40. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
BUILD PIPELINE
43. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
RESULTS
▸ Total build time per service < 10 minutes
▸ Significantly improved page load times
▸ Improved audience stats (time on page, pages per session,
session duration, traffic, seo ranking, etc)
▸ Increased confidence and velocity
▸ Experimented with new tech/stacks (angular, jvm,
eventsourcing)
▸ More fun
44. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
LESSONS LEARNED
▸ Team acceptance
▸ Change is hard
▸ Overhead of weekly sprint; requires discipline
▸ Docker orchestration
▸ Issues with traffic between Amazon <-> on-premise
datacenter
▸ Javascript testing
45. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
LESSONS LEARNED
▸ Experience with new tech
▸ Stability of build pipelines
▸ Management/leadership buy-in
▸ Not enough focus on replacing legacy application
46. THE ROAD TO CONTINUOUS DEPLOYMENT - A CASE STUDY
QUESTIONS & DISCUSSION
Please leave feedback at https://joind.in/talk/4dab5
Thank you!