<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Damian Brady]]></title><description><![CDATA[cloud, devops and developer process]]></description><link>https://damianbrady.com.au/</link><image><url>https://damianbrady.com.au/favicon.png</url><title>Damian Brady</title><link>https://damianbrady.com.au/</link></image><generator>Ghost 3.7</generator><lastBuildDate>Wed, 19 Feb 2020 13:16:07 GMT</lastBuildDate><atom:link href="https://damianbrady.com.au/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[MLOps, or DevOps for Machine Learning]]></title><description><![CDATA[DevOps is full of great practices and patterns, and most of these can be applied to machine learning and data science projects.]]></description><link>https://damianbrady.com.au/2019/10/28/mlops-or-devops-for-machine-learning/</link><guid isPermaLink="false">5db2347d087e5300387c03e0</guid><category><![CDATA[DevOps]]></category><category><![CDATA[Process]]></category><category><![CDATA[Machine Learning]]></category><category><![CDATA[Data Science]]></category><dc:creator><![CDATA[Damian Brady]]></dc:creator><pubDate>Mon, 28 Oct 2019 02:13:18 GMT</pubDate><media:content url="https://damianbrady.com.au/content/images/2019/10/fdlf-dmm-1.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://damianbrady.com.au/content/images/2019/10/fdlf-dmm-1.png" alt="MLOps, or DevOps for Machine Learning"><p>Over the past year or so, I've been spending a lot of time in the world of machine learning and data science. Not as a data scientist, but as a DevOps practitioner*.</p>
<p>I wanted to know -</p>
<ul>
<li>How do machine learning projects work?</li>
<li>Who is involved?</li>
<li>What is the process like from idea through to running in production?</li>
<li>Most importantly - can DevOps help?</li>
</ul>
<p><img src="https://media.giphy.com/media/vgsj2QCJGv7Xi/giphy.gif" alt="MLOps, or DevOps for Machine Learning"></p>
<p><em>*As an aside, I tried about 4 different words before &quot;practitioner&quot;. It feels so businessey. But here we are.</em></p>
<h1 id="learningmachinelearning">Learning Machine Learning</h1>
<p>When I first encountered any kind of machine learning, it was at university in the form of &quot;deep neural networks&quot;. It wasn't my project, but another student's.</p>
<p>He had great success with it, so I spoke to him about what was involved. After 5min, <strong>I was lost</strong>. It felt <em>so</em> inaccessible.</p>
<p>Non-linear activation functions, multi-dimensional calculus, stochastic gradient decent... I would have spent as much time with a dictionary as with a computer.</p>
<p><img src="https://media.giphy.com/media/1oHOrPkIa9qHuJcW4Z/giphy.gif" alt="MLOps, or DevOps for Machine Learning"></p>
<p>So, as any good student would do... I dropped it and started my career writing Visual Basic for the government.</p>
<p>Fast forward a few years, and I'm working at Microsoft as a Cloud Advocate. I'm here because I've apparently convinced the company that I know about DevOps and can communicate those ideas well. Sure. I'll take it.</p>
<p>The great thing about being in this role is I have access to fantastic experts in <em>other</em> fields, who are great at communicating. Enter <a href="https://twitter.com/sethjuarez">Seth Juarez</a>.</p>
<p>If I had to put my knowledge of AI and ML on a scale against Seth's, it would look a bit like this:</p>
<p><img src="https://damianbrady.com.au/content/images/2019/10/knowing-stuff-graph-1.jpg" alt="MLOps, or DevOps for Machine Learning"></p>
<p>It's taken a while, and a lot of experimentation and conversations, but I feel like I've got a handle on what's involved in a machine learning project.</p>
<p>I mean, you probably shouldn't hire me to build a predictive model for you just yet, but I'm no longer completely clueless.</p>
<h1 id="aboutthatprocess">About that process</h1>
<p>One of the things that all these conversations taught me was that the majority of ML projects don't have a great story when it comes to DevOps.</p>
<p>But let's back up a bit - isn't DevOps traditionally used to help deliver software?</p>
<p><strong>Yes. And machine learning is software.</strong></p>
<p><img src="http://giphygifs.s3.amazonaws.com/media/ap6wcjRyi8HoA/giphy.gif" alt="MLOps, or DevOps for Machine Learning"></p>
<p>&quot;MLOps&quot;, or &quot;Machine Learning Operations&quot; seems to be the term that much of the industry has landed on. I don't <em>love</em> it - it implies a narrow focus on operationalizing the results of a machine learning project and not the broader idea of creating value - but if that's the term used, I'll play along.</p>
<p>I really prefer &quot;DevOps for Machine Learning&quot;. The reason? &quot;DevOps&quot; can <strong>absolutely</strong> apply to machine learning projects - without even stretching the definition.</p>
<h2 id="devops">DevOps</h2>
<p>Let's quickly look at Microsoft's DevOps definition:</p>
<blockquote>
<p>DevOps is the union of people, process, and products to enable continuous delivery of <strong>value</strong> to our end users</p>
</blockquote>
<p>The important part of this definition is the word &quot;value&quot;. DevOps isn't about features or bug fixes or infrastructure as code, it's about <em>value</em>. ML is software that provides value.</p>
<p>For example, if you're working on producing a predictive model for evaluating lending risk for a bank, what's more valuable than improving the accuracy of that model?</p>
<p><img src="http://giphygifs.s3.amazonaws.com/media/rM9Cl7MZphBqU/giphy.gif" alt="MLOps, or DevOps for Machine Learning"></p>
<h1 id="backtotheprocess">Back to the process</h1>
<p>DevOps is full of great practices and patterns, and most of these can be applied to ML projects.</p>
<p>For me, the main differences between a machine learning project and a software development project come down to the following two distinctions:</p>
<h2 id="theresalotmoreexperimentation">There's a lot more experimentation</h2>
<p>When writing a new feature in a piece of software, you <em>generally</em> know what you need to do up front.</p>
<p>For example, for a new &quot;customer orders&quot; report, you know there's probably a database query, some data processing logic, and a few screens or pages of some kind of reporting UI. There's a direction right away, even if you may have to try a few things.</p>
<p>ML Projects often involve a lot more experimentation. While the end goal is generally known, the path to that goal is often far less clear.</p>
<p><img src="https://media.giphy.com/media/xT0xewLy70uaFY3Vte/giphy.gif" alt="MLOps, or DevOps for Machine Learning"></p>
<p>There are countless algorithms you could use and limitless ways to transform the data and select features. Undiscovered outliers, biases in the data, or poorly-tuned hyperparameters could push you off course for weeks.</p>
<p>Experience is important, and great data scientists have a feel for what will work, what to look for, and how to solve these tricky problems.</p>
<p>Data science is a specialist art form.</p>
<p><img src="https://media.giphy.com/media/lp0nBuaRjcj13j3nMH/giphy.gif" alt="MLOps, or DevOps for Machine Learning"></p>
<p>All that said, <strong>the actual execution of these experiments is ripe for automation</strong>.</p>
<p>The training, scoring, evaluation and testing are all things that require scripts and processing. And DevOps helps us with this.</p>
<h2 id="trainingrunsarelikereallyexpensivebuilds">Training runs are like really expensive builds</h2>
<p>When we build our software on a build server, it's usually a process measured in minutes. Maybe hours if we're unlucky. That means CI is definitely something we should do</p>
<p>Producing a predictive model on an ML project might take weeks.</p>
<p>Each training run may require many thousands of compute hours on expensive GPU-laden machines and cost a senior developer's salary each time.</p>
<p><img src="https://media.giphy.com/media/zlNrCRIG5PIys/giphy.gif" alt="MLOps, or DevOps for Machine Learning"></p>
<p>So you may not want to do a <em>full</em> training run for every small change (like you would with continuous integration). You <em>may</em> want to do a run with a subset of data to prove the idea first. Or maybe you just want to run tests or linting (it is code after all)?</p>
<p>Even so, the idea of a &quot;training run&quot; as a parallel to a &quot;build&quot; makes sense to me.</p>
<p><strong>A build is essentially a compute-intensive process that produces an artifact that can be deployed or used by other software.</strong></p>
<p>A training run is the same - except it's also very data-intensive.</p>
<p>The same DevOps techniques around CI, pull request builds, and even security, performance, and load testing can apply.</p>
<h1 id="samesamebutdifferent">Same same, but different</h1>
<p>The skills required to produce a good result may be very different. The cadence of work may be slower at first, and less cleanly broken down.<br>
The tools used day to day might be very different.</p>
<p>But ultimately it's all writing code, running automated tasks, and deploying the artifacts safely.</p>
<blockquote>
<p>If it's <strong>not</strong> all in code and in source control, it should be!</p>
</blockquote>
<blockquote>
<p>If model training requires manual work, it should be automated!</p>
</blockquote>
<blockquote>
<p>If deployment is manual and scary, it should be automated and gradual!</p>
</blockquote>
<blockquote>
<p>Finally, if the project is &quot;done&quot; when the model is in production, it can get stale and stop delivering value. There's a great opportunity to continue delivering value by using telemetry, monitoring, and ideally automated retraining strategies.</p>
</blockquote>
<p>Apply DevOps practices to your ML projects. Work on delivering value more effectively on a continuous basis.</p>
<p><img src="https://damianbrady.com.au/content/images/2019/10/fdlf-dmm.png" alt="MLOps, or DevOps for Machine Learning"></p>
<h1 id="findoutmore">Find out more</h1>
<p>There will be more blog posts drilling into some of these ideas in much more detail.</p>
<p>I've been <a href="https://www.youtube.com/watch?v=ClPcKZHMFBg">speaking about MLOps or DevOps for Machine Learning at a few events recently</a>, and there are more to come.</p>
<p>You can find out what Microsoft has been doing in the MLOps space on our <a href="https://docs.microsoft.com/en-us/azure/machine-learning/service/concept-model-management-and-deployment?WT.mc_id=mlops-blog-dabrady">Azure Machine Learning docs pages</a>. We have some amazing tooling to help solve a lot of MLOps problems, and there's so much more to come!</p>
<h1 id="relatedevents">Related events</h1>
<h2 id="microsoftignite">Microsoft Ignite</h2>
<p>One of the big events on the Microsoft calendar is <a href="https://ignite.microsoft.com">Microsoft Ignite</a>. It's less than a week away - November 4-8.</p>
<p><img src="https://damianbrady.com.au/content/images/2019/10/ms-ignite-logo.jpeg" alt="MLOps, or DevOps for Machine Learning"></p>
<p><strong>I'll be delivering a <a href="https://myignite.techcommunity.microsoft.com/sessions/83003?source=sessions">session on exactly this topic</a> on Thursday afternoon. I'd love you to come along!</strong></p>
<p>Also...</p>
<p><strong>If you're going to Ignite and have an interest in MLOps, I'd love to speak to you!</strong></p>
<p>I'll even have some of those &quot;friends don't let friends&quot; stickers in the image above. Just ask! 😀</p>
<p><a href="https://twitter.com/damovisa/status/1188642000708358145?s=19">Send me a message on Twitter</a>, or just come by the Debug Bar in the Hub. I'll be there 11am-1pm Monday and Tuesday, from 1pm-4pm Wednesday, and from 12pm-2pm Thursday.</p>
<h2 id="microsoftignitethetour">Microsoft Ignite The Tour</h2>
<p><a href="https://www.microsoft.com/en-au/ignite-the-tour/?WT.mc_id=mitt-blog-dabrady">Microsoft Ignite The Tour</a> is an event that Microsoft is running in 30 cities across the world, starting just after Ignite and running through to May next year.</p>
<p>The AIML50 session is focused completely on MLOps. I won't be delivering any of the tour sessions, but the presenters are amazing. Even though it won't be me saying the words and running the demos, the session is my work and I'm really proud of it.</p>
<p>Don't miss the (free) event when it comes to your city!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Azure Pipelines YAML #2  -  more ways to learn what YAML you need!]]></title><description><![CDATA[In my last post I gave you two suggestions for how to find out what to type when creating an Azure Pipelines YAML Build. Here are a few more!]]></description><link>https://damianbrady.com.au/2018/11/27/azure-pipelines-yaml-2-more-ways-to-learn-what-to-type/</link><guid isPermaLink="false">5bfc7b306e5a1b00bfc28028</guid><category><![CDATA[DevOps]]></category><category><![CDATA[YAML]]></category><category><![CDATA[Azure]]></category><dc:creator><![CDATA[Damian Brady]]></dc:creator><pubDate>Tue, 27 Nov 2018 05:18:03 GMT</pubDate><media:content url="https://damianbrady.com.au/content/images/2018/11/new-pipeline-visual-1.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://damianbrady.com.au/content/images/2018/11/new-pipeline-visual-1.png" alt="Azure Pipelines YAML #2  -  more ways to learn what YAML you need!"><p>In my last post - <a href="https://damianbrady.com.au/2018/10/11/what-yaml-do-i-need-for-azure-pipelines/">Azure Pipelines YAML - Uh, what do I type?</a> - I gave you two suggestions for how to find out what to type - both links to the docs.</p>
<p>Shortly after publishing, a few people from the awesome DevOps community recommended a few other ways, so I thought I'd share them. I totally already knew about all of them of course. Absolutely definitely.</p>
<p>So, more answers!</p>
<h2 id="answer3usethevisualdesigner">Answer #3 - Use the Visual Designer</h2>
<p>But wait, Damian, isn't the whole point that we're <em>not</em> using the visual designer?</p>
<p>Yes. Yes, it is. However it can be very useful to use the visual designer just so you can then view the equivalent YAML.</p>
<p>To create a build with the visual designer, there's a not terribly obvious link in step 1 of the New Pipeline flow.</p>
<p><img src="https://damianbrady.com.au/content/images/2018/11/new-pipeline-visual.png" alt="Azure Pipelines YAML #2  -  more ways to learn what YAML you need!"></p>
<p>The YAML required for tasks is usually very straightforward, but by using the visual designer, you get a UI showing you every possible parameter.</p>
<p>It's especially useful for tasks you're unfamiliar with, or marketplace tasks where the YAML isn't documented or obvious. The name of those tasks is usually very long as well.</p>
<p>Just add the task, set the parameters, then click &quot;View YAML&quot;. You can also &quot;View YAML&quot; for the whole pipeline if you want to build it with the UI but use YAML.</p>
<p><img src="https://damianbrady.com.au/content/images/2018/11/yaml-from-visual.gif" alt="Azure Pipelines YAML #2  -  more ways to learn what YAML you need!"></p>
<p>It's a bit like using the <a href="https://msdn.microsoft.com/en-us/library/k4cbh4dh.aspx">Visual Studio ASPX design view</a> in old-school Web Forms before switching back to source view to see what OH NO WHERE DID ALL THESE BR TAGS COME FROM WHY WOULD YOU DO THIS!?</p>
<p><img src="https://media.giphy.com/media/dILrAu24mU729pxPYN/giphy.gif" alt="Azure Pipelines YAML #2  -  more ways to learn what YAML you need!"></p>
<p>Ok, it's not completely like that.</p>
<h2 id="answer4lookatthetasksgitrepo">Answer #4 - look at the task's git repo</h2>
<p>Every out-of-the-box task in Azure Pipelines is open source. If that surprises you, you haven't been paying attention to this new Microsoft!</p>
<p>You can find all these tasks on GitHub at <a href="https://github.com/Microsoft/azure-pipelines-tasks">https://github.com/Microsoft/azure-pipelines-tasks</a> in the Tasks folder. At time of writing, there are 135 of them.</p>
<p>To help you work out the YAML, the file you're looking for is <code>task.json</code>. Here's an example for the Kubernetes task (version 1): <a href="https://github.com/Microsoft/azure-pipelines-tasks/blob/master/Tasks/KubernetesV1/task.json">https://github.com/Microsoft/azure-pipelines-tasks/blob/master/Tasks/KubernetesV1/task.json</a></p>
<p><img src="https://damianbrady.com.au/content/images/2018/11/github-task.png" alt="Azure Pipelines YAML #2  -  more ways to learn what YAML you need!"></p>
<p>The name of the task is the name in the json file plus the version - e.g. <code>Kubernetes@1</code>.</p>
<p>The json file also contains all the possible <code>input</code> parameters you can use.</p>
<p>It can take a little bit of practice to understand these json files, but as a bonus - once you understand them, you can write your own tasks! That's right, just copy ours to create your own!</p>
<h2 id="answer5morecomprehensivedocs">Answer #5 - More comprehensive docs</h2>
<p>I <em>kind of</em> covered this in the first post, but it deserves another mention because I didn't link to it specifically.</p>
<p>There's a <a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/?view=vsts&amp;WT.mc_id=blog-medium-dabrady">reference section in the Azure Pipelines docs</a> that lists every out of the box task along with the YAML required to use it.</p>
<p><img src="https://damianbrady.com.au/content/images/2018/11/all-task-docs.gif" alt="Azure Pipelines YAML #2  -  more ways to learn what YAML you need!"></p>
<p>Unlike the quickstarts or language-specific guidance, the reference section lists every parameter each task can use. It's far more comprehensive and is extremely useful if you need to drill down a bit deeper.</p>
<h2 id="checkitoutagain">Check it out. Again.</h2>
<p>It's incredibly easy to get started with Azure Pipelines, especially if you have your code in GitHub already. Just add the <a href="https://github.com/marketplace/azure-pipelines">Marketplace app</a> and follow the prompts.</p>
<p>Does your code live somewhere else? No problem, just go to <a href="https://dev.azure.com">https://dev.azure.com</a> and create a new organization and project.</p>
<p>And once again, Azure Pipelines is free. Not add-a-credit-card-but-make-sure-you-cancel-3-months-before-the-trial free, but totally free.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Azure Pipelines YAML - uh, what do I type?]]></title><description><![CDATA[Azure DevOps now encourages you to define your builds in YAML. This is awesome, but if you're used to the UI (like me) how do you know what to type? Here's how to find out.]]></description><link>https://damianbrady.com.au/2018/10/10/what-yaml-do-i-need-for-azure-pipelines/</link><guid isPermaLink="false">5bbd38f77d402c00bf6e1fe7</guid><category><![CDATA[DevOps]]></category><category><![CDATA[Azure]]></category><category><![CDATA[YAML]]></category><category><![CDATA[Build]]></category><category><![CDATA[Continuous Integration]]></category><category><![CDATA[Continuous-Deployment]]></category><dc:creator><![CDATA[Damian Brady]]></dc:creator><pubDate>Wed, 10 Oct 2018 23:45:54 GMT</pubDate><media:content url="https://damianbrady.com.au/content/images/2018/10/new-pipeline-yaml-1.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://damianbrady.com.au/content/images/2018/10/new-pipeline-yaml-1.png" alt="Azure Pipelines YAML - uh, what do I type?"><p>A few months ago, a preview feature was launched in <a href="https://dev.azure.com?WT.mc_id=azurepipelines-blog-dabrady">Azure DevOps</a> (then VSTS), letting you define your build in a YAML file that lived with your code.</p>
<p><img src="https://damianbrady.com.au/content/images/2018/10/new-pipeline-yaml.png" alt="Azure Pipelines YAML - uh, what do I type?"></p>
<p><strong>This was awesome</strong>. It meant you could use the same branching and code review practices for your build definitions as you did for your code.</p>
<p>Now with the launch of Azure DevOps (which, by the way, <strong><a href="https://azure.microsoft.com/en-au/pricing/details/devops/azure-devops-services/?WT.mc_id=azurepipelines-blog-dabrady">is free</a></strong>), the service <em>really</em> encourages using YAML. In fact, if you start a new project, those feature flags are turned on by default, and the flow through the <a href="https://github.com/marketplace/azure-pipelines">GitHub Marketplace app</a> also pushes you to a YAML definition.</p>
<p><em>However</em>, if you're like me and were used to the UI, or you're just completely new to Azure DevOps, it could be a bit confusing.</p>
<p>Namely - <strong>uh, what do I actually put in the YAML file?</strong></p>
<p><img src="https://media.giphy.com/media/3oz8xUFUB65tXgvHwI/giphy.gif" alt="Azure Pipelines YAML - uh, what do I type?"></p>
<blockquote>
<p>Note: If you do want to keep using the UI, you can turn the feature off by <a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/get-started-designer?view=vsts&amp;tabs=new-nav&amp;WT.mc_id=azurepipelines-blog-dabrady">following the instructions here</a>.</p>
</blockquote>
<h2 id="answer1thetemplates">Answer #1 - the templates</h2>
<p>There are a whole lot of templates available for you to choose from and they contain some nice starting points.</p>
<p>When you create a new build definition, Azure Pipelines analyzes your code (at a pretty high level) and will suggest a template to start with. Or you can click &quot;All templates&quot;, and pick one. There are quite a few!</p>
<p><img src="https://damianbrady.com.au/content/images/2018/10/templates.gif" alt="Azure Pipelines YAML - uh, what do I type?"></p>
<p>In most cases, this will be a super simple definition that just builds the app. For example, the ASP.NET Core template (see the screenshot above) has a single step that runs <code>dotnet build</code> on the commandline.</p>
<p>Even if you plan to build out a task-rich build, the templates are a good place to start for a couple of reasons:</p>
<ul>
<li>
<p>First, they show you the syntax you'll need, and will already have the recommended build agent pool, variables, and basic tasks set.</p>
</li>
<li>
<p>Second, there's a link at the top of the template that points you at the documentation <em>for that specific project type</em>. Which is exactly what you need right now.</p>
</li>
</ul>
<p>So choose a template that makes sense, then [ctrl/⌘]-click on that link. It'll tell you the YAML you'll need for pretty much everything you'll want to do. If it doesn't, let me know and I'll get it fixed!</p>
<p>For example, here's what my ASP.NET Core build looks like. Every task I added is listed in the docs page linked to in the header - <a href="https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core?WT.mc_id=azurepipelines-blog-dabrady">https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core</a></p>
<pre><code class="language-yml"># ASP.NET Core
# Build and test ASP.NET Core projects targeting .NET Core.
# Add steps that run tests, create a NuGet package, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core

pool:
  vmImage: 'Ubuntu 16.04'

variables:
  buildConfiguration: 'Release'

steps:
- script: dotnet restore
  displayName: 'dotnet restore'

- script: dotnet build --configuration $(buildConfiguration)
  displayName: 'dotnet build $(buildConfiguration)'

- task: DotNetCoreCLI@2
  displayName: 'dotnet test $(buildConfiguration)'
  inputs:
    command: test
    projects: '**/*Tests/*.csproj'
    arguments: '--configuration $(buildConfiguration) --collect &quot;Code coverage&quot;'

- task: DotNetCoreCLI@2
  displayName: 'dotnet publish $(buildConfiguration)'
  inputs:
    command: publish
    publishWebProjects: True
    arguments: '--configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory)'
    zipAfterPublish: True

- task: PublishBuildArtifacts@1
  displayName: 'publish artifacts'
</code></pre>
<p>That definition restores, builds, runs tests, pushes test results and code coverage back to Azure DevOps, packages the site for deployment, and pushes the packaged artifact back to Azure DevOps for safekeeping.</p>
<h2 id="answer2thedocsbutton">Answer #2 - the &quot;Docs&quot; button</h2>
<p>You may have noticed the &quot;Docs&quot; button at the top of the screenshot as well. To save you scrolling, I'll paste it again:</p>
<p><img src="https://damianbrady.com.au/content/images/2018/10/new-pipeline-yaml-docs.png" alt="Azure Pipelines YAML - uh, what do I type?"></p>
<p>That link takes you to <a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/?view=vsts&amp;WT.mc_id=azurepipelines-blog-dabrady">an awesome docs page</a> with links to quickstarts for (at time of writing) <strong>15 different app types</strong>. There are also some links to pages showing how to deploy to 11 different deployment targets.</p>
<p>I firmly believe you should deploy with a separate <a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/release/what-is-release-management?view=vsts&amp;WT.mc_id=azurepipelines-blog-dabrady">Release pipeline</a> (build once, deploy many!), but you can do it in the build if you want. It's yours, you can do whatever you like!</p>
<h2 id="checkitout">Check it out</h2>
<p>It's incredibly easy to get started with Azure Pipelines, especially if you have your code in GitHub already. Just add the <a href="https://github.com/marketplace/azure-pipelines?WT.mc_id=azurepipelines-blog-dabrady">Marketplace app</a> and follow the prompts.</p>
<p>Does your code live somewhere else? No problem, just go to <a href="https://dev.azure.com?WT.mc_id=azurepipelines-blog-dabrady">https://dev.azure.com</a> and create a new organization and project.</p>
<p>No credit card required - it's free. Did I mention that? Free!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Accelerate State of DevOps Report 2018]]></title><description><![CDATA[Every year, DORA releases an awesome "State of DevOps" report based on tens of thousands of surveys responses. Here are my highlights.]]></description><link>https://damianbrady.com.au/2018/09/06/asodr-2018-highlights/</link><guid isPermaLink="false">5b8cd1fca234d200bf9e5acd</guid><category><![CDATA[DevOps]]></category><dc:creator><![CDATA[Damian Brady]]></dc:creator><pubDate>Thu, 06 Sep 2018 22:15:55 GMT</pubDate><media:content url="https://damianbrady.com.au/content/images/2018/09/asodr-elite-vs-low-2.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://damianbrady.com.au/content/images/2018/09/asodr-elite-vs-low-2.png" alt="Accelerate State of DevOps Report 2018"><p>Every year, <a href="https://devops-research.com">DORA</a> (DevOps Research and Assessment) releases an awesome <a href="https://bit.ly/2018-devops-report">&quot;State of DevOps&quot; report</a> based on tens of thousands of surveys responses. For loud, talky DevOps people like me, it's an awesome opportunity to a) validate, and b) justify all the stuff we say is important.</p>
<p>The report is put together by <a href="https://twitter.com/nicolefv">Nicole Forsgren</a>, <a href="https://twitter.com/jezhumble">Jez Humble</a>, and <a href="https://twitter.com/RealGeneKim">Gene Kim</a>. You should follow them <span style="font-size:0.6em;">(<a href="https://twitter.com/damovisa" alt="Damian Brady">and me</a>)</span> on Twitter.</p>
<p>The 2018 report came out a few days ago, so I sat down to read it and summarise my highlights!</p>
<p><img src="https://media.giphy.com/media/WoWm8YzFQJg5i/giphy.gif" alt="Accelerate State of DevOps Report 2018"></p>
<p>After 25 pages, I realised I was just writing bullet points of the whole report.</p>
<p>Yeah, highlights aren't highlights if they just summarize <em>everything</em>.</p>
<p><img src="https://media.giphy.com/media/3XEgV9kfwLy1i/giphy.gif" alt="Accelerate State of DevOps Report 2018"></p>
<p>So that leads to my first recommendation:</p>
<p><strong><a href="https://bit.ly/2018-devops-report">Read the whole thing</a>.<br>
Then a couple of days later, <a href="https://bit.ly/2018-devops-report">read it again</a>.<br>
And then later that week, you've probably forgotten it, so <a href="https://bit.ly/2018-devops-report">read it again</a>.</strong></p>
<h2 id="myhighlights">My highlights</h2>
<p>Ok, I'll give you some highlights anyway. I managed to find highlights in my summary. Then highlights in those highlights.</p>
<p>The research itself used cluster analysis to group the respondents into three &quot;software delivery performance&quot; groups - high performers, medium performers, and low performers. There are also a couple of subgroups. Elite performers is a subset of high performers, and a really interesting &quot;misguided performers&quot; is a subset of low performers - more on that later.</p>
<p>So how are these groups measured?</p>
<h3 id="fourmeasuresyoushouldcareabout">Four measures you should care about</h3>
<p>There are four key measures you should care about when it comes to software delivery performance:</p>
<ul>
<li><strong>Deployment frequency</strong> (how often you can push into production)</li>
<li><strong>Lead time for changes</strong> (how long it takes to get a change from commit to production)</li>
<li><strong>Time to restore service</strong> (When stuff goes wrong, how long does it take you to fix it)</li>
<li><strong>Change fail rate</strong> (how often do your changes break stuff)</li>
</ul>
<p>Here's how the best and worst groups compare:</p>
<p><img src="https://damianbrady.com.au/content/images/2018/09/asodr-elite-vs-low-1.png" alt="Accelerate State of DevOps Report 2018"></p>
<p>That's the page you want to print out and hand to your manager. Convert that human-resource-time-dollars (or whatever managers use) and it can be pretty compelling. 💰💰💰💰💰</p>
<h3 id="misguidedperformers">Misguided performers</h3>
<p>One of the more interesting parts of this report was the discussion on misguided performers.</p>
<p>There is a tendency, especially in highly-regulated industries, to <em>slow down</em>. Be careful and cautious and make sure nothing can go wrong. You ask what happens when something <em>does</em> go wrong with a deployment and it's often deflected with, &quot;Oh, it won't. We've made sure.&quot;</p>
<p>So then it <em>does</em> go wrong and because there's no process for dealing with this, the time to recover is <em>horrible</em>.</p>
<p><img src="https://media.giphy.com/media/l378m8mNCUdjA3Euk/giphy.gif" alt="Accelerate State of DevOps Report 2018"></p>
<p>These are &quot;misguided performers&quot;. Low performers, but with <em>reasons</em>*.</p>
<p>The data shows that these teams actually do tend to make fewer mistakes. Their change failure rate is better than other low performers. Not as good as medium performers, but better than the lowest.</p>
<p>Where this all falls down is the recovery. When it comes to recovering from an issue, they're <em>worse</em> than low performers. Like <strong>way</strong> worse. Up to 6 months worse.</p>
<h3 id="manualwork">Manual work</h3>
<p>Measuring how much time is spent on manual work is a great way of measuring quality. There was a really interesting set of measures here too.</p>
<p><img src="https://damianbrady.com.au/content/images/2018/09/asodr-medium-manual-work.png" alt="Accelerate State of DevOps Report 2018"></p>
<p>The medium group in that table is interesting and seems wrong at first glance - why would they be doing <em>more</em> manual work?!</p>
<p>But as the report explains, it makes sense. As teams start improving and automating things, there's suddenly a lot more testing that needs to happen. Technical debt builds up and can block progress. It's only after continually improving things that things start looking better.</p>
<p>So, like... &quot;don't give up!&quot; or something equally inspiring.</p>
<p><img src="https://media.giphy.com/media/12vJgj7zMN3jPy/giphy.gif" alt="Accelerate State of DevOps Report 2018"></p>
<h3 id="therichgetricher">The rich get richer</h3>
<p>One interesting thing in this report was that the best performers are getting better, and the worst are getting worse.</p>
<p>Compared with previous years, low performers have more failures and take longer to restore service. The gap is widening.</p>
<p>As DevOps matures in a lot of organisations, it's understandable that the highest performers continue improving, but why are the lowest performers getting worse?</p>
<p>Maybe it's the complexity of applications these days (microservices anyone?). Maybe it's doubling down on proven bad ideas?<br>
Maybe it's viral chaos engineering meets artificial intelligence and the start of Skynet?</p>
<p><img src="https://media.giphy.com/media/XeXzWgD6P4LG8/giphy.gif" alt="Accelerate State of DevOps Report 2018"></p>
<h3 id="docloudbutdoitproperly">Do Cloud, but do it properly</h3>
<p>If you're on the cloud, it's important that you are <em>actually</em> doing cloud stuff.</p>
<p>Ok, that doesn't make much sense. Let me try again.</p>
<p>The report references the <a href="https://csrc.nist.gov/publications/detail/sp/800-145/final">NIST definition of cloud computing</a>, which defines five essential characteristics. Things like on-demand self-service, and rapid elasticity. You can think of these characteristics as representing &quot;doing cloud properly&quot;.</p>
<p>If you're just running a VM in the cloud, but doing everything else the same, you're probably not checking those 5 boxes. But if you actually meet all these cloud characteristics, you're <strong>23 times</strong> more likely to be in the elite group when it comes to software delivery. That's a lot of times.</p>
<p><img src="https://media.giphy.com/media/maIEBUU5OmrMA/giphy.gif" alt="Accelerate State of DevOps Report 2018"></p>
<h3 id="outsourcingisbadmkay">Outsourcing is bad m'kay?</h3>
<p>This was really interesting. As a dev who has worked in quite a few companies across quite a few industries, it absolutely rings true. But that was just my anecdata. This puts real data behind that idea.</p>
<p>In short, if you outsource <em>by function</em> (e.g. all your testing goes to this third party company, or all the dev work is done by another org), you're far more likely to be in the low performing group.</p>
<p>And remember those <a href="#misguidedperformers">Misguided performers</a>? Yeah, turns out they're the worst for this. They use more functional outsourcing than any other group.</p>
<p>The reason? Contracts and agreements and change requests and batched work and all that stuff. Can you tell I did an MBA?</p>
<p><img src="https://media.giphy.com/media/5hkya8RZAYgR7a2Hda/giphy.gif" alt="Accelerate State of DevOps Report 2018"></p>
<p>Look, all features are not equal. And if there's an agreement to deliver 10 features as part of some work, then it's possible that really important features are waiting around for <em>nice-to-have</em>'s just to fulfil that agreement. I've seen it many, many times. It's nice to see my feelings backed up it in a real report.</p>
<h3 id="afewotherquicksnippets">A few other quick snippets</h3>
<p>I realise I'm in danger of just summarizing the whole report again, so here are a few other highlights:</p>
<ul>
<li>Continuous Delivery contributes to reductions in burnout!</li>
<li>If software relies on <em>anything</em> that's handled in a different department (e.g. infrastructure, security, databases), <em>a)</em> involve those teams super early (shift left!) not at the end, and <em>b)</em> include them in the software delivery process</li>
</ul>
<p>One more that was amazing (from Google research):</p>
<ul>
<li><strong>The most important factor in predicting a high-performing team is <em>psychological safety</em>.</strong></li>
</ul>
<p>Yep. If you feel safe taking a risk or admitting a mistake, your team will perform better.</p>
<p><img src="https://media.giphy.com/media/4LZMbupmy8i3NLzbW2di/giphy.gif" alt="Accelerate State of DevOps Report 2018"></p>
<h2 id="finalnote">Final note</h2>
<p>Remember, all of this ties back to <em>organisational performance</em>. That's super important. If all these recommendations just made you better at delivering software, but that didn't have any impact on your bottom line, then why bother?</p>
<p>But it does. Regardless of industry.</p>
<p>Teams that are elite performers when it comes to software delivery and operational performance are 1.53 times more likely to meet or exceed their own goals.</p>
<p>So this stuff works.</p>
<p><img src="https://media.giphy.com/media/2vA33ikUb0Qz6/giphy.gif" alt="Accelerate State of DevOps Report 2018"></p>
<p>Again, <a href="https://bit.ly/2018-devops-report">check out the whole report</a>, and let me know your thoughts!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Running a VSTS build/release/deployment agent on a Raspberry Pi]]></title><description><![CDATA[Us Microsofties like to talk about "Any Language, Any Platform". Just to test that theory, I managed to configure a VSTS agent on my Raspberry Pi. Here's how!]]></description><link>https://damianbrady.com.au/2018/08/17/running-a-build-release-deployment-agent-on-a-raspberry-pi/</link><guid isPermaLink="false">5b6a42ac4da92300bf760303</guid><category><![CDATA[DevOps]]></category><category><![CDATA[IoT]]></category><category><![CDATA[RaspberryPi]]></category><category><![CDATA[VSTS]]></category><dc:creator><![CDATA[Damian Brady]]></dc:creator><pubDate>Fri, 17 Aug 2018 11:37:47 GMT</pubDate><media:content url="https://damianbrady.com.au/content/images/2018/08/raspberry-pi.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://damianbrady.com.au/content/images/2018/08/raspberry-pi.png" alt="Running a VSTS build/release/deployment agent on a Raspberry Pi"><p>Awww Yeeeaah. That's right.</p>
<p><img src="https://media.giphy.com/media/3o84UaGEtyayvBIFwc/giphy.gif" alt="Running a VSTS build/release/deployment agent on a Raspberry Pi"></p>
<p style="border:2px solid #aaa;background-color:#ffc;padding:10px;text-align:center;">If you're just here for the <strong>absolutely-totally-not-supported</strong> agent, <br>you can <a href="https://damovisa.blob.core.windows.net/public/vsts-agent-rpi-2.136.2.tar.gz" alt="Raspberry Pi Agent">download it here</a>.</p>
<p>Us <a href="https://visualstudio.com/team-services?WT.mc_id=vsts-blog-dabrady">VSTS</a> Microsofties like to talk about &quot;Any Language, Any Platform&quot;. We do demos with .NET and Java and Node on Macs and Ubuntu machines, and deploy code to Azure and AWS and on-prem.</p>
<p>So when I saw this tweet from Edward Thomson, I was intrigued 🤔:</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">I ported the <a href="https://twitter.com/VSTS?ref_src=twsrc%5Etfw">@VSTS</a> build agent to Raspberry Pi - if you’re at <a href="https://twitter.com/hashtag/OSCON?src=hash&amp;ref_src=twsrc%5Etfw">#OSCON</a> and interested in talking about cross-platform CI/CD drop by the Microsoft booth.</p>&mdash; Edward Thomson (@ethomson) <a href="https://twitter.com/ethomson/status/1019995027097862149?ref_src=twsrc%5Etfw">July 19, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<br>
<h2 id="existingagentflavours">Existing agent flavours</h2>
<p>VSTS gives you a <a href="https://docs.microsoft.com/en-us/vsts/pipelines/agents/agents?view=vsts&amp;WT.mc_id=vstsdocs-blog-dabrady">really easy way to install agents for Windows, macOS, Red Hat, and Ubuntu 14.04 and 16.04</a>. Unfortunately, the Linux builds don't work on a Raspberry Pi. Probably not a surprise.</p>
<p>BUT, in typical recent-Microsoft style, <a href="https://github.com/Microsoft/vsts-agent">the agents are open source</a>! And they're written in C# for .NET Core!</p>
<p><img src="https://damianbrady.com.au/content/images/2018/08/vsts-agent-filesize.png" alt="Running a VSTS build/release/deployment agent on a Raspberry Pi"></p>
<p>So it should be totally possible to compile it for the Pi, right?</p>
<p>Well, yes, but there were a few changes needed.</p>
<h2 id="buildingaraspberrypiagent">Building a Raspberry Pi agent</h2>
<p>Thankfully (for everyone), I didn't have to write any code, because <a href="https://twitter.com/ethomson">Edward</a> already did that for me. He had a <a href="https://github.com/Microsoft/vsts-agent/pull/1703">pull request</a> already in the works (don't be surprised if that link breaks soon), so I just grabbed that PR and compiled it on my Pi.</p>
<p>To compile, I needed to run two commands:</p>
<pre><code>&gt; ./dev.sh build
&gt; ./dev.sh package
</code></pre>
<p>In fact, that second command is probably totally useless because I just unzipped it again.</p>
<p>But lo and behold, I had a zipped up agent, just like the ones VSTS gave me!</p>
<p>Well, kind of.</p>
<h2 id="missingbit1">Missing bit #1</h2>
<p>The agents you download from VSTS include a few things that this compiled agent doesn't have.</p>
<p>The first was the configuration and run scripts. I'd just compiled the pure, unadulterated agent. I imagine the scripts aren't <em>totally</em> necessary to run the agent, but I'm lazy. So...</p>
<p>I downloaded a Linux agent using the &quot;Download agent&quot; link in the <code>Admin settings &gt; Agent pools</code> section of VSTS (<code>https://your-account.visualstudio.com/_settings/agentpools</code>) to pilfer those files and copy them to my new agent folder.</p>
<p><img src="https://damianbrady.com.au/content/images/2018/08/agent-files.png" alt="Running a VSTS build/release/deployment agent on a Raspberry Pi"></p>
<p>Now, I could run <code>config.sh</code> to configure and connect to VSTS, then <code>run.sh</code> to execute... and OMG the agent works!</p>
<p><img src="https://damianbrady.com.au/content/images/2018/08/build-agent-running.png" alt="Running a VSTS build/release/deployment agent on a Raspberry Pi"></p>
<p><img src="https://damianbrady.com.au/content/images/2018/08/pi-agent-capabilities.png" alt="Running a VSTS build/release/deployment agent on a Raspberry Pi"></p>
<h2 id="deploymentagents">Deployment agents</h2>
<p>A small aside.</p>
<p>Did you know the exact same agent is used for <a href="https://docs.microsoft.com/en-us/vsts/pipelines/agents/agents?view=vsts&amp;WT.mc_id=vstsdocs-blog-dabrady">builds, releases</a>, and even targets in <a href="https://docs.microsoft.com/en-us/vsts/pipelines/release/deployment-groups/?view=vsts?WT.mc_id=vstsdocs-blog-dabrady">deployment groups</a>?</p>
<p>Yeah, we're big into reuse.</p>
<p><img src="https://media.giphy.com/media/C6JQPEUsZUyVq/giphy.gif" alt="Running a VSTS build/release/deployment agent on a Raspberry Pi"></p>
<p>I really just wanted to use the Pi as a machine to deploy <em>to</em>, so I reconfigured it as a target in a deployment group.</p>
<p>What's the difference between those three agent types? Here's my 2 second summary:</p>
<ul>
<li>Build agent - What you build your application <em>with</em></li>
<li>Release agent - What you release your application <em>with</em> (actually the same agents)</li>
<li>Deployment agent - What you deploy your application <em>to</em> (different)</li>
</ul>
<p>The separation isn't that black and white, but I'm getting off track, so ANYWAY...</p>
<p>I <a href="https://docs.microsoft.com/en-us/vsts/pipelines/release/deployment-groups/howto-provision-deployment-group-agents?view=vsts#runscript&amp;WT.mc_id=vstsdocs-blog-dabrady">configured the agent as a deployment group target</a>, ran it using <code>run.sh</code> again, and hooray, it connected!</p>
<p><img src="https://damianbrady.com.au/content/images/2018/08/deployment-agent.png" alt="Running a VSTS build/release/deployment agent on a Raspberry Pi"></p>
<p><img src="https://damianbrady.com.au/content/images/2018/08/rpi-deployment-group-target.png" alt="Running a VSTS build/release/deployment agent on a Raspberry Pi"></p>
<p>All that's left now is to create a basic release definition using the Deployment Group (the Bash script is just a hello world at this point), and run it!</p>
<p><img src="https://damianbrady.com.au/content/images/2018/08/release-definition.png" alt="Running a VSTS build/release/deployment agent on a Raspberry Pi"></p>
<p><img src="https://media.giphy.com/media/d2Z9QYzA2aidiWn6/giphy.gif" alt="Running a VSTS build/release/deployment agent on a Raspberry Pi"></p>
<h2 id="missingbit2">Missing bit #2</h2>
<p>And it didn't work!</p>
<p><img src="https://media.giphy.com/media/YVPwi7L2izTJS/giphy.gif" alt="Running a VSTS build/release/deployment agent on a Raspberry Pi"></p>
<p>Why?</p>
<p>Well it turns out all* the tasks run via node. Yep, even if I have a single bash script in my build or release, it runs that baby through node.</p>
<p>There's probably a good reason. I should look into that.</p>
<p><em>* I don't actually know if it's all of them, but bash and python definitely do</em></p>
<p>The <em>second</em> missing bit is a packaged version of node. Remember that <code>externals</code> folder? Turns out there's a known version of node in there that the tasks use to run.</p>
<p><img src="https://damianbrady.com.au/content/images/2018/08/agent-files.png" alt="Running a VSTS build/release/deployment agent on a Raspberry Pi"></p>
<p>Which poses a problem - the versions that come with the supported agents won't work (I tried). They're for other OSs...</p>
<p>So what did I do? I just found similar folders elsewhere on the Pi and naively copied them over!</p>
<p><strong>Hey, if it's stupid and it works, it's not stupid. 👉👉</strong></p>
<p>For the record, here's what I copied:</p>
<ul>
<li><code>externals/node/bin</code> - copy <code>node</code> from <code>/usr/bin</code>, and the <code>npm</code> shortcut from the linux agent (it won't resolve yet, but that's ok)</li>
<li><code>externals/node/lib/node_modules/npm</code> - copy the whole <code>npm</code> folder from <code>/usr/lib/node_modules</code></li>
</ul>
<p>Sure enough, success!</p>
<p><img src="https://damianbrady.com.au/content/images/2018/08/rpi-deployment-group.png" alt="Running a VSTS build/release/deployment agent on a Raspberry Pi"></p>
<h2 id="shouldidothis">Should I do this?</h2>
<p>Probably not.</p>
<p>I mean, don't get me wrong, it's pretty cool being able to deploy directly to the Pi using an agent like this, but what if you have hundreds of devices, or you're actually deploying to 25 light globes or a refrigerator?</p>
<p>This works great for a Pi, but otherwise you're better served using <a href="https://azure.microsoft.com/en-au/services/iot-hub/">Azure IoT Hub</a>. That's what it's for after all.</p>
<p>So... off to research that!</p>
<p><img src="https://media.giphy.com/media/WMnTK3XEo7064/giphy.gif" alt="Running a VSTS build/release/deployment agent on a Raspberry Pi"></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[DevOps as a Department]]></title><description><![CDATA[Someone sent me a message the other day asking for some help. They'd recently joined a new company that was thinking of setting up a "DevOps Department".
My immediate thought? 
That's a recipe for failure before they've even begun.]]></description><link>https://damianbrady.com.au/2018/08/07/devops-as-a-department/</link><guid isPermaLink="false">5b67e17d4da92300bf7602fa</guid><category><![CDATA[DevOps]]></category><category><![CDATA[VSTS]]></category><dc:creator><![CDATA[Damian Brady]]></dc:creator><pubDate>Tue, 07 Aug 2018 03:35:54 GMT</pubDate><media:content url="https://damianbrady.com.au/content/images/2018/08/pexels-photo-533189.jpeg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://damianbrady.com.au/content/images/2018/08/pexels-photo-533189.jpeg" alt="DevOps as a Department"><p>Someone sent me a message the other day asking for some help. They'd recently joined a new company that was thinking of setting up a &quot;DevOps Department&quot;.</p>
<p>My immediate thought:</p>
<p><strong>🚨🚨🚨 That's a recipe for failure before they've even begun. 🚨🚨🚨</strong></p>
<h3 id="kbutwhytho">K but why tho?</h3>
<p>Usually when I see a &quot;DevOps Department&quot; or a &quot;DevOps Team&quot; or similar, it's implemented as a silo in the organisation. That silo holds <em>all</em> the knowledge regarding how to deploy and manage applications, and they're the only ones who can create new pipelines.</p>
<p>When that happens, development and operations don't work together any more than they did, they just have another group of people with their own priorities to contend with.</p>
<p>A new silo between Dev and Ops (or sometimes just replacing Ops) is completely against the point of DevOps.</p>
<p><img src="https://damianbrady.com.au/content/images/2018/08/devops-sticker.png" alt="DevOps as a Department"></p>
<h3 id="caniteverwork">Can it ever work?</h3>
<p>Yes. I think so.</p>
<p>But only if that &quot;department&quot; is considered a knowledge center, and concentrates on the services and tools the developers and operations teams need to do things properly.</p>
<p>Tools like <a href="https://visualstudio.microsoft.com/team-services/?WT.mc_id=vsts-blog-dabrady">VSTS</a> and <a href="https://azure.microsoft.com/en-us/services/application-insights/?WT.mc_id=appinsights-blog-dabrady">Application Insights</a>.</p>
<p>Or maybe <a href="https://github.com">GitHub</a>, <a href="https://jetbrains.com/teamcity">Team City</a>, <a href="https://octopus.com">Octopus Deploy</a>, and <a href="https://raygun.com">Raygun</a>.</p>
<p>There are a ton of tools out there. The important thing is that <em>the DevOps department not be the sole operators of those tools</em>. They can guide, train, maintain, and manage those tools, but the developers and operations folks should be using them day to day. Not just clicking the buttons, but configuring builds, defining releases, pushing code that defines the infrastructure, watching production metrics, etc.</p>
<p>Cue happy teamwork shot:</p>
<p><img src="https://damianbrady.com.au/content/images/2018/08/team.jpeg" alt="DevOps as a Department"></p>
<p>The organisers of the <a href="https://globaldevopsbootcamp.com/">Global DevOps Bootcamp</a> put it well. The DevOps tooling should be self-service - it should be easy to configure a new pipeline, manage work, define new infrastructure, and monitor production.</p>
<p><strong>✨ Easy does not mean raising a ticket with the DevOps department. ✨</strong></p>
<h3 id="oksoismydevopsdepartmentdestinedtofail">Ok, so is my DevOps department destined to fail?</h3>
<p>Is DevOps only practiced within that department?</p>
<p>There's your probable answer.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[MS Build 2018 - My Movements]]></title><description><![CDATA[Microsoft Build 2018 is coming up and I'll be there with my team and a whole lot of CDAs! Here's where I'll be during the week.]]></description><link>https://damianbrady.com.au/2018/05/03/ms-build-2018-my-movements/</link><guid isPermaLink="false">5b6117f76e3aea001795e4a5</guid><dc:creator><![CDATA[Damian Brady]]></dc:creator><pubDate>Thu, 03 May 2018 04:08:34 GMT</pubDate><media:content url="https://damianbrady.com.au/content/images/2018/05/build-logo-1.jpeg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://damianbrady.com.au/content/images/2018/05/build-logo-1.jpeg" alt="MS Build 2018 - My Movements"><p><a href="https://build.microsoft.com">Microsoft Build 2018</a> is coming up next week and I'll be there with the rest of my team, as well as a whole lot of Cloud Developer Advocates and awesome Microsoft folk!</p>
<p><a href="https://build.microsoft.com"><img src="https://damianbrady.com.au/content/images/2018/05/build-logo.jpeg" alt="MS Build 2018 - My Movements"></a></p>
<p>Here's where I'll be during the week (subject to change!).</p>
<p><em>FYI In the gaps between these times, I'll most likely be at the Lounge, or the VSTS booth  - both in the conference hall.</em></p>
<h3 id="day1monday">Day 1 (Monday):</h3>
<div style="float:left;clear:both;font-weight:bold;">1:00-3:00 pm:</div><div style="margin-left:9em;">Podcast recordings</div>
<div style="float:left;clear:both;font-weight:bold;">5:00-5:30 pm:</div><div style="margin-left:9em;">Channel 9 show recording</div>
<div style="float:left;clear:both;font-weight:bold;">6:30-8:30 pm:</div><div style="margin-left:9em;"><a href="https://www.eventbrite.com/e/dinner-and-a-talk-no-barriers-registration-45460143513" title="Dinner and a Talk at The Riveter">Dinner and a Talk at The Riveter</a></div>
<p>
### Day 2 (Tuesday):
<div style="float:left;clear:both;font-weight:bold;">7:00-9:00 am:</div><div style="margin-left:9em;">Partner breakfast</div>
<div style="float:left;clear:both;font-weight:bold;">10:30-11:45 am:</div><div style="margin-left:9em;">Channel 9 show recordings</div>
<div style="float:left;clear:both;font-weight:bold;">1:15-2:30 pm:</div><div style="margin-left:9em;"><a href="https://mybuild.microsoft.com/sessions?p1=eyJzcGVha2VyIjpbXSwidGltZXNsb3QiOltdLCJkYXkiOltdLCJyb29tIjpbXSwibG9jYXRpb24iOltdLCJzdGFydCI6IiIsImZpbmlzaCI6IiIsInBhZ2VudW1iZXIiOjEsImNhdGVnb3JpZXMiOnt9LCJrZXl3b3JkIjoiV1JLMjIxNCJ9" title="Workshop: Deploying Azure Functions with VSTS">Workshop: Deploying Azure Functions with VSTS</a></div>
</p><p>
### Day 3 (Wednesday):
<div style="float:left;clear:both;font-weight:bold;">9:00-10:00 am:</div><div style="margin-left:9em;">Meet The League at the DevOps Booth</div>
<div style="float:left;clear:both;font-weight:bold;">10:15-11:30 am:</div><div style="margin-left:9em;"><a href="https://mybuild.microsoft.com/sessions?p1=eyJzcGVha2VyIjpbXSwidGltZXNsb3QiOltdLCJkYXkiOltdLCJyb29tIjpbXSwibG9jYXRpb24iOltdLCJzdGFydCI6IiIsImZpbmlzaCI6IiIsInBhZ2VudW1iZXIiOjEsImNhdGVnb3JpZXMiOnt9LCJrZXl3b3JkIjoiQlJLMjEwNSJ9" title="Azure DevOps with VSTS">Azure DevOps with VSTS</a> (with <a href="https://twitter.com/abelsquidhead" title="Abel Wang on Twitter">Abel Wang</a>)</div>
<div style="float:left;clear:both;font-weight:bold;">12:30-2:30 pm</div><div style="margin-left:9em;">Talk Shop at the Lounge</div>
<div style="float:left;clear:both;font-weight:bold;">1:45-2:15 pm</div><div style="margin-left:9em;"><a href="https://channel9.msdn.com/" title="Build Live on Channel 9">Build Live on Channel 9</a></div>
<div style="float:left;clear:both;font-weight:bold;">3:00-3:20 pm:</div><div style="margin-left:9em;"><a href="https://mybuild.microsoft.com/sessions?p1=eyJzcGVha2VyIjpbXSwidGltZXNsb3QiOltdLCJkYXkiOltdLCJyb29tIjpbXSwibG9jYXRpb24iOltdLCJzdGFydCI6IiIsImZpbmlzaCI6IiIsInBhZ2VudW1iZXIiOjEsImNhdGVnb3JpZXMiOnt9LCJrZXl3b3JkIjoiVEhSMzUwMSJ9" title="DevOps for Data Science">DevOps for Data Science</a> (with <a href="https://twitter.com/dynamicwebpaige" title="Paige Bailey on Twitter">Paige Bailey</a>)</div>
</p><p>
</p><p>If you want to meet up any time around these commitments, either come find me in the Lounge, or <a href="https://twitter.com/damovisa">hit me up on Twitter</a></p>
<p>I hope to see you there!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Friends don't let friends right-click publish]]></title><description><![CDATA[I've been throwing out this one-liner for years. It resonated so much I made a sticker! Here's why you shouldn't right-click publish.]]></description><link>https://damianbrady.com.au/2018/02/01/friends-dont-let-friends-right-click-publish/</link><guid isPermaLink="false">5b6117f76e3aea001795e4a4</guid><category><![CDATA[DevOps]]></category><category><![CDATA[Process]]></category><category><![CDATA[Visual Studio]]></category><dc:creator><![CDATA[Damian Brady]]></dc:creator><pubDate>Thu, 01 Feb 2018 04:00:34 GMT</pubDate><media:content url="https://damianbrady.com.au/content/images/2018/02/friends-sticker.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://damianbrady.com.au/content/images/2018/02/friends-sticker.png" alt="Friends don't let friends right-click publish"><p>I've been throwing out this little one-liner for years and it seems to have resonated with some people. So much so that I made a sticker!</p>
<p><img src="https://damianbrady.com.au/content/images/2018/01/friends-sticker.png" alt="Friends don't let friends right-click publish"></p>
<p>If you want one of these stickers, you have three options:</p>
<ul>
<li>Download the photoshop file here: <a href="https://brdy.in/fdlfrcp">https://brdy.in/fdlfrcp</a></li>
<li><a href="https://twitter.com/damovisa">Tell me</a> the email you use for <a href="https://stickermule.com">StickerMule</a> and I'll share the design</li>
<li>Come and see me or one of the <a href="http://loecda.com">#LoECDA</a> at <a href="http://loecda.com/talks">one of the events we're going to</a> and we'll probably just give you one!</li>
</ul>
<h3 id="coolcoolbutwhatdoesitmean">Cool, cool, but what does it mean?</h3>
<p>Great question. Glad you asked.</p>
<p>&quot;Right-click publish&quot; refers to the really, really, really, super common practice of publishing your web application to Azure directly from Visual Studio. It's a really popular technique used by developers everywhere... and far too frequently by Microsoft presenters on stage.</p>
<p><img src="https://damianbrady.com.au/content/images/2018/02/right-click-publish-1.png" alt="Friends don't let friends right-click publish"></p>
<p>This is an awesome way to deploy your web application to Azure.<br>
To try it out.<br>
Like, once or twice, by yourself.<br>
Then <em>never</em> do it again.</p>
<p>The moment you need to work with anyone else on the application, and/or start caring about what you're pushing to production, you should <strong>stop doing this</strong>.</p>
<p><img src="https://damianbrady.com.au/content/images/2018/02/right-click-publish-explode.gif" alt="Friends don't let friends right-click publish"></p>
<h3 id="butitssoeasydamianwhyareyoumakingmylifehard">But it's so easy, Damian, why are you making my life hard?</h3>
<p>Well first, doing it properly is really not that hard. More on that in a bit.</p>
<p>But second, and more important, right-click publish is a fantastic way to <em>accidentally</em> break production. Which is bad. Obviously.</p>
<p>There's so much that's dependent on one person and one machine in the right-click publish scenario.</p>
<p><em>Maybe</em> you have something installed on your machine that's not in production.<br>
<em>Maybe</em> you didn't merge <em>all</em> the changes people made.<br>
<em>Maybe</em> you did, but you resolved that tricky bit slightly wrong.<br>
<em>Maybe</em> you merged successfully, but forgot to run tests.<br>
<em>Maybe</em> you did run the tests, and they work fine on your machine, but not in production.<br>
<em>Maybe</em> there are untested bugs that don't show up until the app is on a server.<br>
<em>Maybe</em> your OS just got an upgrade and the code no longer compiles.</p>
<p>The list goes on.</p>
<p>What you really want is a repeatable, automatic pipeline that takes your code, merges it with everyone else's, runs some tests, deploys it to a test server, runs some more testing and validation, then automatically promotes it to production once you know it works.</p>
<p>Yeah, that sentence was long and scary, but it's honestly not hard. <a href="https://twitter.com/donovanbrown">Donovan</a> builds <a href="https://twitter.com/DonovanBrown/status/849701480445730816">4 of these pipelines in an hour</a> on stage. All in different languages. From different operating systems. Even I've done it a bunch of times - you can build these things in a few minutes.</p>
<p><img src="https://damianbrady.com.au/content/images/2018/02/easy-button.jpg" alt="Friends don't let friends right-click publish"></p>
<p>But if you're <strong>really</strong> attached to right-clicking, you can still do that. Just install the <a href="https://marketplace.visualstudio.com/items?itemName=VSIDEDevOpsMSFT.ContinuousDeliveryToolsforVisualStudio">Continuous Delivery Tools for Visual Studio</a> and now you can right-click <em>Configure Continuous Delivery</em>! Much better.</p>
<h3 id="butitsjustasmallapptheresnopointbuildingawholepipeline">But it's just a small app, there's no point building a whole pipeline!</h3>
<p>I see you're not letting go of this. Ok:</p>
<p>As <a href="https://twitter.com/donovanbrown">Donovan</a> frequently says, <em>&quot;you play how you practice&quot;</em>. If you don't bother doing things properly for small apps (that sometimes grow into big ones), then you're less likely to do it for &quot;real&quot; projects.</p>
<p>When I worked in consulting, it became standard practice to build a pipeline all the way to production on day 1 of a project (yes, that's all the time it took). Sure, at that point you're only deploying &quot;Hello World&quot;, but it makes every subsequent change <strong>so much easier</strong> to deploy safely. And if the process needs adjusting, you're only <em>tweaking</em> a pipeline rather than debating whether to build one from scratch.</p>
<p><img src="https://damianbrady.com.au/content/images/2018/02/amazing.gif" alt="Friends don't let friends right-click publish"></p>
<p>Let's do the math(s🇦🇺), if it takes you 4 hours to set up a basic pipeline with Continuous Integration and Continuous Deployment you're happy with, how long until you've recovered that time?</p>
<p>Think about how long it takes to merge, compile, run tests, deploy to test, then deploy to production. If you're committing and deploying to (at least) test servers regularly, you'll get that time back really quickly.</p>
<p>Can you use right-click publish to go to production? Sure, you can, but you shouldn't.</p>
<p>Friends don't let friends right-click publish.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Visual Studio Team Services - What you might have missed in 2017]]></title><description><![CDATA[VSTS rocks, but with a 3 week release cycle, it can be hard to keep up. Here are some of my favourite (possibly) lesser-known features released in 2017.]]></description><link>https://damianbrady.com.au/2018/01/04/visual-studio-team-services-what-you-might-have-missed-in-2017/</link><guid isPermaLink="false">5b6117f76e3aea001795e4a3</guid><category><![CDATA[VSTS]]></category><category><![CDATA[DevOps]]></category><category><![CDATA[Microsoft]]></category><dc:creator><![CDATA[Damian Brady]]></dc:creator><pubDate>Thu, 04 Jan 2018 00:01:41 GMT</pubDate><media:content url="https://damianbrady.com.au/content/images/2018/01/story-burnup-1.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://damianbrady.com.au/content/images/2018/01/story-burnup-1.png" alt="Visual Studio Team Services - What you might have missed in 2017"><p>Visual Studio Team Services (which I'll call VSTS from now on to save the extra time I've just wasted typing this) has long been one of my favourite products. Now that I work for Microsoft, I can be a bit more effusive and open about my fanboyism.</p>
<iframe src="https://giphy.com/embed/2dQ3FMaMFccpi" width="480" height="460" frameborder="0" class="giphy-embed" allowfullscreen></iframe><p><a href="https://giphy.com/gifs/love-i-you-that-70s-show-2dQ3FMaMFccpi">via GIPHY</a></p>
<p>One of the great things about VSTS is the fast release cycle. Every 3 weeks there's a decent-sized release. Occasionally the changes are less visible (along the lines of &quot;bug-fixes and performance improvements&quot;), but often it's a massive slab of super useful new features.</p>
<p><img src="https://damianbrady.com.au/content/images/2018/01/bug-fixes-and-performance-improvements.jpg" alt="Visual Studio Team Services - What you might have missed in 2017"></p>
<p>With that cracking pace, it's often hard to keep up. Even if you work for Microsoft and have a direct line to the product teams.</p>
<p>Luckily, the <a href="https://www.visualstudio.com/team-services/release-notes/">Visual Studio Team Services Release Notes blog</a> is really useful. Whenever I get a bit behind, it's easy to go through the recent sprints to see what fancy new features I missed.</p>
<p><img src="https://damianbrady.com.au/content/images/2018/01/release-notes.png" alt="Visual Studio Team Services - What you might have missed in 2017"></p>
<p>Even so, it's easy to miss something, so I thought I'd put together a post with my (maybe) lesser-known VSTS highlights from 2017.</p>
<h2 id="featureflagsforpreviewfeatures"><a href="https://docs.microsoft.com/en-us/vsts/release-notes/2017/jan-05-team-services#try-out-new-features-we-are-working-on">Feature flags for preview features</a></h2>
<p>In the very first release of the year, a nice UI for preview feature flags was added. The VSTS team sometimes experiments with new features, and practices &quot;testing in production&quot; (the good kind, not the I-don't-have-a-test-environment kind). When a new feature is about to be released, it may be available to you early as an opt-in preview. It's worth checking out the available flags from time to time - you might be surprised!</p>
<p><img src="https://damianbrady.com.au/content/images/2018/01/preview-features.png" alt="Visual Studio Team Services - What you might have missed in 2017"></p>
<h2 id="continuousdeliveryintheazureportalwithanygitrepo"><a href="https://docs.microsoft.com/en-us/vsts/release-notes/2017/mar-29-team-services#continuous-delivery-in-the-azure-portal-supports-any-git-repo">Continuous Delivery in the Azure Portal with any git repo!</a></h2>
<p>Way back in March, the team added the ability to do continuous delivery to an Azure App Service from <em>any</em> git repo. If you're using GitHub or VSTS, it's easy to set up a hook, but for other git repos Azure will periodically check for changes. It's CI/CD for everyone!</p>
<p><img src="https://damianbrady.com.au/content/images/2018/01/any-git-repo.gif" alt="Visual Studio Team Services - What you might have missed in 2017"></p>
<h2 id="commithistorygraphforgit"><a href="https://docs.microsoft.com/en-us/vsts/release-notes/2017/apr-19-team-services#visualize-your-git-repository">Commit history graph for git</a></h2>
<p>A very welcome addition to the commit history for files or repositories. In April, we got a beautiful commit history graph right in the browser. It's beautifully done and uses <code>canvas</code> which is one of those HTML things I don't really know how to do so it's black magic.</p>
<p><img src="https://damianbrady.com.au/content/images/2018/01/commit-history.png" alt="Visual Studio Team Services - What you might have missed in 2017"></p>
<h2 id="deploymentgroupsfordeployingtovms"><a href="https://docs.microsoft.com/en-us/vsts/release-notes/2017/may-11-team-services#vm-deployment-public-preview">Deployment Groups for deploying to VMs</a></h2>
<p>VSTS has been great at deploying to Azure, but it was previously a little tricky to deploy to a bunch of VMs. With Deployment Groups, introduced in Preview in May, you can install agents on target machines and run release tasks directly on those machines! Yes. I know. Just like Octopus.</p>
<p><img src="https://damianbrady.com.au/content/images/2018/01/deployment-groups.png" alt="Visual Studio Team Services - What you might have missed in 2017"></p>
<h2 id="exportandimportbuilddefinitions"><a href="https://docs.microsoft.com/en-us/vsts/release-notes/2017/jun-22-team-services#export-and-import-build-definitions">Export and Import Build Definitions</a></h2>
<p>This was a top-ten request on UserVoice, so it's awesome it was made available in June. You've managed to get your build definition exactly right and want to use it in a different project or account? Easy - export the JSON, and import it elsewhere!</p>
<p><img src="https://damianbrady.com.au/content/images/2018/01/export-definition.png" alt="Visual Studio Team Services - What you might have missed in 2017"></p>
<h2 id="anewreleasedefinitioneditor"><a href="https://docs.microsoft.com/en-us/vsts/release-notes/2017/jul-14-team-services#release">A new Release Definition Editor</a></h2>
<p>In July, the team introduced this UI update. I love this one because it's JUST SO PRETTY. It's a beautiful way to visualize how you move between environments. Again, there's that <code>svg</code> and <code>canvas</code> black magic going on. It was <a href="https://docs.microsoft.com/en-us/vsts/release-notes/2017/aug-28-team-services#new-release-definition-editor">taken out of preview and made generally available in August</a>.</p>
<p><img src="https://damianbrady.com.au/content/images/2018/01/release-definition-ui.png" alt="Visual Studio Team Services - What you might have missed in 2017"></p>
<h2 id="newburndownandburnupwidgets"><a href="https://docs.microsoft.com/en-us/vsts/release-notes/2017/sep-15-team-services#reporting">New Burndown and Burnup widgets</a></h2>
<p>A small thing maybe, but burndown and burnup charts were awesome additions to the <a href="https://marketplace.visualstudio.com/items?itemName=ms.vss-analytics">Analytics Extension</a> in September. Especially useful for managers who are riding you about deadlines and estimates and stuff. Just give 'em a dashboard. Managers love dashboards.</p>
<p><img src="https://damianbrady.com.au/content/images/2018/01/story-burnup.png" alt="Visual Studio Team Services - What you might have missed in 2017"></p>
<h2 id="deploymentoutputsasvariables"><a href="https://docs.microsoft.com/en-us/vsts/release-notes/2017/oct-30-vsts#azure-resource-group-task---deployment-outputs-as-variables">Deployment Outputs as Variables</a></h2>
<p>Often you want to use some information from the output of one deployment task in another task. For example, if you're deploying to an Azure Web App, you might need to use the URL in a testing task later on. It was always possible (albeit a little tricky), but this October addition made it much easier for some tasks - just give the variable a name and it's now available to you later.</p>
<p><img src="https://damianbrady.com.au/content/images/2018/01/output-variable.png" alt="Visual Studio Team Services - What you might have missed in 2017"></p>
<h2 id="yamlbuilddefinitions"><a href="https://docs.microsoft.com/en-us/vsts/release-notes/2017/nov-28-vsts#configuration-as-code-yaml-builds-in-public-preview-build-tagimgrelease-notes-tagbuildpng">YAML build definitions</a></h2>
<p>My final pick, and this is a big one for a lot of reasons. For me, there are two reasons worth mentioning.</p>
<p>First, whenever a code update required changes to the build definition, you were left with a choice - commit the changes and watch the CI build fail (then update the build), or update the build first, then commit your changes and hope everything lined up. The story was much worse if you had multiple branches - you'd need multiple builds, managed separately, and a merge into master would require changing to what was the branched build... it got complicated.</p>
<p>Second, the build definition (i.e. the way to turn your code into software) was managed completely independently from the code itself. It makes much more sense for them to live together. Many companies and teams used build scripts checked into source control (<code>build.ps1</code> or <a href="https://cakebuild.net/">Cake</a>) which worked fine, but really didn't make use of the awesome VSTS Build engine.</p>
<p>This is the first step to the best of both worlds! Have a YAML build definition that lives alongside your code. It uses the build engine, but also solves the two problems above. Ideally, it'll be able to be run completely independently of VSTS as well. Even better, <a href="https://docs.microsoft.com/en-us/vsts/release-notes/2017/dec-11-vsts#generate-yaml-templates-from-existing-build-definitions">in December</a> we got the ability to view the YAML of an existing build definition!</p>
<p><img src="https://damianbrady.com.au/content/images/2018/01/view-yaml.png" alt="Visual Studio Team Services - What you might have missed in 2017"></p>
<p>Ok, that's it for me!</p>
<p>There are a TON of features released all the time with VSTS, and many more coming soon. To keep up to date, check out the <a href="https://www.visualstudio.com/team-services/release-notes/">Release Notes blog</a>, as well as the <a href="https://docs.microsoft.com/en-us/vsts/release-notes/index">VSTS Features Timeline</a> which has future features as well.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Awareness, Acknowledgement, and Adjustment]]></title><description><![CDATA[There's a common pattern in IT that frequently leads to new buzzwords: Awareness, Acknowledgement, and Adjustment. Make it work for you!]]></description><link>https://damianbrady.com.au/2017/08/22/awareness-acknowledgement-and-adjustment/</link><guid isPermaLink="false">5b6117f76e3aea001795e498</guid><dc:creator><![CDATA[Damian Brady]]></dc:creator><pubDate>Tue, 22 Aug 2017 15:31:37 GMT</pubDate><media:content url="https://damianbrady.com.au/content/images/2017/08/lightbulbs-hanging-1.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://damianbrady.com.au/content/images/2017/08/lightbulbs-hanging-1.jpg" alt="Awareness, Acknowledgement, and Adjustment"><p>There's a common pattern in IT. In many cases, it ultimately leads to a new buzzword. It's not complicated. In fact it's fairly obvious. But <em>understanding what you can do with it</em> can help immensely when it comes to pushing change in your organisation.</p>
<p>Agile, DevOps, Microservices, Containerization, whatever the next buzzword is - all of these &quot;revolutions&quot; are really a result of these three steps.</p>
<blockquote>
<ol>
<li>Awareness</li>
</ol>
</blockquote>
<blockquote>
<ol start="2">
<li>Acknowledgement</li>
</ol>
</blockquote>
<blockquote>
<ol start="3">
<li>Adjustment</li>
</ol>
</blockquote>
<p><img src="https://damianbrady.com.au/content/images/2017/08/binoculars.jpg" alt="Awareness, Acknowledgement, and Adjustment"></p>
<h2 id="examples">Examples:</h2>
<p>Let's look at a couple of examples to solidify what I'm talking about. I'm simplifying for the purposes of brevity, but consider Agile and Microservices:</p>
<h3 id="agile">Agile:</h3>
<ol>
<li><em>Awareness</em> of slipping timelines, incorrect estimates, project failures.</li>
<li><em>Acknowledgement</em> that big, upfront plans never seem to go smoothly, no matter how long you spend on them or how many people are involved. Some things you just can't know until you start.</li>
<li><em>Adjustment</em> of how projects are run - you can't plan for the long term, so let's just plan a short distance ahead and iterate.</li>
</ol>
<h3 id="microservices">Microservices:</h3>
<ol>
<li><em>Awareness</em> that even small changes can be expensive in a monolithic architecture, and side-effects can be hard to predict.</li>
<li><em>Acknowledgement</em> that isolated and decoupled services can make change easier and more predictable.</li>
<li><em>Adjustment</em> of how software is put together - small, self-contained components that can be iterated on more quickly.</li>
</ol>
<p><strong>The same pattern can apply for DevOps:</strong></p>
<h3 id="devops">DevOps:</h3>
<ol>
<li><em>Awareness</em> that software in production is the aim, and that there are some obvious bottlenecks that slow things down.</li>
<li><em>Acknowledgement</em> that software should be able to help with this - most of what we do is able to be automated!</li>
<li><em>Adjustment</em> by removing the bottlenecks using software and scripts, adding surety through automated testing, and reducing the cycle time from idea to production.</li>
</ol>
<p><img src="https://damianbrady.com.au/content/images/2017/08/lightbulbs-hanging.jpg" alt="Awareness, Acknowledgement, and Adjustment"></p>
<h2 id="sowhatcanidowiththis">So what can I do with this?</h2>
<p>I've given a few talks lately on the challenges of implementing DevOps in an organisation where you have little to no control over how the business operates.</p>
<p>In particular, my &quot;<a href="https://vimeo.com/223984407">Doing DevOps as a Politically Powerless Developer</a>&quot; talk has resonated with a lot of people lately.</p>
<p>As a &quot;politically powerless developer&quot; in an organisation, it can be difficult to instigate change, even when you know it's the right thing to do. In short, you probably don't have the power to implement the <em>Adjustment</em> part of this pattern.</p>
<p><strong>But you can definitely affect <em>Awareness</em>. It's easy - start measuring.</strong></p>
<p><img src="https://damianbrady.com.au/content/images/2017/08/ruler.jpg" alt="Awareness, Acknowledgement, and Adjustment"></p>
<p>Measure how long it takes for a change you commit to make it to production. What happens in that time? Is there a lot of waiting?</p>
<p>Measure how long it takes for a user-reported issue to get to your backlog. Add some production monitoring, and measure how much time is saved by learning about issues first-hand. How much time did you save?</p>
<p>Measure the time it takes to write tests, and compare that to the time you take fixing bugs for code that doesn't have tests around it. Can you prove that writing tests is beneficial overall?</p>
<p>Once you have information, you can give it to your boss or pass it up the chain. You've already acknowledged there's a better way, so you'll be ready with solutions once management acknowledges there's a problem!</p>
<p><img src="https://damianbrady.com.au/content/images/2017/08/report.jpg" alt="Awareness, Acknowledgement, and Adjustment"></p>
<h2 id="summary">Summary</h2>
<p>To really instigate change and <em>adjust</em> how your organisation delivers software, there needs to be an <em>acknowledgement</em> that there's a problem. That won't happen unless there's <em>awareness</em>.</p>
<p><strong>If you're having trouble pushing change, focus on <em>awareness</em> first.</strong></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Continuous Integration, not Continuous Isolation]]></title><description><![CDATA[Continuous Integration is important for modern software developers. But are you practicing Continuous Integration, or Continuous Isolation?]]></description><link>https://damianbrady.com.au/2017/07/11/continuous-integration-not-continuous-isolation/</link><guid isPermaLink="false">5b6117f76e3aea001795e4a2</guid><category><![CDATA[DevOps]]></category><category><![CDATA[Process]]></category><category><![CDATA[Continuous Integration]]></category><dc:creator><![CDATA[Damian Brady]]></dc:creator><pubDate>Tue, 11 Jul 2017 20:53:44 GMT</pubDate><media:content url="https://damianbrady.com.au/content/images/2017/07/paths-1.jpeg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://damianbrady.com.au/content/images/2017/07/paths-1.jpeg" alt="Continuous Integration, not Continuous Isolation"><p><strong>Merging can suck.</strong></p>
<p>My first real-world exposure to version control was in the good old Visual SourceSafe days. Back then (and continuing into server-side Team Foundation Version Control), it was common to have exclusive locks on files - i.e. only one person could work on a file at a time. If someone changed a file, you had to &quot;Get Latest&quot; before you could start working on it.</p>
<p>In practice, big changes required many files being locked by one person, and everyone was blocked until it was done.</p>
<p><strong>This was unproductive.</strong></p>
<p>So we worked on branches. We knew that the merge at the end was going to be horrible, but that was a problem for the future. Not worth worrying about now.</p>
<p><img src="https://damianbrady.com.au/content/images/2017/07/padlock.jpeg" alt="Continuous Integration, not Continuous Isolation"></p>
<p>Then exclusive locks went away, and we started working on the same files, merging as we went. We could even work offline with distributed solutions like mercurial and git, and make changes in tiny branches (rather than branching the whole codebase), which meant smaller merges and less pain.</p>
<p>But big changes and refactorization were still a problem. You still had to merge your changes with everyone else's, and with everyone working on the same files, it became easier to work on your own branch (or a team branch) and worry about merging later. You could even push broken code to the server without bothering everyone else.</p>
<p><strong>So we deferred merging.</strong></p>
<p>Again, we knew the merge at the end was going to be horrible, so <em>for big changes, our situation hadn't improved much</em>.</p>
<p><img src="https://damianbrady.com.au/content/images/2017/07/working-back-to-back.jpeg" alt="Continuous Integration, not Continuous Isolation"></p>
<h2 id="continuousintegration">Continuous Integration</h2>
<p><a href="https://www.martinfowler.com/articles/continuousIntegration.html">Continuous Integration</a> means merging all of your changes into everyone else's changes on a continuous basis in order to make sure problems are caught early. You can ensure that the code compiles, all the tests pass, and even run analysis tools to check for code quality or security vulnerabilities.</p>
<p>There are obvious advantages to continuous integration. It's common knowledge that problems are cheaper to fix the earlier they're identified. Whether that's a bug or a merge conflict, if you can resolve it immediately, it will save time in the long run. You want to know straight away whether you've &quot;broken the build&quot;. Not a week later when another team member pulls your changes and can't compile, and certainly not a few months later when it's time to push to production<sup>1</sup>.</p>
<p>If everyone on the team is working on the same code, and they're all pushing their changes regularly, continuous integration will identify problems quickly.</p>
<p><strong>If a team is working with long-lived branches, they're not doing <em>continuous integration</em>. Instead, they're doing <em>continuous isolation</em>.</strong></p>
<p><img src="https://damianbrady.com.au/content/images/2017/07/paths.jpeg" alt="Continuous Integration, not Continuous Isolation"></p>
<p>The term &quot;continuous isolation&quot; came from a tweet by <a href="https://twitter.com/benjiweber/status/831193574502961154">benjiwebber</a> and was expanded upon by <a href="https://paulhammant.com/2017/02/14/fake-news-via-continuous-isolation/">Paul Hammant</a>. Thoughtworks later identified the practice as <a href="https://www.thoughtworks.com/radar/techniques/ci-theatre">&quot;CI Theatre&quot;</a>.</p>
<p>By working on a long-running branch, changes become more and more isolated from the other branches, including trunk (or master). CI builds can still exist against that branch, but they're only integrating changes within that branch, not the code that the other teams are committing. They might make the team feel good, but they're just deferring the pain.</p>
<h2 id="trunkbaseddevelopment">Trunk-based development</h2>
<p>The solution seems obvious - don't work on branches! Or if you do, use short-lived branches and merge back into the trunk as soon as you can.</p>
<p><img src="https://damianbrady.com.au/content/images/2017/07/railroad-tracks.jpeg" alt="Continuous Integration, not Continuous Isolation"></p>
<p>I promote this way of working as much as I possibly can, but in practice, it's not always that simple. Not every change can be knocked over in a few days.</p>
<p><a href="https://trunkbaseddevelopment.com/">trunkbaseddevelopment.com</a> is a fantastic website that goes through this idea in detail, including the practicalities of doing it in real teams. I'd highly recommend reading through it.</p>
<p>The other technique that can help is <a href="https://en.wikipedia.org/wiki/Feature_toggle">feature toggles</a> (or any of a bunch of names that mean the same thing). The idea is that even unfinished code can be merged into the trunk, as long as it's hidden behind a flag. As long as it <em>a)</em> compiles, and <em>b)</em> doesn't break anything, you can deploy it all the way to production with the flag turned off. The code won't run, but you can still continuously integrate your code.</p>
<p>Feature toggles deserve their own blog post, so I won't expand further here.</p>
<h2 id="summary">Summary</h2>
<p>While long-running branches may feel more productive day to day, <em>realise that you're just deferring the merge pain</em>. That conflict you introduced is <em>going</em> to need attention at some point. The sooner you address it, the easier it will be to resolve.</p>
<p><strong>Integrate continuously, and don't let your branches last long</strong>.</p>
<p>Incidentally, there's a <a href="https://www.youtube.com/watch?v=lqRQYEHAtpk">recording of an excellent talk on this very topic</a> from <a href="http://gotochgo.com/">GOTO Chicago</a> earlier this year by the always-impressive <a href="https://twitter.com/samnewman">Sam Newman</a>. Do yourself a favour and watch it!</p>
<p><sup>1</sup> <span style="font-size:smaller;">Of course you should be deploying to production more regularly than once a month. Why wait if you've got something meaningful to ship!?</span></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[VSTS Pull Request Alerts in Microsoft Teams]]></title><description><![CDATA[We use Microsoft Teams, so what better way to learn about new PRs than through a chat client that's always open? Here's how!]]></description><link>https://damianbrady.com.au/2017/06/29/pull-request-alerts-in-microsoft-teams/</link><guid isPermaLink="false">5b6117f76e3aea001795e4a1</guid><category><![CDATA[Teams]]></category><category><![CDATA[VSTS]]></category><category><![CDATA[LoECDA]]></category><dc:creator><![CDATA[Damian Brady]]></dc:creator><pubDate>Thu, 29 Jun 2017 16:26:58 GMT</pubDate><media:content url="https://damianbrady.com.au/content/images/2017/06/teams-vsts-post-1.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://damianbrady.com.au/content/images/2017/06/teams-vsts-post-1.png" alt="VSTS Pull Request Alerts in Microsoft Teams"><p>When you start something new, first on your agenda should be a website! Right?</p>
<p>One of the first things <a href="https://twitter.com/donovanbrown">Donovan</a> set up for the new &quot;League of Extraordinary Cloud DevOps Advocates&quot; team was a new <a href="http://loecda.com">LoeCDA.com</a> website. The <a href="http://loecda.com/home/talks">&quot;Tour Dates&quot;</a> section will be extremely useful if you'd like to see any of us at an event near you!</p>
<p>He used the extremely useful <a href="http://donovanbrown.com/post/yo-Team"><code>yo team</code> yeoman generator</a> and had a new ASP.NET Core website, complete with a CI/CD pipeline, running on docker in Azure in just a few minutes. <em>This still blows my mind</em>, but I digress - that's not the point of this post.</p>
<p><a href="http://loecda.com"><img src="https://damianbrady.com.au/content/images/2017/06/loecda-website.png" alt="VSTS Pull Request Alerts in Microsoft Teams"></a></p>
<h2 id="ourdevprocess">Our dev process</h2>
<p>Even though this is a very simple website, we agreed to make all changes via pull requests (PRs). This helps us in two ways:</p>
<ol>
<li>We can exercise the PR process in Team Services and Visual Studio</li>
<li>It helps us learn from each other</li>
</ol>
<p>Exercising features that real dev teams will be using is really important. Half of the Cloud Dev Advocate role is bringing feedback back to the engineering teams. What better way to do that than using the features?</p>
<p>Learning from each other is an often-overlooked benefit of working with pull requests. It forces code reviews, which is a great way to learn about new techniques or better ways to implement features.</p>
<p><img src="https://damianbrady.com.au/content/images/2017/06/dotcom-prs.png" alt="VSTS Pull Request Alerts in Microsoft Teams"></p>
<p>So every change will occur on a feature branch (or topic branch), we'll submit a PR, another team member reviews and approves it, and merges in those changes. Of course once that happens, CI/CD ensures it gets to production with almost no more effort!</p>
<h2 id="findingoutaboutprs">Finding out about PRs</h2>
<p>We use <a href="https://products.office.com/en-us/microsoft-teams/group-chat-software">Microsoft Teams</a> for day-to-day communication, so what better way to learn about new pull requests than through a chat client that's always open?</p>
<p>Teams has a great feature called <a href="https://msdn.microsoft.com/en-us/microsoft-teams/connectors">Connectors</a>, which allows you to integrate with third-party applications. Thankfully, there's a connector for VSTS.</p>
<h3 id="configuringthevstsconnector">Configuring the VSTS connector</h3>
<p>The first (optional) step is to set up a new channel in Teams. You can easily add a connector to an existing channel, but having a specific channel for PRs reduces the noise in your other channels.</p>
<p>To do this, just click on the ellipsis next to your team, and choose <em>Add Channel</em>.</p>
<p><img src="https://damianbrady.com.au/content/images/2017/06/teams-add-channel.png" alt="VSTS Pull Request Alerts in Microsoft Teams"></p>
<p>Now click on the ellipsis next to the new channel, and choose <em>Connectors</em>.</p>
<p><img src="https://damianbrady.com.au/content/images/2017/06/teams-add-connector.png" alt="VSTS Pull Request Alerts in Microsoft Teams"></p>
<p>Find the Visual Studio Team Services connector. If you already have some VSTS integration, you'll see a <em>Configure</em> button. If not, it will be <em>Add</em>.</p>
<p><img src="https://damianbrady.com.au/content/images/2017/06/teams-vsts-connector.png" alt="VSTS Pull Request Alerts in Microsoft Teams"></p>
<p>If you're adding a VSTS connector for the first time, you'll need to walk through the steps to connect to VSTS. Once you've done so, you'll be able to choose your connection (or &quot;Profile&quot;) for subsequent VSTS connector configurations.</p>
<p>The next part is easy - just go through the fields and choose the appropriate entries from the dropdowns. You'll need to choose a VSTS Account and Project, and you can choose to be alerted by events for individual VSTS teams, or for all teams.</p>
<p>You'll then be asked for an event type. There are a lot of VSTS events you can choose from here.</p>
<p><img src="https://damianbrady.com.au/content/images/2017/06/teams-event-type.png" alt="VSTS Pull Request Alerts in Microsoft Teams"></p>
<p>In our case, we want to hear about both &quot;Pull request created&quot; events, and &quot;Pull request merge commit created&quot; events - i.e. when there's a new PR, and when one has been merged. Unfortunately you can't choose both at the same time, so we had to go through this configuration twice. Not a big deal - it's a once-off configuration and only takes a couple of minutes.</p>
<p>Once done, going back to <em>Connectors</em> (from the channel ellipsis) allows us to see the connectors we've configured.</p>
<p><img src="https://damianbrady.com.au/content/images/2017/06/teams-configured-connectors.png" alt="VSTS Pull Request Alerts in Microsoft Teams"></p>
<h2 id="theendresult">The end result</h2>
<p>When a new PR is submitted by anyone in the team, there's a new message in the channel - complete with a direct link to view the PR!</p>
<p><img src="https://damianbrady.com.au/content/images/2017/06/teams-vsts-post.png" alt="VSTS Pull Request Alerts in Microsoft Teams"></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[I'm joining Microsoft]]></title><description><![CDATA[I'm excited to announce that I'm joining as a Sr. Cloud Developer Advocate in the Cloud and Enterprise group, working with Donovan Brown.]]></description><link>https://damianbrady.com.au/2017/06/01/im-joining-microsoft/</link><guid isPermaLink="false">5b6117f76e3aea001795e49f</guid><category><![CDATA[Octopus Deploy]]></category><category><![CDATA[Microsoft]]></category><category><![CDATA[Career]]></category><dc:creator><![CDATA[Damian Brady]]></dc:creator><pubDate>Thu, 01 Jun 2017 10:08:00 GMT</pubDate><media:content url="https://damianbrady.com.au/content/images/2017/06/damo-donovan-cropped.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://damianbrady.com.au/content/images/2017/06/damo-donovan-cropped.jpg" alt="I'm joining Microsoft"><p><strong>I'm excited to announce that I'm joining <a href="https://microsoft.com">Microsoft</a> as a Sr. Cloud Developer Advocate in the Cloud and Enterprise group!</strong></p>
<p>In a seriously ego-boosting Twitter DM, <a href="https://twitter.com/donovanbrown">Donovan Brown</a> asked whether I'd be interested in the role and encouraged me to apply. I went through the process, and I'll be starting on his team next week, on the 7th of June.</p>
<p><img src="https://damianbrady.com.au/content/images/2017/06/from-donovan.jpg" alt="I'm joining Microsoft"></p>
<h2 id="whataboutoctopus">What about Octopus?</h2>
<p>I joined <a href="https://octopus.com">Octopus Deploy</a> early in 2015 as a Solution Architect. When I joined, I was one of only six in the company, but since then the company has grown to about 25 and my role started revolving more around the community. I also wrote our <a href="https://marketplace.visualstudio.com/items?itemName=octopusdeploy.octopus-deploy-build-release-tasks">extension for Visual Studio Team Services</a>.</p>
<p>I love <a href="https://octopus.com">Octopus</a>, and leaving wasn't in the plan at all, but this new opportunity was far too good to pass up. I consider myself extremely lucky to have worked with such a dedicated and smart group of people for over 2 years. I have no doubt that Octopus will continue pushing out awesome software.</p>
<p>While Octopus occupies a commanding position in the world of deployment automation, Microsoft (through <a href="https://visualstudio.com">VSTS</a> and <a href="https://azure.com">Azure</a>) has a set of tools and services for the whole DevOps lifecycle. I'm looking forward to talking to a broader audience about everything from requirements gathering to monitoring in production.</p>
<p>However... you can still expect me to recommend Octopus as part of that process. :)</p>
<p><a href="https://octopus.com/blog/webinar-automating-deployments-vsts-octopus"><img src="https://i.octopus.com/blog/201612-img_blog_vstsoctopusextension_2016_02-01-SBMS.png" alt="I'm joining Microsoft"></a></p>
<h2 id="whatwillibedoing">What will I be doing?</h2>
<p>It's been made clear to me that <strong>my goal at Microsoft is to help people succeed</strong>. Not to help them succeed with a Microsoft-only stack. Not even to help them succeed with a <em>mainly</em> Microsoft stack. If Microsoft tech can be used anywhere in the pipeline, I'll try to help out.</p>
<p>This is really important to me, and is another example of Microsoft putting their money where their mouth is. Gone are the days of Microsoft lock-in - today it's all about <a href="https://github.com/aspnet/benchmarks">competing on merit</a>, enabling <a href="https://developer.microsoft.com/en-gb/">any platform</a>, and <a href="http://www.zdnet.com/article/from-open-source-hater-to-no-1-fan-microsoft-now-tops-google-facebook-in-github-contributors/">open-source</a>. The Microsoft of ten years ago didn't excite me, but that's changed dramatically.</p>
<p>As for my day to day, you can expect to see me at <a href="https://damianbrady.com.au/speaking">more conferences and events</a>. I'll be creating useful content to help people succeed, and hopefully visiting a few customers directly. It'll take me a little while to settle in, but feel free to <a href="https://twitter.com/damovisa">reach out on Twitter </a> if there's something I can help with.</p>
<p><img src="https://damianbrady.com.au/content/images/2017/06/damo-donovan.jpg" alt="I'm joining Microsoft"></p>
<p>Microsoft is hiring, so if you have a passion for developer advocacy, <a href="https://careers.microsoft.com/search.aspx#&amp;&amp;p2=all&amp;p1=all&amp;p3=1014&amp;p4=US&amp;p0=%22cloud+developer+advocate%22&amp;p5=all">maybe you'd be a good fit as well</a>!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[DevOps for Brownfields - The code]]></title><description><![CDATA[Deploying continuously is easier said than done, but there are some practical changes you can make to your codebase and how you work with it that can help.]]></description><link>https://damianbrady.com.au/2017/04/25/devops-for-brownfields-architecture/</link><guid isPermaLink="false">5b6117f76e3aea001795e49e</guid><category><![CDATA[DevOps]]></category><category><![CDATA[Process]]></category><dc:creator><![CDATA[Damian Brady]]></dc:creator><pubDate>Tue, 25 Apr 2017 21:39:26 GMT</pubDate><media:content url="https://damianbrady.com.au/content/images/2017/04/code-1-1.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://damianbrady.com.au/content/images/2017/04/code-1-1.jpg" alt="DevOps for Brownfields - The code"><p>It's easy to <em>decide</em> you want to get away from long, painful, weekend deployments, but it takes much more than just a decision. For legacy code (<a href="https://vimeo.com/142347209">whatever your definition of legacy might be</a>), there are likely some things that prevent you from deploying fast and frequently.</p>
<p>In my previous Brownfields posts I talked about <a href="https://damianbrady.com.au/2017/01/24/devops-as-a-culture/">DevOps as a Culture</a> and <a href="https://damianbrady.com.au/2017/04/03/devops-for-brownfields-process/">changing the dev process</a>. In this post, I'll talk about some practical changes you can make to your codebase and how you work with it. These changes will make it easier to deploy regularly and without fuss.</p>
<p><img src="https://damianbrady.com.au/content/images/2017/04/code-1.jpg" alt="DevOps for Brownfields - The code"></p>
<h2 id="onecodebase">One codebase</h2>
<p>An application should only have a single codebase, and only one branch that you deploy to production from. There are two common practices that get in the way of this:</p>
<ol>
<li>Separate copies of code for different scenarios</li>
<li>Long-lived branches</li>
</ol>
<h3 id="codefordifferentscenarios">Code for different scenarios</h3>
<p>This is a surprisingly common practice. I've worked with organisations in the past that had different, almost-the-same codebases for different flavours of the application. They could be separated based on country, set of features, or individual customers.</p>
<p>The common thread is that at some point there was a diversion based on two seemly unreconcilable differences. <strong>Rather than a larger effort to refactor, two versions emerged.</strong> The result is that it's incredibly difficult to apply changes and bug fixes to all versions consistently and safely.</p>
<h3 id="longlivedbranches">Long-lived branches</h3>
<p>It's also common to separate versions of code into branches. This can be a way of implementing the previous practice (code for different scenarios) that gives the feeling that it's the same codebase. It can make changes a little easier to propagate across versions, provided the versions are similar.</p>
<p>It's also common to have separate long-lived branches for different environments. The team writes code on a <code>dev</code> branch which then gets merged into <code>staging</code> for a test deployment, then to <code>production</code> for production deployment.</p>
<p>In my opinion, this is a mistake. Each time you need to deploy, you're merging and ending up with a brand new codebase. That means <strong>when you deploy, it's the <em>first time</em> you've ever deployed that code</strong>.</p>
<p>If a successful deployment relies on a clean merge, that should scare you!</p>
<p><img src="https://damianbrady.com.au/content/images/2017/04/chess-one-standing.jpeg" alt="DevOps for Brownfields - The code"></p>
<p>So how do you get to a single codebase? Well, it's likely to require (sometimes significant) refactoring.</p>
<h2 id="identifyandisolatevariations">Identify and isolate variations</h2>
<p>There will invariably be variations between deployments of your application. Whether they're environmental (test vs production) or otherwise (e.g. customer configuration).</p>
<p>It's important to find these differences and isolate them. Rather than <code>if</code> statements scattered throughout your code, properly independent classes or assemblies make it much easier and safer to make changes to your software without unexpected side-effects.</p>
<p><a href="https://en.wikipedia.org/wiki/Dependency_injection">Dependency injection</a> is great for this, but of course you don't want to have to change the code that resolves your dependencies each time you compile for a different scenario. You need to be able to change your configuration without recompiling.</p>
<h2 id="externaliseconfiguration">Externalise configuration</h2>
<p>To avoid having to recompile for each different deployment scenario, <strong>it's important that your configuration is <em>outside</em> the compiled application</strong>.</p>
<p>That means you can deploy the same binaries and compiled code, but change the configuration based on the environment you're in, or the customer you're deploying to.</p>
<p>It's really up to you where you keep your configuration. .NET developers tend to keep config settings in <code>.config</code> files, but environment variables or even external databases are reasonable alternatives. <strong>As long as you don't have to recompile to deploy to a new location!</strong></p>
<p><img src="https://damianbrady.com.au/content/images/2017/04/settings.jpeg" alt="DevOps for Brownfields - The code"></p>
<h2 id="getyourversioningright">Get your versioning right</h2>
<p>Finally, it's extremely important that you can easily distinguish between different compiled versions of your software. The usual way to do this is with versioning.</p>
<p>Because there's only a single codebase, and we only deploy from the <code>master</code> branch, we only need <em>one</em> version number. At least for production candidates.</p>
<p>Following <a href="http://semver.org/">Semantic Versioning</a> is an awesome way to manage your versions, but if you can't do that, you just need to follow two rules:</p>
<ol>
<li><strong>Each build has a new version number</strong></li>
<li><strong>New code has a higher version number</strong></li>
</ol>
<p>These two rules mean that given any two builds, you can easily determine whether they're the same, and if not, which is newer. Remember, we only have one branch, so we're comparing like with like!</p>
<p><img src="https://damianbrady.com.au/content/images/2017/04/cars-1280.jpg" alt="DevOps for Brownfields - The code"></p>
<h2 id="summary">Summary</h2>
<p>There are changes you can make to your code and the way you work with it that will make deployments easier.</p>
<ol>
<li>Get to one codebase</li>
<li>Identify and isolate variations</li>
<li>Externalise your configuration</li>
<li>Get your versioning right</li>
</ol>
<p>Once deployments are easier, you can feel confident doing them more often, which will ultimately lead to a better DevOps story!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Social Media and why I won't "add you"]]></title><description><![CDATA[If you've asked me to "add you" on a particular social media channel, I might have ignored you or refused. This post explains why.]]></description><link>https://damianbrady.com.au/2017/04/04/social-media-and-why-i-wont-add-you/</link><guid isPermaLink="false">5b6117f76e3aea001795e49d</guid><category><![CDATA[General]]></category><category><![CDATA[Social Media]]></category><dc:creator><![CDATA[Damian Brady]]></dc:creator><pubDate>Tue, 04 Apr 2017 23:03:13 GMT</pubDate><media:content url="https://damianbrady.com.au/content/images/2017/04/network-cables-line-network-connector-cable-47735.jpeg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://damianbrady.com.au/content/images/2017/04/network-cables-line-network-connector-cable-47735.jpeg" alt="Social Media and why I won't "add you""><p>There are a lot of options for connecting with people online these days, and I use many of them. To differing degrees, the main ones I use are <a href="https://twitter.com/damovisa">Twitter</a>, <a href="https://www.linkedin.com/in/damianbrady">LinkedIn</a>, Facebook, Email, Skype, and Slack.</p>
<p>So which do I use for what purpose, and why did I only supply links for two of them?!</p>
<p>Over the past few years, I've started being more careful about the contacts I have through these channels. If you've asked me to &quot;add you&quot; on a particular channel, I might have ignored you or refused. This post explains why.</p>
<p><em>Note: There's a chance I'll come across like an arsehole in this post. My intent is to explain, not offend. But if you think I'm doing it wrong... uh, I'm sorry you feel that way.</em></p>
<h3><img src="https://damianbrady.com.au/content/images/2017/04/Twitter-48.png" style="vertical-align:middle;" alt="Social Media and why I won't "add you""> Twitter</h3>
<p>I use Twitter a lot. My profile and tweets are public, and I tweet a mix of personal and work-related stuff. I'm really happy for anyone to follow me. Seriously, <a href="https://twitter.com/damovisa">go do it</a>.</p>
<p>I respond to most @ tweets, but fair warning - if an account is abusive or a bit too spammy, I won't hesitate to block and report.</p>
<p style="background:#ddeaee;text-align:center;font-weight:bold;padding:5px;"> Twitter is almost certainly the best way to connect with me.</p>
<p>The accounts I follow are extremely varied as well. There are a lot of tech people, but also family, sports people, companies, parody accounts - basically anything I want to read. If I don't follow you and you think I should, let me know! I might! But I also might not. Please don't be offended.</p>
<h3><img src="https://damianbrady.com.au/content/images/2017/04/LinkedIn-48.png" style="vertical-align:middle;" alt="Social Media and why I won't "add you""> LinkedIn</h3>
<p>I rarely use LinkedIn. I'll keep my profile more or less up to date, but blog posts happen on my blog, and I'll post interesting links to Twitter.</p>
<p>I do have a lot of LinkedIn contacts, but I'm pretty strict on who I &quot;connect with&quot;.</p>
<p style="background:#ddeaee;text-align:center;font-weight:bold;padding:5px;"> If I've annoyed you by "not connecting", there's a good chance it was on LinkedIn.</p>
<p>As a rule, <em>I don't connect with recruiters</em>. No, I'm not interested in the job you think I'm perfect for because my profile matched the keywords in your search.</p>
<p>I also don't connect with people I haven't met. It's great that you have a similar job as me, or you like the same things, but I treat LinkedIn as a place to keep track of people I actually know.</p>
<h3><img src="https://damianbrady.com.au/content/images/2017/04/Facebook-48.png" style="vertical-align:middle;" alt="Social Media and why I won't "add you""> Facebook</h3>
<p>I use Facebook frequently, but <em>only for friends and family</em>. Luckily Facebook friend requests are few and far between. I'll let you read into that what you will.</p>
<p style="background:#ddeaee;text-align:center;font-weight:bold;padding:5px;"> The overlap between business connections and Facebook friends is small,<br> and I intend to keep it that way.</p>
<p>Occasionally, work-related stuff will creep onto Facebook, but I'm conscious that most of my Facebook friends, well, couldn't care less. So it doesn't happen a lot.</p>
<h3><img src="https://damianbrady.com.au/content/images/2017/04/Message-50.png" style="vertical-align:middle;" alt="Social Media and why I won't "add you""> Email</h3>
<p>I welcome emails! So why didn't I provide a link to my email above?</p>
<p>It's not hard to find an email address for me, and I'd prefer if you did a little bit of work. It indicates that you actually wanted to contact me (and not that you spammed an address you found somewhere). It's a coarse-grained filter. Of course, if I meet you in person and you ask, there's a good chance I'll give it to you.</p>
<p style="background:#ddeaee;text-align:center;font-weight:bold;padding:5px;"> If I haven't given you my email address,<br> it's not hard to find if you actually want to contact me.</p>
<p>I've set up a lot of email addresses. Ultimately they filter into the same couple of accounts, but into different folders. Some I care about deeply, some not so much. Some only exist so I can see who sold my details.</p>
<p>For that reason, I'll check the publicly-available ones a lot less than the others.</p>
<p>Of course, just because I welcome emails, doesn't mean I'm great at returning them. By its very nature, email is asynchronous, so I might not reply to you today. Or tomorrow. Or this month.</p>
<h3><img src="https://damianbrady.com.au/content/images/2017/04/Skype-48.png" style="vertical-align:middle;" alt="Social Media and why I won't "add you""> Skype</h3>
<p>Skype is great for voice and video conversations. That means if we're connected on Skype, it's almost certainly because we needed to <em>see and/or hear</em> each other at some point in the past.</p>
<p style="background:#ddeaee;text-align:center;font-weight:bold;padding:5px;"> My Skype contact list consists almost exclusively of people<br>I previously needed to have a conversation with.</p>
<p>Unless we need to speak remotely, I won't add anyone on Skype. For me, it has one purpose, and making new friends isn't it.</p>
<h3><img src="https://damianbrady.com.au/content/images/2017/04/Slack-48.png" style="vertical-align:middle;" alt="Social Media and why I won't "add you""> Slack</h3>
<p>At time of writing, I'm up to eleven Slack Teams. Yes, it feels like a lot, and yes, they're sometimes a pain to manage. They're all tech-related, and I'm very unlikely to join a Slack Team unless it has relevance to me right now.</p>
<p style="background:#ddeaee;text-align:center;font-weight:bold;padding:5px;"> Each Slack Team has a purpose,<br>but if we're on the same Slack Team, let's chat!</p>
<p>I find them extremely useful. For example, the Octopus Slack Team is how I communicate with the rest of the company about 99% of the time.</p>
<p>Interestingly, I'm not in <em>any</em> public teams. All are invitation-only, and I only manage one of them myself.</p>
<h3 id="summary">Summary</h3>
<p>So that's how I treat my social media accounts, and why I might have ignored your &quot;friend request&quot; or &quot;network connection&quot;. Don't take it personally!</p>
<p style="background:#eaeedd;text-align:center;font-weight:bold;padding:5px;">I like to meet new people in person, not online.</p>
<p>I'm friendly, I promise. So come say hi to me at <a href="https://damianbrady.com.au/speaking">a conference</a>, or ping me on <a href="https://twitter.com/damovisa">Twitter</a>!</p>
<div style="font-size:0.6em;text-align:center;border-top:1px solid #ccc">All icons sourced from https://icons8.com/</div><!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>