<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Developer Experience on Andrew Khoury</title><link>https://www.drewkhoury.com/tags/developer-experience/</link><description>Recent content in Developer Experience on Andrew Khoury</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>Copyright © 2021, Andrew Khoury; all rights reserved.</copyright><lastBuildDate>Fri, 01 Sep 2023 19:22:11 +0000</lastBuildDate><atom:link href="https://www.drewkhoury.com/tags/developer-experience/index.xml" rel="self" type="application/rss+xml"/><item><title>Tips for how to use 3 Musketeers to supercharge your Developer Experince</title><link>https://www.drewkhoury.com/post/2023-09-13_3-musketeers-docker-make-compose-tips/</link><pubDate>Fri, 01 Sep 2023 19:22:11 +0000</pubDate><guid>https://www.drewkhoury.com/post/2023-09-13_3-musketeers-docker-make-compose-tips/</guid><description>
&lt;p>&lt;a href="https://3musketeersdev.netlify.app/">3 Musketeers&lt;/a> is a pattern popularized by Frederic L where you can Test, build, and deploy your apps from anywhere, the same way.&lt;/p>
&lt;p>&lt;em>Note: Frederic's website was preivously available via 3musketeers.io but is now &lt;a href="https://3musketeersdev.netlify.app/">https://3musketeersdev.netlify.app/&lt;/a>&lt;/em>&lt;/p>
&lt;p>The key benifits include being able to have a mix of Linux, Mac, and Windows workstations. You also get consistency with pipeline/CI tools that also run the same steps in the same way.&lt;/p>
&lt;p>&lt;strong>More Info:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://3musketeersdev.netlify.app/guide/patterns.html">https://3musketeersdev.netlify.app/guide/patterns.html&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/liatrio/3musketeers">https://github.com/liatrio/3musketeers&lt;/a> (brief intro, and install guide)&lt;/li>
&lt;li>&lt;a href="https://github.com/drewkhoury/katacoda-scenarios-contino">https://github.com/drewkhoury/katacoda-scenarios-contino&lt;/a> - interactive lessons (before katacoda got taken down) - but you can look at the readme's for each lesson to see the steps&lt;/li>
&lt;li>&lt;a href="https://github.com/drewkhoury/minimum-viable-delivery/blob/main/cicd-spec.md#portability-directive-runtime-must-be-independent-of-pipelinebuilddeploy">https://github.com/drewkhoury/minimum-viable-delivery/blob/main/cicd-spec.md#portability-directive-runtime-must-be-independent-of-pipelinebuilddeploy&lt;/a> - CI/CD spec I wrote a while back to explain the philosophy/reason behind it&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Examples that also include docs in their READMEs:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://github.com/drewkhoury/gsd-hello-world">https://github.com/drewkhoury/gsd-hello-world&lt;/a> - demo (Golang) and docs (and link to detailed blog)&lt;/li>
&lt;li>&lt;a href="https://github.com/drewkhoury/3-musketeers-base">https://github.com/drewkhoury/3-musketeers-base&lt;/a> - setup, env, aws profile, python and docs&lt;/li>
&lt;li>&lt;a href="https://github.com/drewkhoury/static-site">https://github.com/drewkhoury/static-site&lt;/a> - Demo of a static site using AWS CDK with Python&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>More Examples:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://github.com/liatrio/3musketeers/tree/main/examples/cloud-in-a-box">https://github.com/liatrio/3musketeers/tree/main/examples/cloud-in-a-box&lt;/a> (LocalStack w/EKS cluster)&lt;/li>
&lt;li>&lt;a href="https://github.com/drewkhoury/pact-5-minute-getting-started-guide/blob/main/README-demo.md">https://github.com/drewkhoury/pact-5-minute-getting-started-guide/blob/main/README-demo.md&lt;/a> (PACT dockerized)&lt;/li>
&lt;li>&lt;a href="https://github.com/drewkhoury/cucumber-declarative-gherkin">https://github.com/drewkhoury/cucumber-declarative-gherkin&lt;/a> (shows chrome headless testing of apps, w/screenshots through selenium web driver, in containers - also happens to be a full BDD example with more than just some trivial tests)&lt;/li>
&lt;li>&lt;a href="https://github.com/drewkhoury/backstage-3m">https://github.com/drewkhoury/backstage-3m&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/drewkhoury/communities">https://github.com/drewkhoury/communities&lt;/a> - static site with hugo&lt;/li>
&lt;/ul>
&lt;h1 id="when-to-use-3-musketeers">When to use 3 musketeers&lt;/h1>
&lt;p>It's important to understand the goals of &lt;em>Consistancy, Control and Confidence&lt;/em> and the part each tool plays in the pattern.&lt;/p>
&lt;h2 id="cant-i-just-skip-this-and-use-my-tools-directly">Can't I just skip this and use my tools directly?&lt;/h2>
&lt;p>The benfitis of using these tools together might not be obvious if you've only worked in a single project, or in a small team or if you haven't seen a project grow in complexity over time.&lt;/p>
&lt;p>You might also be new to tools such as &lt;code>make&lt;/code>, &lt;code>compose&lt;/code> and &lt;code>docker&lt;/code> and as such the idea of introducing them into your pipeline might seem unessasary. This might be especially true if your team is working with legacy applications and you don't have any container presense in your organization or team.&lt;/p>
&lt;p>Only your organization and your team can decide if the goals of &lt;em>Consistancy, Control and Confidence&lt;/em> are worth the investment in pipeline standarization.&lt;/p>
&lt;p>These patterns and tools truely shine when:&lt;/p>
&lt;ul>
&lt;li>Developers start to seek &amp;quot;fast feedback&amp;quot; by &amp;quot;shifting left&amp;quot; - ie wanting to run some tests early (before they commit code)&lt;/li>
&lt;li>Working in larger teams&lt;/li>
&lt;li>With different underlying development machines - or with developers who install different versions of software (how much time did a new developer spend getting a working build env?)&lt;/li>
&lt;li>Across multiple teams in large oragnizations&lt;/li>
&lt;li>With CI/CD agents managed by other teams where changes to agents are not easy and you don't have permission/flexibility (did someone upgrade a build agent and break how java works for you? how would you know?)&lt;/li>
&lt;li>When having to share code between vendors&lt;/li>
&lt;li>The more complex the application gets, or as more changes are made to the application and it's build steps (having to refactor or share build steps either within your team or between teams)&lt;/li>
&lt;li>Testing your pipeline code (how many times have you done 20 check-ins of code just to test one bit of functionaility &amp;quot;on the build server&amp;quot;)&lt;/li>
&lt;/ul>
&lt;h1 id="the-3-tools">The 3 tools&lt;/h1>
&lt;p>As the name implies 3 musketeers is made up of 3 tools: &lt;a href="https://3musketeersdev.netlify.app/about/tools.html">https://3musketeersdev.netlify.app/about/tools.html&lt;/a>&lt;/p>
&lt;h2 id="docker">Docker&lt;/h2>
&lt;p>Docker is the &lt;strong>most important musketeer of the three&lt;/strong>.&lt;/p>
&lt;p>Many tasks such as testing, building, running, and deploying can all be done inside a lightweight Docker container.&lt;/p>
&lt;p>The &lt;strong>portability of Docker&lt;/strong> ensures you can &lt;strong>execute the same tasks, the same way, on different environments&lt;/strong> like MacOS, Linux, Windows, and CI/CD tools.&lt;/p>
&lt;p>Example: Docker can be invoked directly from &lt;code>make&lt;/code>, or can be invoked from a &lt;code>docker-compose&lt;/code> command in &lt;code>make&lt;/code>.&lt;/p>
&lt;h2 id="make">Make&lt;/h2>
&lt;p>Make is a cross-platform build tool to test and build software and it is used as an &lt;strong>interface between the CI/CD server and the application code&lt;/strong>.&lt;/p>
&lt;p>A single Makefile per application defines and encapsulates all the steps for testing, building, and deploying that application.&lt;/p>
&lt;p>Of course other tools like rake or ant can be used to achieve the same goal, but having Makefile pre-installed in many OS distributions makes it a convenient choice.&lt;/p>
&lt;div class="highlight">&lt;pre class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="ln">1&lt;/span>&lt;span class="c1"># Makefile&lt;/span>
&lt;span class="ln">2&lt;/span>echo:
&lt;span class="ln">3&lt;/span> docker-compose run --rm alpine &lt;span class="nb">echo&lt;/span> &lt;span class="s1">&amp;#39;Hello, World!&amp;#39;&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="compose">Compose&lt;/h2>
&lt;p>Docker Compose, or simply Compose, manages Docker containers in a very neat way.&lt;/p>
&lt;p>It allows multiple Docker commands to be written as a single one, which &lt;strong>allows our Makefile to be a lot cleaner and easier to maintain&lt;/strong>.&lt;/p>
&lt;p>Testing also often involves &lt;strong>container dependencies&lt;/strong>, such as a database, which is an area where Compose really shines. No need to create the database container and link it to your application code container manually — Compose takes care of this for you.&lt;/p>
&lt;div class="highlight">&lt;pre class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="ln">1&lt;/span>&lt;span class="c1"># docker-compose.yml&lt;/span>
&lt;span class="ln">2&lt;/span>version: &lt;span class="s1">&amp;#39;3&amp;#39;&lt;/span>
&lt;span class="ln">3&lt;/span>services:
&lt;span class="ln">4&lt;/span> alpine:
&lt;span class="ln">5&lt;/span> image: alpine
&lt;/code>&lt;/pre>&lt;/div>&lt;h1 id="cant-i-choose-my-own-mukseteers">Can't I choose my own mukseteers?&lt;/h1>
&lt;p>Who says &lt;code>make&lt;/code>, &lt;code>compose&lt;/code>, &lt;code>docker&lt;/code> are the perfect combo?&lt;/p>
&lt;p>The key to &lt;em>Consistancy, Control and Confidence&lt;/em> is not &lt;strong>only&lt;/strong> in the specific combination of &lt;code>make&lt;/code>, &lt;code>compose&lt;/code>, &lt;code>docker&lt;/code> but actually the agreement of your team and your organization to use a standard that's easy for everyone to follow.&lt;/p>
&lt;p>Consider:&lt;/p>
&lt;ul>
&lt;li>Do most of your development teams have easy access to &lt;code>make&lt;/code>, &lt;code>compose&lt;/code>, &lt;code>docker&lt;/code> - or can you agree/reach a state where this is possible?&lt;/li>
&lt;li>Do you want to replace &lt;code>make&lt;/code> with something else? (zeus, python, shell) Sure thing, just agree as a team what would be more easily to install and maintain&lt;/li>
&lt;li>Do you want to start with &lt;code>Make&lt;/code> and &lt;code>Docker&lt;/code> and introduce &lt;code>Compose&lt;/code> only when the complexity demands it?&lt;/li>
&lt;/ul>
&lt;h1 id="q--a">Q &amp;amp; A&lt;/h1>
&lt;h2 id="are-there-pre-reqs-what-if-my-workload-or-app-isnt-docker-based">Are there pre-reqs? What if my workload or app isn't docker based?&lt;/h2>
&lt;p>This pattern doesn't operate at your workload or application/deployment architecture level, it's all about the CI steps (like build, test, publish, deploy etc).&lt;/p>
&lt;p>The workload could be anything, that scope is outside of the pattern. It could be the case that your workload is containerized but that's unrelated to the higher-level pattern and how the local/CI steps are run.&lt;/p>
&lt;p>You need to agree on having Make, Compose and Docker available on developer workstations, and for the CI tool.&lt;/p>
&lt;h2 id="make-is-difficult-to-use-and-hard-to-learn">Make is difficult to use, and hard to learn&lt;/h2>
&lt;p>&lt;code>make&lt;/code> is a powerful tool that can do a lot of things. However, the intent is to use &lt;code>make&lt;/code> as a simple interface between your build tool and your build steps.&lt;/p>
&lt;p>As you should only be using the most basic features of &lt;code>make&lt;/code> it shouldn't be difficult to implement. If you're having a lot of difficulties, consider if you're over complicating your task.&lt;/p>
&lt;p>Consider some real-life simple make files (easy to read, maintain and run):&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://github.com/drewkhoury/devyo/blob/master/makefile">https://github.com/drewkhoury/devyo/blob/master/makefile&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/drewkhoury/buildkite/blob/master/Makefile">https://github.com/drewkhoury/buildkite/blob/master/Makefile&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>You could consider using &lt;a href="https://3musketeersdev.netlify.app/guide/make.html#multiple-makefiles">multiple makefiles&lt;/a> or consider &lt;a href="https://3musketeersdev.netlify.app/guide/make.html#complex-targets">another language&lt;/a> if you have complex logic that demands it.&lt;/p>
&lt;h2 id="i-really-dont-want-to-use-docker-compose---im-not-even-deploying-anything--im-using-k8s">I really don't want to use docker compose - I'm not even deploying anything / I'm using k8s&lt;/h2>
&lt;p>Don't confuse using &lt;code>docker-compose&lt;/code> during your build/test steps with deploying your application in production. With 3musketers we're looking at the patterns we use to inteface with our build tool (like building and testing your application in your pipeline).&lt;/p>
&lt;p>People often use compose files (with 3musketeers) to avoid having long and messy make files.&lt;/p>
&lt;h2 id="to-compose-or-not-to-compose">To Compose or Not to Compose?&lt;/h2>
&lt;p>If your use of docker is simple for a particular task, feel free to skip the compose file.&lt;/p>
&lt;p>&lt;a href="https://3musketeersdev.netlify.app/guide/patterns.html#docker">https://3musketeersdev.netlify.app/guide/patterns.html#docker&lt;/a>&lt;/p>
&lt;p>Make calls directly Docker instead of Compose. Everything that is done with Compose can be done with Docker. Using Compose helps to keep the Makefile clean.&lt;/p>
&lt;p>When you have a multi-line docker invocation, or 5 lines of docker commands in a single task, consider if compose could simplify things for you.&lt;/p>
&lt;p>&lt;a href="https://3musketeersdev.netlify.app/guide/patterns.html#task-management-tool">https://3musketeersdev.netlify.app/guide/patterns.html#task-management-tool&lt;/a> shows an example of how to implement an &amp;quot;npm&amp;quot; command &amp;quot;cleanly&amp;quot;.&lt;/p>
&lt;p>Notice that the compose file does all the volume mounting, workdir (and would do all the env injection etc).&lt;/p>
&lt;p>Consider an even more complex senerio that invovled multiple services, logs, naming of containers, starting and stopping containers, cleanup when done.&lt;/p>
&lt;h2 id="how-will-i-manage-container-versionsinstances">How will I manage container versions/instances&lt;/h2>
&lt;p>Without container images in your CI pipeline you may have managed binaries and software through an artifact store like Artifactory. You would use a similar approach for containers too.&lt;/p>
&lt;p>Your organization will need to decide how teams can pull images (directly from the Internet, or through Artifactory as a proxy etc), and have a model for developers to be able to maintain and update docker images. Often docker images that need customization will need their own pipelines and independent lifecycle management (assuming you need to extend the features of a docker image maintained somewhere like Docker Hub).&lt;/p>
&lt;p>This concern also exists without the use of 3 Muskteers, if your organization uses docker images in anywhere in any capacity (ie for application deployment or in any other part of the organization). As long as docker images aren't banned in your organization, and you have any need to modify or update a docker image anywhere, you'll have to solve for this.&lt;/p>
&lt;h2 id="wont-i-have-to-do-more-scripting-to-do-things-like-export-the-results-of-scan-details-and-test-results-out-to-another-location">Won't I have to do more scripting to do things like export the results of scan details and test results out to another location?&lt;/h2>
&lt;p>Yes, there's an extra layer with docker that introduces volume mounts, a more careful look at permissions and ownership, and files need to be stored/saved outside the container run. That's an overhead and a bit of a learning journey which can be painful to begin with, especially without docker knowledge. Generally once you get those patterns working well, you have less issues moving forward (and you can repeat/share the patterns), and imprpoving your docker skills may be useful if you need them for your app development too.&lt;/p>
&lt;p>This question ends up being one about tradeoffs as you get more consistency and reuse across Linux/Mac/Windows and your CI tool, you make life easier if you ever move CI tools (think about moves to GitLab, Azure, GitHub etc), and setup is a breeze for new devs joining the company or the team.&lt;/p>
&lt;p>The key advice here is to use small containers that have a single binary and a single purpose, when they do an operation that produces an output it should be available via a volume mount that allows easy access either via your workstation or CI tool, after that it's functionally the same as having run it without docker.&lt;/p>
&lt;p>&lt;em>Alternative:&lt;/em> In theory you could cheat the pattern a little here by using native container image steps in a tool like GitLab/GitHub to reduce the work you need to do to mount files and export them, but it does make it less portable for local usage or if you ever move CI tools.&lt;/p>
&lt;p>&lt;em>Alternative:&lt;/em> If you were to not use containers at all you wouldn't be able to run everywhere as easily and as consistently, which would arguably shift some toil back to developers.&lt;/p>
&lt;h2 id="whos-responsibility-is-it">Who's responsibility is it?&lt;/h2>
&lt;p>3musketeers &lt;strong>will not&lt;/strong> stop you from writing bad pipelines or bad code.&lt;/p>
&lt;p>3musketeers &lt;strong>will not&lt;/strong> write your build steps for you.&lt;/p>
&lt;p>3musketeers &lt;strong>will not&lt;/strong> replace your build process or your build tool.&lt;/p>
&lt;p>3musketeers &lt;strong>will not&lt;/strong> deploy your application for you.&lt;/p>
&lt;p>3musketeers &lt;strong>will not&lt;/strong> store metadata or artifacts during your build process.&lt;/p>
&lt;p>For example, if your project, team or organization creates a docker container to provide some sort of functionality (e.g a sonar scanner image) this docker image should have it's own:&lt;/p>
&lt;ul>
&lt;li>documentation&lt;/li>
&lt;li>development lifecycle&lt;/li>
&lt;li>versioning / latest tags in git and in it's artifact store&lt;/li>
&lt;li>versions should be immutable - never override a version with new code&lt;/li>
&lt;li>if the container is run without the approriate environment variables, it should set sensible defaults where it can, and fail with explict error messages where it can't set a defaults&lt;/li>
&lt;li>requirements about connectitity should be well documented (and properly testing with proper errors when there's lack of connecivity)&lt;/li>
&lt;li>auth should be clearly documented and variablized&lt;/li>
&lt;li>if volume mounts are required and if files are outputted, this should be clearly articulated&lt;/li>
&lt;/ul>
&lt;p>Making changes:&lt;/p>
&lt;ul>
&lt;li>scripts/containers should allow you to override config files and/or supply additional config files or variables to override defaults (thus reducing the need to change the container/script itself each time)&lt;/li>
&lt;li>if your container is really a packaging mechinisum for a script consider how the script will be used and if it's better to be baked into the container (ie each change to the script should cause a new version of the container) or if you'd like users to maintain the script themselves and simply call the container with the script mounted into it&lt;/li>
&lt;/ul></description></item><item><title>Optimizing for a Cloud-native Developer Experience</title><link>https://www.drewkhoury.com/post/2022-03-23_optimizing-for-cloud-native-developer-experience/</link><pubDate>Wed, 23 Mar 2022 19:22:11 +0000</pubDate><guid>https://www.drewkhoury.com/post/2022-03-23_optimizing-for-cloud-native-developer-experience/</guid><description>
&lt;p>Chris and Drew share their combined knowledge around developer experience, why (micro) feedback loops matter a whole lot, and present a live demo of a Cloud Native application working locally - complete with unit tests, end-to-end tests and smoke tests.&lt;/p>
&lt;ul>
&lt;li>Originally presented by Chris and Drew &lt;a href="https://www.meetup.com/AWSMeetupGroup/events/284359969/">Optimizing for Developer Experience in a Cloud Native World&lt;/a> - AWS Meetup Group&lt;/li>
&lt;li>Concepts based on the work from Tim Cochran via Martin Fowler &lt;a href="https://martinfowler.com/articles/developer-effectiveness.html">Maximizing Developer Effectiveness&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://miro.com/app/board/uXjVOR9lSQM=/">Cloud Native DX&lt;/a> miro board for presentation content&lt;/li>
&lt;li>Following the &lt;a href="https://www.drewkhoury.com/post/gsd/3-musketeers-for-an-epic-developer-experience-8676ddaf33b2/">3 Musketeers&lt;/a> pattern&lt;/li>
&lt;/ul>
&lt;p>This talk is packed with real patterns used by Chris and Drew working with teams to help them increase their effectiveness. The demo was designed so you can follow along on your own workstation - and be up and running within minutes without the need to install and configure the underlying tech (Node, AWS SAM, Python, Playwright, etc).&lt;/p>
&lt;div class="video embed-responsive embed-responsive-16by9">
&lt;iframe src="https://www.youtube.com/embed/6MP1u7O_3bY?enablejsapi=1" allowfullscreen>&lt;/iframe>
&lt;/div>
&lt;h2 id="micro-feedback-loops">Micro feedback loops&lt;/h2>
&lt;blockquote>
&lt;p>&amp;quot;From what I have observed, you have to nail the basics, the things that developers do 10, 100 or 200 times a day. I call them micro-feedback loops. This could be running a unit test while fixing a bug. It could be seeing a code change reflected in your local environment or development environments.&amp;quot; - Tim Cochran&lt;/p>
&lt;/blockquote>
&lt;p>&lt;img src="https://www.drewkhoury.com/images/drew-and-chris-white.png" alt="">&lt;/p>
&lt;h2 id="demo">Demo&lt;/h2>
&lt;p>Demo Repo: &lt;a href="https://github.com/chrishart0/gsd-aws-cdk-serverless-example">GSD-AWS-CDK-Serverless-Example&lt;/a>&lt;/p>
&lt;p>If you have &lt;code>make&lt;/code>, &lt;code>docker-compose&lt;/code> and &lt;code>docker&lt;/code> installed you should be able to have a local env running in a few minutes.&lt;/p>
&lt;div class="highlight">&lt;pre class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="ln">1&lt;/span>git clone git@github.com:chrishart0/gsd-aws-cdk-serverless-example.git &amp;amp;&amp;amp; cd gsd-aws-cdk-serverless-example
&lt;span class="ln">2&lt;/span>make install &amp;amp;&amp;amp; make run
&lt;/code>&lt;/pre>&lt;/div>&lt;p>Hint: If you run &lt;code>make&lt;/code> after cloning the repo, it will show you the help menu and let you know what commands to run to build, test and deploy the application.&lt;/p>
&lt;p>Micro feedback loops demonstrated in this repo:&lt;/p>
&lt;ul>
&lt;li>Unit tests (front-end, back-end, infra)&lt;/li>
&lt;li>Local environment - available in the browser&lt;/li>
&lt;li>End-to-end tests&lt;/li>
&lt;li>Direct deployment to AWS from your workstation&lt;/li>
&lt;li>CI/CD runs the same as local, with additional security checks&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="https://github.com/chrishart0/gsd-aws-cdk-serverless-example/blob/master/infrastructure/Infra-Diagram.drawio.png?raw=true" alt="">&lt;/p>
&lt;h1 id="giving-us-your-feedback-loop">Giving us your feedback (loop)&lt;/h1>
&lt;p>We'd love to hear what you think about these patterns, and get some feedback on your own developer experience using the demo repo.&lt;/p>
&lt;ul>
&lt;li>Contact &lt;a href="https://arcadian.cloud/contact-me">Chris&lt;/a>&lt;/li>
&lt;li>Contact &lt;a href="https://www.drewkhoury.com/drew/">Drew&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/chrishart0/gsd-aws-cdk-serverless-example/issues">Raise an issue&lt;/a> in the repo&lt;/li>
&lt;/ul></description></item><item><title>3 Musketeers for an epic Developer Experience</title><link>https://www.drewkhoury.com/post/gsd/3-musketeers-for-an-epic-developer-experience-8676ddaf33b2/</link><pubDate>Sat, 28 Aug 2021 14:18:09 +0000</pubDate><guid>https://www.drewkhoury.com/post/gsd/3-musketeers-for-an-epic-developer-experience-8676ddaf33b2/</guid><description>
&lt;p>We all want to reduce toil and improve the developer experience (when starting new applications or joining the team). Developers have had to invest significant time in creating production-ready pipelines when building new products and configuring their workstations when joining teams. Their workstations may not run all the same tests as their pipeline and thus they’re left with &lt;a href="https://www.linkedin.com/feed/hashtag/?keywords=slowfeedback&amp;amp;highlightedUpdateUrns=urn%3Ali%3Aactivity%3A6835918781475246080">#slowfeedback&lt;/a> and an inconsistent experience.&lt;/p>
&lt;p>The larger the organization (ie Enterprise with 10’s-100’s of teams and applications) the worse the problem gets.&lt;/p>
&lt;p>GSD is built on the principle of reusability through a pattern called &lt;a href="https://3musketeers.io/">3 Musketeers&lt;/a> (test, build, and deploy your apps from anywhere, the same way). It gives consistency, control, and confidence to development teams.&lt;/p>
&lt;p>Docker is a key part of this pattern, but the use of &lt;code>docker&lt;/code>, &lt;code>docker-compose&lt;/code> and &lt;code>make&lt;/code> together really unlock the powers of consistency, control and confidence in your application build, test and deploy steps. The &lt;a href="https://3musketeers.io/docs/">3musketeers Docs&lt;/a> have some great examples of these patterns.&lt;/p>
&lt;p>Here's what the most simple usage looks like:&lt;/p>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*O8UwDvze7KXEDKLKgqevcw.jpeg" alt="">&lt;/p>
&lt;p>While the pattern itself is simple, the power (and benefit) comes from the widespread usage across your organization. Here’s what usage might look like:&lt;/p>
&lt;ul>
&lt;li>Agree on a standard interface for all pipeline actions (much like API’s have an agreed interface, all pipelines in the org use the same interface, ie `make build`, `make test`, `make deploy`)&lt;/li>
&lt;li>Keep the interface simple (avoid custom pipeline logic, one simple Makefile calls Compose, the container handles all the logic)&lt;/li>
&lt;li>Create docker containers for each pipeline step, make them stateless, reuse them where it makes sense&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*hdKr28atovmEGFkBRaOIXA.jpeg" alt="">&lt;/p>
&lt;p>&lt;strong>Wins:&lt;/strong> Modern pipelines already support running steps in docker containers. This pattern extends portability across almost any pipeline tool or development workstation and runs the same way in every single environment. Pipeline steps can be tested independently and reused. This pattern makes it easy to go one step further and generate pipelines on-demand based on boilerplate starter templates. Oh yeah, and &lt;a href="https://www.linkedin.com/feed/hashtag/?keywords=fastfeedback&amp;amp;highlightedUpdateUrns=urn%3Ali%3Aactivity%3A6835918781475246080">#fastfeedback&lt;/a> (we’re talking pre-commit).&lt;/p>
&lt;div class="notices info">
&lt;div class="label">Info&lt;/div>
&lt;p>Also posted on medium as &lt;a href="https://medium.com/@drew.khoury/3-musketeers-for-an-epic-developer-experience-8676ddaf33b2">3 Musketeers for an epic Developer Experience&lt;/a>.&lt;/p>
&lt;/div>
&lt;p>_&lt;/p></description></item><item><title>Optimizing for DX — The Developer Experience</title><link>https://www.drewkhoury.com/post/optimizing-for-dx-the-developer-experience-f37fe168642d/</link><pubDate>Sun, 19 Jan 2020 19:18:39 +0000</pubDate><guid>https://www.drewkhoury.com/post/optimizing-for-dx-the-developer-experience-f37fe168642d/</guid><description>
&lt;p>One thing I’m very much obssessed with is something I’m calling the Developer Experience (DX). I’m literally on a global &amp;amp; lifelong mission to optimize DX.&lt;/p>
&lt;p>&lt;em>Hint: Once you’re sold on the benefits of a great DX you can skip ahead to the “3 Steps for success” section&lt;/em>.&lt;/p>
&lt;p>&lt;strong>What is DX and why should you care?&lt;/strong>&lt;/p>
&lt;p>If you’re part of a team/organization that does development then you’re likely going to run into one or more of the following:&lt;/p>
&lt;ul>
&lt;li>Having to keep README’s up to date&lt;/li>
&lt;li>Building &amp;amp; testing your code&lt;/li>
&lt;li>Bringing new people onto the team &amp;amp; showing them how your code works&lt;/li>
&lt;li>Building pipelines &amp;amp; debugging them when they don’t behave&lt;/li>
&lt;li>Fixing your dev environment when it breaks&lt;/li>
&lt;li>Supporting that one person who wants to use &amp;lt;insert whatever OS the rest of the team isn’t using&amp;gt;&lt;/li>
&lt;li>Starting new projects and re-doing the basic building blocks to get started&lt;/li>
&lt;li>Trying to support 10 teams all working on their own software but all needing to be able to work closely together (and not re-invent the wheel)&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>My perfect world!&lt;/strong>&lt;/p>
&lt;p>In a perfect world the mundane parts of development would be simple:&lt;/p>
&lt;ul>
&lt;li>Creating a new project should be fast (I shouldn’t worry about any of the ‘boilerplate’ steps that would be the same between projects)&lt;/li>
&lt;li>&lt;em>As a consumer of code:&lt;/em> I shouldn’t have to worry about how code is built, tested &amp;amp; deployed&lt;/li>
&lt;li>&lt;em>As a developer of code:&lt;/em> I should be able to easily update how my code is built, tested &amp;amp; deployed without affecting other developers or build servers wanting to consume my code&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>If I have to talk to a developer, install some special software dependencies, read a confluence page or README.md, figure out how to get things working on my OS or spend more than 5 minutes getting your software built or a new project setup then you’ve failed to streamline the DX.&lt;/p>
&lt;/blockquote>
&lt;h3 id="3-steps-forsuccess">3 Steps for success&lt;/h3>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*o548VIWo3J7WLwRLwkumOw.jpeg" alt="">&lt;/p>
&lt;p>The’s a concept called 3 Musketeers which is really just an agreed pattern for standardization when building software. It’s most common form uses Make as a standard interface to Compose &amp;amp; Docker Containers but you can adapt the concept to suit your needs.&lt;/p>
&lt;p>&lt;a href="https://3musketeers.io/" title="https://3musketeers.io/">&lt;strong>3 Musketeers&lt;/strong>&lt;br>
_Test, build, and deploy your apps from anywhere, the same way. Get Started → Run the same commands no matter where you…_3musketeers.io&lt;/a>&lt;a href="https://3musketeers.io/">&lt;/a>&lt;/p>
&lt;p>The net result is a consistent experience that works the same on Windows, Mac &amp;amp; Linux. It’s portable across development machines, build servers and provides consistency that scales from 1 team to 100 teams.&lt;/p>
&lt;p>If you’re already using containers in your build server steps or as part of your development then you’re one step closer to a utopia of standardization!&lt;/p>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*l3oNIw1tkOSwS6IQOHK46g.jpeg" alt="">&lt;/p>
&lt;p>Containers, and the 3 Musketeers concept can be applied any time you need to simplify a process or some instructions. You can consider it “self-documenting”. A good way to check if you’re giving the best DX is to look at what you need to put in your README to explain your process.&lt;/p>
&lt;p>&lt;strong>No Musketeers&lt;/strong>&lt;/p>
&lt;p>Just &lt;figure it out>…&lt;/p>
&lt;blockquote>
&lt;p>Install node version 4 but definitely not version 3, and I have no idea about version 5. I’ve you’re on Windows then I can’t help you at all. There are also a few dependencies that you’ll need but I can’t remember what they were. The following 12 page document is incomplete and you’re about to waste half a day that you’ll never get back.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;strong>1 Musketeer — Docker&lt;/strong>&lt;/p>
&lt;p>Just run the following docker command:&lt;/p>
&lt;blockquote>
&lt;p>docker run --rm -v foo:bar -v foo:bar -e FOO=BAR container bash -c ’echo hello world’&lt;/p>
&lt;/blockquote>
&lt;p>&lt;strong>2 Musketeers — Docker &amp;amp; Docker Compose&lt;/strong>&lt;/p>
&lt;p>Just run the following compose command:&lt;/p>
&lt;blockquote>
&lt;p>docker-compose run --rm alpine echo ‘foo’&lt;/p>
&lt;/blockquote>
&lt;p>&lt;strong>3 Musketeers — Docker, Docker Compose &amp;amp; Make&lt;/strong>&lt;/p>
&lt;p>Just run the following make command:&lt;/p>
&lt;blockquote>
&lt;p>make echo&lt;/p>
&lt;/blockquote>
&lt;p>And it’s as simple as that. Developers typically implement steps like “make build test validate deploy” but you can be as creative as you like and write the steps that make sense for you!&lt;/p>
&lt;h3 id="supercharge-your-development">Supercharge your development&lt;/h3>
&lt;p>Using an agreed pattern like 3 Musketeers is a great way to standardize among your teams. As the number of teams you have in your organization grows so too will the benefits. Humans (and those robot automation scripts) will be able to consume your repos more easily and that’s a great thing.&lt;/p>
&lt;blockquote>
&lt;p>But why stop there?&lt;/p>
&lt;/blockquote>
&lt;p>&lt;strong>What if we could template what a good project looks like and deliver that to development teams in a self-documenting and self-updating fashion?&lt;/strong>&lt;/p>
&lt;p>The most basic implementation of this would be writing a “hello world” application and asking your development copy/paste the code when starting new projects.&lt;/p>
&lt;p>But there’s a tool called &lt;a href="https://yeoman.io/">https://yeoman.io/&lt;/a> and it provides scaffolding for modern web apps. It’s another simple yet impressive concept executed well. What it provides is a templating mechanism with a really slick user-input feature and enough glue in-between to great that amazing DX we’re all chasing.&lt;/p>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*AIrnL4EBoI-duVrvk6MwAQ.jpeg" alt="">&lt;/p>
&lt;p>With yeoman development teams can setup and maintain examples of good software delivery with teams benefiting from the learnings of others. You can create a generator for just about anything, so the only thing left is your imagination!&lt;/p>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*Hn7NJOWEPOC43mPSg6nn8A.png" alt="">&lt;/p>
&lt;p>Yeoman has it’s own generator to help you create your first generator (how meta, right?). The only thing missing for me was a reliable docker container to do some development in. I created a repo with a yeoman development container to make life easier. Hopefully you find it useful and make some steps to improve your own DX!&lt;/p>
&lt;p>&lt;a href="https://github.com/drewkhoury/devyo" title="https://github.com/drewkhoury/devyo">&lt;strong>drewkhoury/devyo&lt;/strong>&lt;br>
_yeoman container - for local development of yeoman generators - drewkhoury/devyo_github.com&lt;/a>&lt;a href="https://github.com/drewkhoury/devyo">&lt;/a>&lt;/p>
&lt;h3 id="want-more">Want more?&lt;/h3>
&lt;p>Presentation (PDF): &lt;a href="https://drewkhoury.files.wordpress.com/2020/04/optimizing-for-dx-in-a-cloud-native-world.pdf" title="Optimizing for DX in a Cloud Native world">Optimizing for DX in a Cloud Native world&lt;/a>&lt;br>
Presentation (Video): &lt;a href="https://www.youtube.com/watch?v=ZYlbNnaoseI">https://www.youtube.com/watch?v=ZYlbNnaoseI&lt;/a>&lt;/p>
&lt;div class="notices info">
&lt;div class="label">Info&lt;/div>
&lt;p>Also posted on medium as &lt;a href="https://medium.com/@drew.khoury/optimizing-for-dx-the-developer-experience-f37fe168642d">Optimizing for DX — The Developer Experience&lt;/a>.&lt;/p>
&lt;/div></description></item></channel></rss>