<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    
    
    

    

    <title type="text">Capgemini Software Engineering</title>
<generator uri="https://github.com/mojombo/jekyll">Jekyll</generator>
<link rel="self" type="application/atom+xml" href="https://capgemini.github.io/feed.Open source.xml"/>
<link rel="alternate" type="text/html" href="https://capgemini.github.io/"/>
<updated>2026-06-01T11:01:53+01:00</updated>
<id>https://capgemini.github.io/</id>
<author>
  <name>Capgemini</name>
  <uri>https://capgemini.github.io/</uri>
</author>

    
    <entry>
  <title type="html"><![CDATA[The ramblings of an open source newbie]]></title>
  <link rel="alternate" type="text/html" href="https://capgemini.github.io/open%20source/experiences-of-open-source/"/>
  <id>https://capgemini.github.io/open%20source/experiences-of-open-source</id>
  <published>2016-05-13T00:00:00+01:00</published>
  <updated>2016-05-13T00:00:00+01:00</updated>
  
  
  
  
  
  <author>
      <name>Gareth Sullivan</name>
      <uri>https://capgemini.github.io/alumni#author-gareth-sullivan</uri>
    </author>
  
  <category scheme="https://capgemini.github.io/tags/#Development" term="Development" /><category scheme="https://capgemini.github.io/tags/#Open%20source" term="Open source" />
  <content type="html">
    
    &lt;p&gt;As with most developers, I’ve used open source software.  As with most developers I expect to find this free, well documented, easy to use software within a few clicks and I expect it to perform and to deliver the advertised functionality.&lt;/p&gt;

&lt;p&gt;Having never contributed back to any open source projects, I was lured into helping with the newly created &lt;a href=&quot;https://github.com/Capgemini/spring-boot-capgemini&quot;&gt;spring-boot-capgemini&lt;/a&gt; project that would provide some useful common spring boot starters.  With Spring (and I still don’t know how this happened) being very new to me, it seemed a useful and effective way for me to put some of the theory into practice.&lt;/p&gt;

&lt;p&gt;I’m no writer, so some bullet points with some of my thoughts, experiences and perhaps some prompts for discussion will have to suffice.&lt;/p&gt;

&lt;h2 id=&quot;i-think-im-alone-now&quot;&gt;“I think I’m alone now”&lt;/h2&gt;

&lt;p&gt;Joining the project opened up multiple lines of communication via github issue tracking, emails, &amp;amp; &lt;a href=&quot;https://slack.com/&quot;&gt;slack&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I missed the face to face contact and the quick “can you just look at this over my shoulder, it’s bound to be something stupidly obvious”.  Slack was bamboozling me with too much detail - commits, builds and IMs notification were popping up continuously.&lt;/p&gt;

&lt;p&gt;I suggested a few changes to minimise the noise, but this resulted in a longer than expected discussion and debate, which again I felt could have just been sorted quickly had we sat down and discussed.&lt;/p&gt;

&lt;p&gt;I struggled when I got stuck with things - this wasn’t like my day job, I couldn’t tap up the many experts available to me.  The usual suspects (Google, StackOverflow) were useful to a point, but i did spend some time staring at slack, waiting for one of the other guys to come on line!&lt;/p&gt;

&lt;h2 id=&quot;learning-curves&quot;&gt;Learning curves&lt;/h2&gt;

&lt;p&gt;As previously mentioned, being new to Spring and Spring Boot I expected to struggle - but there were far more hurdles in the way than I expected.&lt;/p&gt;

&lt;p&gt;Gradle? Where’s Maven?  GitHub? Where’s SVN? Jenkins….where are you?&lt;/p&gt;

&lt;p&gt;I see this as a plus - being dragged out of your comfort zone and learning new technologies because you need to.  You have some context and specific goals, so you are more driven and focused to get past specific and relevant hurdles, rather than picking up something new, getting “Hello World!” out of the way and then wondering where to go now.&lt;/p&gt;

&lt;h2 id=&quot;whats-the-number-for-the-guys-in-support&quot;&gt;“What’s the number for the guys in support?”&lt;/h2&gt;

&lt;p&gt;I took on the task of integrating the repo with a build system.  I realised how spoiled I was on my day to day project work, with Jenkins a click away and someone else to fix and maintain it.&lt;/p&gt;

&lt;p&gt;Finding a solution compatible with our private repo was a challenge, but &lt;a href=&quot;https://circleci.com/&quot;&gt;circleci.com&lt;/a&gt; was chosen,	and again, configuring it, picking up YAML and getting it all working seamlessly, was down to me.&lt;/p&gt;

&lt;p&gt;On the flip side, you’re not bogged down with someone else’s choices - your project can have what you like as long as you sort it out and maintain it, although I imagine on an open source project of any serious scale, democracy and/or mob rule and even a &lt;a href=&quot;http://www.theatlantic.com/technology/archive/2014/01/on-the-reign-of-benevolent-dictators-for-life-in-software/283139/&quot;&gt;dictatorship&lt;/a&gt; decides the technology and infrastructure.&lt;/p&gt;

&lt;h2 id=&quot;quality-control&quot;&gt;Quality Control&lt;/h2&gt;

&lt;p&gt;Checkstyle issues breaking the build! I wasn’t expecting that, but at its inception it was the right time to make decisions like this.&lt;/p&gt;

&lt;p&gt;No time or cost considerations, no imminent deadlines - why not strive for the highest quality software? I have heard horror stories of simple pull requests turning into scathing attacks on people’s work, warring factions and even submitters not toeing the line being banned!&lt;/p&gt;

&lt;p&gt;This &lt;a href=&quot;http://www.theregister.co.uk/2015/11/01/linus_torvalds_fires_off_angry_compilermasturbation_rant/&quot;&gt;story&lt;/a&gt;, seemingly one of many examples of the Linux guru Linus Torvalds	 throwing his toys out of the pram, are testament to the “keyboard warrior” culture present in some open source environments.&lt;/p&gt;

&lt;p&gt;Every line of submitted code being reviewed, every checkin requiring a test - this is how it should be done. Does this discourage contributors, or does it just weed out the bad/lazy ones?&lt;/p&gt;

&lt;h2 id=&quot;documentation-is-king&quot;&gt;Documentation is King&lt;/h2&gt;

&lt;p&gt;“The code is the best documentation” - a quote I’ve heard several times, but in open source, surely the README.md file is the most important file in the repo? This is the project’s marketing, sales, and support, all in a file which will get rapidly scanned and form the basis of an opinion or decision - is this worth looking at let alone forking? Is it a serious contender compared to the competition? Is this project still even active and how well will it be supported if I choose to use it?&lt;/p&gt;

&lt;h2 id=&quot;longevity&quot;&gt;Longevity&lt;/h2&gt;

&lt;p&gt;The spring-boot-capgemini repo started off strong, enthusiasm was high and activity was sustained and productive. It tailed off however, day to day account work is always higher priority, and I wonder perhaps this was inevitable?&lt;/p&gt;

&lt;p&gt;When someone is paying for software, expecting features on a certain date, there is a drive to deliver, deadlines to hit, functionality to provide. On larger, more established open source projects I imagine this is the same, but how does a small open source project get to that point?&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;In conclusion, I think I have ended up with more questions than answers.&lt;/p&gt;

&lt;p&gt;The more I write the more I realise that the spring-boot-capgemini project is too small, too early in its lifecycle on which to base anything than a first impression of open source. I don’t feel I can make any firm opinions or judgements until I have looked into and/or contributed to a number of open source products, and that goes beyond just pulling in the jar as a dependency.&lt;/p&gt;

&lt;p&gt;That’s the great bit - the transparency, clue’s in the name, “open” source ! I can find how the libraries I use day to day are written, tested, documented, versioned, and released. I don’t need to be an active contributor, until I feel ready, and I choose what I contribute.&lt;/p&gt;

&lt;p&gt;I’m sure in time I’ll look back on this as a bit of a naive blog entry, and hopefully come back with some answers, backed up with experience.&lt;/p&gt;

    
    &lt;p&gt;&lt;a href=&quot;https://capgemini.github.io/open%20source/experiences-of-open-source/&quot;&gt;The ramblings of an open source newbie&lt;/a&gt; was originally published by Capgemini at &lt;a href=&quot;https://capgemini.github.io&quot;&gt;Capgemini Software Engineering&lt;/a&gt; on May 13, 2016.&lt;/p&gt;</content>
</entry>
    
    <entry>
  <title type="html"><![CDATA[Continuously deploying Apollo with Wercker]]></title>
  <link rel="alternate" type="text/html" href="https://capgemini.github.io/open%20source/continuously-deploying-apollo/"/>
  <id>https://capgemini.github.io/open%20source/continuously-deploying-apollo</id>
  <published>2015-07-03T00:00:00+01:00</published>
  <updated>2015-07-03T00:00:00+01:00</updated>
  
  
  
  
  
  <author>
      <name>Alberto Garcia Lamela</name>
      <uri>https://capgemini.github.io/alumni#author-alberto-garcia-lamela</uri>
    </author>
  
  
  
  <author>
      <name>Cam Parry</name>
      <uri>https://capgemini.github.io/alumni#author-cam-parry</uri>
    </author>
  
  <category scheme="https://capgemini.github.io/tags/#Development" term="Development" /><category scheme="https://capgemini.github.io/tags/#DevOps" term="DevOps" /><category scheme="https://capgemini.github.io/tags/#Continuous%20Integration" term="Continuous Integration" /><category scheme="https://capgemini.github.io/tags/#Continuous%20Delivery" term="Continuous Delivery" /><category scheme="https://capgemini.github.io/tags/#Continuous%20Deployment" term="Continuous Deployment" />
  <content type="html">
    
    &lt;p&gt;When deploying &lt;a href=&quot;https://github.com/Capgemini/Apollo&quot;&gt;Apollo&lt;/a&gt; it will create the cluster infrastructure in the cloud using an image built by &lt;a href=&quot;http://atlas.hashicorp.com/&quot;&gt;Atlas&lt;/a&gt; and &lt;a href=&quot;https://www.packer.io/&quot;&gt;Packer.&lt;/a&gt; Additionally, it will provision and configure the new machines providing a full PAAS ready for deploying containers across the datacenter.&lt;/p&gt;

&lt;p&gt;When dealing with several layers of abstraction and using many different technologies (Bash, Packer, &lt;a href=&quot;https://www.terraform.io/&quot;&gt;Terraform&lt;/a&gt;, &lt;a href=&quot;http://www.ansible.com/home&quot;&gt;Ansible&lt;/a&gt;, etc.) it is fairly easy to break things during development.&lt;/p&gt;

&lt;p&gt;We need to make sure we are not committing syntax errors, that every commit is deployable and that the behaviour of the platform with all the bits communicating to each other works as expected.&lt;/p&gt;

&lt;p&gt;Changes need to be continuously integrated and driven by tests. For this purpose we chose &lt;a href=&quot;http://wercker.com/&quot;&gt;Wercker&lt;/a&gt; out of a list of available CI as a service tools like &lt;a href=&quot;https://travis-ci.org/&quot;&gt;Travis&lt;/a&gt;, &lt;a href=&quot;https://circleci.com/&quot;&gt;circleci&lt;/a&gt;, &lt;a href=&quot;http://docs.drone.io/&quot;&gt;Drone&lt;/a&gt; and &lt;a href=&quot;http://docs.shippable.com/&quot;&gt;Shippable&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;“Wercker is an open automation platform for developing, building and delivering your applications” from the simplicity of a YAML file and it is highly customizable via &lt;a href=&quot;http://devcenter.wercker.com/learn/steps/step-registry.html&quot;&gt;custom steps&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For achieving our continuous deployment approach we’ll use two different pipelines: &lt;a href=&quot;http://devcenter.wercker.com/learn/build/introduction.html&quot;&gt;build&lt;/a&gt; and &lt;a href=&quot;http://devcenter.wercker.com/learn/build/introduction.html&quot;&gt;deploy&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;build&quot;&gt;Build&lt;/h2&gt;

&lt;p&gt;“Builds are the result of a run-through of the steps in the wercker pipeline. If all steps in the pipeline are successful, a build has passed”.&lt;/p&gt;

&lt;p&gt;Every time a Pull Request is created the build steps below will run:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Syntax checks against all our json packer templates using &lt;a href=&quot;https://www.packer.io/docs/command-line/validate.html&quot;&gt;packer validate&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;cwd&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;packer/&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;validate packer template for AMI&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;./packer validate ubuntu-14.04_amd64-amis.json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Linting checks against the ansible code using our custom &lt;a href=&quot;https://github.com/Capgemini/step-ansible-lint&quot;&gt;step-ansible-lint&lt;/a&gt; that relies on &lt;a href=&quot;https://github.com/willthames/ansible-lint&quot;&gt;https://github.com/willthames/ansible-lint&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;capgemini/ansible-lint:
  name: run ansible-lint against the site.yml playbook
  playbook: site.yml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/Capgemini/Apollo/blob/master/bootstrap/tests/test.sh&quot;&gt;Very simplistic Bash unit testing&lt;/a&gt; for ensuring our bash functions do what they are meant to do.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;scripts testing&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;cwd&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;bootstrap/tests&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;/bin/bash test.sh&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In the future we might be adding a new step here for “packer push” the images into &lt;a href=&quot;https://atlas.hashicorp.com/&quot;&gt;Atlas&lt;/a&gt; when merging into master branch.&lt;/p&gt;

&lt;p&gt;You can see the feedback for every build in wercker:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2015-07-03-continuously-deploying-apollo/builds.jpg&quot; alt=&quot;Fig 1. Wercker builds&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;deploy&quot;&gt;Deploy&lt;/h2&gt;

&lt;p&gt;Wercker allows you to deploy your application into supported platforms like Heroku or OpenShift or you can create you own Deployment Target.&lt;/p&gt;

&lt;p&gt;Every successful build from any specific commit can be deployed either automatically or manually.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2015-07-03-continuously-deploying-apollo/deploy.jpg&quot; alt=&quot;Fig 2. Wercker deploy&quot; /&gt;&lt;/p&gt;

&lt;p&gt;At the moment we are continuously deploying Apollo into Amazon and Digitalocean using a &lt;a href=&quot;https://github.com/Capgemini/step-apollo-deploy/&quot;&gt;step-apollo-deploy&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;deploy&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;install-packages&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;packages&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;wget unzip&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;pip-install&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;requirements_file&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;requirements.txt&quot;&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;capgemini/apollo-deploy&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;cloud&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$CLOUD&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;artifact_name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$ARTIFACT_NAME&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;artifact_version&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$ARTIFACT_VERSION&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;terraform_version&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;0.5.3&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;run_tests&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Environment variables can be set for every target you create in wercker:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2015-07-03-continuously-deploying-apollo/variables.jpg&quot; alt=&quot;Fig 3. Slack notification&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We have created &lt;a href=&quot;https://github.com/Capgemini/step-apollo-deploy/&quot;&gt;step-apollo-deploy&lt;/a&gt; step for:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Installing a given version of Terraform.&lt;/li&gt;
  &lt;li&gt;Deploying Apollo in parallel into multiple clouds.&lt;/li&gt;
  &lt;li&gt;Running different types of testing inside the vms. At the moment &lt;a href=&quot;http://serverspec.org/&quot;&gt;Serverspecs&lt;/a&gt; and &lt;a href=&quot;https://github.com/docker/docker-bench-security&quot;&gt;docker bench security.&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Destroying the whole platform.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every change in step-apollo-deploy is also continuously integrated by wercker itself using &lt;a href=&quot;https://github.com/wercker/step-validate-wercker-step&quot;&gt;step-validate-wercker-step&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;wercker/default&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;validate-wercker-step&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So in essence with both “build” and “deploy” in place we have the ability to automatically triggering a fully tested ephemeral Apollo deployment for any specific commit.&lt;/p&gt;

&lt;h2 id=&quot;test&quot;&gt;Test&lt;/h2&gt;

&lt;p&gt;We use ansible roles for installing and running &lt;a href=&quot;https://github.com/Capgemini/Apollo/tree/master/roles/dockerbench&quot;&gt;dockerbench&lt;/a&gt; and &lt;a href=&quot;https://github.com/Capgemini/Apollo/tree/master/roles/serverspec&quot;&gt;serverspecs&lt;/a&gt; covering components of Apollo:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Mesos&lt;/li&gt;
  &lt;li&gt;Marathon&lt;/li&gt;
  &lt;li&gt;Docker&lt;/li&gt;
  &lt;li&gt;Weave&lt;/li&gt;
  &lt;li&gt;Consul&lt;/li&gt;
  &lt;li&gt;Registrator&lt;/li&gt;
  &lt;li&gt;Dnsmasq&lt;/li&gt;
  &lt;li&gt;HAProxy&lt;/li&gt;
  &lt;li&gt;Zookeeper&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Testing during a deploy can be optionally enabled using a toggle environment variable.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;APOLLO_serverspec_run_tests&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true
export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;APOLLO_dockerbench_run_test&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;dockerbench&quot;&gt;Dockerbench&lt;/h3&gt;

&lt;p&gt;We have recently decided to try and integrate &lt;a href=&quot;https://github.com/Capgemini/Apollo/tree/master/roles/dockerbench&quot;&gt;dockerbench&lt;/a&gt; into our test suite.&lt;/p&gt;

&lt;p&gt;The Docker Bench for Security is a script that checks for all the automatable tests included in the &lt;a href=&quot;https://benchmarks.cisecurity.org/tools2/docker/CIS_Docker_1.6_Benchmark_v1.0.0.pdf&quot;&gt;CIS Docker 1.6 Benchmark &lt;/a&gt;. It gives INFO, PASS and WARNING messages for each of the tests that run. We run tests at deploy time, to check we haven’t slipped any unwanted security risks into our build. Currently we only test if WARNING’s are above a certain configurable threshold.&lt;/p&gt;

&lt;p&gt;The dockerbench project is still fairly young, and is still to settle on a standard way all tests can be run across any environment, whilst having configurable rules. We think this is a great project, as it allows us to bring security into our Continuous Integration cycle, which can decrease attack vectors and catch risks earlier in development cycles.&lt;/p&gt;

&lt;h3 id=&quot;serverspecs&quot;&gt;Serverspecs&lt;/h3&gt;

&lt;p&gt;Apollo default deployment provides 3 machines playing mesos master role and running zookeeper and marathon. As some configuration like the ips can be assigned on deployment time we need to populate some of the serverspecs dynamically by using an ansible &lt;a href=&quot;http://docs.ansible.com/template_module.html&quot;&gt;j2 template&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;curl --silent --show-error --fail --dump-header /dev/stderr --retry 2 http://{{ marathon_hostname }}:8080/v2/info&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;its&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;.*&quot;master&quot;:&quot;zk://&quot;{{ marathon_peers|join(&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;) }}/mesos&quot;.*&apos;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;its&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;.*&quot;zk&quot;:&quot;zk://{{ marathon_peers|join(&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;) }}/marathon&quot;.*&apos;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;its&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;.*&quot;name&quot;:&quot;marathon&quot;.*&apos;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;its&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;.*&quot;mesos_user&quot;:&quot;root&quot;.*&apos;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;its&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;.*&quot;executor&quot;:&quot;//cmd&quot;.*&apos;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;its&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:exit_status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eq&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Below are some examples with more of the serverspecs we run for marathon:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;docker_container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;marathon&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;be_running&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;have_volume&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;/store&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;/etc/marathon/store&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8080&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;be_listening&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/usr/local/bin/marathon-wait-for-listen.sh&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;its&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:exit_status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eq&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;marathon&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;be_running&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;under&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;upstart&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;curl -s -XPOST 127.0.0.1:8080/v2/apps -d@spec/marathon/sample.json -H &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Content-Type: application/json&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &amp;amp;&amp;amp; sleep 3&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;its&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:exit_status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eq&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;curl -s 127.0.0.1:8080/v2/deployments&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;its&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;[]&apos;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;its&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:exit_status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eq&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;curl -s 127.0.0.1:8080/v2/apps/serverspecs-app&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;its&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;.*&quot;id&quot;:&quot;/serverspecs-app&quot;.*&apos;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;its&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;.*&quot;tasksRunning&quot;:1.*&apos;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;its&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:exit_status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eq&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;feedback&quot;&gt;Feedback&lt;/h2&gt;

&lt;p&gt;Finally we get the feeback for the deployment in every cloud in our Slack channel using &lt;a href=&quot;https://github.com/wantedly/step-pretty-slack-notify&quot;&gt;wantedly/pretty-slack-notify&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;after-steps&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;wantedly/pretty-slack-notify&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;webhook_url&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$SLACK_WEBHOOK_URL&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;channel&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;apollo&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;wercker-bot&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/images/2015-07-03-continuously-deploying-apollo/slack.png&quot; alt=&quot;Fig 4. Slack notification&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You can check out the &lt;a href=&quot;https://github.com/Capgemini/Apollo/blob/master/wercker.yml&quot;&gt;full wercker.yml file here&lt;/a&gt;
and below is a video showing the whole cycle:&lt;/p&gt;

&lt;div class=&quot;small-12 medium-8 large-4 small-centered columns&quot;&gt;
  &lt;div class=&quot;flex-video&quot;&gt;
    &lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/ApSa8J_8SF8&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h2 id=&quot;whats-next&quot;&gt;What’s next&lt;/h2&gt;

&lt;p&gt;If for your use case you need to keep track of the state of Terraform you might find this &lt;a href=&quot;https://hashicorp.com/blog/atlas-terraform-github.html&quot;&gt;Atlas and GitHub integration&lt;/a&gt; useful.&lt;/p&gt;

&lt;p&gt;Check out our upcoming posts if you want to hear more about CI, CD and our Continuous Delivery approach for services running inside docker containers deployed by Apollo, running Serverspecs into ephemeral containers via “docker exec” across multiple environments.&lt;/p&gt;

    
    &lt;p&gt;&lt;a href=&quot;https://capgemini.github.io/open%20source/continuously-deploying-apollo/&quot;&gt;Continuously deploying Apollo with Wercker&lt;/a&gt; was originally published by Capgemini at &lt;a href=&quot;https://capgemini.github.io&quot;&gt;Capgemini Software Engineering&lt;/a&gt; on July 03, 2015.&lt;/p&gt;</content>
</entry>
    
    <entry>
  <title type="html"><![CDATA[Automation as a way of thinking... and docker]]></title>
  <link rel="alternate" type="text/html" href="https://capgemini.github.io/open%20source/automation/"/>
  <id>https://capgemini.github.io/open%20source/automation</id>
  <published>2014-11-10T00:00:00+00:00</published>
  <updated>2014-11-10T00:00:00+00:00</updated>
  
  
  
  
  
  <author>
      <name>Alberto Garcia Lamela</name>
      <uri>https://capgemini.github.io/alumni#author-alberto-garcia-lamela</uri>
    </author>
  
  <category scheme="https://capgemini.github.io/tags/#Docker" term="Docker" /><category scheme="https://capgemini.github.io/tags/#Fig" term="Fig" /><category scheme="https://capgemini.github.io/tags/#Puppet" term="Puppet" /><category scheme="https://capgemini.github.io/tags/#Behat" term="Behat" /><category scheme="https://capgemini.github.io/tags/#DevOps" term="DevOps" /><category scheme="https://capgemini.github.io/tags/#Testing" term="Testing" /><category scheme="https://capgemini.github.io/tags/#Automation" term="Automation" />
  <content type="html">
    
    &lt;p&gt;Automation is a key and essential fact when solving problems and assembling pieces together. By automating you only need to do the same thing once, reducing the possibility of human errors so it helps to increase quality, efficiency and productivity with less effort.&lt;/p&gt;

&lt;h3 id=&quot;the-everyday-life&quot;&gt;The everyday life&lt;/h3&gt;
&lt;p&gt;It doesn’t matter what programming language, technologies or tools you use. It doesn’t matter what sector of Software Engineering you are focused on and it doesn’t really matter which discipline you work on. I would say automation can be more of a way of thinking that could even be applied to almost everything in your everyday life.&lt;/p&gt;

&lt;p&gt;When you automate a process you are creating and increasing productivity whether the process is “a virtual machine provision”, “the steps you follow since you wake up until you get into the office” or “flirting with somebody”. You are giving an automatic solution to a problem by creating a system with the ability for saving, reading and reproducing a series of steps for achieving an objective that is going to save you time in the future.&lt;/p&gt;

&lt;p&gt;When you face and solve the same or similar problems again and again you soon realise patterns and known techniques (e.g: &lt;a href=&quot;http://en.wikipedia.org/wiki/Don&apos;t_repeat_yourself&quot;&gt;DRY&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Information_hiding&quot;&gt;Information hiding&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Open/closed_principle&quot;&gt;Open/closed principle&lt;/a&gt;, etc.) that will help you create a better design. Once you identify a regular pattern for solving a problem, you can then reuse this pattern every time you are building an automatic solution with common characteristics. But these patterns are not magic, they are always dependent to the context so you will need to suit them for fitting in your context. (E.g: There is no universal way to “break the ice with” a person as the reaction can be different depending on who you are approaching…)&lt;/p&gt;

&lt;h3 id=&quot;going-back-to-the-it-world&quot;&gt;Going back to the IT world&lt;/h3&gt;
&lt;p&gt;Going back to the IT world, we are always trying to find, create and contribute to the best tools for automating our processes and ensuring high quality, reliable and scalable solution delivery to any users and clients we work with.
In this &lt;a href=&quot;https://github.com/enxebre/fig-docker-uat&quot;&gt;repo you can see the technical details&lt;/a&gt; of one solution that fits together a traditional Virtual Machine, &lt;a href=&quot;https://docs.puppetlabs.com/&quot;&gt;puppet&lt;/a&gt;, &lt;a href=&quot;https://docs.docker.com/installation/&quot;&gt;docker&lt;/a&gt;, &lt;a href=&quot;http://www.fig.sh/&quot;&gt;fig&lt;/a&gt; and a behaviour-driven development framework (&lt;a href=&quot;http://docs.behat.org/en/v2.5/&quot;&gt;E.g. Behat&lt;/a&gt;) for automating the creation and execution of an &lt;strong&gt;ephemeral User Acceptance Testing environment.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We use the power of the &lt;a href=&quot;http://docs.docker.com/reference/builder/&quot;&gt;dockerfiles&lt;/a&gt; for reusing the “uat_environment” puppet module (a wrapper over &lt;a href=&quot;https://forge.puppetlabs.com/jhoblitt/selenium&quot;&gt;selenium module&lt;/a&gt; and its dependencies) and create a docker image with selenium running.&lt;/p&gt;

&lt;p&gt;A “behat service” will be created to check if the selenium container is ready using the script inspired by &lt;a href=&quot;https://github.com/aanand/docker-wait&quot;&gt;docker-wait&lt;/a&gt; so it will run behat, which code is passed as a volume to the container.&lt;/p&gt;

&lt;p&gt;We use  &lt;a href=&quot;http://www.fig.sh/&quot;&gt;fig&lt;/a&gt; for running the &lt;a href=&quot;https://github.com/docker/docker/blob/master/README.md&quot;&gt;containers&lt;/a&gt; and managing our basic UAT environment.
You can add as many selenium services as you need to your fig.yml and run different behaviour-tests projects simultaneously because as we are &lt;a href=&quot;http://docs.docker.com/userguide/dockerlinks/&quot;&gt;linking containers&lt;/a&gt; we don’t have to worry about port collision troubles.&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;selenium:
 build: dockerfiles/selenium-image
behat:
 build: dockerfiles/behat-image
 volumes:
  - behat/:/behat/
 links:
  - selenium:selenium
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Run “fig up” or any other fig command for automating and orchestrating your services.&lt;/p&gt;

&lt;h4 id=&quot;here-is-a-list-to-summarise-some-of-the-benefits&quot;&gt;Here is a list to summarise some of the benefits:&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;As we only need to run processes in isolation here docker containers will be fast and less consuming than traditional Virtual Machines.&lt;/li&gt;
  &lt;li&gt;By using “fig” you can easily scale your UAT environment.&lt;/li&gt;
  &lt;li&gt;As we are passing the BDD Framework as a volume, the environment is totally decoupled from the code.&lt;/li&gt;
  &lt;li&gt;The environment can be recreated and destroyed as many times as you need without being consuming resources unnecessarily in the meantime.&lt;/li&gt;
  &lt;li&gt;Everything is under version control system and is reusable.&lt;/li&gt;
  &lt;li&gt;You can now run “fig” from Jenkins or any other Continuous Integration tool.&lt;/li&gt;
&lt;/ul&gt;

    
    &lt;p&gt;&lt;a href=&quot;https://capgemini.github.io/open%20source/automation/&quot;&gt;Automation as a way of thinking... and docker&lt;/a&gt; was originally published by Capgemini at &lt;a href=&quot;https://capgemini.github.io&quot;&gt;Capgemini Software Engineering&lt;/a&gt; on November 10, 2014.&lt;/p&gt;</content>
</entry>
    
    <entry>
  <title type="html"><![CDATA[Automated testing for POODLE]]></title>
  <link rel="alternate" type="text/html" href="https://capgemini.github.io/open%20source/testing-for-poodle/"/>
  <id>https://capgemini.github.io/open%20source/testing-for-poodle</id>
  <published>2014-10-10T00:00:00+01:00</published>
  <updated>2014-10-10T00:00:00+01:00</updated>
  
  
  
  
  
  <author>
      <name>Mike Wallis</name>
      <uri>https://capgemini.github.io/alumni#author-mike-wallis</uri>
    </author>
  
  <category scheme="https://capgemini.github.io/tags/#Testing" term="Testing" /><category scheme="https://capgemini.github.io/tags/#DevOps" term="DevOps" /><category scheme="https://capgemini.github.io/tags/#Infrastructure" term="Infrastructure" /><category scheme="https://capgemini.github.io/tags/#Security" term="Security" />
  <content type="html">
    
    &lt;p&gt;Why should systems and infrastructure not be treated in the same way as other
software components, especially when it comes to implementing security concerns.
With today’s POODLE &lt;a href=&quot;http://googleonlinesecurity.blogspot.co.uk/2014/10/this-poodle-bites-exploiting-ssl-30.html&quot;&gt;announcement&lt;/a&gt; of another SSL vulnerability it makes sense to
add infrastructure tests to your regression tests&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://serverspec.org&quot;&gt;ServerSpec&lt;/a&gt; is a solid way of testing for this, and can be done as follows:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;describe &lt;span class=&quot;nb&quot;&gt;command&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;openssl s_client -connect localhost:443 -ssl3 &amp;lt; /dev/null&apos;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do
    &lt;/span&gt;its&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;:exit_status&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; should eq 1 &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    its&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;:stdout&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; should match /no peer certificate available/ &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Use of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt; /dev/null&lt;/code&gt; is to force the openssl client to terminate instead of
waiting for input from the shell as we are only interested in the key exchange.&lt;/p&gt;


    
    &lt;p&gt;&lt;a href=&quot;https://capgemini.github.io/open%20source/testing-for-poodle/&quot;&gt;Automated testing for POODLE&lt;/a&gt; was originally published by Capgemini at &lt;a href=&quot;https://capgemini.github.io&quot;&gt;Capgemini Software Engineering&lt;/a&gt; on October 10, 2014.&lt;/p&gt;</content>
</entry>
    
    <entry>
  <title type="html"><![CDATA[Reflections on Symfony Live London 2014]]></title>
  <link rel="alternate" type="text/html" href="https://capgemini.github.io/open%20source/symfony-live/"/>
  <id>https://capgemini.github.io/open%20source/symfony-live</id>
  <published>2014-10-10T00:00:00+01:00</published>
  <updated>2014-10-10T00:00:00+01:00</updated>
  
  
  
  
  
  <author>
      <name>Tom Phethean</name>
      <uri>https://capgemini.github.io/authors#author-tom-phethean</uri>
    </author>
  
  <category scheme="https://capgemini.github.io/tags/#Development" term="Development" /><category scheme="https://capgemini.github.io/tags/#Symfony" term="Symfony" /><category scheme="https://capgemini.github.io/tags/#Drupal" term="Drupal" /><category scheme="https://capgemini.github.io/tags/#Conferences" term="Conferences" />
  <content type="html">
    
    &lt;p&gt;At the end of September, I went to my first “non-Drupal” PHP event,
&lt;a href=&quot;http://london2014.live.symfony.com/&quot;&gt;Symfony Live London 2014&lt;/a&gt;. With Symfony components
becoming a large part of Drupal 8 it was an excellent opportunity to learn a bit about
what it all means, and meet the Symfony community. I’ve dabbled with Drupal 8,
and we use some Symfony components in our existing Drupal 6 and 7 projects, so I
wasn’t coming in completely cold.&lt;/p&gt;

&lt;h3 id=&quot;decoupling-for-re-use&quot;&gt;Decoupling for re-use&lt;/h3&gt;

&lt;p&gt;Throughout the conference, I was struck by how much focus there was on re-use,
decoupling and framework interoperability. It was the most common thread running
through both days - from a workshop diving &lt;a href=&quot;http://london2014.live.symfony.com/workshops/#into-the-kernel-and-back&quot;&gt;into the depths of the HTTPKernel&lt;/a&gt;,
talks on avoiding &lt;a href=&quot;https://speakerdeck.com/jakzal/the-dependency-trap&quot;&gt;The Dependency Trap&lt;/a&gt;
 and &lt;a href=&quot;http://ddd.io/sflive-london14-stack&quot;&gt;building composable HTTP middlewares using Stack&lt;/a&gt; -
 as well as one I couldn’t make it to, which covered &lt;a href=&quot;http://www.slideshare.net/everzet/decoupling-with-design-patterns-and-symfony2-dic&quot;&gt;Decoupling with design patterns&lt;/a&gt; -
 all driving home a message of using frameworks to give you power, but to ensure
 your code has minimal dependencies and maximum opportunity for re-use.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“Decoupled code is easier to maintain, easier to re-use, easier to read”&lt;/p&gt;

  &lt;p&gt;&lt;cite&gt;&lt;a href=&quot;https://twitter.com/jakub_zalas&quot;&gt;Jakub Zalas&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;the-naked-bundle&quot;&gt;The Naked Bundle&lt;/h3&gt;

&lt;p&gt;Top among these presentations for me though, was &lt;a href=&quot;http://london2014.live.symfony.com/speakers/#matthias-noback&quot;&gt;The Naked Bundle&lt;/a&gt;
presented by &lt;a href=&quot;https://twitter.com/matthiasnoback&quot;&gt;Matthias Noback&lt;/a&gt;. Matthias focused on how the bundle (Symfony’s equivalent
of a module) could be stripped back to the minimum Symfony specific code, and merely
act as a bridge between the framework and your business logic (which, he asserted,
  has no place belonging in a framework specific implementation, and should be in
  its own standalone, interoperable library).&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“The framework is for you, but your code doesn’t need it”&lt;/p&gt;

  &lt;p&gt;&lt;cite&gt;&lt;a href=&quot;https://twitter.com/matthiasnoback&quot;&gt;Matthias Noback&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The short summary of The Naked Bundle was the premise that it should be easy to take
your business logic and expose it to a Symfony bundle, a Laravel package, a Drupal
module - it’s all PHP after all. Rather than repeat the talk here, I’ll direct you to
the &lt;a href=&quot;http://www.slideshare.net/matthiasnoback/the-naked-bundle-symfony-live-london-2014&quot;&gt;excellent slides&lt;/a&gt;
describing a number of approaches to meet this goal.&lt;/p&gt;

&lt;h3 id=&quot;drupal-modules&quot;&gt;Drupal modules&lt;/h3&gt;

&lt;p&gt;The concept of a Naked Bundle has some direct relevancy for the Drupal world. We’re
in the middle of the Drupal 7 lifecycle, many of us still supporting or evolving
Drupal 6 sites, and most of us looking forward to Drupal 8 and the changes that it
will bring to the Drupal ecosystem. It’s therefore not unreasonable that a large number
of Drupal developers are building functionality which may be in use on three versions of Drupal,
or maybe more, not to mention the likelihood of Drupal developers looking at
other solutions for some sites, whether it be Symfony, Laravel or something different.&lt;/p&gt;

&lt;h3 id=&quot;the-naked-module&quot;&gt;The Naked Module?&lt;/h3&gt;

&lt;p&gt;So then, is the Naked Module a concept worth considering? Why not move as much
business logic as possible into interoperable PHP libraries which get pulled into
Drupal via a bridge module? There’s obviously a fine line to tread in ensuring
you don’t throw out all the benefits of Drupal’s core and contrib functionality, but
if building something specific to your domain then there’s a lot to be said for
this approach:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Portability - PHP libraries are more easily moved between Drupal versions, or to
other frameworks altogether. Migrating functionality from one version of Drupal to another
therefore becomes much less of an issue, as your custom code is now less coupled to
specific versions.&lt;/li&gt;
  &lt;li&gt;Testability - a standalone PHP library is more easily unit testable, regardless of
whether it’s going to be used in Drupal or not.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;how&quot;&gt;How?&lt;/h3&gt;

&lt;p&gt;In projects at Capgemini, we’re already using several approaches which lets us get
some way towards this concept:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Writing domain specific logic in standalone libraries, for example, code to handle
 creation, validation and manipulation of business objects implemented in PHP classes,
 and called out to from Drupal hooks&lt;/li&gt;
  &lt;li&gt;Integrating with internal or external remote services via a service wrapper which can again
be called from within the Drupal module&lt;/li&gt;
  &lt;li&gt;Using the &lt;a href=&quot;https://www.drupal.org/project/composer_manager&quot;&gt;Composer Manager&lt;/a&gt; to
include these PHP libraries in our Drupal installations so that they can be managed separately to
site or module repositories&lt;/li&gt;
  &lt;li&gt;Using a shared ORM and DBAL such as Doctrine to access custom database objects consistently
regardless of Drupal version or framework, particularly when they don’t need to be
Entities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most, if not all, of these approaches are already in use in the community, for example &lt;a href=&quot;https://github.com/commerceguys/addressing&quot;&gt;Commerce Guys
recently released a generic PHP addressing library&lt;/a&gt;
to handle creating, manipulating and formatting postal addresses for shipping or billing
across different countries. Providing this as a generic library rather than hiding it in a
Drupal module means the support for this logic can benefit the entire PHP community.&lt;/p&gt;

&lt;h3 id=&quot;libraries-first&quot;&gt;Libraries first&lt;/h3&gt;

&lt;p&gt;As Matthias stated in his Naked Bundle talk, it’s only sensible to seek &lt;strong&gt;practical
reusability&lt;/strong&gt;. In the case of Symfony bundles an example of an allowed dependency would be
the HTTPFoundation classes and trusting the HTTPKernel.&lt;/p&gt;

&lt;p&gt;In Drupal, we’d want to take advantage of existing hooks, and well defined, well tested APIs 
rather than re-inventing things. However, with a libraries first approach, modules can be
made smaller, slimmer, avoid framework specific conventions and dependencies,
and simply expose resources to add rich domain specific functionality for easier
porting to other versions or frameworks.&lt;/p&gt;

    
    &lt;p&gt;&lt;a href=&quot;https://capgemini.github.io/open%20source/symfony-live/&quot;&gt;Reflections on Symfony Live London 2014&lt;/a&gt; was originally published by Capgemini at &lt;a href=&quot;https://capgemini.github.io&quot;&gt;Capgemini Software Engineering&lt;/a&gt; on October 10, 2014.&lt;/p&gt;</content>
</entry>
    
</feed>
