<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-gb"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://serialseb.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://serialseb.com/" rel="alternate" type="text/html" hreflang="en-gb" /><updated>2025-11-05T21:50:33+00:00</updated><id>https://serialseb.com/feed.xml</id><title type="html">SerialSeb</title><subtitle>SerialSeb</subtitle><author><name>Sebastien Lambla</name><email>seb@serialseb.com</email></author><entry><title type="html">Happy old year</title><link href="https://serialseb.com/blog/2016/12/31/happy-old-year/" rel="alternate" type="text/html" title="Happy old year" /><published>2016-12-31T11:00:00+00:00</published><updated>2016-12-31T11:00:00+00:00</updated><id>https://serialseb.com/blog/2016/12/31/happy-old-year</id><content type="html" xml:base="https://serialseb.com/blog/2016/12/31/happy-old-year/"><![CDATA[<p>It is customary to wish people a happy new year, to take on new year’s resolutions, and generally to celebrate the upcoming unknown. Rather than do this, I’d like to take a second, for we have an extra one in 2016, to look back on 2016, and thank all the people that have made it what it was: a year I’ll remember with fondness.</p>

<p>This year has been the best in a long time. I’ve relaunched this website, spoke at conferences in many countries on two continents, met hundreds of you, restarted work on both OpenRasta and “the book”, albeit not as much as I’d have liked, launched the httpapis.com chat room, worked with great clients and even greater people, laughed, cried and generally lived. There were a few downs, some friendships disappeared, some people upset unintentionally, some projects didn’t happen, and on my path of self discovery, some cuts and life changes had to be made. So is life, up and downs often feed one another. I wouldn’t have had any of the great times without an amazing group of people around me, and for once I’d like to tell them how much it all means to me. I may edit the post as I remember more names, I do apologise to anyone I forgot, it’s probably only temporary!</p>

<p>Thank you to my family, for having me, being there, inviting me to share your happy and your less happy moments. I’m very glad and very lucky to have such a fulfilling environment. A special thank you to mom, for being there through everything over the past 35 years, such endurance! Than you to Dominique, for making LA peaceful for me; Thank you Nana for organising a surprise birthday dinner, first one I ever had. Thank you to all the others, I love you all, you know who you are.</p>

<p>Thank you to my friends, old and new. Jon and Simon, always there in my life. We’re ageing rather well, and I hope we continue Friday nights for many years to come. Thank you to my favourite BA, Rossana, I’m so glad to see you grow year on year, your strength and determination is a lesson to us all. Thank you to Marion, Pierre, Marie, Christina and Alessandro, for all the good moments we have in Monaco; Colin and Paul, ever present, kindest spirits, Scotland feels at home thanks to you; Didier, you made it in Barcelona, thanks for a great night; Richard, I don’t see enough of you, but you’re with me on all my easyjet flights nevertheless.</p>

<p>I can’t not mention all the geeks I have spent such a good time with, and I am very privileged to call friends: Toby, for being the best maintainer of OpenRasta since ever; Ian for making sure hugs go around, people and repositories alike; Liam without which cheese wouldn’t have the same appeal; Dylan, a rock I have had the privilege of hanging on many times; Ben and Barbara, so many dinners, good times and swimming pool moments, one of you get a ring on it already; Barry and Nikky for being the best hosts in Seattle, the seafood buttered orgy memories will stay with me forever; Glenn, for the great times in Portland, our conversations, and your enormous kindness; Chris and Joao, I wouldn’t enjoy lunches without you, and your work to promote diversity is so badly needed in our industry; Adam, Vancouver wouldn’t be the same without you, and no I won’t switch to Linux in 2017, maybe the year after :-P; Jef, those selfies turned out pretty great, and thank you for making me discover the wonders of Caesar cocktails, they’re pretty awesome.</p>

<p>You spend a lot of time with clients, and I’ve been very lucky to work alongside pretty awesome people: Dave, welcome to adulthood; Nigel and Chris, Brighton was such a fun time, just what I needed to start the year on a high note; Allan, Simon, Atif, Matt, Aaron, Sam and the others, you make that office fun to be in, here’s hoping I spend more time there.</p>

<p>Conferences have been amazing this year, and it wouldn’t happen without organisers sweating their arse off for months to enable us a platform for sharing knowledge. I can’t mention you all, it takes a village, but a few special mentions are in order, in no particular order: Jakob, you make NDC great, and that beach day and dinner was awesome, we should do more of that; Iva for making Las Vegas happen; Dominika and the whole crew at get.net, your dedication and support went well beyond the call of duty, thank you for everything you did; Andreas for tirelessly giving me more speaking space at Oredev, I had such fun in no small parts thanks to you; Anna and Yann, for being the most organised and efficient planners I’ve ever met, and even better skiers, thanks for the opportunity to discover Whistler and Vancouver; Todd for making conferences in pubs possible, I can’t believe you managed to haggle that jumper from that waitress, this is tons of awesome.</p>

<p>Sickness is part of life, and this year has been very tough on the people around me. I’ve done the dryathlon in September, and collected a bit of money for cancer research, because I think of you all often: Laurie, Violaine, Morten, Patrick, Steven and Anthony, your strength of character is enlightening. 
To those that didn’t pull through, thank you for having been in my life: Mark, I will never look at a Guinness without thinking of you, you would have loved your send off so much; Pieter, you loved your send off, and I’ll always be grateful for your guidance, late night skype sessions, and your guide to psychopaths, I was brought out of the darkness in part thanks to your vision.</p>

<p>Thank you to the people of the two slacks I always stay on, ddd-cqrs-es and httpapis, your insights are humbling, and banter refreshing: Damian, Dan, Joao, Adam Ralph, James G, Mike Amundsen, and all the others.
And for those that were in my life and no longer are, I wish you all the best in your endeavours, let your future be bright and your life full of love and happiness.</p>

<p>Happy old year to one and all.</p>]]></content><author><name>Sebastien Lambla</name><email>seb@serialseb.com</email></author><summary type="html"><![CDATA[It is customary to wish people a happy new year, to take on new year’s resolutions, and generally to celebrate the upcoming unknown. Rather than do this, I’d like to take a second, for we have an extra one in 2016, to look back on 2016, and thank all the people that have made it what it was: a year I’ll remember with fondness.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://serialseb.com/404" /><media:content medium="image" url="https://serialseb.com/404" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">VeST Redux – What’s so wrong with mocking frameworks?</title><link href="https://serialseb.com/blog/2016/09/13/what-is-so-wrong-with-mocking-libs/" rel="alternate" type="text/html" title="VeST Redux – What’s so wrong with mocking frameworks?" /><published>2016-09-13T09:00:00+01:00</published><updated>2016-09-13T09:00:00+01:00</updated><id>https://serialseb.com/blog/2016/09/13/what-is-so-wrong-with-mocking-libs</id><content type="html" xml:base="https://serialseb.com/blog/2016/09/13/what-is-so-wrong-with-mocking-libs/"><![CDATA[<p>While working on a project, on a nice summer day, and after many hours of
frustration and disbelief at my incapacity to make sense of some test code
using a mocking framework, I expressed an opinion I wanted to share with you.</p>

<blockquote>
  <p><strong>Mocking frameworks are actively harmful, and probably infringe on my human
rights.</strong></p>
</blockquote>

<p>It’s not just a matter of taste, there are fundamental issues that make it
harder to design good and maintainable software.</p>

<h2 id="they-lead-to-code-duplication">They lead to code duplication</h2>

<p>The code starts simple enough, you write a class, you mock the first interface’s
method it implements, test pass, you move on to your next test.</p>

<p>After you write 50 tests, you end up with 50 implementations of the
same method, littered all over your testing code. Some will argue that it’s just
a matter of reusing and refactoring your test code. If you’re going to reuse
your mocking setup, then…</p>

<h2 id="they-are-a-poor-way-to-implement-a-class">They are a poor way to implement a class</h2>

<p>I <a href="https://serialseb.com/blog/2007/12/13/why-mock-frameworks-suck-and-how-to/">already made that point a long time ago</a>: mocking frameworks
are a poor way to implement fakes. The code is noisy, with some frameworks it
does not refactor well, and let’s face it, no amount of magic will compete with
writing classes in an actual language.</p>

<p>If you have a one-off method on one interface that has 50, and you are already
in hell, maybe a mocking framework will help you. Those cases are rare and
don’t explain how often these things get used. Given the choice, I’d split
the interface into smaller chunks, and test that. It’s easier and result in
cleaner and simple code, and seggregates functionality as you refactor.</p>

<h2 id="they-often-introduce-incorrect-contracts">They often introduce incorrect contracts</h2>

<p>The author of a class or interface is the closest to knowing the contract.
Understanding when the code throws, what arguments can be null or not, and what
values will cause error is a matter for the contract author to define. This is
done in documentation, type systems and / or pre/post conditions.</p>

<p>When you fake an interface you don’t own, you have to re-implement this
contract, and often you will not know enough to implement this correctly. In
a VeST library, the author would be the one providing the test double for you.
If you do not, then implementing a fake only once, by refactoring it
continuously with your new understanding of the contract will allow your whole
testing codebase to improve under those scenarios.</p>

<p>It’s however very common for you to own the interface, the implementation and
the consumer, at which point you’re in the best position to do the right thing,
and ship fast in-memory versions of the implementations you expect people to
use.</p>

<p>If you don’t, you risk hitting the next issue.</p>

<h2 id="they-break-encapsulation">They break encapsulation</h2>

<p>An object, in object-oriented development, is by definition encapsulating data
and behaviour. Each object is a black box, that you can tell to act, hence the
<a href="http://martinfowler.com/bliki/TellDontAsk.html">“tell, don’t ask” mantra</a>.</p>

<p>Because an object may use one or many dependencies, building the code by stubbing
each method of a dependency as you go along, you implement in your test a lot
of knowledge of the inside functioning of your class. This breaks encapsulation,
which makes your tests brittle, and refactorings harder.</p>

<h2 id="they-introduce-extra-dependencies">They introduce extra dependencies</h2>

<p>Out of all the issues I’ve already discussed, this is probably the least visible
immediately, especially in a world of package managers.</p>

<p>Over time, frameworks and libraries are like fashion, they get in quick and
loud, and they get replaced by younger, slimmer next generations, and on and on.</p>

<p>Your test code, just like your applicationcode, suffers from this. The cost of
rewriting all test doubles using littered mocking frameworks is high, and you
hit the <a href="http://martinfowler.com/bliki/TellDontAsk.html">pit of failure</a>. It doesn’t get done. You end up in
nonsensical situations, having 4 mocking frameworks in the same library, in
code that hasn’t been refactored or touched in years. This code is, for all 
intent and puproses, dead. And mocking frameworks were probably an accessory to
murder.</p>

<h2 id="they-lead-to-auto-mocking-containers">They lead to auto-mocking containers</h2>

<p>This was a thing for a long time, and it is very unfortunate that people still
try to do this. The combination of containers, automocking and large dependency
trees result in many issues that make code more and more costly to keep.</p>

<p>Large amounts of dependency in a class is a tell-tale sign it’s doing too much.
Stop feeding that class new responsabilities and split it.</p>

<p>Large dependency graphs often are because it’s easy to take a dependency, and
results in overly-complicated levels of abstractions that serve no purpose. You
neither need a repository wrapping a data access class wrapping an actual vendor
library, nor do you need 3 levels of logging frameworks talking to one another.</p>

<p>And finally, the encapsulation breakage is worse than with a single class, it
now pans out to a whole object tree, making your tests even more brittle.
Friends don’t let friends use auto-mocking containers.</p>

<h2 id="they-allow-for-interaction-testing-too-easily">They allow for interaction testing too easily</h2>

<p>I mention this only for the sake of completeness, because that’s one part of
mocking that is not used as much anymore. Interaction testing wants to know
how and how often dependencies’ methods are called. This is even more
non-sensical than the precedent breakages of encapsulation, you write a class
and write a test to verify exactly what the class ends up doing.</p>

<p>Interaction testing has a place, but it’s very small, in a very limited number
of scenarios where it’s not possible to test visible effects of the various
calls made to a system.</p>

<h2 id="conclusion">Conclusion</h2>

<p>Mocking frameworks are nearly always the wrong choice: they are not a good way
to write classes, they lead to the path of brittleness, badly factored code,
unwildly class hiearchies, and code duplication.</p>

<p>Do yourself a favour, write in-memory fakes and ship them alongside your code.</p>]]></content><author><name>Sebastien Lambla</name><email>seb@serialseb.com</email></author><category term="vest" /><category term="mocking" /><summary type="html"><![CDATA[While working on a project, on a nice summer day, and after many hours of frustration and disbelief at my incapacity to make sense of some test code using a mocking framework, I expressed an opinion I wanted to share with you.]]></summary></entry><entry><title type="html">Architecture in code</title><link href="https://serialseb.com/blog/2016/08/18/architecture-in-code/" rel="alternate" type="text/html" title="Architecture in code" /><published>2016-08-18T19:38:00+01:00</published><updated>2016-08-18T19:38:00+01:00</updated><id>https://serialseb.com/blog/2016/08/18/architecture-in-code</id><content type="html" xml:base="https://serialseb.com/blog/2016/08/18/architecture-in-code/"><![CDATA[<p>When we build systems, we model the world around us: models, commands, events,
resources, they’re all intellectual spectres of reality that help us reason. 
Yet, most of the code we build tends to focus on implementation. From the code,
you would have no way of knowing what models you used.</p>

<p>Messaging is a good example. I’ve been working on distributed messaging systems
for eons now, and I see the same implementation over and over again.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// not an actual library</span>
<span class="n">MyAwesomeQueueSystem</span>
  <span class="p">.</span><span class="nf">ListenOn</span><span class="p">(</span><span class="nf">MyFabTopicNameBuilder</span><span class="p">(</span><span class="s">"home"</span><span class="p">))</span>
  <span class="p">.</span><span class="nf">IntoQueue</span><span class="p">(</span><span class="s">"reaction"</span><span class="p">)</span>
  <span class="p">.</span><span class="nf">Handle</span><span class="p">(</span><span class="n">message</span> <span class="p">=&gt;</span> <span class="k">new</span> <span class="nf">MyHandler</span><span class="p">().</span><span class="nf">Handle</span><span class="p">(</span><span class="n">message</span><span class="p">));</span>

<span class="k">class</span> <span class="nc">MyHandler</span> <span class="p">:</span> <span class="n">IHandle</span><span class="p">&lt;</span><span class="n">Event</span><span class="p">&gt;</span> <span class="p">{</span>
  <span class="k">void</span> <span class="nf">Handle</span><span class="p">(</span><span class="n">Event</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">Event</span> <span class="k">is</span> <span class="n">Spider</span><span class="p">)</span>
      <span class="n">me</span><span class="p">.</span><span class="nf">Jump</span><span class="p">();</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>If you look at this code as-is, you can only know that a thing happens that
causes a message to be posted and a “handler” to “handle” said message.</p>

<p>In reality, external stimulii often trigger certain actions from us, which 
themselves cause other events. An enormous spider next to me may make me jump
which may well result into me breaking glasses. I have external stimulii that
I know, like spiders crawling, which are events. I have commands, like jumping. I have breaking
glasses, which are other events.</p>

<p>Now that explanation makes sense, but the code is not giving you that. The code
gives you a very different explanation. The sun, through thermonuclear reaction
causes photons to travel at the speed of light all the way through my windows to
my sofa, which get scattered by a calcium-based molecular structure, hitting my
retina. Through a set of neurons interconnected through electrochemical
 connections, triggers a flight response, releasing a high dose
of adrenaline, causing an automatic muscular response…</p>

<p>The description is now too detailed, and it becomes very hard to know why I
broke the glass. It would also become increasingly difficult to explain to you
various other reactions that would lead me to break the glass. Without a model,
I can’t explain clearly that a divorce and a zombie would also cause me to break
glass.</p>

<p>In terms of code, the fact that we focus on the low level of event subscription
doesn’t allow us to do anything but what the procedural code dictates,
introducing systematic variance, not due to need but due to having no model.</p>

<p>It also prevents us from reflecting on the model. I used to have panic attacks
when boarding plane, which for a conference hopper is a rather problematic
condition. It’s only once I managed to model my triggers, and model my commands,
that I managed to get rid of it. All the same, in code, without a model that
can be introspected on, I have no way of reflecting on what my software does, 
be it that I want to understand it, or like <a href="http://www.codingthearchitecture.com/blogentries/1.html">Simon Brown</a> does,
document, graph and represent it.</p>

<p>Instead of going for pure messaging, model your messaging patterns to encode
in your code what concepts they implement. For example, instead of the 
<code class="language-plaintext highlighter-rouge">IHandle&lt;T&gt;</code>, why not model what you do?</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">interface</span> <span class="nc">IHandleComponentCommand</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="p">{</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">interface</span> <span class="nc">IListenToExternalEvent</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="p">{</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Going one step further, both OpenRasta and FubuMvc used to favour the idea of
a configuration model, where all information about your system are pulled into
before you actually spin up the system. This allows any further component to
have enough information to configure queues, add http handlers, and everything
else you may need to spin up the software.</p>

<p>If your model is not rich enough to generate all the plumbing from it, then
your model is insufficient to document what your software does. And when you
need something that your model can’t cope with, update your model.</p>]]></content><author><name>Sebastien Lambla</name><email>seb@serialseb.com</email></author><category term="architecture" /><summary type="html"><![CDATA[When we build systems, we model the world around us: models, commands, events, resources, they’re all intellectual spectres of reality that help us reason. Yet, most of the code we build tends to focus on implementation. From the code, you would have no way of knowing what models you used.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://serialseb.com/404" /><media:content medium="image" url="https://serialseb.com/404" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Don’t version your HTTP APIs</title><link href="https://serialseb.com/blog/2016/08/01/dont-version-apis/" rel="alternate" type="text/html" title="Don’t version your HTTP APIs" /><published>2016-08-01T07:17:00+01:00</published><updated>2016-08-01T07:17:00+01:00</updated><id>https://serialseb.com/blog/2016/08/01/dont-version-apis</id><content type="html" xml:base="https://serialseb.com/blog/2016/08/01/dont-version-apis/"><![CDATA[<p>Infoq has <a href="https://www.infoq.com/news/2016/07/web-api-versioning">released an article covering</a> <a href="https://serialseb.com/evilver">my talk on “Versioning is evil”</a>,
which is awesome. I’m preparing new content for the blog about the subject,
and a new version of the talk for later in the year, which will complete and expand on
this.</p>

<p>Thanks to all that attended this talk at NDC and Progressive.net!</p>]]></content><author><name>Sebastien Lambla</name><email>seb@serialseb.com</email></author><category term="http" /><category term="rest" /><category term="evilver" /><summary type="html"><![CDATA[Infoq has released an article covering my talk on “Versioning is evil”, which is awesome. I’m preparing new content for the blog about the subject, and a new version of the talk for later in the year, which will complete and expand on this.]]></summary></entry><entry><title type="html">HTTP APIs’ Slack room is live!</title><link href="https://serialseb.com/blog/2016/06/21/http-apis-slack-is-live/" rel="alternate" type="text/html" title="HTTP APIs’ Slack room is live!" /><published>2016-06-21T12:29:00+01:00</published><updated>2016-06-21T12:29:00+01:00</updated><id>https://serialseb.com/blog/2016/06/21/http-apis-slack-is-live</id><content type="html" xml:base="https://serialseb.com/blog/2016/06/21/http-apis-slack-is-live/"><![CDATA[<p>HTTP APIs, from the RPC-style all the way to ReST, are difficult to discuss over twitter. Fear not, we now have a solution.</p>

<p>You can join the <a href="http://slack.httpapis.com">HTTP APIs Slack channel</a> now.</p>

<p>There isn’t a code of conduct yet, but I’ll be discussing with the community to set one up shortly. In the meantime, be kind, be nice, and think of others.</p>

<p>Feel free to share the link with your communities. Welcome.</p>]]></content><author><name>Sebastien Lambla</name><email>seb@serialseb.com</email></author><category term="http" /><category term="rest" /><summary type="html"><![CDATA[HTTP APIs, from the RPC-style all the way to ReST, are difficult to discuss over twitter. Fear not, we now have a solution.]]></summary></entry><entry><title type="html">How to always be right on the Internets</title><link href="https://serialseb.com/blog/2016/06/11/how-to-be-right/" rel="alternate" type="text/html" title="How to always be right on the Internets" /><published>2016-06-11T21:21:00+01:00</published><updated>2016-06-11T21:21:00+01:00</updated><id>https://serialseb.com/blog/2016/06/11/how-to-be-right</id><content type="html" xml:base="https://serialseb.com/blog/2016/06/11/how-to-be-right/"><![CDATA[<p>Thanks to everyone that came to <a href="http://pubconf.io">PubConf</a>. In case you wonder how to always be right on the Internets by leveraging fallacies, the slides are now available on the <a href="https://serialseb.com/speaker/fallacies/">talk’s page</a>. Don’t hesitate to comment there!</p>]]></content><author><name>Sebastien Lambla</name><email>seb@serialseb.com</email></author><category term="speaking" /><summary type="html"><![CDATA[Thanks to everyone that came to PubConf. In case you wonder how to always be right on the Internets by leveraging fallacies, the slides are now available on the talk’s page. Don’t hesitate to comment there!]]></summary></entry><entry><title type="html">Progressive.net</title><link href="https://serialseb.com/blog/2016/06/10/progressivedotnet/" rel="alternate" type="text/html" title="Progressive.net" /><published>2016-06-10T13:03:00+01:00</published><updated>2016-06-10T13:03:00+01:00</updated><id>https://serialseb.com/blog/2016/06/10/progressivedotnet</id><content type="html" xml:base="https://serialseb.com/blog/2016/06/10/progressivedotnet/"><![CDATA[<p>If anyone is wondering what to do later this month, we’re having an amazing line-up for progresive.net, June 22nd to 23rd.</p>

<p>I’ll be presenting a newer version of my <a href="https://serialseb.com/evilver/">“versioning is evil – how to do without in your http apis”</a>, with code samples.</p>

<p>If you haven’t yet, <a href="https://t.co/7uUKicRSwH">register now</a> and use the code SPECIAL_LDNUG_PROGNET for 40% off, but be quick, the offer expires soon!</p>]]></content><author><name>Sebastien Lambla</name><email>seb@serialseb.com</email></author><category term="speaking" /><summary type="html"><![CDATA[If anyone is wondering what to do later this month, we’re having an amazing line-up for progresive.net, June 22nd to 23rd.]]></summary></entry><entry><title type="html">Speaking updates</title><link href="https://serialseb.com/blog/2016/05/23/speaking-updates/" rel="alternate" type="text/html" title="Speaking updates" /><published>2016-05-23T13:03:00+01:00</published><updated>2016-05-23T13:03:00+01:00</updated><id>https://serialseb.com/blog/2016/05/23/speaking-updates</id><content type="html" xml:base="https://serialseb.com/blog/2016/05/23/speaking-updates/"><![CDATA[<p>Having just finished a couple of contracts, I have a bit of time to refocus on finishing off this site a bit. That means I’m available for work by the way :)</p>

<p>I’ve had a great weekend recelty at <a href="http://ddd.scot">DDD Scotland</a>, if you haven’t been, just go. The atmosphere is lovely, the conversations interesting, the food good the attendees (and organisers!) very friendly.</p>

<p>I presented two talks, my <a href="https://serialseb.com/speaker/versions-are-evil/">Versions are evil</a> talk on how to avoid versions in Web APIs, and a new one, <a href="https://serialseb.com/speaker/aliceagile/">Alice in Agile Wonderland</a>, a keynote-style story of all that goes wrong in the wonderland of agile, which I had much fun delivering.</p>

<p>Comment sections have been added to the various talks, so if you have been there and want to continue the conversation, there’s a place to do that. I’ll post the various ratings for each of the talk as the next update to this site, and if I get a bit more time all the questions I can find that were asked at each of those talks.</p>

<p>I’m also thrilled to be presenting at <a href="http://ndcoslo.com">NDC Oslo</a> a revamped version of the “Versions are evil talk”, at <a href="https://pubconf.io">PubConf Oslo</a> with “How to always be right on the internet”, and to be presenting at <a href="http://oredev.org">Oredev</a> a bit later in the year with a completely new talk. I’m hoping to see you there!</p>]]></content><author><name>Sebastien Lambla</name><email>seb@serialseb.com</email></author><category term="speaking" /><summary type="html"><![CDATA[Having just finished a couple of contracts, I have a bit of time to refocus on finishing off this site a bit. That means I’m available for work by the way :)]]></summary></entry><entry><title type="html">Working around the lack of count in Terraform modules</title><link href="https://serialseb.com/blog/2016/05/11/terraform-working-around-no-count-on-module/" rel="alternate" type="text/html" title="Working around the lack of count in Terraform modules" /><published>2016-05-11T15:50:00+01:00</published><updated>2016-05-11T15:50:00+01:00</updated><id>https://serialseb.com/blog/2016/05/11/terraform-working-around-no-count-on-module</id><content type="html" xml:base="https://serialseb.com/blog/2016/05/11/terraform-working-around-no-count-on-module/"><![CDATA[<p>Terraform modules  do not currently support <code class="language-plaintext highlighter-rouge">count</code>, and so reusing a module a dynamic number of ways is impossible. To work around this, we can rely on a small DSL and <code class="language-plaintext highlighter-rouge">null_resources</code>.</p>

<p>Same advice as previous entries apply, this is advanced stuff, harder to read and more complex, use with caution and for good reason.</p>

<p>Let’s imagine that I have a module that spins up a variable number of machines, one per release branch in my source control system. Due to the dynamic nature of this, and without access to <code class="language-plaintext highlighter-rouge">count</code> on module, i’d either have to use a templating language, something i’m not happy doing, or I’d use a little dsl.</p>

<p>I’ll define my module with a variable called instances, with a format I invent, a coma-separated list of instance names and their instance types, themselves separated with a colon.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>variable "instances" { default = "webserver:t2.micro,api:t2.small" }
</code></pre></div></div>

<p>We already know that <code class="language-plaintext highlighter-rouge">split</code> allows us to have collections by splitting strings, so the initial, and pretty unreadable, first step is to abuse string interpolation as is.</p>

<div class="language-tf highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">resource</span> <span class="s2">"aws_instance"</span> <span class="s2">"servers"</span> <span class="p">{</span>
  <span class="c1">// number of servers is simply the string split by coma</span>
  <span class="nx">count</span> <span class="p">=</span> <span class="s2">"</span><span class="k">${</span><span class="nx">length</span><span class="p">(</span><span class="nx">split</span><span class="p">(</span><span class="s2">","</span><span class="p">,</span><span class="kd">var</span><span class="p">.</span><span class="nx">instances</span><span class="p">))</span><span class="k">}</span><span class="s2">"</span>
  <span class="c1">// name is the first bit in each string</span>
  <span class="nx">name</span> <span class="p">=</span> <span class="s2">"</span><span class="k">${</span><span class="nx">element</span><span class="p">(</span><span class="nx">split</span><span class="p">(</span><span class="s2">":"</span><span class="p">,</span><span class="nx">element</span><span class="p">(</span><span class="nx">split</span><span class="p">(</span><span class="s2">","</span><span class="p">,</span><span class="kd">var</span><span class="p">.</span><span class="nx">instances</span><span class="p">),</span><span class="nx">count</span><span class="p">.</span><span class="nx">index</span><span class="p">)),</span> <span class="mi">1</span><span class="p">)</span><span class="k">}</span><span class="s2">"</span>
  <span class="nx">instance_type</span> <span class="p">=</span> <span class="s2">"</span><span class="k">${</span><span class="nx">element</span><span class="p">(</span><span class="nx">split</span><span class="p">(</span><span class="s2">":"</span><span class="p">,</span><span class="nx">element</span><span class="p">(</span><span class="nx">split</span><span class="p">(</span><span class="s2">","</span><span class="p">,</span><span class="kd">var</span><span class="p">.</span><span class="nx">instances</span><span class="p">),</span><span class="nx">count</span><span class="p">.</span><span class="nx">index</span><span class="p">)),</span> <span class="mi">1</span><span class="p">)</span><span class="k">}</span><span class="s2">"</span>
<span class="p">}</span>
</code></pre></div></div>

<p>My brain has already melted. Things get a bit easier if you pass lists around, but not that much.</p>

<p>One alternative is to create a instances and instance_types variables, keeping two lists in sync makes interpolation a bit less obtuse, but as a user makes things pretty hard to get right.</p>

<p>Another one is to use the less-known <code class="language-plaintext highlighter-rouge">null_resource</code>. We abuse its triggers a little bit by doing the splitting there instead, which allows us to give nicer names to things.</p>

<div class="language-tf highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">resource</span> <span class="s2">"null_resource"</span> <span class="s2">"let"</span> <span class="p">{</span>
  <span class="c1">// we reuse this in all counts because count only interpolates from variables</span>
  <span class="nx">count</span> <span class="p">=</span> <span class="s2">"</span><span class="k">${</span><span class="nx">length</span><span class="p">(</span><span class="nx">split</span><span class="p">(</span><span class="s2">","</span><span class="p">,</span><span class="kd">var</span><span class="p">.</span><span class="nx">instances</span><span class="p">))</span><span class="k">}</span><span class="s2">"</span>
  <span class="nx">triggers</span> <span class="p">{</span>
    <span class="c1">// we do the coma splitting here text splitting here</span>
    <span class="nx">server_raw</span> <span class="p">=</span> <span class="s2">"</span><span class="k">${</span><span class="nx">element</span><span class="p">(</span><span class="nx">split</span><span class="p">(</span><span class="s2">","</span><span class="p">,</span> <span class="kd">var</span><span class="p">.</span><span class="nx">instances</span><span class="p">),</span><span class="nx">count</span><span class="p">.</span><span class="nx">index</span><span class="p">)</span><span class="k">}</span><span class="s2">"</span>
  <span class="p">}</span>
<span class="p">}</span>
<span class="k">resource</span> <span class="s2">"null_resource"</span> <span class="s2">"servers"</span> <span class="p">{</span>
  <span class="nx">count</span> <span class="p">=</span> <span class="s2">"</span><span class="k">${</span><span class="nx">length</span><span class="p">(</span><span class="nx">split</span><span class="p">(</span><span class="s2">","</span><span class="p">,</span><span class="kd">var</span><span class="p">.</span><span class="nx">instances</span><span class="p">))</span><span class="k">}</span><span class="s2">"</span>
  <span class="nx">triggers</span> <span class="p">{</span>
    <span class="c1">// we do the colon splitting here</span>
    <span class="nx">name</span> <span class="p">=</span> <span class="s2">"</span><span class="k">${</span><span class="nx">element</span><span class="p">(</span><span class="nx">split</span><span class="p">(</span><span class="s2">":"</span><span class="p">,</span><span class="nx">element</span><span class="p">(</span><span class="nx">null_resource</span><span class="p">.</span><span class="nx">let</span><span class="p">.</span><span class="o">*</span><span class="p">.</span><span class="nx">triggers</span><span class="p">.</span><span class="nx">server_raw</span><span class="p">,</span> <span class="nx">count</span><span class="p">.</span><span class="nx">index</span><span class="p">)),</span><span class="mi">0</span><span class="p">)</span><span class="k">}</span><span class="s2">"</span>
    <span class="nx">instance_type</span> <span class="p">=</span> <span class="s2">"</span><span class="k">${</span><span class="nx">element</span><span class="p">(</span><span class="nx">split</span><span class="p">(</span><span class="s2">":"</span><span class="p">,</span><span class="nx">element</span><span class="p">(</span><span class="nx">null_resource</span><span class="p">.</span><span class="nx">let</span><span class="p">.</span><span class="o">*</span><span class="p">.</span><span class="nx">triggers</span><span class="p">.</span><span class="nx">server_raw</span><span class="p">,</span> <span class="nx">count</span><span class="p">.</span><span class="nx">index</span><span class="p">)),</span><span class="mi">1</span><span class="p">)</span><span class="k">}</span><span class="s2">"</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>We’ve now kept all the nasty string processing somewhere away from our resources. It has an added bonus, the tf plan is rather useful to read:</p>

<div class="language-tf highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">+</span> <span class="nx">null_resource</span><span class="err">.</span><span class="nx">let</span><span class="err">.</span><span class="mi">0</span>
    <span class="nx">triggers</span><span class="err">.</span><span class="c1">#:          "" =&gt; "1"</span>
    <span class="nx">triggers</span><span class="err">.</span><span class="nx">server_raw</span><span class="err">:</span> <span class="s2">""</span> <span class="err">=&gt;</span> <span class="s2">"web:t2.micro"</span>

<span class="err">+</span> <span class="nx">null_resource</span><span class="err">.</span><span class="nx">let</span><span class="err">.</span><span class="mi">1</span>
    <span class="nx">triggers</span><span class="err">.</span><span class="c1">#:          "" =&gt; "1"</span>
    <span class="nx">triggers</span><span class="err">.</span><span class="nx">server_raw</span><span class="err">:</span> <span class="s2">""</span> <span class="err">=&gt;</span> <span class="s2">"app:t2.small"</span>

<span class="err">+</span> <span class="nx">null_resource</span><span class="err">.</span><span class="nx">servers</span><span class="err">.</span><span class="mi">0</span>
    <span class="nx">triggers</span><span class="err">.</span><span class="c1">#:             "" =&gt; "2"</span>
    <span class="nx">triggers</span><span class="err">.</span><span class="nx">instance_type</span><span class="err">:</span> <span class="s2">""</span> <span class="err">=&gt;</span> <span class="s2">"t2.micro"</span>
    <span class="nx">triggers</span><span class="err">.</span><span class="nx">name</span><span class="err">:</span>          <span class="s2">""</span> <span class="err">=&gt;</span> <span class="s2">"web"</span>

<span class="err">+</span> <span class="nx">null_resource</span><span class="err">.</span><span class="nx">servers</span><span class="err">.</span><span class="mi">1</span>
    <span class="nx">triggers</span><span class="err">.</span><span class="c1">#:             "" =&gt; "2"</span>
    <span class="nx">triggers</span><span class="err">.</span><span class="nx">instance_type</span><span class="err">:</span> <span class="s2">""</span> <span class="err">=&gt;</span> <span class="s2">"t2.small"</span>
    <span class="nx">triggers</span><span class="err">.</span><span class="nx">name</span><span class="err">:</span>          <span class="s2">""</span> <span class="err">=&gt;</span> <span class="s2">"app"</span>
</code></pre></div></div>

<p>We can now declare our instances using some better symbolic names.</p>

<div class="language-tf highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">resource</span> <span class="s2">"aws_instance"</span> <span class="s2">"servers"</span> <span class="p">{</span>
  <span class="c1">// kept so we can interpolate correctly</span>
  <span class="nx">count</span> <span class="p">=</span> <span class="s2">"</span><span class="k">${</span><span class="nx">length</span><span class="p">(</span><span class="nx">split</span><span class="p">(</span><span class="s2">","</span><span class="p">,</span><span class="kd">var</span><span class="p">.</span><span class="nx">instances</span><span class="p">))</span><span class="k">}</span><span class="s2">"</span>
  
  <span class="nx">name</span> <span class="p">=</span> <span class="s2">"</span><span class="k">${</span><span class="nx">element</span><span class="p">(</span><span class="nx">null_resource</span><span class="p">.</span><span class="nx">servers</span><span class="p">.</span><span class="nx">triggers</span><span class="p">.</span><span class="o">*</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">count</span><span class="p">.</span><span class="nx">index</span><span class="p">)</span><span class="k">}</span><span class="s2">"</span>
  <span class="nx">instance_type</span> <span class="p">=</span> <span class="s2">"</span><span class="k">${</span><span class="nx">element</span><span class="p">(</span><span class="nx">null_resource</span><span class="p">.</span><span class="nx">servers</span><span class="p">.</span><span class="nx">triggers</span><span class="p">.</span><span class="o">*</span><span class="p">.</span><span class="nx">instance_type</span><span class="p">,</span> <span class="nx">count</span><span class="p">.</span><span class="nx">index</span><span class="p">)</span><span class="k">}</span><span class="s2">"</span>
<span class="p">}</span>
</code></pre></div></div>

<p>If you can’t avoid the complexity, with this trick you keep it localised and more readable. Terraform will soon allow lists and maps passed to modules, but count is still somewhat far off. If you’re interested in an alternative syntax I suggested, check out the <a href="https://github.com/hashicorp/terraform/issues/4084">github issue</a>.</p>]]></content><author><name>Sebastien Lambla</name><email>seb@serialseb.com</email></author><category term="terraform" /><category term="devops" /><category term="aws" /><summary type="html"><![CDATA[Terraform modules do not currently support count, and so reusing a module a dynamic number of ways is impossible. To work around this, we can rely on a small DSL and null_resources.]]></summary></entry><entry><title type="html">Passing empty arrays to resource arguments in Terraform</title><link href="https://serialseb.com/blog/2016/05/10/empty-arrays-from-variables-in-terraform/" rel="alternate" type="text/html" title="Passing empty arrays to resource arguments in Terraform" /><published>2016-05-10T14:04:00+01:00</published><updated>2016-05-10T14:04:00+01:00</updated><id>https://serialseb.com/blog/2016/05/10/empty-arrays-from-variables-in-terraform</id><content type="html" xml:base="https://serialseb.com/blog/2016/05/10/empty-arrays-from-variables-in-terraform/"><![CDATA[<p>The interpolation syntax of terraform allows you to do many other things to make your modules reuseable, but one of the common problems we find is passing empty strings from variables in arrays.</p>

<p>Note that the strange syntax I show you are obtuse, and while someone who has done terraform for a while may well recognise the patterns, they’re non-obvious and come with an increased cost in complexity and maintenance. Make sure you make the right decision between all the costs associated with reuse.</p>

<p>So let’s say you have a module that registers an auto-scaling group, but you want to allow module consumers to pass an elastic load balancer they defined themselves. The naive approach would be to just pass it in the array attribute.</p>

<div class="language-tf highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">variable</span> <span class="s2">"elb"</span> <span class="p">{</span> <span class="nx">default</span> <span class="p">=</span> <span class="s2">""</span> <span class="p">}</span>
<span class="k">resource</span> <span class="s2">"aws_autoscaling_group"</span> <span class="s2">"asg"</span> <span class="p">{</span>
  <span class="c1">// stuff here</span>
  <span class="nx">load_balancers</span> <span class="p">=</span> <span class="p">[</span><span class="s2">"</span><span class="k">${</span><span class="kd">var</span><span class="p">.</span><span class="nx">elb</span><span class="k">}</span><span class="s2">"</span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div></div>

<p>If you try to apply this, it will return an array of 1 with an empty string, which is not what the api expect.</p>

<p>The trick here is to force turning the string in an array.</p>

<div class="language-tf highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">resource</span> <span class="s2">"aws_autoscaling_group"</span> <span class="s2">"asg"</span> <span class="p">{</span>
  <span class="c1">// stuff here</span>
  <span class="nx">load_balancers</span> <span class="p">=</span> <span class="p">[</span><span class="s2">"</span><span class="k">${</span><span class="nx">compact</span><span class="p">(</span><span class="nx">split</span><span class="p">(</span><span class="s2">""</span><span class="p">,</span><span class="kd">var</span><span class="p">.</span><span class="nx">elb</span><span class="p">))</span><span class="k">}</span><span class="s2">"</span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div></div>

<p>And voila, an array of 0 or 1 element. Note that this problem will go away with terraform 0.7, as modules will be able to take lists as variables.</p>]]></content><author><name>Sebastien Lambla</name><email>seb@serialseb.com</email></author><category term="terraform" /><category term="devops" /><category term="aws" /><summary type="html"><![CDATA[The interpolation syntax of terraform allows you to do many other things to make your modules reuseable, but one of the common problems we find is passing empty strings from variables in arrays.]]></summary></entry></feed>