Florian Sellmayr A blog about build pipelines, dev and ops https://flosell.github.io/ Sun, 22 Feb 2026 04:10:42 +0000 Sun, 22 Feb 2026 04:10:42 +0000 Jekyll v3.10.0 Introducing LambdaCD <h1 id="preface">Preface</h1> <p>In my <a href="/cd/2015/03/29/build-pipelines-as-code.html">last post</a> I argued that we should start treating our build pipelines as code, as potentially complex applications that serve a single purpose: To test, publish and deploy your software.</p> <p>What I didn’t mention was how to get there. Do I want everyone to throw away their beloved Jenkins and go develop their own buildservers?</p> <p>Well, yes, but I also want to do the heavy lifting for you:</p> <h1 id="introducing-lambdacd">Introducing LambdaCD</h1> <p><a href="https://github.com/flosell/lambdacd">LambdaCD</a> is a library that gives you</p> <ul> <li>An execution engine to execute your build steps one after another (and stops on failure)</li> <li>Persistence and and API to access state and history of your pipeline</li> <li>A basic UI to visualize and interact with your pipeline.</li> <li>A few basic building-blocks for your pipeline, e.g. manual triggers, parallel execution of steps, …</li> </ul> <p>What is left for you to do is code the structure of your pipeline and your build-steps. Build steps are regular Clojure functions that take input data and return a map with results. The structure of your pipeline is a nested list of such functions.</p> <p>In short, this is what you code:</p> <figure class="highlight"><pre><code class="language-clojure" data-lang="clojure"><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">some-step-that-does-nothing</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="w"> </span><span class="n">_</span><span class="p">]</span><span class="w"> </span><span class="p">{</span><span class="no">:status</span><span class="w"> </span><span class="no">:success</span><span class="p">})</span><span class="w"> </span><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">some-step-that-echos-foo</span><span class="w"> </span><span class="p">[</span><span class="n">_</span><span class="w"> </span><span class="n">ctx</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nf">shell/bash</span><span class="w"> </span><span class="n">ctx</span><span class="w"> </span><span class="s">"/"</span><span class="w"> </span><span class="s">"echo foo"</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">some-step-that-echos-bar</span><span class="w"> </span><span class="p">[</span><span class="n">_</span><span class="w"> </span><span class="n">ctx</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nf">shell/bash</span><span class="w"> </span><span class="n">ctx</span><span class="w"> </span><span class="s">"/"</span><span class="w"> </span><span class="s">"echo bar"</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">some-failing-step</span><span class="w"> </span><span class="p">[</span><span class="n">_</span><span class="w"> </span><span class="n">ctx</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nf">shell/bash</span><span class="w"> </span><span class="n">ctx</span><span class="w"> </span><span class="s">"/"</span><span class="w"> </span><span class="s">"echo \"i am going to fail now...\""</span><span class="w"> </span><span class="s">"exit 1"</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">pipeline-def</span><span class="w"> </span><span class="o">`</span><span class="p">(</span><span class="w"> </span><span class="nf">lambdacd.manualtrigger/wait-for-manual-trigger</span><span class="w"> </span><span class="n">some-step-that-does-nothing</span><span class="w"> </span><span class="p">(</span><span class="nf">in-parallel</span><span class="w"> </span><span class="n">some-step-that-echos-foo</span><span class="w"> </span><span class="n">some-step-that-echos-bar</span><span class="p">)</span><span class="w"> </span><span class="n">lambdacd.manualtrigger/wait-for-manual-trigger</span><span class="w"> </span><span class="n">some-failing-step</span><span class="w"> </span><span class="p">))</span></code></pre></figure> <p>And this is what you get: (yes, I know this isn’t stellar web design)</p> <p><img src="/assets/lambdacdPipeline.png" alt="LambdaCD" /></p> <h1 id="getting-started">Getting started</h1> <p>The easiest way to get started is to use <a href="http://leiningen.org/">Leiningen</a> to generate a project for you: <code class="language-plaintext highlighter-rouge">lein new lambdacd &lt;SOME-PROJECT-NAME&gt;</code>. This will create a project for you that you can run using <code class="language-plaintext highlighter-rouge">lein run</code>. <code class="language-plaintext highlighter-rouge">lein uberjar</code> creates a self-contained jar-file that can run on any server with java installed. That’s all you need for your very own, custom built build-server!</p> <p>Now go ahead, have a look at the generated code, play around a bit and then come back, tell me what you think.</p> Sun, 29 Mar 2015 21:50:00 +0000 https://flosell.github.io/cd/2015/03/29/introducing-lambdacd.html https://flosell.github.io/cd/2015/03/29/introducing-lambdacd.html cd Build Pipelines as Code <h1 id="the-problem">The problem</h1> <p>Do you have a build pipeline that is more complex than just <code class="language-plaintext highlighter-rouge">build</code>, <code class="language-plaintext highlighter-rouge">test</code>, <code class="language-plaintext highlighter-rouge">deploy</code>? Are you happy with it? Do you fully understand what all those build-steps are doing, what input they take and where this input comes from? Do you like all those fragile plugins you need just to convince your CI server to do the thing you want to do? Do you like clicking your way through a web interface to get stuff done? Is your build pipeline versioned? Is it <em>tested</em>?</p> <p>Or maybe your organization is trying out microservices. How easy is it for you to set up a pipeline for a new microservice? Have you figured out how to reuse aspects that are common for all services, how to share them between teams and still have stable interfaces, abstractions and dependencies?</p> <h1 id="an-idea">An idea</h1> <p>As developers, we know those problems are already solved in other parts of our world: Our code is readable, it has abstractions, testing, dependency management and versioning works effortlessly. Or servers are immutable and their deployment automated, everything built with the same concepts and tools as is our code.</p> <p>One thing is missing: The glue, the build pipeline between a commit and your critical live systems. The thing that, supposedly, <a href="http://www.martinfowler.com/articles/continuousIntegration.html#FixBrokenBuildsImmediately">is the highest priority</a> of the development team.</p> <p>What we need is a way to put our build pipelines where our business logic, our database-layout and our server configuration already is: <strong>in code</strong>!</p> <p>What does that get us? It gets us everything we love about code: We can structure it, version it, test it, share it with others any way we like! We can take advantage of all the tools and libraries we know and love!</p> <p>You want to find out if your deployment really stops when a smoketest fails on staging? A small test with the right mock will tell you!</p> <p>All your development teams should use the same process to deploy to your private cloud? Just put everything into a small library for everyone to include in their pipelines!</p> <p>Your management requires your pipeline to behave differently on mondays, except for rainy days? You can build that! (not saying you should)</p> <p>Simply put: Our build pipeline can be just like any other piece of software we release, with the same tools, methods and quality we are used to!</p> <p><strong>Next up:</strong> A clojure library that let’s you do all that!</p> Sun, 29 Mar 2015 21:39:00 +0000 https://flosell.github.io/cd/2015/03/29/build-pipelines-as-code.html https://flosell.github.io/cd/2015/03/29/build-pipelines-as-code.html cd