<?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:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Sheep Code]]></title><description><![CDATA[Hear our insights on software engineering, cloud, and tech.]]></description><link>https://sheepcode.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!HmFw!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fad1c0af3-ae21-4c90-9d08-1dd82862963f_1280x1280.png</url><title>Sheep Code</title><link>https://sheepcode.substack.com</link></image><generator>Substack</generator><lastBuildDate>Sat, 15 Aug 2026 07:13:36 GMT</lastBuildDate><atom:link href="https://sheepcode.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Daniel Dersch]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[sheepcode@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[sheepcode@substack.com]]></itunes:email><itunes:name><![CDATA[Daniel Dersch]]></itunes:name></itunes:owner><itunes:author><![CDATA[Daniel Dersch]]></itunes:author><googleplay:owner><![CDATA[sheepcode@substack.com]]></googleplay:owner><googleplay:email><![CDATA[sheepcode@substack.com]]></googleplay:email><googleplay:author><![CDATA[Daniel Dersch]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[I'm glad to be a 33 years old (ancient) software engineer]]></title><description><![CDATA[A letter to my 22 years old stupid self. Nothing prompted this!]]></description><link>https://sheepcode.substack.com/p/im-glad-to-be-a-33-years-old-ancient</link><guid isPermaLink="false">https://sheepcode.substack.com/p/im-glad-to-be-a-33-years-old-ancient</guid><dc:creator><![CDATA[Daniel Dersch]]></dc:creator><pubDate>Wed, 22 Jan 2025 15:12:07 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!myxn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd005d614-46c6-43d3-a7dd-30014f818dac_1024x768.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!myxn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd005d614-46c6-43d3-a7dd-30014f818dac_1024x768.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!myxn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd005d614-46c6-43d3-a7dd-30014f818dac_1024x768.jpeg 424w, https://substackcdn.com/image/fetch/$s_!myxn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd005d614-46c6-43d3-a7dd-30014f818dac_1024x768.jpeg 848w, https://substackcdn.com/image/fetch/$s_!myxn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd005d614-46c6-43d3-a7dd-30014f818dac_1024x768.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!myxn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd005d614-46c6-43d3-a7dd-30014f818dac_1024x768.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!myxn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd005d614-46c6-43d3-a7dd-30014f818dac_1024x768.jpeg" width="1024" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d005d614-46c6-43d3-a7dd-30014f818dac_1024x768.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:121144,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!myxn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd005d614-46c6-43d3-a7dd-30014f818dac_1024x768.jpeg 424w, https://substackcdn.com/image/fetch/$s_!myxn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd005d614-46c6-43d3-a7dd-30014f818dac_1024x768.jpeg 848w, https://substackcdn.com/image/fetch/$s_!myxn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd005d614-46c6-43d3-a7dd-30014f818dac_1024x768.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!myxn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd005d614-46c6-43d3-a7dd-30014f818dac_1024x768.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Dear 22-Year-Old stupid self,</p><p>Congratulations on starting your first software engineering job! Keep in mind that $60k a year is <em>really low</em> even for an entry level engineer. Give it a couple of years, and you can easily earn a 6-figure salary. Also, take pride in the time you spent in school grinding away on difficult problems instead of partying. </p><p>Trust me when I say that you will enjoy coding more in 10 years than you do now. I know that right now, you count down the hours till the work day is done so that you can go home and do things that you think you want to do. In 10 years, you&#8217;ll enjoy your work so much that at the end of the day, you&#8217;ll wonder where all the time went.</p><p>I probably shouldn&#8217;t say this, but a $500k salary is possible for you. Yes, I know your career goal is $100k. That&#8217;s fine for now. But you&#8217;ll find out that there are <em>certain companies</em> that pay far more than the legacy company you work at now. Will you get to $500k by 33? That&#8217;s a secret you&#8217;ll have to find out, but you won&#8217;t get there without some hard work.<br><br>Eventually you&#8217;ll consider getting a masters degree by working on it part time while working full time. This will help you a little bit, but not as much as mastering AWS will. Get those certifications. Get that experience. You&#8217;ll eventually leave this certifications behind, but that is OK. They played an important role in your growth.</p><p>At some point, you&#8217;ll get into management. Try not to hate yourself too much. You&#8217;ll have the opportunity to lead some <em>incredible</em> people during this time. You probably won&#8217;t be their best mentor, but do <em>your</em> best.</p><p>Your big break won&#8217;t come until you have about 8-9 years of experience. A horrible virus will kill millions of people and cause companies (including Big Tech companies) to begin hiring remote employees. You&#8217;ll join a team at AWS. It will be the best opportunity of your life up until that time. <a href="https://sheepcode.substack.com/p/my-work-life-under-threat-by-amazons">It won&#8217;t end well</a>, but that&#8217;s OK!</p><p>Don&#8217;t listen to anyone who insists you&#8217;ll burn out of the industry. Yes, this happens to a lot of people, but there&#8217;s no reason it should happen to you. As a remote software engineer, you don&#8217;t have to commute, get to spend more time with your wife and kids, and get to live in a nice home that you couldn&#8217;t afford in more expensive parts of the country. So what if you hit a salary ceiling? If you do, it will be high enough to continue living how you want for your whole life.</p><p>One thing you&#8217;ll discover at AWS and other big tech companies is that <em>you&#8217;re not as smart as you think you are</em>. But that's OK! Intelligence is just one variable in your success and not the most important one. You&#8217;ll find that many very intelligent people job hop too much to become truly effective at any other companies. Some are very intelligent, but leverage their intelligence to coast and <a href="https://sheepcode.substack.com/p/a-brilliant-slacker-is-still-a-slacker">don&#8217;t actually work very much</a>.</p><p>One of the people at AWS you look up to the most was promoted to Senior Principal engineer. That&#8217;s not quite a distinguished engineer, but it&#8217;s pretty close! You won&#8217;t know all the details, but you suspect a big part of their promotion had to do with solving organizational problems that their leaders (management) were ill equipped to deal with.</p><p>Maybe you&#8217;ll go out on your own someday. If you do, find other people to run most of the business while you focus on the software. </p><p>I&#8217;ve been in the industry for over a decade now. I use AI every day, and it hasn&#8217;t robbed me of my joy when coding. In fact, it makes the frustrating parts of coding much less frustrating!</p><p>Have a nice day.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">If you enjoyed reading this silly letter to myself, then I hope you&#8217;ll subscribe to my newsletter.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[My work-life under threat by Amazon’s return-to-office mandate]]></title><description><![CDATA[How the tech giant&#8217;s RTO policy reshaped careers, priorities, and the industry.]]></description><link>https://sheepcode.substack.com/p/my-work-life-under-threat-by-amazons</link><guid isPermaLink="false">https://sheepcode.substack.com/p/my-work-life-under-threat-by-amazons</guid><dc:creator><![CDATA[Daniel Dersch]]></dc:creator><pubDate>Mon, 16 Dec 2024 15:59:22 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/33127577-0d9a-4963-905f-79c74d763bd8_1792x1024.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>&#128075; Hey there, it&#8217;s Daniel again. I&#8217;ve not written in a while, but I&#8217;m now feeling much more settled into my new role that I&#8217;m ready to begin writing again. Thanks for sticking around!</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IypB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58d0a40d-b674-451b-a57b-0d63ca24979b_1792x1024.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IypB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58d0a40d-b674-451b-a57b-0d63ca24979b_1792x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!IypB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58d0a40d-b674-451b-a57b-0d63ca24979b_1792x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!IypB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58d0a40d-b674-451b-a57b-0d63ca24979b_1792x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!IypB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58d0a40d-b674-451b-a57b-0d63ca24979b_1792x1024.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IypB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58d0a40d-b674-451b-a57b-0d63ca24979b_1792x1024.webp" width="1456" height="832" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/58d0a40d-b674-451b-a57b-0d63ca24979b_1792x1024.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:832,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:676388,&quot;alt&quot;:&quot;An engineer at AWS returning to the office. Image generated by DALL E.&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="An engineer at AWS returning to the office. Image generated by DALL E." title="An engineer at AWS returning to the office. Image generated by DALL E." srcset="https://substackcdn.com/image/fetch/$s_!IypB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58d0a40d-b674-451b-a57b-0d63ca24979b_1792x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!IypB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58d0a40d-b674-451b-a57b-0d63ca24979b_1792x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!IypB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58d0a40d-b674-451b-a57b-0d63ca24979b_1792x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!IypB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58d0a40d-b674-451b-a57b-0d63ca24979b_1792x1024.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">An engineer at AWS returning to the office. Image generated by DALL E.</figcaption></figure></div><h3>The Bombshell Announcement</h3><p>In September 2024, Andy Jassy dropped the bombshell: Amazon employees would soon be back in the office five days a week. No more hybrid. No more halfway. This wasn&#8217;t entirely unexpected&#8212;Amazon had been signaling a shift since February 2023&#8212;but the official announcement still landed like a gut punch for hybrid employees. This post reflects on what that shift&#8212;&#8220;RTO&#8221; for short&#8212;meant for me, others, and the industry.</p><div class="pullquote"><p><em>If you can&#8217;t disagree and commit, it&#8217;s probably not going to work out for you at Amazon because we are going back to the office at least three days a week.</em> &#8212; Amazon&#8217;s CEO</p></div><h3>My Dream Job</h3><p>When I first got my offer from AWS in early 2022, it was a thrilling opportunity that felt almost too good to be true. Tech giants like Amazon were hiring beyond their usual hubs, and I got in at just the right time. I passed the interview loop and received a Senior SDE offer that nearly doubled my total compensation. Those early days were incredible: I soaked up wisdom from big-tech veterans while mentoring younger engineers. The pandemic-era remote setup gave me a unique shot at growth, balance, and fulfillment. At least a third of my 100+ person org lived nowhere near an Amazon office. We thrived under the remote model.</p><h3>The Quiet Push</h3><p>The first sign of change came quietly: a &#8220;soft&#8221; announcement about a three-day return-to-office requirement. It was buried in an internal news post, and I remember the sinking feeling I got reading it. It reminded me of the moment years ago when I was informed of a layoff. Details were sparse. People were skeptical. An internal Slack channel sprang up to advocate for remote work policies. Many colleagues dismissed it as a blip, something Amazon would inevitably reverse. We all hoped. We were wrong.</p><h3>Andy Jassy&#8217;s Message</h3><p>Months later at a company meeting, <a href="https://www.theverge.com/2023/8/28/23849754/amazon-ceo-andy-jassy-remote-employees-return-to-office">Andy Jassy delivered this clear directive:</a> &#8220;If you can&#8217;t disagree and commit, it&#8217;s probably not going to work out for you at Amazon because we are going back to the office at least three days a week.&#8221; While definitive, the word &#8220;probably&#8221; stood out to me. Could incredible performance override the relocation demand? I clung to that sliver of ambiguity.</p><h3>A Looming Deadline</h3><p>Relocation was no longer a question of &#8220;if&#8221; but &#8220;when,&#8221; unless I received an exception. Would the demand come right before a vest date? During peak hiring season? These questions weighed heavily on me, forcing me to evaluate not just my career but my life priorities. I had some factors in my favor: I was a high performer in my org, and we had a major release planned for re:Invent. The timing was critical&#8212;how could I deliver on such a pivotal project while navigating relocation logistics? I hoped leadership would recognize the stakes and prioritize the project&#8217;s success. Thankfully, they did, or at least they didn&#8217;t demand relocation during this critical period.</p><h3>Living with Uncertainty</h3><p>RTO didn&#8217;t occur in isolation. During this same period, Amazon implemented extensive cost-cutting measures, including layoffs, reorganizations, and the elimination of entire divisions. Leadership tried to keep these developments under wraps, but leaks surfaced&#8212;sometimes weeks in advance&#8212;on platforms like Blind. I thought AWS might be immune, but eventually, layoffs hit us too.</p><p>Most days, I carried on as if nothing had changed. But every so often, the reality blindsided me: &#8220;Why am I pouring my soul into this when my future here feels so uncertain?&#8221; For months, I worked with the nagging dread that I&#8217;d be forced to relocate or leave. That unease never fully went away. The lead-up to re:Invent 2023 was especially grueling. Long hours were spent racing to meet the release deadline, all while knowing the company could demand relocation the moment the dust settled. Fortunately, re:Invent came and went without that ultimatum. I exhaled with relief, having crossed the two-year mark and secured a brief window to plan my exit. In June 2024, I was gone.</p><p>I didn&#8217;t realize how much stress I was carrying until I left. The constant uncertainty&#8212;the questioning, the worrying&#8212;had taken its toll. After leaving, the fog lifted. I could breathe again. That clarity was a gift, and it reminded me of the importance of aligning work with the life I wanted to live.</p><h3>Reflections on Amazon Culture</h3><p>Despite everything, I truly enjoyed Amazon&#8217;s culture. The emphasis on ownership, the high standards, the energy&#8212;it was challenging, but rewarding. Amazon pushed me to grow in ways I hadn&#8217;t expected, and I&#8217;ll always be grateful for that. If conditions were right&#8212;if remote work or local office options became feasible again&#8212;I&#8217;d absolutely consider returning.</p><p>For me, going into an office wasn&#8217;t the problem. The problem was relocation. There wasn&#8217;t an Amazon office near my home, and uprooting my family wasn&#8217;t on the table. If I were younger, childless, and more eager for adventure, I might have taken the leap. But that wasn&#8217;t my reality.</p><h3>What&#8217;s Next for the Industry and AWS?</h3><p>Amazon and AWS are not going anywhere. When the RTO announcement was originally made back in February 2023, the $AMZN stock price averaged under $100 for the month. As I write this, the price is around $230&#8212;higher than it has ever been. Since announcing RTO, Amazon has also implemented numerous cost-cutting measures such as layoffs and deprecations. Their business is becoming more focused (a good thing). While I still think eliminating remote work was the wrong decision, I hold no illusions that it will visibly harm Amazon&#8217;s trajectory.</p><p>Some might argue that Amazon will lose its best engineers and struggle to attract top talent because of this decision. However, this was likely an intentional calculation by leadership. Their conclusion appears to be that Amazon doesn&#8217;t necessarily need the  most talented engineers&#8212;it needs diligent and driven ones. Historically, Amazon has never been regarded as the most employee-friendly company, and the removal of remote work has dispelled any lingering perceptions of it aspiring to be the world&#8217;s best employer.</p><p>Amazon&#8217;s move to implement RTO was a boon for the leadership of other companies across the industry. Before this shift, competing with the largest software engineering employer that embraced remote work posed a significant challenge. Now, that pressure has eased. Following Amazon&#8217;s lead, many companies have rolled out their own RTO policies with newfound confidence. However, companies still offering remote opportunities now have access to some of the best talent in the market.</p><p>Realistically, remote work isn&#8217;t going away, but there won&#8217;t be as many remote jobs available as there were during COVID. I do think there&#8217;s more available than there were pre-COVID.  </p><h3>For the Remaining Remote Workers at Amazon</h3><p>The reality is that many people at Amazon are still working remotely. They&#8217;ve likely managed this due to fortunate circumstances or because their leaders have prioritized other concerns over enforcing RTO. A lucky few may have even secured long-term exceptions. However, my advice to those in this position is clear: most of you should start planning to either relocate or leave. Even if you manage to extend your remote arrangement for years, the trade-offs can be steep. You may feel like a second-class employee&#8212;excluded from opportunities for advancement. Promotions will likely be off the table, yet the effort you&#8217;ll need to exert will remain as demanding as if you were striving for one.</p><p>For most of you, this means exiting right after a vest date with another job lined up. Consider yourself fortunate (as I do) if you&#8217;re able to find a position with comparable compensation, but you might not find that. </p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">I hope you enjoyed reading about my experience as a remote worker during Amazon&#8217;s RTO push! If you did, I hope that you will subscribe!</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[AWS deprecations]]></title><description><![CDATA[My thoughts and what it means for you]]></description><link>https://sheepcode.substack.com/p/aws-deprecations</link><guid isPermaLink="false">https://sheepcode.substack.com/p/aws-deprecations</guid><dc:creator><![CDATA[Daniel Dersch]]></dc:creator><pubDate>Wed, 31 Jul 2024 15:56:31 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/8499a286-3983-4013-8091-9a7f775174bd_1280x1280.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>&#128075; <em>Hi, this is Daniel with my second issue of the year. I&#8217;ve been away a long time, but I&#8217;m back! I recently left my role at Amazon Web Services on the Amazon CodeCatalyst team to join Airbnb as a software engineer! I wasn&#8217;t able to write as much during this transition because I was interviewing/prepping for interviews (<a href="https://sheepcode.substack.com/p/how-to-prep-for-an-aws-sde-interview">click here for tips on how)</a> but that&#8217;s done now. I look forward to writing much more often now!</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Sheep Code is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>In the past few weeks, a number of X (formerly known as Twitter) users in the tech community discovered that some AWS services are being deprecated (or something, it&#8217;s not entirely consistent or clear). These services are <a href="https://x.com/jeffbarr/status/1818488419347317217">identified by Jeff Barr in the following Tweet </a>(or post or whatever it is now):</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!b8to!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8425244b-f9d4-436f-9b8c-7c8f0c24293c_1164x444.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!b8to!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8425244b-f9d4-436f-9b8c-7c8f0c24293c_1164x444.png 424w, https://substackcdn.com/image/fetch/$s_!b8to!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8425244b-f9d4-436f-9b8c-7c8f0c24293c_1164x444.png 848w, https://substackcdn.com/image/fetch/$s_!b8to!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8425244b-f9d4-436f-9b8c-7c8f0c24293c_1164x444.png 1272w, https://substackcdn.com/image/fetch/$s_!b8to!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8425244b-f9d4-436f-9b8c-7c8f0c24293c_1164x444.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!b8to!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8425244b-f9d4-436f-9b8c-7c8f0c24293c_1164x444.png" width="1164" height="444" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8425244b-f9d4-436f-9b8c-7c8f0c24293c_1164x444.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:444,&quot;width&quot;:1164,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:97113,&quot;alt&quot;:&quot;I hear you and we are making improvements so this is clearer for customers.  The services I'm referring to are: S3 Select, CloudSearch, Cloud9, SimpleDB, Forecast, Data Pipeline, and CodeCommit.&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="I hear you and we are making improvements so this is clearer for customers.  The services I'm referring to are: S3 Select, CloudSearch, Cloud9, SimpleDB, Forecast, Data Pipeline, and CodeCommit." title="I hear you and we are making improvements so this is clearer for customers.  The services I'm referring to are: S3 Select, CloudSearch, Cloud9, SimpleDB, Forecast, Data Pipeline, and CodeCommit." srcset="https://substackcdn.com/image/fetch/$s_!b8to!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8425244b-f9d4-436f-9b8c-7c8f0c24293c_1164x444.png 424w, https://substackcdn.com/image/fetch/$s_!b8to!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8425244b-f9d4-436f-9b8c-7c8f0c24293c_1164x444.png 848w, https://substackcdn.com/image/fetch/$s_!b8to!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8425244b-f9d4-436f-9b8c-7c8f0c24293c_1164x444.png 1272w, https://substackcdn.com/image/fetch/$s_!b8to!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8425244b-f9d4-436f-9b8c-7c8f0c24293c_1164x444.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Jeff Barr, Chief Evangelist at AWS, announces that S3 Select, CloudSearch, Cloud9, SimpleDB, ForeCast, Data Pipeline and CodeCommit are having new access to these services discontinued. </figcaption></figure></div><p>Additionally, my understanding is the QLDB (not mentioned) is also deprecated.</p><p>Of this list, most of the deprecations make sense. I&#8217;ll go through each one with my thoughts. Note that even with my recent employment at AWS, I don&#8217;t really have any  inside info on this. These are my own thoughts.</p><h3>Why is AWS deprecating services?</h3><p>The leaders at AWS must believe that they can discontinue these (I assume unprofitable) services without losing customer trust. For each of these services, one of more of the following is likely true:</p><ul><li><p>not many customers use it</p></li><li><p>the customers have other options that are relatively straightforward to migrate with minimal financial impact (or they are allowed to stay)</p></li></ul><h4>CodeCommit</h4><p>CodeCommit is inferior to alternatives like GitLab, BitBucket and GitHub. At some point in the distant past, AWS chose not to make CodeCommit a competitive service compared to these other Git providers. So, deprecation (or whatever this is) makes sense to me. Interestingly, I have friends who work for government companies and contractors that use CodeCommit extensively in AWS GovCloud. I am curious to see how that will play out. I&#8217;m betting that CodeCommit will continue to exist in GovCloud pretty much indefinitely.</p><h4>Data Pipeline</h4><p>I&#8217;ll admit I&#8217;m not super familiar with Data Pipeline. I&#8217;ve used it in the past to back up DyanmoDB tables, but that use case is no longer necessary as DDB natively supports backups. If I wanted to perform ETL using native services today, I would NOT involve data pipeline. Instead, I would use modern (and Serverless) services like Glue, S3 and Lambda (and potentially step functions). So, this deprecation makes sense to me. It does seem like the kind of thing though that if a company was using Data Pipeline, migration off of it might not be very straightforward. </p><h4>ForeCast</h4><p>What is ForeCast? I vaguely recall it being announced. I have no idea whether this service deserves to be deprecated or not because I know nothing about it.</p><h4>SimpleDB</h4><p>SimpleDB is inferior to DynamoDB which has replaced it. SimpleDB customers should be able to move to DynamoDB. It is interesting that Jeff had this in the list. My understanding is that &#8220;new signups&#8221; for SimpleDB have been discontinued for a very long time.</p><h4>Cloud9</h4><p>At some point in the past, AWS must have decided it did not want to seriously compete with Visual Studio Code. So, the deprecation of Cloud9 makes sense with that in mind. That said, customers of this product liked it a lot. I&#8217;m sure it will be sad for them to see it go.</p><h4>CloudSearch</h4><p>I don&#8217;t think I&#8217;ve ever heard of anyone using CloudSearch. I think what customers really want is a Serverless search service. OpenSearch supposedly has that, but I don&#8217;t consider a service to be truly Serverless unless it scales to $0 when not being used. Think of things like an empty DynamoDB table or an empty S3 bucket.</p><h4>QLDB</h4><p>Again, this is a service I don&#8217;t understand. How can there be a crypto service? I thought the whole point of crypto was decentralization? Unlike the other services, it sounds like AWS plans to actually delete the data in this services. That tells me there are very few customers using it.</p><h4>S3 Select</h4><p>Of every service mentioned, S3 Select is the biggest surprise. S3 itself is a service that will outlive everyone reading this, so it&#8217;s odd seeing a feature of it being discontinued. That said, I don&#8217;t think much is lost here because AWS Athena is in every a way a more powerful service that can do everything S3 Select could do and much more (correct me if I&#8217;m wrong). I&#8217;m honestly shocked that the implementation of S3 Select isn&#8217;t just Athena on the backend.</p><p>I guess that S3 Select works without much configuration whereas Athena requires some configuration to be setup. So at most, this will just annoy the few people that were using it.</p><h3>What do AWS Deprecations mean for me?</h3><p>These deprecations mean that AWS services that are unprofitable for AWS or lack users or meet whatever criteria AWS sets aren&#8217;t guaranteed to be around forever. It means that any shiny new service announced at re:invent might not be all that it is marketed to be. QLDB was announced at re:invent 2019. AWS Forecast went GA in 2019 as well. S3 Select went GA late in 2018. These services aren&#8217;t really all that old, but AWS doesn&#8217;t feel the need to continue with them. We can expect more deprecations to be announced in the future, even for products being released in 2024 and beyond.</p><p>Hopefully these deprecations lead new product teams at AWS to be more careful about what products are being built. </p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Sheep Code is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[The Engineering Rating Bell Curve]]></title><description><![CDATA[Don't be on the left. Get to the right.]]></description><link>https://sheepcode.substack.com/p/the-engineering-rating-bell-curve</link><guid isPermaLink="false">https://sheepcode.substack.com/p/the-engineering-rating-bell-curve</guid><dc:creator><![CDATA[Daniel Dersch]]></dc:creator><pubDate>Fri, 05 Jan 2024 16:41:58 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ugxm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df3c90e-c164-4f64-9c70-5886a7568cc1_1660x970.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As a software engineer (and I assume most jobs) your relationship with your manager is incredibly important. You almost always need positive feedback from your manager in order to get promoted. So it is important that your manager view you as a valued contributor on your team.</p><p>As with all things where people are involved, engineering performance tends to land on a bell curve. This post will generally <strong>be directed toward people</strong> who are currently <strong>in the middle of the curve</strong>, and are looking for tips getting further to the right. My guidance is also biased towards engineers working in a corporate type of environment as opposed to a startup environment (though the tips should be helpful regardless).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ugxm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df3c90e-c164-4f64-9c70-5886a7568cc1_1660x970.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ugxm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df3c90e-c164-4f64-9c70-5886a7568cc1_1660x970.png 424w, https://substackcdn.com/image/fetch/$s_!ugxm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df3c90e-c164-4f64-9c70-5886a7568cc1_1660x970.png 848w, https://substackcdn.com/image/fetch/$s_!ugxm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df3c90e-c164-4f64-9c70-5886a7568cc1_1660x970.png 1272w, https://substackcdn.com/image/fetch/$s_!ugxm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df3c90e-c164-4f64-9c70-5886a7568cc1_1660x970.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ugxm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df3c90e-c164-4f64-9c70-5886a7568cc1_1660x970.png" width="1456" height="851" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6df3c90e-c164-4f64-9c70-5886a7568cc1_1660x970.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:851,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:91008,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ugxm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df3c90e-c164-4f64-9c70-5886a7568cc1_1660x970.png 424w, https://substackcdn.com/image/fetch/$s_!ugxm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df3c90e-c164-4f64-9c70-5886a7568cc1_1660x970.png 848w, https://substackcdn.com/image/fetch/$s_!ugxm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df3c90e-c164-4f64-9c70-5886a7568cc1_1660x970.png 1272w, https://substackcdn.com/image/fetch/$s_!ugxm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6df3c90e-c164-4f64-9c70-5886a7568cc1_1660x970.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Most engineers get placed in the middle of the bell curve even if they think they are a top performer! </figcaption></figure></div><p><strong>On the left,</strong> you have the lowest performers in your organization. In my experience, people on the left of the curve tend to think they should be somewhere in the middle and are often clueless about their poor performance. In one situation, an engineer on my team came from a company where little to nothing was expected of him. He carried that mindset into my team. In the worst situations, I&#8217;ve seen engineers with 0 accomplishments during their entire tenure with a company. Engineers far to the left generally don&#8217;t receive raises and are often subject to performance improve plans and terminations. My observation is that people tend to be on the left due to laziness instead of incompetence. In other words, incredibly smart and knowledgable people can end up there. Don&#8217;t be on the left!</p><p><strong>On the right</strong>, you have the highest performers on your team or in your organization. These engineers are highly reliable, deliver independently, and have a long list of accomplishments. These are the people your management hopes to promote quickly. </p><p>And of course, most people fall <strong>in the middle</strong> of the curve. But even the middle has a left side and a right side. At high performing companies, these distinctions are important. Being in the middle-left might be similar to being in the far left if your company is looking to reduce headcount. Being in the middle-right might be equivalent to being on the far right if you&#8217;re on a high-performing team.</p><div><hr></div><h4>Getting further to the right</h4><p><strong>Your first step is figuring out where you are on the curve</strong>. Your company might have an official mechanism or tool for this. If so, you can use that to determine approximately where you are. Otherwise, you should speak with your manager and potentially your skip level manager to find out where you land. If your manager for some reason won&#8217;t tell or you think they might not be as forthcoming as you&#8217;d like, try to estimate where you compared to the rest of your team. (<strong>note</strong>: managers tend to be more forthcoming with their highest performers). Do you ship more or fewer features than the rest of your team? Does your manager go to you or others when they have important work to be done? Are you able to help others on the team more than you require help from others?</p><p>Remember, it&#8217;s OK if others on the team are stronger in some or many ways than you. You generally want to be on a team where you can learn from and be inspired by others.</p><p><strong>Ask your manager what you need to do differently to get a higher performance rating. </strong>If you&#8217;re in the middle of the curve, and you ask this of your manger then you might be surprised at their response. At my first full-time job as an engineer, I thought &#8220;writing a lot of code&#8221; was the most important metric. It turned out that anyone on the team could write a lot of code, but only a couple of people on the team were trusted to release the code. </p><p>At another job, I was on a team with an engineer who was a pull request machine. He would find the easiest tasks in the sprint and quickly pump out high quality pull requests until there were no more tasks. However, another engineer on the team was promoted before him because they were better at supporting engineers from other teams. In other words, their non-coding skills like &#8220;feature design&#8221;, &#8220;prioritization&#8221;, and &#8220;building rapport&#8221; were weighted higher than coding ability. Additionally, positive feedback for an engineer from outside of your immediate team is often more strongly weighted than positive feedback from engineers within your team. The incredible coder on my team lacked positive feedback from outside of the team.</p><p><strong>Do what your manager told you to do</strong>. Once you&#8217;ve identified what it is you need to do to improve your performance, make a habit of doing it!</p><div><hr></div><h4>Getting to the far right of the curve</h4><p>Depending on where you work, your company likely has at least some extraordinary engineers. If that is the case, then simply following your manager&#8217;s guidance might not be enough to get you to the far right of the curve.</p><p>Here are some qualities of top engineers I&#8217;ve observed:</p><ul><li><p><strong>Their leadership goes to them for help</strong>. Every manager or director in software has engineers that they trust for help and advice. These people tend to be the top performing engineers on the team or organization.</p></li><li><p><strong>They quickly recognize bad decisions based on past experience.</strong> For example, I presented a design to an incredible engineer who I worked with at the time. The design included a short-term solution that was a bit of a workaround until a long-term solution could be identified. <em>The incredible engineer immediately told me that I should assume the short-term solution would be around forever.</em> He was right! This totally changed the way I approached the problem and sent me back the drawing board.</p></li><li><p><strong>They are incredibly detail oriented.</strong> If you present them with a big idea that you&#8217;ve thought through already, they&#8217;ll recognize quickly that the idea is fine and dive into areas of the implementation or execution where you might run into trouble. For example, an engineer I was working with put together a design and asked <a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a>me to review it. In the design, the engineer assumed they could access some data via an API. They were correct, but the API was more of a control plane API (pretty low traffic) whereas the API he was designing was clearly a data plane API (high traffic). Thus, his design needed to include ensuring the existing control plane API could be made ready to handle the additional volume.</p></li><li><p><strong>They think in terms of trade-offs, including business trade-offs</strong>. Even well-accepted best practices in software engineering should not always be followed in certain circumstances. Top performing engineers understand this and can articulate to leadership and engineers when conventionally good ideas should not be implemented. A good example of this is understanding when a process should be automated vs. having the manual steps documented. As someone who used to manage a DevOps teams, I believed for a while that everything should be automated, but this isn&#8217;t actually the case. For instance, if a process is only performed once a year and can be reliably performed by reading some instructions, then it likely isn&#8217;t worth the time spent automating it. How many times does the automation need to be run to cover the cost of the automation development effort? Additionally, you want to think about the opportunity cost of having an engineer write the automation. If you&#8217;re automating something that rarely runs when there&#8217;s innovation work needed, then maybe you&#8217;re doing the wrong thing.</p></li></ul><h4>Closing thoughts</h4><p>One thing I think about is the situation where almost everyone on a team is pretty equally high performing (toward the right). This can actually happen and does happen. I have actually seen teams formed by taking top engineers from other teams and placing them all on the same team. If you put these people on the curve, they might all end up in the middle. If they are then compared with lower performing team, then the comparison will not be accurate or fair. In these cases, the manager of the high performing team should put the engineers toward the right and justify that placement with their management. The team may need to have many accomplishments to justify this sort of placement, but it&#8217;s the correct thing to do.</p><p>As an engineer, if you have a choice to be on a team with many other high performing engineers or a more &#8220;curve fitting team&#8221;, then you should try to be on the high performing team. You might not standout on your team as much, but you&#8217;ll improve faster than you would on the more normal team. Additionally, if your company is good, they will recognize your team as exemplary and place engineers (hopefully) according to how I described in the preceding paragraph.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/p/the-engineering-rating-bell-curve?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thank you for reading my thoughts on engineering bell curves! If you found it useful, I&#8217;d appreciate it if you shared this post!</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/p/the-engineering-rating-bell-curve?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://sheepcode.substack.com/p/the-engineering-rating-bell-curve?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>Yes, I&#8217;m using myself as an example of a &#8220;good engineer&#8221; here. I don&#8217;t think I&#8217;m a &#8220;far to the right on the curve extraordinary engineer&#8221;, but I&#8217;m working on it!</p></div></div>]]></content:encoded></item><item><title><![CDATA[Rise of the Full-Stack Engineer]]></title><description><![CDATA[Be everything. Do anything.]]></description><link>https://sheepcode.substack.com/p/rise-of-the-full-stack-engineer</link><guid isPermaLink="false">https://sheepcode.substack.com/p/rise-of-the-full-stack-engineer</guid><dc:creator><![CDATA[Daniel Dersch]]></dc:creator><pubDate>Sat, 23 Dec 2023 18:34:33 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/bae4ccc0-b1f7-44fb-b8f5-70254f235d3e_8400x5600.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Supposedly, the industry is trending toward hiring fewer separate front-end and back-end engineers and instead hiring more full-stack engineers. The idea is that a full-stack engineer can deliver an entire application (front-end, back-end, database, ops, etc) instead of specializing in one of those areas. Is this trend real? I am not yet convinced, but let&#8217;s assume it is real in this post.</p><h4>Why it makes sense</h4><p>I would argue that whether this trend is true or not, there are reasons for it that make sense. The tooling available to full-stack engineers has never been better. For instance, a full-stack engineer can use tools like React Native or Google Flutter to build applications that be deployed to every major platform using the same code base. Furthermore, the server side code can be written using TypeScript and deployed on Node. Coupled with React Native, this means that the full-stack engineer need only master a single language.</p><h4>Where it falls apart</h4><p>Writing non-trivial front-end applications targeted for many platforms is tricky and time-consuming. Furthermore, designing complex backend applications for modern applications is also tricky and time-consuming for different reasons. With that in mind, it makes sense to keep the disciplines separate. However, this same logic applied to development and operations. Many companies have found success combining development and operations into a single role. They likely see the same opportunity with front-end and back-end work.</p><h4>My advice</h4><p>If you&#8217;re a backend engineer, you&#8217;d serve yourself well to begin delving into front-end tools using a framework like React or React Native. There are numerous available resources to begin learning.</p><p>If you&#8217;re a frontend engineer, learning backend design is less straightforward (imo) since it is less about jumping into code and more about developing &#8220;systems thinking&#8221;. With front-end code, you tend to have a single user using a given instance of the application at a time. With back-end, a single application instance should serve thousands of concurrent users. The database and app must gracefully handle concurrent writes. To learn more, start watching systems design videos on YouTube.</p><h4>Versatility a driving factor?</h4><p>Companies and leaders (even smart ones) are obsessed with treating every engineer as equivalent. They want to create an environment where skillset need not be considered when reassigning engineers to other teams and projects. Of course, this sounds crazy to any sane engineer. However, requiring that every engineer be a full-stack engineer drives reality closer to this management utopia.</p><h4>Full-stack might make most sense for established teams</h4><p>If your application or application component is mature, then full-stack engineers might make a lot of sense. When is your application mature? Let&#8217;s just say that once you are at the point where new features require some modifications to a mostly complete back-end codebase and an established front-end codebase that deploy to a running app, then we&#8217;ll consider it mature within the context of this post.</p>]]></content:encoded></item><item><title><![CDATA[Microservices limit the productivity of high performing coders]]></title><description><![CDATA[Expertise needed shifts more towards systems design]]></description><link>https://sheepcode.substack.com/p/microservices-impair-the-productivity</link><guid isPermaLink="false">https://sheepcode.substack.com/p/microservices-impair-the-productivity</guid><dc:creator><![CDATA[Daniel Dersch]]></dc:creator><pubDate>Thu, 10 Aug 2023 10:54:59 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/47070a50-ec8a-414a-a38b-b68618ca3005_5184x3456.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A software product or service designed as a collection of microservices <em>divided amongst many engineering teams</em> limits the impact of high performing programmers (what some people refer to as 10x engineers or code ninjas). Why is this? Consider this scenario.</p><p><em><strong>Microservices Scenario</strong></em>: You are tasked with implementing a new feature for a service consisting of 20 microservices divided amongst 5 software engineering teams (Teams A, B, C, D, E). Of the 20 microservices, you find that 8 of them need development work in order to complete the feature. However, the 8 services belong to 3 of the teams. Team A owns 4. Team B owns 2, Team C has 2. You are on Team A. How do you proceed?</p><p>A 10x engineer/code ninja might proceed by quickly completing all of the work in the 4 microservices that their team (Team A) owns and then just wait for the other teams to complete their work. This is a valid path forward for a junior engineer sometimes. However, it often isn&#8217;t feasible. What if Team A&#8217;s code changes cannot be completed without dependencies from Team B or Team C first? If that is the case, then you cannot complete the work any quicker than it takes Team B and Team C to complete theirs (even if you are a 1000x engineer).</p><p>A better way to proceed would be to put together a design document detailing the changes required by each team and micro to complete the feature. Present the design to your leadership and the other teams to make sure you have buy-in. Answer any questions and fill in design gaps that the other teams point out (they know their services better than you do after all).</p><p>Now contrast the above scenario with this one.</p><p><em><strong>Monolith Scenario</strong></em><strong>: </strong>You are tasked with implementing a new feature for a service consisting primarily of a monolith and a few supporting micros for things like auth and notifications. You have access to all of the code for the monolith and the few micros. How do you proceed?</p><p>In this scenario, a 10x engineer/code ninja quickly implementing the feature is almost certainly the proper course of action. A design document is likely not needed.</p><div><hr></div><p>At this point, you might be thinking I&#8217;m advocating monoliths over microservices. I&#8217;m not. A strong case can be made for either and is dependent on context. Realistically, a strong programmer will likely be more productive in a microservices system when they are implementing features that only require code changes to microservices that their team owns because microservices consist of inherently less complex code bases than an equivalent monolith. The key is the <em>team</em> separation that hinders the impact of strong coders.</p><p>For services and products that are distributed amongst microservices across many teams, the key area of expertise needed shifts from the code base to the design of the system and how the various pieces interact. In other words, the design you put together on the whiteboard and diagrams and then formalize in the separation of teams and microservices becomes <em>more important</em> to the productivity of the organization than any single engineer&#8217;s strong coding ability. </p><p>So, being a 10x engineer for a microservice product is less dependent on your coding ability and more dependent on your ability to harmonize the various microservices and the teams that own them.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! I plan to write more about the tradeoffs between microservices and monoliths. If this interests you, I hope you&#8217;ll subscribe for free!</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Google kills Site Reliability Engineering?]]></title><description><![CDATA[Is SRE gone forever?]]></description><link>https://sheepcode.substack.com/p/google-kills-site-reliability-engineering</link><guid isPermaLink="false">https://sheepcode.substack.com/p/google-kills-site-reliability-engineering</guid><dc:creator><![CDATA[Daniel Dersch]]></dc:creator><pubDate>Mon, 24 Jul 2023 10:30:09 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/27ba0310-0bb2-4a72-9cb8-5d4479de012f_7360x4912.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>On the <a href="https://www.teamblind.com/post/Fake-or-real-Google-killing-SRE-ao4ZVAMd">&#8220;Blind&#8221; app</a> I recently read a rumor that Google is transitioning away from having dedicated Site Reliability Engineering (SRE) teams. This came as a mild shock to me because Google is the company that introduced the SRE position to the world. <a href="https://sre.google/sre-book/table-of-contents/">The book is great</a>, and you should read it if you haven&#8217;t.</p><p>As a quick reminder, Site Reliability Engineering approaches software operations as software engineering problems and seeks to solve operational problems using software. This is distinct from DevOps which is where the software engineering team for a particular service is additionally responsible for running that service in production. And as always, this is muddied by the fact that there are &#8220;DevOps&#8221; teams which would be better named &#8220;SRE&#8221; teams because they don&#8217;t actually do any software engineering for a service. </p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Sheep Code is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Anyways, getting back to Google. I still have not been able to find whether the rumor is true or not, but I suspect that given the current market conditions and their layoff earlier in the year that Google might be taking a deeper look at how they run their software.</p><p>Much of what Site Reliability Engineering originally set out to accomplish can now be achieved using various services, platforms, and practices. The container image has made packaging software standardized (mostly). Kubernetes has standardized container orchestration. CloudFormation/CDK/Terraform/etc. has made cloud infrastructure more manageable. There are a million managed observability (logging, tracing, metrics, alarms, etc) services to choose from as well. Even if you are running in a data center and use few managed services, you can still use open source tools like Kubernetes/ElasticSearch/Grafana and have what feels like modern managed platform (at least for software engineering teams).</p><p>I suspect Google (if the rumor is true) intends to shift the operations responsibilities fully to the software engineering teams. Many successful software companies already operate that way. I am speculating here, but I also suspect that Google may have identified they would get more value by having their SRE teams focused on producing cloud services in the observability realm.</p><p>I do not think that SRE (including misnamed DevOps teams) will go away in most of the industry. A typical &#8220;SRE/DevOps Engineer&#8221; is well-versed in the services/tools/practices I mentioned above whereas many software engineers prefer to solves problems primarily in their application codebase. However, many companies do tend to follow Google&#8217;s lead, so we&#8217;ll see.</p>]]></content:encoded></item><item><title><![CDATA[AWS Developer Innovation Day]]></title><description><![CDATA[Come see what I've been working on the past year]]></description><link>https://sheepcode.substack.com/p/aws-developer-innovation-day</link><guid isPermaLink="false">https://sheepcode.substack.com/p/aws-developer-innovation-day</guid><dc:creator><![CDATA[Daniel Dersch]]></dc:creator><pubDate>Wed, 26 Apr 2023 11:14:13 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/023e4f11-5aa8-43e0-9b9f-d640b734d6dc_127x127.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Not my typical post, but I hope some of you will be able to attend <a href="https://pages.awscloud.com/GLOBAL-event-LS-aws-developer-innovation-day-2023-reg-event.html">AWS Developer Innovation Day</a> today starting at 1:00 PM ET (it is a virtual event). Since joining Amazon, I&#8217;ve been working hard on making Amazon CodeCatalyst a great product, and CodeCatalyst will be heavily featured!</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Sheep Code is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[IaC Proliferation]]></title><description><![CDATA[Flowchart for choosing an Infrastructure-as-Code tool]]></description><link>https://sheepcode.substack.com/p/iac-proliferation</link><guid isPermaLink="false">https://sheepcode.substack.com/p/iac-proliferation</guid><dc:creator><![CDATA[Daniel Dersch]]></dc:creator><pubDate>Mon, 20 Mar 2023 10:57:08 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!knKS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f1f17c-fdbb-4a8d-9bbf-9eb127f8e86d_2963x1800.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The best way to deploy cloud resources is almost always to use an infrastructure-as-code (IaC) tool. What isn&#8217;t clear is <em>which</em> IaC tool to use in your scenario. So, I present to you an opinionated flow chart of which tool to use depending on your scenario. Here it is:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!knKS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f1f17c-fdbb-4a8d-9bbf-9eb127f8e86d_2963x1800.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!knKS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f1f17c-fdbb-4a8d-9bbf-9eb127f8e86d_2963x1800.png 424w, https://substackcdn.com/image/fetch/$s_!knKS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f1f17c-fdbb-4a8d-9bbf-9eb127f8e86d_2963x1800.png 848w, https://substackcdn.com/image/fetch/$s_!knKS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f1f17c-fdbb-4a8d-9bbf-9eb127f8e86d_2963x1800.png 1272w, https://substackcdn.com/image/fetch/$s_!knKS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f1f17c-fdbb-4a8d-9bbf-9eb127f8e86d_2963x1800.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!knKS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f1f17c-fdbb-4a8d-9bbf-9eb127f8e86d_2963x1800.png" width="1456" height="885" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/48f1f17c-fdbb-4a8d-9bbf-9eb127f8e86d_2963x1800.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:885,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:272919,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!knKS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f1f17c-fdbb-4a8d-9bbf-9eb127f8e86d_2963x1800.png 424w, https://substackcdn.com/image/fetch/$s_!knKS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f1f17c-fdbb-4a8d-9bbf-9eb127f8e86d_2963x1800.png 848w, https://substackcdn.com/image/fetch/$s_!knKS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f1f17c-fdbb-4a8d-9bbf-9eb127f8e86d_2963x1800.png 1272w, https://substackcdn.com/image/fetch/$s_!knKS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f1f17c-fdbb-4a8d-9bbf-9eb127f8e86d_2963x1800.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Everyone has their favorite tool, so I have no doubt that this will make some people upset. In this post, I&#8217;ll discuss some of my reasoning.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Over that past decade, I have worked with numerous IaC tools. I plan to write more about IaC, so please subscribe to this newsletter for free if you are interested!</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h4>Software Engineers prefer programming languages</h4><p>My main opinion around IaC is that that software engineers <em>should prefer </em>a full programming language and framework for doing infrastructure as code. IaC Frameworks that allow for this include:</p><ul><li><p>AWS CDK</p></li><li><p>Pulumi</p></li><li><p>Terraform CDK</p></li></ul><p>Of these tools, I recommend AWS CDK if you&#8217;re on AWS as it is covered by AWS Support Plans and is actively developed and used internally by Amazon. For other clouds, I prefer Pulumi over Terraform CDK because Pulumi is more mature. In a couple of years, if HashiCorp keeps up its commitment to Terraform CDK, I expect it to become more compelling.</p><h4>Less skilled programmers should NOT use a full programming language</h4><p>If your team doesn&#8217;t include at least a couple of skilled programmers, then I would not advise picking an IaC that uses a full programming language. You&#8217;re better off using an IaC that uses a DSL/JSON/YAML like </p><ul><li><p>CloudFormation</p></li><li><p>Terraform</p></li><li><p>Bicep</p></li><li><p>GCP Config Connector</p></li></ul><p>If your team has a mix of strong programmers and less skilled programmers, then it&#8217;s probably fine to use a programming language IaC.</p><h4>Take advantage of Support Plans</h4><p>If you are using IaC at a large corporation, then you very likely have an enterprise level support plan with one or more cloud providers. You should strongly consider selecting IaC tools that are covered by these plans. Should you run into issues with the covered IaC, then your cloud provider is &#8220;on the hook&#8221; to provide support.</p><p>These tools include</p><ul><li><p>AWS CloudFormation</p></li><li><p>Azure Bicep</p></li><li><p>AWS CDK</p></li><li><p>GCP Config Connector?</p></li></ul><p>Pulumi and Terraform both have Enterprise Plans that you can pay for. Of course, you would generally pay for these separately from your cloud provider support plan.</p><h4>Single-Cloud</h4><p>Each big Cloud Provider has robust IaC using a domain specific language (DSL) offering for single-cloud if you choose their Cloud. AWS has CloudFormation. GCP has Config Connector. Azure has Bicep. Terraform works well for all of these as well.</p><p>The tricky part is that teams with programmers should prefer an IaC tool that uses a programming language. This is easy in AWS because you can just use CDK. However, as far as I know, Config Connector for GCP is not supported by any programming languages. This leads me to prefer Pulumi for GCP (Terraform CDK would also work).</p><h4>Multi-Cloud</h4><p>Most of the cloud specific tools provide little or no support for third party resources. Bicep is just for Azure. Config Connector pretty much just supports GCP.</p><p>CloudFormation has public and private registries now. I highly recommend using them for companies that are already deeply embedded in AWS CloudFormation.</p><p>However, no tool has better multi-cloud and third-party functionality than <strong>Terraform</strong> and by extension <strong>Pulumi</strong> since it can make a Terraform provider into a Pulumi provider. Both tools are open source so custom providers can be written.</p><h4>Hybrid Cloud</h4><p>For Hybrid Cloud cases, I believe that Ansible is likely the best tool though I wouldn&#8217;t say Ansible is strictly an IaC tool (it really isn&#8217;t one at all). However, it can be combined with IaC tools like Terraform.</p><p>Reality is that if you&#8217;re doing Hybrid cloud, the most difficult thing you&#8217;ll be doing is data center automation. Various hardware components have very specific tools for configuring them. These tools can almost always be configured by Ansible. None of the other tools mentioned in this post would support this.</p><h4>DSL &gt; JSON/YAML</h4><p>I prefer IaC tools that use a DSL for the configuration language over tools that use JSON or YAML. JSON is difficult to write because of quote escaping and multi-line hell. In YAML, it is easy to make indentation errors. Furthermore, a truncated YAML file is often still valid YAML which can lead to issues should the file be corrupted.</p><p>DSLs like HashiCorp Configuration Language for Terraform or Azure Bicep are better suited for IaC. They are much more readable than YAML/JSON and much more writeable YAML/JSON. They still can be prone to truncation issues, but not to the extent YAML is.</p><p>Of course, as a programmer using AWS CDK, Terraform CDK, or Pulumi you don&#8217;t have to care too much about this. A CDK that produces JSON is a good model.</p><h4>Serverless IaC</h4><p>If you are deploying Serverless apps, then much of this discussion isn&#8217;t highly applicable because there are IaC options specific to Serverless that do a great job. I may do a separate post on those.</p><h4>Kubernetes</h4><p>Like Serverless, I would have to do another post on IaC for Kubernetes. Overall, I am underwhelmed by some of the popular tools for Kubernetes IaC like Helm which I view as total garbage. That said, most of the tools described in this post actually do a pretty good job deploying to Kubernetes so much of this post could still apply.</p><h4>Conclusion</h4><p>Choosing the right IaC is an important decision and often not one that is easy to change. I&#8217;ve only touched on some of the dimensions used in making a decision. Other dimensions include cost, developer community, and leveraging your existing experience. </p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Sheep Code is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[DevLife #5: Microservice Hell]]></title><description><![CDATA[Our technical debt is your debt]]></description><link>https://sheepcode.substack.com/p/devlife-5-microservice-hell</link><guid isPermaLink="false">https://sheepcode.substack.com/p/devlife-5-microservice-hell</guid><dc:creator><![CDATA[Daniel Dersch]]></dc:creator><pubDate>Tue, 07 Feb 2023 12:48:01 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/87654a10-98e9-4509-9743-a4ff2dd12aaf_7680x4320.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The way I see it, most SaaS applications are deployed as microservices because it is easy to structure an organization into teams by micros (there are other compelling reasons too). Perhaps your organization has 6 or so development teams. Each team gets 1 micros. Responsibilities and division of labor is well-defined. Here&#8217;s a possible architecture.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OIGC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba5bcbed-e844-4598-8a54-3b3af6395818_1440x820.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OIGC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba5bcbed-e844-4598-8a54-3b3af6395818_1440x820.png 424w, https://substackcdn.com/image/fetch/$s_!OIGC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba5bcbed-e844-4598-8a54-3b3af6395818_1440x820.png 848w, https://substackcdn.com/image/fetch/$s_!OIGC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba5bcbed-e844-4598-8a54-3b3af6395818_1440x820.png 1272w, https://substackcdn.com/image/fetch/$s_!OIGC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba5bcbed-e844-4598-8a54-3b3af6395818_1440x820.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OIGC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba5bcbed-e844-4598-8a54-3b3af6395818_1440x820.png" width="1440" height="820" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ba5bcbed-e844-4598-8a54-3b3af6395818_1440x820.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:820,&quot;width&quot;:1440,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:43562,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!OIGC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba5bcbed-e844-4598-8a54-3b3af6395818_1440x820.png 424w, https://substackcdn.com/image/fetch/$s_!OIGC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba5bcbed-e844-4598-8a54-3b3af6395818_1440x820.png 848w, https://substackcdn.com/image/fetch/$s_!OIGC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba5bcbed-e844-4598-8a54-3b3af6395818_1440x820.png 1272w, https://substackcdn.com/image/fetch/$s_!OIGC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba5bcbed-e844-4598-8a54-3b3af6395818_1440x820.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">An architecture that works well with an organizational chart!</figcaption></figure></div><p>I like how this looks. It&#8217;s clean. Each component <em>should</em> be able to evolve and scale independently of the others.</p><p>Except that&#8217;s not really how it works .</p><p>In reality, each micro is heavily constrained by their callers (upstreams) or their dependencies (downstreams) or both. Let&#8217;s redraw the diagram to see what it really looks like.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!q-Rj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5519fbc0-3316-4262-8021-9d831058e97d_1440x860.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!q-Rj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5519fbc0-3316-4262-8021-9d831058e97d_1440x860.png 424w, https://substackcdn.com/image/fetch/$s_!q-Rj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5519fbc0-3316-4262-8021-9d831058e97d_1440x860.png 848w, https://substackcdn.com/image/fetch/$s_!q-Rj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5519fbc0-3316-4262-8021-9d831058e97d_1440x860.png 1272w, https://substackcdn.com/image/fetch/$s_!q-Rj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5519fbc0-3316-4262-8021-9d831058e97d_1440x860.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!q-Rj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5519fbc0-3316-4262-8021-9d831058e97d_1440x860.png" width="1440" height="860" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5519fbc0-3316-4262-8021-9d831058e97d_1440x860.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:860,&quot;width&quot;:1440,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:47954,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!q-Rj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5519fbc0-3316-4262-8021-9d831058e97d_1440x860.png 424w, https://substackcdn.com/image/fetch/$s_!q-Rj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5519fbc0-3316-4262-8021-9d831058e97d_1440x860.png 848w, https://substackcdn.com/image/fetch/$s_!q-Rj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5519fbc0-3316-4262-8021-9d831058e97d_1440x860.png 1272w, https://substackcdn.com/image/fetch/$s_!q-Rj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5519fbc0-3316-4262-8021-9d831058e97d_1440x860.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">oh no</figcaption></figure></div><p>Every single one of these micros likely has to interact with the user and tenant management service. Every request will need to be authenticated and authorized. The caller context has to be verified as it flows through every service. Each service will have to figure out how to ship their data to the Search micro. The various business logic services likely have dependencies on each other to avoid duplicated effort. </p><p>In general, <strong>these pains are worth it.</strong> More micros means a smaller blast radius if a single micro is breached, more fault tolerance in case one of the micros becomes unavailable (unless it&#8217;s auth or user management), better resource utilization for heavily used services (like auth) and rarely used micros.</p><p><strong>However, the one alleged &#8220;benefit&#8221; that I completely find ridiculous is the idea that micros evolve independently.</strong> I have never found this to be the case. Let&#8217;s look at this from the perspective of callers (upstreams) and dependencies (downstreams).</p><h4>The Upstream Problem</h4><p>By <em>upstreams</em> I mean services that are early in the call flow. The client (frontend/Web browser) is the most upstream on this diagram (the client isn&#8217;t a micro though). API Gateway is second. Auth is likely third. User/tenant management is probably fifth. Everything else is after that. </p><p>The issue for upstream services is that downstream micros often do not yet provide sufficient APIs to enable your features. Why? Usually, this is because those services are owned by other teams which have differing priorities from your team. This creates overhead in that leadership and the two teams need to negotiate priority. However, if the downstream team is unable to provide the needed functionality in a timely manner, then the upstream might i<strong>mplement it themselves or find a clunky workaround</strong>.</p><p>This is often necessary, but it is problematic because it has potential to create technical debt that is difficult to unwind because micros end up having functionality built into them that logically should be elsewhere.</p><p>For example, what would happen if the Users/Tenants team failed to deliver their data to the Search team. Thus, the Search team cannot provide search functionality containing user data. However, Business Logic 1 service <em>needs<strong> </strong></em>this functionality. Business Logic 1 finds a way to maintain a list of users, so instead of using the Search team, they use their own data. To make matters worse, Business Logic 2 service decides to invoke Business Logic 1 to search user data <em>because the functionality is ready</em>.</p><p>Months later, the Search to finally is able to get the data they need from the Users/tenants team. Search builds the search functionality for user data. However, Business Logic 2 team does not adopt it because they already have the functionality they need.</p><h4>The Downstream Problem</h4><p>By <em>downstream </em>I mean services that are late in the call flow. The User/Tenants service in the above diagrams serves as our example.</p><p>The issue for downstreams is that changing the interface is hard. For one, you MUST  never break your callers/upstreams (except under rare circumstances like an active breach in which case it might be necessary). For instance, you own the user service and have an API for retrieving a user by social security number that is invoked over HTTP like the following:</p><pre><code><code>HTTP GET /users?ssn=333-33-3333</code></code></pre><p>A few years after your product launch, your leadership realizes that querying for user data by social security number is a bad idea. In fact, a compliance agency threatens to remove one of your certifications when they discover this API. The decision is made to remove it as quickly as possible.</p><p>But you can&#8217;t remove it immediately. The API is used by nearly every other micro. The best you can do is allow it to optionally take in a second field called id like the following:</p><pre><code><code>HTTP GET /users?ssn=333-33-3333&amp;id=abcde-fghi-jklmnopq</code></code></pre><p>Your upstream micros can then invoke you either using ssn or id. This gives them a migration path off of the API. <em>But you are stuck with <strong>ssn</strong> as a parameter until the last caller switches to using <strong>id</strong>. </em>Removing <em>ssn</em> prior to that would break the upstream services and cause the product to lose service.</p><p>This is the downstream problem. Fixing your technical debt often requires your callers to change. If your clients are external, then moving your customers onto the non-deprecated feature could take years. This is why companies like Amazon and Microsoft very rarely remove APIs and take the interface very seriously.</p><h4>Solving these Problems</h4><p>The management and leads of each micro must periodically meet to align on their mission. Teams must commit to adhering to the principles of the architecture except as a last resort. Should the principles be compromised, teams must commit to resolving once a principled solution is ready. Teams must strive to rarely deprecate APIs or change the APIs that require a difficult migration.</p><p>Many of these problems shows up less often by increasing the number of micros owned by each team or simply combining those micros into a single service. This empowers teams to more often unblock themselves.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">I&#8217;ve been developing and operating microservices for over a decade now and have a lot more to say about them. If you&#8217;re interested, I hope you&#8217;ll subscribe for free to this newsletter.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><p>To sum it up, the benefits of microservices include</p><ul><li><p>easy to divvy up the work to a lot of teams</p></li><li><p>better fault tolerance</p></li><li><p>low blast radius</p></li><li><p>independent scaling</p></li></ul><p>The drawbacks include </p><ul><li><p><strong>technical debt is often shared across many micros</strong></p></li><li><p>migrations involving multiple teams have to be carefully orchestrated</p></li><li><p>latency has to constantly be dealt with</p></li></ul><p></p>]]></content:encoded></item><item><title><![CDATA[DevLife #4: System tests are better than unit tests]]></title><description><![CDATA[In the world of software engineering, testing your code is critical.]]></description><link>https://sheepcode.substack.com/p/devlife-4-system-tests-are-better</link><guid isPermaLink="false">https://sheepcode.substack.com/p/devlife-4-system-tests-are-better</guid><dc:creator><![CDATA[Daniel Dersch]]></dc:creator><pubDate>Tue, 31 Jan 2023 12:35:58 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/cdfe5845-8727-4ef4-b699-0097a3a8f624_5184x3456.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the world of software engineering, testing your code is critical. All testing is important. However, some types of tests are <em>more important</em> than others for a variety of reasons. In this post, I&#8217;ll discuss why <strong>System</strong> <strong>Tests </strong>are the most important type of software test.</p><p>Here&#8217;s a few types of tests that are common in software development:</p><ol><li><p><strong>Unit Tests </strong>test a class or function without testing its dependencies. No connecting to databases, the file system, or making real network calls. If your function does those things, you need to find a way to mock those dependencies. Otherwise, a unit test isn&#8217;t possible.</p></li><li><p><strong>Integration Tests </strong>test a class or function and its dependencies (though not necessarily the dependencies&#8217; dependencies). These tests do not connect over the network to any dependencies (though this rule can be bent).</p></li><li><p><strong>System Tests </strong>test the running software connected to all dependencies including databases, other APIs, etc. System tests test the interface that the end users or clients interact with. So for a Web site, a proper System test would use a Web browser to click buttons and make sure proper things happen. To system test an API, you would invoke it and then use other APIs to make sure it did what it was supposed to do.</p></li></ol><p>Pretty much all programmers are familiar with unit tests, but system and integration tests are often less familiar to newer programmers. We&#8217;ll focus on system tests in this post.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">I am really passionate about all forms of software testing and plan to write a lot more about it. If that interests you, I hope you&#8217;ll subscribe to this newsletter!</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h3>System Testing Command Line Tic-tac-toe</h3><p>Below we have a code block written in Go that is a simple game of tic-tac-toe based on the command line. The game assumes that the two players are sharing a terminal. The users input a number between 1 and 9 where 1 is the upper left hand square, 5 is the middle square, and 9 is the bottom right hand square. It&#8217;s pretty simple.</p><pre><code>package main

import (
  "fmt"
)

var board [3][3]string

func init() {
  for i := 0; i &lt; 3; i++ {
    for j := 0; j &lt; 3; j++ {
      board[i][j] = "-"
    }
  }
}

func displayBoard() {
  for i := 0; i &lt; 3; i++ {
    for j := 0; j &lt; 3; j++ {
      fmt.Print(board[i][j])
      if j != 2 {
        fmt.Print("|")
      }
    }
    fmt.Println()
  }
}

func didPlayerWin(player string) bool {
  for i := 0; i &lt; 3; i++ {
    if (board[i][0] == player &amp;&amp; board[i][1] == player &amp;&amp; board[i][2] == player) ||
      (board[0][i] == player &amp;&amp; board[1][i] == player &amp;&amp; board[2][i] == player) {
      return true
    }
  }

  if board[0][0] == player &amp;&amp; board[1][1] == player &amp;&amp; board[2][2] == player {
    return true
  }

  if board[0][2] == player &amp;&amp; board[1][1] == player &amp;&amp; board[2][0] == player {
    return true
  }

  return false
}

func main() {
  var player = "X"
  var move int
  var row, col int
  var gameOver = false
  var winner string
  numMoves := 0
  for !gameOver &amp;&amp; numMoves &lt; 9 {
    displayBoard()
    fmt.Print("Player ", player, ", enter move (1-9): ")
    fmt.Scan(&amp;move)
    row = (move - 1) / 3
    col = (move - 1) % 3
    if board[row][col] == "-" {
      board[row][col] = player

    } else {
      fmt.Println("Invalid move, try again.")
      continue
    }
    if didPlayerWin(player) {
      winner = player
      gameOver = true
    }

    if player == "X" {
      player = "O"
    } else {
      player = "X"
    }

    numMoves = numMoves + 1

  }
  displayBoard()
  if winner != "" {
    fmt.Println("Player", winner, "wins!")
  } else {
    fmt.Println("It's a tie")
  }
}
</code></pre><p>Here is a simple (and very incomplete) unit test for the <strong>didPlayerWin</strong> function:</p><pre><code><code>package main

import "testing"

func TestDidPlayerWin(t *testing.T) {

  board[0][0] = "X"
  board[0][1] = "X"
  board[0][2] = "X"

  board[1][0] = "O"
  board[1][0] = "O"

  if !didPlayerWin("X") {
    t.Fail()
  }
}
</code></code></pre><p>In this test, it simply checks if a player won. In the tested case, the X player won by connecting 3 in a row on the top row. It&#8217;s pretty straightforward.</p><p>The rest of the code is not easily unit testable because it is a monolithic function (though for a trivial code base like this, it is possible). </p><p><strong>Writing system tests for this game is easy</strong> and can be done with a simple bash script. Here is an example system test for the game:</p><pre><code>echo "1 2 3 5 2 9 8 4" | go run main.go | grep -q "Player O wins\!" &amp;&amp; echo SUCCESS || echo FAILED | grep "SUCCESS"</code></pre><p>If you run the above code, then the result will be &#8220;SUCCESS&#8221; printed to the screen. If change the grep statement to check if Player X wins then the result will be that &#8220;FAILED&#8221; will print.</p><p>How does this snippet work? Let&#8217;s break it down:</p><ol><li><p><code>echo "1 2 3 5 2 9 8 4"</code></p><ol><li><p>Simply prints the string  <code>"1 2 3 5 2 9 8 4" to the console</code></p></li><li><p>This gets piped to the next command</p></li></ol></li><li><p>go run main.go</p><ol><li><p>Runs the tic tac go program which prompts for input</p></li><li><p>Receives the &#8220;1 2 3 5 2 9 8 4&#8221; string from the previous command</p></li><li><p>Writes &#8220;Player 0 wins!&#8221; (and other stuff) to stdout (or it should if the code works!)</p></li><li><p>Pipes the output to the next command</p></li></ol></li><li><p>grep -q &#8220;Player O wins\!&#8221; &amp;&amp; echo SUCCESS || echo FAILED</p><ol><li><p>Checks if the output from the previous command contains &#8220;Player O wins&#8221;. Writes &#8220;SUCCESS&#8221; to stdout if so other writes writes &#8220;FAILED</p></li><li><p>The -q flag suppresses the output from showing up in stdout. This isn&#8217;t necessary, but it makes the test cleaner</p></li></ol></li><li><p>grep &#8220;SUCCESS&#8221;</p><ol><li><p>Checks to make sure the previous command writes &#8220;SUCCESS&#8221; to stdout or not.</p></li><li><p>I simply added this so that the proper error code would show up in $?. This allows the code to be run in a larger script and know when the test is failing</p></li></ol></li></ol><p>We can add many more tests like the following:</p><pre><code># check if O wins
echo "1 2 3 5 2 9 8" | go run main.go | grep -q "Player O wins\!" &amp;&amp; echo SUCCESS || echo FAILED

# check if X wins
echo "1 4 2 5 3" | go run main.go | grep -q "Player X wins\!" &amp;&amp; echo SUCCESS || echo FAILED

# check for a tie
echo "1 2 4 7 9 5 8 6 3" | go run main.go | grep -q "tie" &amp;&amp; echo SUCCESS || echo FAILED</code></pre><p>You can just keep adding tests like this. Unlike our unit test, it tests all of the code.</p><p>Now you might be thinking &#8220;well, can&#8217;t we just write more unit tests&#8221;? Yes of course, and we should! However, much of the code is not very easily unit testable. </p><p><strong>Let&#8217;s refactor the code to be more unit testable.</strong> We&#8217;ll also put everything into a struct because why not.</p><pre><code>package main

import (
  "fmt"
)

var game *TicTacToe

func init() {
  game = &amp;TicTacToe{
    board:         [3][3]string{},
    currentPlayer: "X",
    numMoves:      0,
    over:          false,
    winner:        "",
  }
  for i := 0; i &lt; 3; i++ {
    for j := 0; j &lt; 3; j++ {
      game.board[i][j] = "-"
    }
  }
}

type TicTacToe struct {
  numMoves      int
  board         [3][3]string
  currentPlayer string
  over          bool
  winner        string
}

func (game *TicTacToe) overMessage() {
  if game.winner != "" {
    fmt.Println("Player", game.winner, "wins!")
  } else {
    fmt.Println("It's a tie")
  }
}

func (game *TicTacToe) setCurrentPlayerAsWinner() {
  game.winner = game.currentPlayer
}

func (game *TicTacToe) promptInput() int {
  var move int
  fmt.Print("Player ", game.currentPlayer, ", enter move (1-9): ")
  fmt.Scan(&amp;move)
  return move
}

func (game *TicTacToe) convertInputToCoordinates(move int) (int, int) {
  row := (move - 1) / 3
  col := (move - 1) % 3

  return row, col
}

func (game *TicTacToe) isOver() bool {
  if (game.numMoves) &gt; 8 {
    game.setIsOver()
  }
  return game.over
}

func (game *TicTacToe) displayBoard() {
  for i := 0; i &lt; 3; i++ {
    for j := 0; j &lt; 3; j++ {
      fmt.Print(game.board[i][j])
      if j != 2 {
        fmt.Print("|")
      }
    }
    fmt.Println()
  }
}

func (game *TicTacToe) didCurrentPlayerWin() bool {
  for i := 0; i &lt; 3; i++ {
    if (game.board[i][0] == game.currentPlayer &amp;&amp; game.board[i][1] == game.currentPlayer &amp;&amp; game.board[i][2] == game.currentPlayer) ||
      (game.board[0][i] == game.currentPlayer &amp;&amp; game.board[1][i] == game.currentPlayer &amp;&amp; game.board[2][i] == game.currentPlayer) {
      return true
    }
  }

  if game.board[0][0] == game.currentPlayer &amp;&amp; game.board[1][1] == game.currentPlayer &amp;&amp; game.board[2][2] == game.currentPlayer {
    return true
  }

  if game.board[0][2] == game.currentPlayer &amp;&amp; game.board[1][1] == game.currentPlayer &amp;&amp; game.board[2][0] == game.currentPlayer {
    return true
  }

  return false
}

func (game *TicTacToe) move(row, col int) {
  game.board[row][col] = game.currentPlayer
  game.numMoves++
}

func (game *TicTacToe) switchPlayer() {
  if game.currentPlayer == "X" {
    game.currentPlayer = "O"
  } else {
    game.currentPlayer = "X"
  }

}

func (game *TicTacToe) isValidMove(row, col int) bool {
  if row &lt; 0 || row &gt; 2 {
    return false
  }

  if col &lt; 0 || col &gt; 2 {
    return false
  }

  return game.board[row][col] != "-"
}

func (game *TicTacToe) setIsOver() {
  game.over = true
}

func main() {

  for !game.isOver() {
    game.displayBoard()
    move := game.promptInput()
    row, col := game.convertInputToCoordinates(move)
    if game.isValidMove(row, col) {
      fmt.Println("Invalid move, try again.")
      continue
    }

    game.move(row, col)

    if game.didCurrentPlayerWin() {
      game.setIsOver()
      game.setCurrentPlayerAsWinner()
    }

    game.switchPlayer()
  }
  game.displayBoard()
  game.overMessage()
}
</code></pre><p>This code is much easier to unit test. Here are some unit tests:</p><pre><code>package main

import "testing"

func TestDidCurentPlayerWin(t *testing.T) {

  game.move(0, 0)

  game.move(1, 0)
  game.move(0, 1)
  game.move(1, 0)

  game.move(0, 2)

  if !game.didCurrentPlayerWin() {
    t.Fail()
  }

}

func TestIsOver(t *testing.T) {
  game.numMoves = 0
  if game.isOver() {
    t.Fail()
  }

  game.numMoves = 9
  if !game.isOver() {
    t.Fail()
  }
}

func TestConvertInputToCoordinates(t *testing.T) {
  row, col := game.convertInputToCoordinates(1)
  if row != 0 || col != 0 {
    t.Fail()
  }

  row, col = game.convertInputToCoordinates(5)

  if row != 1 || col != 1 {
    t.Fail()
  }
}

func TestSwitchPlayer(t *testing.T) {
  game.currentPlayer = "X"
  game.switchPlayer()
  if game.currentPlayer != "O" {
    t.Fail()
  }
}
</code></pre><p>One thing to note is that <strong>I had to modify the original unit test</strong> because the previous function no longer existed. What modifications did I have to make to the system tests? Well&#8230;</p><h4>System Tests Enable Large Refactors</h4><p>So we just refactored the original code to be more testable. This required the original unit test to be rewritten (or at least heavily modified). Guess what changes I had to make to the system tests? <em><strong>NONE</strong></em>. They are all still valid. (In fact, I used the system tests to validate that the new code works). Why do the system tests still work? They work <strong>because the client interface did not change.</strong> In this case, the client interface is text streams via stdin and stdout. </p><p>The same holds true for software where the interface is an API. As long as the API interface does not change, you can perform a large refactor on the code base and still be confident in your system tests.</p><p>In fact, I would argue that without comprehensive system tests, a large refactor is likely not possible in a reasonable timeframe.</p><h4>Unit Tests are still important</h4><p>The fact that system tests are superior to unit tests is no excuse to skip writing unit tests. Unit tests will generally find bugs earlier in the software lifecycle process than system tests. They can also easily be written during development whereas that isn&#8217;t always possible for system tests (though it was for our tic tac toe example). Unit tests also force you to write code that is unit testable which is a plus. So you should write both types of tests.</p><p>So why point out that system tests are more important if both types of tests should always be written? Let me put it this way. Consider the scenario where I start a new job on a new product. I look at the codebase and find that it isn&#8217;t very well tested. Maybe it has 50% unit test code coverage and one system tests that only tests the most common scenario. Where should my time be spent? <em>Easy</em>. I&#8217;m going to write system tests. A codebase that is in production in this situation probably <em>mostly </em>works. System tests will give more confidence at release time and allow faster iteration. Writing additional unit tests would give me more confidence that the code works as it is, but gives me little additional confidence as the code evolves. This is because evolving code often means evolving unit tests. The system tests will always be valid so long as the interface does not change.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/p/devlife-4-system-tests-are-better?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thank-you for reading about system tests! This post (like all of my posts so far) is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/p/devlife-4-system-tests-are-better?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://sheepcode.substack.com/p/devlife-4-system-tests-are-better?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div>]]></content:encoded></item><item><title><![CDATA[DevLife #3: Responding to a page while on-call]]></title><description><![CDATA[Outages happen. Here's a simple sequence to follow to troubleshoot.]]></description><link>https://sheepcode.substack.com/p/devlife-3-responding-to-a-page-while</link><guid isPermaLink="false">https://sheepcode.substack.com/p/devlife-3-responding-to-a-page-while</guid><dc:creator><![CDATA[Daniel Dersch]]></dc:creator><pubDate>Thu, 19 Jan 2023 16:10:35 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/bbea0dac-f8a7-40ee-823f-3d1db46f327d_5000x3748.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>In a previous post, I wrote about why software engineers <a href="https://sheepcode.substack.com/p/software-engineers-should-be-on-call">should join a team with on-call responsibilities</a>. I then wrote about what you can do to <a href="https://sheepcode.substack.com/p/devlife-2-prepping-for-your-on-call">prep for your first on-call shift</a>. In this post, I&#8217;ll briefly go over what a typical on-call shift might look like.</em></p><p>The vast majority of software engineering teams combine on-call responsibilities with support. Hopefully, you&#8217;ll spend the vast majority of your on-call shift working support tickets and assisting other teams with their questions.</p><p>However, responding to <strong>alarms and outages takes precedence over all support activities</strong>. If you have to choose between keeping your service running versus helping <em>Don</em> <em>from R&amp;D </em>figure out why his proof-of-concept project can&#8217;t access your service, then <em>always</em> choose to keep the service running. Don deserves your attention, but he can wait.</p><p>Make sure you keep your computer close to you. If you go out, make sure you understand how quickly you are expected to respond to a page. If it&#8217;s within minutes, you might need to find another engineer to cover for you while you go out.</p><p><strong>Transient issues will alarm you, potentially often.</strong> A synthetic test might unluckily fail a few times in a row or latency might spike for a few minutes before resolving itself. These types of things happen on the Internet. In general, you should respond to the page when these issues happen and make sure that they get resolved. If it is 2:00 am and the issue resolves itself, then go back to bed and figure out the cause in the morning. Otherwise, it is good to check if you can determine what happened. Common causes for transient issues include:</p><ul><li><p><strong>Hardware failure</strong> if this happens, then your service should automatically spin up new virtual machines or containers on new hardware. However, your service might be under provisioned during this time which can lead to increased fault rates and latency.</p></li><li><p><strong>Eventual consistency</strong>. Many workloads make changes that are <a href="https://en.wikipedia.org/wiki/Eventual_consistency">eventually consistent</a>. This can cause synthetic tests to sometimes fail. The reason for this is because a common pattern for a synthetic test is 1) <em>do something</em> 2) <em>make sure that something was done</em>. If the <em>do something</em> is eventually consistent, then making sure it is done might be done with polling. However, you don&#8217;t want to poll forever, so eventually you need to timeout. All of this can lead to you getting paged in the middle of the night.</p></li><li><p><strong>Deployments/updates</strong>. Maybe your service or one of your dependencies does not gracefully handle a deployment. For instance, it is possible that your deployment system might take too many nodes out of service at a time. This can lead to increased fault rates and increased latency because of constrained resources. </p></li><li><p><strong>Service Provider disruption.</strong> In this case, your cloud provider such as AWS or GCP or hosting provider might have a disruption. If you&#8217;re using AWS, maybe one of the availability zones where your service is partially deployed is disrupted. Your workload/service nodes should shift to a different zone. However, in the process you will likely get paged.</p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">I have a lot to say about on-call, outages, and disruptions! I hope you&#8217;ll subscribe to this newsletter.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>If a a severe service disruption occurs, and it isn&#8217;t apparent how to make the service recover within several minutes, then you should start an outage bridge or join the outage bridge that someone else created. As the on-call engineer, your primary focus is <em>not</em> to figure out why the service is disrupted though sometimes this will be either necessary or become apparent as the outage goes on. <strong>Your primary focus is to make the service recover from the disruption</strong>.</p><p>Your troubleshooting sequence should vary depending on what your service does and what the disruption is. However, this is the sequence I usually follow, and it generally works well:</p><ol><li><p>Check if the application itself is working by signing in and testing the disrupted part of the service.</p></li><li><p>Go to monitoring dashboard. Does anything obvious jump out? Do differing metrics spike or dip around the same time?</p><ol><li><p>Note that a massive traffic spike can indicate a denial of service attack. Most engineers are not equipped to deal with this alone. If you suspect a Denial of Service attack, then you need to engage your network engineers and your cloud provider.</p></li></ol></li><li><p>Check the metrics that caused the alarm. Do they show signs of recovery?</p></li><li><p>Did your team recently deploy a change that correlates with the time the issue started surfacing? <strong>If so, you should immediately begin the rollback process if it is safe to do so. If you are unsure, page the engineer that made the change and have them perform the rollback. </strong>Remember, recovering is more important than figuring our precisely why the disruption is occurring.</p></li><li><p>Query the logs for ERROR logs. Is the frequency of ERROR logs higher than usual? Most logging systems display a histogram which should make that apparent.</p><ol><li><p>Do the ERROR logs indicate that a database is disrupted? <strong>If the database is disrupted, contact your DBA (if you have one) to help troubleshoot. </strong>If you don&#8217;t have a DBA, then it is likely your team&#8217;s job to troubleshoot the database. </p></li><li><p>Is a downstream service disrupted? <strong>If so, make sure that team is represented on the outage bridge. If they recently deployed a change that correlates with the outage, they should roll it back. </strong>Make sure the incident manager on the bridge understand the impact the downstream service&#8217;s disruption is having on your service. One thing you can do to possibly assist that team is provide them with the RequestIDs of requests to them that are failing.</p></li><li><p>If the ERROR logs indicate that a third party service (like a payment system) is disrupted, then engage their support immediately. Create a support ticket with all the details necessary. Get them on the outage bridge if possible as well.</p></li></ol></li><li><p>Check the primitive metrics such as CPU, Memory, and Disk usage. Additionally, check how many VMs/containers are active for your application. Was there a recent scale up or down?</p></li><li><p>At this point, if a path for recovering from the disruption is not apparent, then it is time to bring in other engineers from your team or even others teams to help troubleshoot. </p></li></ol><p>If your service is completely disrupted and there&#8217;s not an apparent fix, then it might be time to enter what I call the <strong>danger zone</strong>. These are actions that you generally should NOT do as they might disrupt your service, <em><strong>but</strong> </em>your service is already disrupted so it is slightly &#8220;safer&#8221; to do them. You shouldn&#8217;t do them alone. Make sure another engineer or manager has eyes on the actions. Here are some ideas:</p><ol><li><p><strong>Replace all the existing VMs/containers with new ones (for stateless services)</strong>. This can usually be done pretty safely. Modern systems will drain existing connections and roll out the new nodes before the existing ones shutdown. This can fix your service because:</p><ol><li><p>The underlying hardware might be disrupted in a somewhat invisible way. Restarting nodes has a strong chance that most of the new nodes are placed on different hardware.</p></li></ol></li><li><p><strong>Restart the machines (for stateful services). </strong>You probably can&#8217;t easily just replace the nodes your database is running on. Instead, you can restart the machine. If you believe it isn&#8217;t safe to restart the machine, consider restarting the services running on the machine.</p></li><li><p><strong>Touch the cloud infrastructure</strong>. One of the worst outages I have ever been a part of was the result of a cloud managed load balancer being partially deployed on bad hardware. We never figured this out during the incident but it became apparent later on. We got lucky. I recommended we change a configuration on the load balancer (without knowing the LB was the problem), and that solved the issue. Why? Not at all because of the configuration changes! It was because the LB was transitioned to new hardware during the process.</p></li><li><p><strong>Emergency hot fix</strong>. Consider pushing out a code change that adds more logging or metrics that you believe might make the issue more apparent. Or, if a developer has a hunch on a fix that might fix the issue, consider pushing that out. </p></li></ol><p>There&#8217;s no denying that outages are stressful. I hope some of these tips help you deal with them.</p>]]></content:encoded></item><item><title><![CDATA[DevLife #2: Prepping for your on-call shift]]></title><description><![CDATA[Don't start your first shift unprepared!]]></description><link>https://sheepcode.substack.com/p/devlife-2-prepping-for-your-on-call</link><guid isPermaLink="false">https://sheepcode.substack.com/p/devlife-2-prepping-for-your-on-call</guid><dc:creator><![CDATA[Daniel Dersch]]></dc:creator><pubDate>Tue, 17 Jan 2023 13:36:12 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/7bb93459-8834-4d69-8d26-c1e0591cf5f7_5999x4000.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em><a href="https://sheepcode.substack.com/p/software-engineers-should-be-on-call">In a previous post</a>, I discussed why software engineers should seek to be on a team with on-call responsibilities. In this post, I&#8217;ll help you prepare for your first on-call shift. In a later post, I&#8217;ll discuss &#8220;what to do&#8221; during your first on-call shift.</em></p><p>If you&#8217;re reading this post, it is possible you are about to start your first on-call shift or perhaps your previous on-call shift was rough. Maybe you&#8217;ve done on-call before, but you&#8217;ve never felt comfortable when working those shifts. <em>You&#8217;ve come to the right place</em>. If you follow these tips, you will be prepared for your next on-call shift!</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">I will be writing several more posts about on-call and other software operations and DevOps topics. If you want to see these posts, I would be honored if you subscribed!</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Here&#8217;s what you you need to do before your first shift:</p><p><strong>Review previous incident/outage logs. </strong>Most companies have their on-call engineers and incident managers write incident logs or an incident report whenever a major service disruption happens. Read through several of these. How did the on-call engineers solve the problem? How long did it take the service to recover? What was determined to be the root cause? Did your service come into play? <em>Who</em> was most responsible for correcting the issue? Which services tend to be &#8220;problematic&#8221;?</p><p>Perhaps your company doesn&#8217;t officially collect these logs. If that is the case, see if you can find the chat thread on Slack where it was discussed. </p><p><strong>Talk to engineers involved in solving outages. </strong>Often times, the incident/outage logs don&#8217;t do a great job of spelling out <em>how</em> the engineer who solved the issue figured it out. So talk directly to the engineer who solved it! The vast majority of engineers will be happy to share this information with you because they will want others to be able to solve such problems. Consider asking these types of questions:</p><ul><li><p><em>How did you solve the latest outage?</em></p></li><li><p><em>What are the most common types of outages at our company?</em></p></li><li><p><em>What are the most important tools you use for diagnosing the service during an outage?</em></p></li><li><p><em>What are the company expectations for escalating or starting a bridge?</em></p></li><li><p><em>Do you have any general tips/advice?</em></p></li></ul><p>As with anything, make sure you thank them for their time. </p><p><strong>Shadow an on-call engineer.</strong> Whenever an incident/outage strikes, ask the current on-call engineer to immediately bring you into a call so that you can watch how they diagnose and resolve the issue. Hopefully, they&#8217;ll be able to explain what they are doing as they do it, but keep in mind that outages can be stressful so they might not be able to do that. That&#8217;s OK! Take what you can get. Keep the following in mind as you observe:</p><ul><li><p><em>How were they notified an incident has happened? Was it the alarms or something else?</em></p></li><li><p><em>Which tools do they open first? Do you have access to those tools? You should.</em></p></li><li><p><em>What do their Web browser bookmarks for on-call look like? Would it be useful to copy their structure?</em></p></li><li><p><em>At what point do they open an outage bridge?</em></p></li></ul><p><strong>Join a few outage bridges. </strong>An outage bridge is a conference call where on-call engineers and incident managers meet to attempt to quickly recover from an outage (and other things, but those are beyond the scope of this post). Generally speaking, only people actively involved in correcting the outage should join an outage bridge. You don&#8217;t want too many cooks in the kitchen. However, joining for the purpose of learning how the process works is a valid exception. Join a bridge and just listen. Join another bridge and see if you can find the root cause before the other people on the bridge do.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a> Don&#8217;t feel the need to speak unless you have something useful to say.</p><h3>Know your Tools</h3><p>Your tools assist you in troubleshooting an issue. Know what you have available to you <em>before</em> you begin your first shift.</p><h4>Logs</h4><p><strong>Logs </strong>are human readable messages that your service emits whenever it does something. Logs are generally categorized by levels like INFO, WARN, and ERROR. INFO is something you expect to happen. WARN is something that you should maybe be concerned about, but also maybe not. ERROR means that something went wrong.</p><p>Usually, ERROR logs are the most helpful logs to look at during an outage. Before you begin your on-call shift, ensure that you know how to search for ERROR logs within a specific time window. Make sure you are comfortable working with date/time in UTC and a 24 hour time format.</p><p>You should hopefully have a <strong>log management system</strong> to help you search the logs. Most log management systems use SQL or a SQL-like syntax to query logs. You should study up on this. Put together a &#8220;querying cookbook&#8221; with example snippets of how to search your logs. <a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax-examples.html">Amazon CloudWatch Logs Insights has a good example here</a>. You don&#8217;t want your first time querying the log management system to be during an outage!</p><h4>RequestID</h4><p>Logs should always include a <strong>RequestID.</strong> After you&#8217;ve searched for ERROR logs, look at the RequestID for one of them and query the log system to find all the logs associated with that RequestID. This will show you what the system actually did before it failed.</p><p><em>Make sure you know how to do this before your on-call shift begins</em>. This will often lead you to the cause.</p><h4>The Source Code</h4><p>If you&#8217;re a software engineer, then you obviously have the of source code for your services available to you. Once you&#8217;ve looked at some logs, check in your code at the entry point and follow the call stack all the way down (or up depending how you visualize a stack in your mind). Are there any logs that aren&#8217;t getting emitted that should? Do you see perhaps where you&#8217;re not catching an evil null pointer exception?</p><p>If you&#8217;re an operations, DevOps, or Site Reliability Engineer then you might not have the source code readily available. I don&#8217;t agree with this approach, but many companies feel that for compliance and security reasons, this is a proper approach.</p><h4><strong>Metrics</strong></h4><p>Whereas Logs are human readable messages, metrics are human readable numbers that can be displayed. In operations, we have what are known as the <a href="https://sre.google/sre-book/monitoring-distributed-systems/#:~:text=The%20four%20golden%20signals%20of,system%2C%20focus%20on%20these%20four.&amp;text=The%20time%20it%20takes%20to,the%20latency%20of%20failed%20requests.">four golden signals</a> which are some of the most important metrics. I&#8217;ll cover three of them here:</p><ul><li><p><strong>Latency </strong>measures how long it takes requests to complete. If you see that your requests are taking a long time, then that is cause for concern!</p></li><li><p><strong>Traffic </strong>measures how many requests your service receives. There are legitimate spikes in traffic like all your users waking up and using your service in the morning and nefarious spikes in traffic like a DDoS attack. However, even legitimate spikes in traffic can take down your service.</p></li><li><p><strong>Faults </strong>rate measures how often requests fail for unexpected reasons. This is distinguished from requests failing for acceptable reasons like passing incorrect parameters. Any fault is concerning. Faults are also known as errors or 500s.</p></li></ul><p>Other metrics to collect are CPU, Memory, Disk, and VM/Instance usage. This is especially important if your application is running in a data center or on a legacy hardware. However, in modern systems these are generally the last place to look when an issue occurs. This is because modern systems are designed for hardware failure and will automatically terminate VMs/Containers that are misbehaving.</p><p>Before beginning your on-call shift, make sure you know how to view Latency, Traffic, and Fault for all of your services. Ideally, this information should be on a Dashboard.</p><h4><strong>Alarms</strong></h4><p>In the on-call world, the worst way to be notified of an incident or outage is by one of your customers telling you about it. This is why operations use alarms.</p><p>The metrics we covered in the previous section are very useful in and of themselves. However, they become much more useful if you hook up alarms to them when they cross a threshold. For instance, if you know that your service should only take 50 milliseconds to complete a request on average, then you should set an alarm to go off if the average latency stays above 60 milliseconds for a few minutes.</p><p>Make sure your alarms do not generate many false positives. In other words, don&#8217;t set them up to page your team for a blip. An exception to this could be if you have 24 hour coverage across many time zones, but even then you want the on-call to focus on actual problems and not transient issues.</p><h4>Synthetic Tests</h4><p>These test your service the same your consumers do and do so continuously, typically every minute. For a Web application, synthetic tests simulate user clicks to browse the Web applications and perform actions like logging in or purchasing an item. For an API, synthetic tests simply call the API and verify the results.</p><p>Synthetic tests should hook up to alarms. If a synthetic test fails (or fails a certain number of times above a threshold), the alarm should page the on-call.</p><p>Note that many services/teams do not have synthetic tests that run continuously. If your team doesn&#8217;t have them, then I highly recommend implementing them.</p><h4>Paging System</h4><p>Alarms should trigger a paging system that pages the on-call. Additionally, the paging system allows you to page your co-workers if you need assistance. Common paging systems include <a href="https://www.pagerduty.com/">PagerDuty</a> and <a href="https://www.atlassian.com/software/opsgenie">Opesgenie</a>.</p><h4><strong>Traces</strong></h4><p>Traces are a more advanced topic for on-call and will be covered more in-depth in a future post.</p><h4><strong>Your Application!</strong></h4><p>One of the first things I do when I get a page is to login to my application and see if I can reproduce the issue. For instance, if I am alarmed for high latency, I login to check if the application feels slow. If a certain feature is alarmed because it supposedly does not work, then I verify that.</p><p>The reason to do this is that sometimes the issue isn&#8217;t with your application. Instead, the issue is with the monitoring system! A non-working application that you have verified yourself is also a strong signal to start an outage bridge.</p><h4><strong>Dashboard</strong></h4><p>A dashboard displays your most useful metrics, logs, and alarms all in once place. If an alarm is triggered, then that should be apparent on your dashboard (usually it will be red and marked with an X instead of a green checkmark). So, make sure you know how to access your dashboards before starting a bridge.</p><p>If your team does not have a dashboard, you can create what I would call a &#8220;makeshift dash&#8221; by having handy links to each of your important metrics and alarms organized using bookmarks. Here&#8217;s a good bookmark hierarchy:</p><ul><li><p>Dashboard/</p><ul><li><p>ServiceA</p><ul><li><p>ApplicationURL</p></li><li><p>Latency</p></li><li><p>Traffic</p></li><li><p>Errors</p></li><li><p>Logs</p></li></ul></li><li><p>ServiceB</p><ul><li><p><em>&#8230;repeat</em></p></li></ul></li></ul></li></ul><p>Chances are that other team members who do on-call might have this setup already in their bookmarks. Ask them if they could export their bookmarks!</p><p>Dashboards are also useful for correlating data. For instance, let&#8217;s say your dashboard contains both a time series chart for request latency and for traffic (number of requests). You get alarmed for request latency. You check the dashboard and see that both latency and traffic have spiked. </p><h4><strong>Chat Software</strong></h4><p>If your company discusses outage in a chat product like Slack, go back a few months and read every message up until the current date. There might be an #incidents channel or something similar to that you can check out. You&#8217;ll likely learn a few things from this.</p><h3>Know your architecture and infrastructure</h3><p>Is your application running in the Cloud or in a data center? If it is in the cloud, which public cloud are you using? If there is an issue with the underlying cloud services or data center, are you responsible for engaging the provider/vendor or is there a dedicated team for that? Does your team manager your application on Virtual Machines? Is your application containerized? Is it running on a Serverless compute engine like AWS Lambda?</p><h4>Database</h4><p>Are you using a Relational Database or a NoSQL database or both? Do you have database administrators that can assist during on-call? If there is a database issue, do you have metrics or logs that would indicate that?</p><h4>Dependencies</h4><p>Do your services interact with other services owned by other teams? Those are you dependencies! Make sure you know how to contact/page the other teams in case an outage is caused by them. Additionally, if your service is called by other teams, make sure they know how to contact you.</p><p>Do your services interact with 3rd parties that are in your application&#8217;s critical path? A good example of a common, critical 3rd party dependency is using a service like Stripe to handle payments. If so, make sure you know how to contact their Support Team in case they bring your service down.</p><h3>Good luck!</h3><p>On-call can be rough. However, going into your shift prepared makes it <em>less</em> painful. I hope this post was helpful for you!</p><p></p><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>An engineer on one of my teams joined an outage bridge within a few weeks of joining the company. He found the issue before anyone else did.</p></div></div>]]></content:encoded></item><item><title><![CDATA[DevLife #1: Software Engineers should be on-call]]></title><description><![CDATA[The benefits of on-call outweigh the frustrations]]></description><link>https://sheepcode.substack.com/p/software-engineers-should-be-on-call</link><guid isPermaLink="false">https://sheepcode.substack.com/p/software-engineers-should-be-on-call</guid><dc:creator><![CDATA[Daniel Dersch]]></dc:creator><pubDate>Tue, 10 Jan 2023 12:20:46 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/6f634f07-110c-4872-bc5a-433c426ff939_1920x1280.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>My first four jobs as a software engineer had no on-call responsibilities.&nbsp;The whole concept of being an on-call engineer was foreign to me until I joined an IT/Cloud Operations organization that was responsible for the company&#8217;s primary SaaS service. </p><p>Most companies do not have on-call responsibilities for their software engineers. Development teams and operations teams are often intentionally kept separate. However, top performing software companies do tend to have on-call responsibilities for software engineers. This is often the case <em>even if</em> those companies additionally have dedicated SRE teams (like Google). </p><p>If you&#8217;ve never been on-call and have no plans to join a team with on-call responsibilities, you might be tempted to think this post isn&#8217;t for you. However, <em>this post is precisely for you.</em> I hope to motivate you to join an on-call team or appreciate the one you are on and what it does for you.</p><p>Let&#8217;s distinguish between support shift<em> </em>and on-call. While most software engineering teams do not have on-call, many of them do have support shifts. When assigned to support, the engineer is responsible for working tickets issued to their team from other teams. The difference between a support shift and on-call is that support shifts do not page engineers in the middle of the night when the service is down.</p><p><em>You should consider joining an on-call/True DevOps team for these reasons.</em></p><p><strong>On-call software engineers write more operationally efficient code. </strong>The working relationship between an operations org and a development org often ends up in a vicious cycle. Operations teams are frustrated because they are constantly up all night dealing with poorly planned upgrades and outages, and development teams are frustrated from being pestered with requests from ops. </p><p>A software engineering team that is responsible for all of their on-call responsibilities is a true DevOps team. The engineers on these teams write more operationally efficient code simply because they don&#8217;t want to be woken up in the middle of the night to respond to a page.</p><p>Tips for writing operationally efficient code will be covered in a later post.</p><p><strong>On-call will improve your troubleshooting skills</strong>. This will be the topic of a future post, but it is inherent that software engineers who wrote the code are best equipped to troubleshoot it when things go wrong. Beyond that, on-call will expose you to metrics, alarms, monitoring, log diving, etc. </p><p><strong>On-call gives you exposure throughout your organization via </strong><em><strong>the outage bridge</strong></em><strong>. </strong>If you&#8217;re an entry or mid-level engineer, then it is possible that the outage bridge could be the primary two-way interaction you have with your upper management. Furthermore, it is likely that people from adjacent teams will be on the bridge as well. This probably sounds scary (and it can be), but it is a huge opportunity. If you can be <em>the engineer</em> who people depend on during these bridges, then that could very well lead to advancement or improved opportunities. </p><p>It could even make you less likely to be laid off or fired. Often times, specific layoff decisions are made by management in a group setting. If your name comes up, management probably isn&#8217;t going to cut the people best at keeping the service running even if you&#8217;re one of the weaker coders on the team. A different manager might even vouch for you solely because of that.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">If I have at all inspired you to consider joining an on-call software engineer team, then I hope you&#8217;ll subscribe to this newsletter! I&#8217;ll have a lot more to write on this topic.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p><strong>Top software companies tend to have an on-call rotations for software engineers.</strong> The reason for this is that true DevOps/Engineers on-call is considered a best practice (for many of the reasons in this post actually). Top software organizations and startups tend to pay well, so it is worth becoming comfortable with on-call responsibilities if you wish to join one.</p><p><strong>On-call makes software engineers more familiar with IT Concepts tangental to coding</strong>. I&#8217;m not going to lie, before joining on-call teams I had very little exposure to many IT concepts and tools that I now consider to be vital to my career. Things like practical computer networking, deployment automation, load balancers, cloud, Linux, database optimization, configuration management, firewalls, etc were things that I had only superficial knowledge about. Understanding the environment my software runs in greatly affects the way I write code.</p><div><hr></div><p><strong>On-call isn&#8217;t for everyone</strong>. I&#8217;m not sure I&#8217;ve ever met anyone who loves being on-call. Getting paged at 2:00 am is only the start of the pain. On-call makes our profession more similar to that of being an ER Nurse/Doctor trying to quickly fix a problem without making it worse in the process (except usually people&#8217;s lives are not on the line in our profession). Outage bridges are undeniably stressful, especially when your leadership joins and asks difficult questions. Fixing a live production service disruption that <em>you caused </em>is more humbling than receiving a bug ticket the following morning when your Ops counterpart runs into it. Maybe you have a strict sleep schedule that can&#8217;t be disrupted.</p><p>There are ways to alleviate some of these hardships that I&#8217;ll cover in a future post. </p><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>I have seen this happen firsthand. A manager wanted to cut an employee, but other leaders didn&#8217;t allow it because &#8220;he was very helpful on bridges&#8221;. </p></div></div>]]></content:encoded></item><item><title><![CDATA[Sheep Code Enters 2023]]></title><description><![CDATA[Preview of what is to come]]></description><link>https://sheepcode.substack.com/p/sheep-code-enters-2023</link><guid isPermaLink="false">https://sheepcode.substack.com/p/sheep-code-enters-2023</guid><dc:creator><![CDATA[Daniel Dersch]]></dc:creator><pubDate>Tue, 03 Jan 2023 12:57:51 GMT</pubDate><enclosure url="https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/ad1c0af3-ae21-4c90-9d08-1dd82862963f_1280x1280.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Happy New Year! 2022 was one of the best years of my life both professionally and personally. I started my dream job at AWS. Our team was part of the <a href="https://codecatalyst.aws/">Amazon CodeCatlalyst</a> launch. Sheep Code was launched! My wife and I had our first daughter. The <a href="https://rolltide.com/">college football team</a> I cheer for didn&#8217;t have the season I wanted, but that&#8217;s OK. </p><p>When my daughter was born, I had to slow down my Sheep Code posts. My development team was also working toward a product launch, so I had very little mental space to allow me to write. However, with the New Year here, I am ready to pick things back up at full speed. Here&#8217;s what to expect this year.</p><h4>Name Change/Rebrand</h4><p>The name &#8220;Sheep Code&#8221; was never meant to be the permanent name of this newsletter. I plan on rebranding it to a new name this year. However, I still have not thought of a name! If you think of anything, please reach out.</p><h4>Series</h4><p>To make my posts a bit more navigable, I&#8217;m going to categorize posts into series. Names are pending, but here is what I have so far.</p><ul><li><p><em><strong>DevLife</strong></em> - these will be short posts about my work as a software engineer and other non management roles (like DevOps). I&#8217;m going to lean heavily into my individual experience on these posts.</p></li><li><p><em><strong>ProCode</strong></em> - infrequent, longer posts focused on exemplary software engineering. Some posts will contain code and diagrams. </p></li><li><p><em><strong>TheMgmt</strong></em> - these posts will focus on management at a tech company. The primary audience is for managers, people seeking to be in management, or those curious about what managers do at tech companies.</p></li></ul><p>Posts in a series will have one of those as the start of the title followed by a counter integer. For instance, the first DevLife posts might be titled &#8220;DevLife #0 My First Internship&#8221;<em>.</em></p><h4>Free posts</h4><p>The vast majority of my posts will not require a paid subscription. Any content I write specifically for beginners or people looking to get into tech will always be free. DevLife posts will almost always be free. ProCode posts will usually be at least partially free.</p><h4>Paid posts</h4><p>I do plan to write posts that require a paid subscription to access the full content. Posts where managements/executives are the primary audience are more likely to be paid. If a post requires a paid subscription I will <em>not </em>send an email to the free subscribers about it <em>unless</em> the post has free content in it that is useful. I don&#8217;t want to spam your inbox!</p><h4>What I won&#8217;t write</h4><p>I will never write posts that are overly critical of specific people or companies. Any negative examples I use will be annonymized. I don&#8217;t write gossip pieces either. I do appreciate other writers that ethically criticize companies, but that isn&#8217;t what this newsletter is about.</p><h4>Should you become a paid subscriber?</h4><p>At this point, I have not written any paid content. Thus, you should only become a paid subscriber <em>now </em>if you wish to support me and have the financial means to do so. My paid content will be directed at professionals and management. If you&#8217;re a beginner, please don&#8217;t feel like you need to become a paid subscriber! If my posts help you break into the industry, then once you get a job perhaps consider paying then.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Sheep Code is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h4>Sneak Peak</h4><p>I have a good number of unpublished drafts that I plan to finish this year and send. Here are some of them (titles will likely change):</p><ul><li><p>DevLife #?: How does on-call work?</p></li><li><p>DevLife #?: Getting the most out of 1-1s</p></li><li><p>DevLife #?: Navigating the dreaded outage bridge </p></li><li><p>DevLife #?: Balancing Security and Risk</p></li><li><p>DevLife #?: Devastating Angry Interteam Dynamics</p></li></ul>]]></content:encoded></item><item><title><![CDATA[Which programming language should you learn first?]]></title><description><![CDATA[Spoiler: I answer this question with a series of questions]]></description><link>https://sheepcode.substack.com/p/which-programming-language-should</link><guid isPermaLink="false">https://sheepcode.substack.com/p/which-programming-language-should</guid><dc:creator><![CDATA[Daniel Dersch]]></dc:creator><pubDate>Wed, 21 Dec 2022 14:27:55 GMT</pubDate><enclosure url="https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/907e94f1-fa42-4cca-b13d-35fb68ac7f59_1061x938.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>People eager to learn programming often ask me which programming language they should learn first. There are plenty of &#8220;wrong&#8221; answers to this question and a few good answers. Like, you really can&#8217;t go wrong with learning Python or JavaScript these days, but you probably shouldn&#8217;t start by learning FORTRAN. However, instead of giving them a straight answer, I ask them a series of questions. Here are some of them.</p><p><em>Why do you want to learn to code?</em> <em>Do you have time to learn how to code? Do you have any friends who know how to code? Or do you have friends that also want to learn how to code? Does your current employer have coding needs where you can get practical experience?</em></p><p>Most people who ask me about learning to code are ultimately seeking to gain employment in IT/Tech. They usually know at least one person who knows how to code (they know me after all), but often don&#8217;t know anyone else looking to learn (sometimes they do). Most of them are not working in jobs where it wouldn&#8217;t be easy to apply their coding skills. Almost all of them dramatically underestimate the level of effort most people need to learn programming.</p><p>Most them don&#8217;t know that IT/Tech consists of a whole lot more than just programming/software engineering. But there are other ways to get into tech than just knowing how to code! I firmly believe that coding is the most important skill for anyone in IT/Tech, but a systems administrator doesn&#8217;t need the same level of proficiency as a software engineer. A support engineer doesn&#8217;t necessarily need to have strong coding skills. A DBA mostly uses SQL. A product manager often doesn&#8217;t need to know how to code at all. A cloud administrator probably spends more time reading documentation and writing short scripts than full software. etc.</p><p>So before I recommend a programming language to start with, I often recommend taking a different path in tech than getting straight into software engineering. I encourage them to get into the industry in a role where coding skills are secondary and grow from there.</p><p>But if they&#8217;ve determined that they want to learn to code, here is some additional information I tell them.</p><p><strong>The most important aid you can get in learning to code is a mentor.</strong> Or even better find several mentors. You should reach out to your mentor when you need help. There&#8217;s a science to asking for help though. I&#8217;ll write a post later about this, but it basically boils down to &#8220;state your goal&#8221; and &#8220;try to be specific&#8221; when stating your problem. The reason for this is that your mentor is busy. Open ended questions take time to answer, but answering a specific question can often be written in 10 minutes or less and sent over email. On the other hand, a specific question with no context can be frustrating to answer because maybe the wrong question is being asked.</p><p>More importantly, a mentor can help you direct your growth. Most technical knowledge is valuable, but some knowledge is way more valuable for you than other knowledge. A mentor can help you choose the best path.</p><p><strong>The second most important aid you can get in learning to code are learning peers.</strong> These are people that are on the journey with you. These people will help keep you sane during the process. One thing to remember though is everyone learns at a different pace. If your peers are ahead of you or picking up stuff quicker than you, do not let that bother you. In fact, peers who are ahead of you can become mentors. That&#8217;s a good thing!</p><p><strong>Completing practical projects is the best way to learn programming.</strong> Notice I didn&#8217;t say this should be the only method. It also shouldn&#8217;t even be your first method. Before trying to tackle a project, you should first go over the introductory tutorial for your chosen programming language. You should then dive deeper into the documentation. Test what you learn with small snippets of code. Watch a Twitch stream of someone coding with your chosen language. After you&#8217;ve done all this, then it is time to pick a project and see it to completion.</p><p>At this point, you might notice that this method of learning suspiciously resembles school/college. Well, yeah it does. College is a good (but expensive in both time and money) way to learn. Self-driven learning is much cheaper in terms of money, but not everyone can do it.</p><p>Unfortunately, many people looking to get into IT/Tech don&#8217;t have friends that are already in the industry or looking to get into the industry. So you might think much of the above doesn&#8217;t apply to you. But it still does! </p><p><strong>Find online communities and influencers<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a> that you enjoy and provide value to you</strong>. Find virtual peers and mentors this way. Follow tech bloggers like me. Twitter/Slack/Discord/Telegram groups that focus on IT/Tech are great resources. Traditional forums are often great too.</p><p>So with all this said, I feel that I am ready to sort of answer the question of which programming language to start with. If know someone who is willing to mentor you, pick a language they know well because that is what they&#8217;ll be able to best help you with. If your have a peer group that leans toward a particular language, pick that language! If you find an online community that you find compelling, choose a programming language that community prefers.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://sheepcode.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>If you still haven&#8217;t figured out which language to pick, here are some suggestions sorted by focus. I also list some languages I recommend beginners to <em>avoid</em>.</p><p><strong>Data Science</strong></p><p>Choose one of these languages if you work with datasets.</p><ul><li><p><strong>Python</strong> - Great language for data science. Numpy and Pandas are your friends and so is Jupyter notebooks. I would recommend Python over R because Python is used widely in the industry and not just for data science. Honestly, Python could show up in every category.</p></li><li><p><strong>R</strong> - statisticians love R and use it. RNotebooks is pretty cool too. I used it a good bit while I was studying at Georgia Tech. Ultimately, if you&#8217;re getting into data science, you&#8217;ll need to know R.</p></li></ul><p><strong>Software Engineering</strong></p><p>We write large software products and services.</p><ul><li><p><strong>Java</strong> - boring but reliable OOP language that is EVERYWHERE. Java has a ton of language features, so mastering it will teach you almost everything you need to know about programming (except for pointers). Will also teach you to fear Null. Once you&#8217;ve become competent with Java you should consider moving on to Kotlin.</p></li><li><p><strong>Go</strong> - simple language that will force you to think about error handling and introduce you to the dangers of pointers. Excellent language for learning the basics of programming because it doesn&#8217;t give you as many shortcuts that languages like Python do. Go is probably my favorite language, and I miss it.</p></li><li><p><strong>SQL</strong> - all software engineers need to know how to work with databases. Sure, NoSQL databases are an option these days but SQL can even be used with DynamoDB. SQL is a great second language to learn.</p></li><li><p><strong>Avoid C/C++</strong> people will hate me for this, but you shouldn&#8217;t start with these languages. A vast amount of incredibly useful software is written in these languages, and you should consider learning them if you want to become an open source contributor to incredible projects like the Linux kernel or Git. But these languages are hard. </p></li></ul><p><strong>Game Development</strong></p><p>Game developers create video games. I actually don&#8217;t know much about game development, so I&#8217;ll do my best with this one.</p><ul><li><p><em>yiiiikes</em>. <strong>C++</strong> is apparently the most common language used for game programming. I am so sorry. Maybe choose Web development instead?</p></li><li><p><strong>C#</strong> - a good alternative and similar to Java. C# is used for programming in Unity. It is much easier to write than C++. C# was also the first programming language I learned, so it holds a special place in my heart. Please start with C# instead of C++. </p></li></ul><p><strong>Linux Systems Administrator</strong></p><p>A linux systems administrator usually is writing scripts that are under 10,000 lines long. Often, they are much shorter.</p><ul><li><p><strong>BASH</strong> - the bourn again shell. Anyone who wants to administer Linux systems should learn bash. Looping is painful, but piping commands together is awesome.</p></li><li><p><strong>Python</strong> - you&#8217;ll use Python for any task too frustrating to complete with BASH (or at least that is what I do).</p></li><li><p>Avoid <strong>Perl</strong>. I don&#8217;t know how this language happened, but it is ugly.</p></li></ul><p><strong>DevOps Engineer</strong></p><p>A DevOps Engineer deploys, updates, and monitors live software services.  They also tend to get paged at 2:00 am. </p><ul><li><p><strong>BASH</strong> - All DevOps engineers need to know some BASH.</p></li><li><p><strong>Ansible</strong> - not really a language, but it sort of is. Lets you make your BASH scripts run on thousands of machines.</p></li><li><p><strong>Go</strong> - Terraform, Docker, and  Kubernetes are both written in Go. Chances are, you&#8217;ll extend one of these and doing so will require you to write Go. Go is also simple enough that learning it is much easier than complicated languages like Java.</p></li><li><p><strong>Python</strong> - seeing a pattern yet? </p></li></ul><p><strong>Web Development</strong></p><p>Web developers make Websites. This includes the code that runs on the frontend and on the server. A couple of languages are widely used for both.</p><ul><li><p><strong>JavaScript</strong> - all the code running in your browser is JavaScript. Additionally, JavaScript is widely used for server side development as well. </p></li><li><p><strong>TypeScript</strong> - makes JavaScript better and safer. It&#8217;s probably better to start with JavaScript though and learn TypeScript as a second language. Anything JavaScript can do, TS can do better!</p></li></ul><p><strong>Database Administrator</strong></p><p>A DBA works with relationship database management systems like Postgresql or MySQL.</p><ul><li><p><strong>SQL</strong> - has many variants, but the base language is generally the same or similar. Watch out for how different SQL variants use quotes. </p></li></ul><p>I hope you enjoyed reading these suggestions. Python of course appears the most on the list. If you want to learn a language and be effective with it fast, then Python is probably a good bet. However, there are many programming language features and concepts that Python will not teach you. Things like pointers, memory allocation, static types etc just don&#8217;t exist in Python. A language like Java would give you a more complete experience. </p><p>One thing to remember is that you don&#8217;t have to wait until you master a language before learning another one. Instead, focus on becoming proficient. Once proficient, there&#8217;s no reason to not try picking up another language. I guarantee you the second one will be easier than the first (unless you started with Python and then try C). </p><p>Once you&#8217;ve picked up a few language, you&#8217;ll want to start learning about <strong>Design Patterns</strong><a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a>. Or, you might read up on why many Design Patterns are now much, much easier to implement due to functional programming concepts becoming so ubiquitous.</p><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>I feel like the term &#8220;influencer&#8221; has a negative connotation with it. I don&#8217;t mean it in a negative way though.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-2" href="#footnote-anchor-2" class="footnote-number" contenteditable="false" target="_self">2</a><div class="footnote-content"><p>Design patterns are mostly just applicable for software engineers and Web developers. I assume they are important for Game development as well, but I have no idea.</p></div></div>]]></content:encoded></item><item><title><![CDATA["Good Tech Things" by Forrest Brazeal]]></title><description><![CDATA[I highly recommend checking out Forrest's work.]]></description><link>https://sheepcode.substack.com/p/good-tech-things-by-forrest-brazeal</link><guid isPermaLink="false">https://sheepcode.substack.com/p/good-tech-things-by-forrest-brazeal</guid><dc:creator><![CDATA[Daniel Dersch]]></dc:creator><pubDate>Thu, 15 Dec 2022 01:30:33 GMT</pubDate><enclosure url="https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/f29760a8-59af-4216-b4c3-44a0932ea77b_96x96.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Forrest Brazeal just launched his rebranded newsletter and Website <a href="https://newsletter.goodtechthings.com/?utm_source=homepage_recommendations&amp;utm_campaign=975522">Good Tech Things</a>.  I highly recommend you go check it out and subscribe! If I&#8217;ve already convinced you, just go over there and don&#8217;t even bother reading the rest of this post!</p><p>I&#8217;ve known Forrest for a decade or so now. He has something for everyone.</p><p><strong>Looking to get into IT/Tech</strong>? Check out the <a href="https://cloudresumechallenge.dev/">Cloud Resume Challenge</a>. I have worked with several really outstanding individuals who got into DevOps by completing the challenge.</p><p><strong>Do you need a good laugh</strong>? <a href="https://www.goodtechthings.com/">Go look at his cartoons</a>. </p><p><strong>Are you longing to listen to someone make all of the AWS services into a song</strong>? <a href="https://www.youtube.com/watch?v=BtJAsvJOlhM&amp;list=PLPUSFL3ut4ibHYoBes2tku_XUOHbpTFJZ">He&#8217;s done that too</a>.</p><p>He also writes <a href="https://newsletter.goodtechthings.com/p/on-building-a-personal-brand-in-tech">serious posts</a> sometimes, but you can just follow me for those, right? </p><p></p>]]></content:encoded></item><item><title><![CDATA[ChatGPT: 7 Bold Predictions for AI Assisted Programming]]></title><description><![CDATA[Will large language models take over?]]></description><link>https://sheepcode.substack.com/p/chatgpt-7-bold-predictions-ai-assisted</link><guid isPermaLink="false">https://sheepcode.substack.com/p/chatgpt-7-bold-predictions-ai-assisted</guid><dc:creator><![CDATA[Daniel Dersch]]></dc:creator><pubDate>Tue, 06 Dec 2022 13:22:39 GMT</pubDate><enclosure url="https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/a1611e09-1c4a-419a-be94-ccba4910aaea_1600x1600.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a href="https://openai.com/">OpenAI</a> recently released <a href="https://openai.com/blog/chatgpt/">ChatGPT</a> for anyone to use on their Website. ChatGPT is a large language model that can have conversations with you and much much more. If you haven&#8217;t checked it out yet, you should consider doing so before reading the rest of this post. ChatGPT content <a href="https://twitter.com/search?q=%23chatgpt">has exploded on Twitter as well</a>.</p><p>For brevity, when I refer to AI, in this post I mean large language models like ChatGPT.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://sheepcode.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>Here are my predictions:</p><p><strong>AI assisted programming will result in increased efficiency for programmers who embrace it</strong>. AI will bootstrap new projects. It will help you find bugs. It will implement algorithms for you. It will write code much faster than you can. It will document your code. It will explain your code. It will write tests for you. It will improve your code. etc. <a href="https://aws.amazon.com/codewhisperer/">Amazon CodeWhisperer</a> and Github Copilot were just the beginning.</p><p><strong>AI assisted programming will not reduce the need for programmers, but it will reduce the demand for programmers who refuse to use AI</strong>. Programmers who utilize AI will have advantages over those who don&#8217;t. If an AI can generate unit tests for your application in seconds what would take you an hour, then you should take advantage of the AI. I personally do not think there will be many (if any) types of programming where AI will not be of great assistance. Think of it this way. When high level languages like FORTRAN were released, did it kill the demand for assembly programmers? Yes and no. Very few companies these days have any need for assembly programmers, but some do and pay very well. Meanwhile, pretty much every software company needs programmers who write in high level languages. </p><p><strong>AI won&#8217;t be able to deliver complex end-to-end applications for a long time</strong> but when it can, product managers and designers will become programmers. By end-to-end, I mean applications that can be fully written and incrementally improved by AI with very minimal human programmer intervention. By complex, I mean anything more complicated than a CRUD application with a frontend slapped onto it.</p><p><strong>Fully managed platforms for AI generated applications will become common</strong>. This is the shortcut to AI being able to deliver end-to-end applications quickly. Companies will design platforms with composable parts with a natural language interface to create applications and run them on the platform. The tech is already to the point where this should be possible so I expect to see it very soon.</p><p><strong>AI competition will be fierce</strong>. OpenGPT will not be the only player. There will be a community of AIs with many tuned to specific domains and at differing price points. I imagine annual competitions will AI will compete on problem sets specifically designed to be challenging for AI.</p><p><strong>Utilizing AI will be a skill. </strong>The existence of AI won&#8217;t mean that everyone will get the same value out of it. Think of it this way. Learning how to efficiently get accurate information on the Internet is a skill that takes time to develop. Google made that easy, but even crafting a Google search query that will give you the results you want is a skill. You&#8217;ll need to recognize when the AI is wrong. You&#8217;ll need to understand where AI is better than you and where its limitations are. Additionally, selecting which AI to use for certain tasks will be important. </p><p><strong>Educators will adapt to AI availability</strong>. Just as Google search made it much easier for students to cheat, so will AI. That said, educators will develop teaching methods that both allow students to learn from AI and prevent students from using AI to cheat. Will verbal exams become a thing again? As an aside, I graduated from Georgia Tech&#8217;s <a href="https://omscs.gatech.edu/">OMSCS</a> program back in 2018 (I think!). Ironically, one of the most difficult courses I took there was &#8220;<a href="https://omscs.gatech.edu/cs-6601-artificial-intelligence">Artificial Intelligence</a>&#8221;. The final exam in this class was a take home exam that took me a week to complete. However, I am confident that OpenGPT could have solved all of the problems for me. So I think that AI will present challenges to online education.</p><p>I hope you enjoyed this post!</p>]]></content:encoded></item><item><title><![CDATA[Workarounds as Proof of Experience]]></title><description><![CDATA[Overcoming limitations is valuable experience]]></description><link>https://sheepcode.substack.com/p/workarounds-as-proof-of-experience</link><guid isPermaLink="false">https://sheepcode.substack.com/p/workarounds-as-proof-of-experience</guid><dc:creator><![CDATA[Daniel Dersch]]></dc:creator><pubDate>Fri, 23 Sep 2022 20:34:37 GMT</pubDate><enclosure url="https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/e46a58a2-898e-4c81-8a36-609380209836_89x81.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>We used Google Cloud Platform (GCP) at one of my previous employers. I led our Cloud Center of Excellence team. Part of leading a team like that is keep up-to-date with all changes that your vendors make. This isn&#8217;t so hard to do because they tend to have handy release/new pages. </p><p>For instance, I visited the following pages every day:</p><ul><li><p><a href="https://aws.amazon.com/new/">https://aws.amazon.com/new/</a></p></li><li><p><a href="https://cloud.google.com/release-notes">https://cloud.google.com/release-notes</a></p></li><li><p><a href="https://www.hashicorp.com/blog">https://www.hashicorp.com/blog</a></p></li></ul><p>In my current role, I have less need to visit these pages every day, but I still do every once in a while. Today, on GCP&#8217;s release notes page, I saw this change:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FHIW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40c42f4-c2ea-4a57-a43d-8538e7e81fbd_885x327.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FHIW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40c42f4-c2ea-4a57-a43d-8538e7e81fbd_885x327.png 424w, https://substackcdn.com/image/fetch/$s_!FHIW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40c42f4-c2ea-4a57-a43d-8538e7e81fbd_885x327.png 848w, https://substackcdn.com/image/fetch/$s_!FHIW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40c42f4-c2ea-4a57-a43d-8538e7e81fbd_885x327.png 1272w, https://substackcdn.com/image/fetch/$s_!FHIW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40c42f4-c2ea-4a57-a43d-8538e7e81fbd_885x327.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FHIW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40c42f4-c2ea-4a57-a43d-8538e7e81fbd_885x327.png" width="885" height="327" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/f40c42f4-c2ea-4a57-a43d-8538e7e81fbd_885x327.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:327,&quot;width&quot;:885,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:68673,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FHIW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40c42f4-c2ea-4a57-a43d-8538e7e81fbd_885x327.png 424w, https://substackcdn.com/image/fetch/$s_!FHIW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40c42f4-c2ea-4a57-a43d-8538e7e81fbd_885x327.png 848w, https://substackcdn.com/image/fetch/$s_!FHIW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40c42f4-c2ea-4a57-a43d-8538e7e81fbd_885x327.png 1272w, https://substackcdn.com/image/fetch/$s_!FHIW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40c42f4-c2ea-4a57-a43d-8538e7e81fbd_885x327.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">From the GCP release notes. Automation engineers rejoice!</figcaption></figure></div><p>These Cloud SQL updates GCP made stuck out to me because the previous functionality was a source of frustration for my team. Let me explain.</p><p>Previously, deleting a Cloud SQL Instance did not release the Instance name from whatever GCP&#8217;s backend name pool is. Why? I have no idea, but I suspect GCP might wisely <em>keep your database around for a while</em> after you &#8220;delete it&#8221; just in case one of their big customers has second thoughts<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a>. Maybe GCP wants to be the hero when they get the following message from a customer:</p><blockquote><p>&#8220;Hello Google, we didn&#8217;t actually mean to delete our production user database that we forgot to take backups on. Is there anything you can do? Also, our spend is $5 million a month with you&#8221;. </p></blockquote><p>So if this is wise of GCP then why was it frustrating for my team? </p><p>Consider the case where you are a cloud engineer. Part of your job is developing automation and testing that it works. This might involve running and re-running Terraform commands such as <strong>plan</strong>, <strong>deploy</strong>, and <strong>destroy</strong>. You might run this on the following snippet to create a database instance called <strong>receipts</strong>:</p><pre><code>resource "google_sql_database_instance" "main" {
  name             = "receipts"
  database_version = "POSTGRES_14"
  region           = "us-central1"

  settings {
    tier = "db-f1-micro"
  }
}</code></pre><p>Straightforward and not so bad! However, once you destroy it and run it again, you&#8217;d get something like this message<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a> after running Terraform plan/apply:</p><pre><code>Error: database name "receipts" already exists</code></pre><p>Do you see our source of frustration now? Once you use a name, it sticks around for a while after being deleted which means you have to pick a new name each time you fully test the automation! To workaround this frustration, we&#8217;d do stuff like this:</p><pre><code>resource "random_id" "name" {
  byte_length = 8
}

resource "google_sql_database_instance" "main" {
  name             = "receipts-${random_id.name.dec}"
  database_version = "POSTGRES_14"
  region           = "us-central1"

  settings {
    tier = "db-f1-micro"
  }
}</code></pre><p>This makes the code only slightly more complicated and your database instance names won&#8217;t be as clean. Like, I would rather look at <strong>receipts</strong> in the console than <strong>receipts-37563856</strong>!</p><p>But now GCP has fixed this&#8230;two years late to make my life simpler, but it&#8217;s good to see they fixed it.</p><p>So why write about this frustration of mine? I hope you&#8217;ll keep reading&#8230;</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Sheep Code is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><p>One of major differences between an experienced engineer and someone new to the field is that the experienced engineer will have gone through problems and frustrations like the one above. And of course they find workarounds to those problems. You really can&#8217;t easily learn these things without experiencing them for yourself because they are rarely present in the official documentation or training materials. It is often simple to Google the answers to these problems but not always. This is why <strong>real world experience is better than certifications and training.</strong> </p><p>I&#8217;ll also add that finding a workaround to a problem will help you solve similar problems in the future or avoid them altogether. From our example, the &#8220;workaround lesson&#8221; is that uses suffixes in your cloud resource names can help you avoid problems!</p><p>Anyways, your troubles will vary based on whatever technology you use. Here are some from my experience that you might find fun or had the misfortune of experiencing yourself:</p><ul><li><p><strong>Kubernetes</strong> - if you&#8217;ve used Kubernetes, then you&#8217;ve almost definitely been burned by the <a href="https://kubernetes.io/blog/2021/04/06/podsecuritypolicy-deprecation-past-present-and-future/">now deprecated PodSecurityPolicy</a>. This monster caused us SO many headaches at my roles where we used Kubernetes.</p></li><li><p><strong>Terraform</strong> - <a href="https://github.com/hashicorp/terraform/issues/19932">ever tried looping over a provider</a>?</p></li><li><p><strong>AWS CDK</strong> - Stack Exports for inter-stack references are magic <a href="https://github.com/aws/aws-cdk/issues/3414">until you have to remove one</a>.</p></li></ul><p>When interviewing an engineer for a cloud engineering role, one of my favorite questions is &#8220;what frustrations have you had with &lt;insert-tool-here&gt;&#8221;? If an engineer has no frustrations with a tool, then they probably don&#8217;t have much experience with it. It&#8217;s also feels pretty validating when I hear people have had the same problems I have had but maybe that&#8217;s selfish.</p><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>DO NOT DELETE YOUR IMPORTANT DATABASES TO TEST THIS OUT. THIS IS SPECULATION ON MY PART.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-2" href="#footnote-anchor-2" class="footnote-number" contenteditable="false" target="_self">2</a><div class="footnote-content"><p>I made up this message. Now that GCP has changed the functionality, I can&#8217;t reproduce it. I hope you&#8217;ll forgive me.</p></div></div>]]></content:encoded></item><item><title><![CDATA[Confessions of a 10x AWS Certified LinkedIn User]]></title><description><![CDATA[I'm done with IT certifications but that doesn't mean you should be.]]></description><link>https://sheepcode.substack.com/p/confessions-of-a-10x-aws-certified</link><guid isPermaLink="false">https://sheepcode.substack.com/p/confessions-of-a-10x-aws-certified</guid><dc:creator><![CDATA[Daniel Dersch]]></dc:creator><pubDate>Mon, 19 Sep 2022 12:11:02 GMT</pubDate><enclosure url="https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/239b1104-949b-410a-a6ed-49e11ca629f9_252x252.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>My cloud certification journey began in 2017. I read one of those &#8220;<a href="https://www.pcmag.com/news/highest-paying-it-certifications">top</a> <a href="https://www.globalknowledge.com/us-en/resources/resource-library/articles/top-paying-certifications/#gref">paying</a> <a href="https://www.comptia.org/blog/top-paying-it-certifications">IT</a> <a href="https://www.whizlabs.com/blog/highest-paying-it-certifications/">certifications</a>&#8221; articles you see from time to time. The salaries listed for the various AWS certifications were significantly higher than my salary as a software engineer at the time, so I wanted to see whether the hype was real or not. So I set out on a journey of obtaining as many certifications as possible as fast as possible. This is partially what my gmail inbox looks like when I search &#8220;CertMetrics&#8221;:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5f2n!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0e06ead-0070-412f-aed3-fbb7054fa8eb_1279x758.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5f2n!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0e06ead-0070-412f-aed3-fbb7054fa8eb_1279x758.png 424w, https://substackcdn.com/image/fetch/$s_!5f2n!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0e06ead-0070-412f-aed3-fbb7054fa8eb_1279x758.png 848w, https://substackcdn.com/image/fetch/$s_!5f2n!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0e06ead-0070-412f-aed3-fbb7054fa8eb_1279x758.png 1272w, https://substackcdn.com/image/fetch/$s_!5f2n!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0e06ead-0070-412f-aed3-fbb7054fa8eb_1279x758.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5f2n!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0e06ead-0070-412f-aed3-fbb7054fa8eb_1279x758.png" width="1279" height="758" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/d0e06ead-0070-412f-aed3-fbb7054fa8eb_1279x758.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:758,&quot;width&quot;:1279,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:334033,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5f2n!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0e06ead-0070-412f-aed3-fbb7054fa8eb_1279x758.png 424w, https://substackcdn.com/image/fetch/$s_!5f2n!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0e06ead-0070-412f-aed3-fbb7054fa8eb_1279x758.png 848w, https://substackcdn.com/image/fetch/$s_!5f2n!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0e06ead-0070-412f-aed3-fbb7054fa8eb_1279x758.png 1272w, https://substackcdn.com/image/fetch/$s_!5f2n!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0e06ead-0070-412f-aed3-fbb7054fa8eb_1279x758.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">inbox of a habitual exam taker</figcaption></figure></div><p>I&#8217;m not going to go over study tips in this post. There are plenty of prep resources elsewhere. You can see above the general order in which I took the exams though. One frustration I experienced through my certification journey was the &#8220;moving target&#8221;. My goal was to obtain ALL AWS certifications which I think did a couple of times, but AWS kept releasing new certifications! I eventually moved on to obtaining Kubernetes and GCP certifications. You can see many of my <a href="https://www.credly.com/users/daniel-dersch">certifications (and past certifications) here</a> if you&#8217;re interested.</p><p>So yeah I&#8217;m one of those obnoxious<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a> 10x cloud certified people you see on LinkedIn from time to time (or at least I used to be)!</p><h3>So was the cloud certification hype real?</h3><p><strong>For my compensation, the hype was real.</strong> After achieving 8 or so AWS certifications (I eventually got 10), my next salary (from switching jobs) increased by 50%. I had multiple comparable offers like this. Additionally, one company I worked for started offering large bonuses (5k-10k) for each additional certification achieved. So getting certified can definitely improve your compensation though it is not guaranteed. You still have to successfully interview!</p><p><strong>For my knowledge, the hype was real</strong>. Before beginning my AWS certification journey, I worked with AWS everyday while wearing multiple hats (Admin/Dev/DevOps/etc). My team administered a non-production AWS account, and we also worked on our company&#8217;s CI/CD tooling. I already knew a lot about AWS! <em>But getting certified forced me to learn more</em>. This is especially true if you take certifications that are less related to your role. For instance, I&#8217;ve never worked in a Big Data role so getting the &#8220;Big Data&#8221; certification (rip<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a>) forced me to learn about Hadoop. </p><p><strong>For job hunting, certifications can be helpful</strong>. Many companies take cloud certifications very seriously (while some do not care at all). I was actually shocked by how easy some of the interviews were. Interviewers often assumed I was cloud competent so they didn&#8217;t really ask technical questions and instead focused on whether I was a cultural fit or not (this is scary btw! As an interviewer don&#8217;t do this!). On a side note, cloud consulting companies take certifications more seriously than most anyone else because having certified employees is often part of their brand.</p><p><strong>Certifications can streamline an interview process</strong> at some companies. Think of it this way. DevOps/Cloud Center of Excellence/Cloud Engineering teams require engineers with broad experience and set of skills. One of the difficulties interviewers face is figuring out how to fairly interview a candidate based on their resume. For instance, a Cloud Center of Excellence team needs people with software engineering, linux administration, cloud knowledge, DevOps, CI/CD, infrastructure as code, IT knowledge, etc. Most candidates will only have some of those qualifications. As an interviewer, it is more fair to focus on what the candidate claims to know for these types of roles. When an interviewer sees certifications on a resume, they immediately can ask questions that a certified individual should know. This makes it easier for an interviewer to interview you!</p><p><strong>Certifications do not replace experience</strong>. I would usually prefer to hire a candidate with experience than a certified candidate with no experience. There&#8217;s no replacement for actually using the technology. However, you CAN get experience outside of work by doing personal projects or challenges! I highly recommend the <a href="https://cloudresumechallenge.dev/docs/the-challenge/aws/">Cloud Resume Challenge</a> if you are in a situation where you have certifications but no real world experience. Not all employers will count this as relevant experience, but some will (and should IMO). </p><h3>I&#8217;m personally &#8220;done&#8221; with certifications</h3><p>Regardless of all these benefits, <strong>I do not plan to renew most of my cloud certifications. </strong>Why? Keep reading.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://sheepcode.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Sheep Code is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p><strong>Recertification sucks</strong>. Since I achieved most of my certifications within a few months of each other, I basically had to re-certify most of them at around the same time.  I did choose to re-certify the AWS Professional exams. The rest I let lapse or am going to let lapse. My GCP Professional Architect certification expired this past month in fact! For me, re-taking an exam every few years that I have already passed in the past (heh) is uninteresting. I would prefer to focus my time on my work and family than taking exams.</p><p><strong>I&#8217;ve reached diminishing returns.</strong> While pursuing more certifications could improve my knowledge, it isn&#8217;t likely to improve my compensation. Furthermore, any additional IT knowledge I need, I can simply gain by reading the docs and trying out the tech.</p><h3><strong>Beware of fraudulently certified people</strong></h3><p>I have interviewed hundred of candidates throughout my career for software engineering, cloud engineering, DevOps engineering, Cloud Architect etc. Often, I interviewed candidates that fall into one or more of the following buckets:</p><ul><li><p>claim to be certified but can&#8217;t prove it</p></li><li><p>are certified but can&#8217;t answer basic cloud questions</p></li></ul><p>Unfortunately, cheating is rampant for certification exams. Cheaters either get someone else to take the exam for them or study &#8220;exam dumps&#8221; that have exact questions that another test taker copied directly from the exam. Either case can lead to an individual being fraudulently certified.</p><p>However, it is pretty easy to identify these people during an interview by asking basic cloud questions. For instance, every AWS certified individual should know the following:</p><ul><li><p>The difference between an AWS region and an availability zone</p></li><li><p>Be able to simply explain what S3 is</p></li><li><p>What IAM Roles are used for</p></li></ul><p>A certified individual should know a lot more than these, but if they can&#8217;t answer these then that is an indicator that they could possibly be fraudulently certified.</p><h3>AWS Certifications for an SDE at AWS</h3><p>So is being AWS certified important for working as a software development engineer at AWS? </p><p><strong>Being AWS certified did not directly help me become an SDE at AWS</strong>. The interview process for an SDE is focused around problem solving with code, system design, and leadership principles. The interviewers do not assume the candidates know anything about AWS and rightfully so because not every software engineer has experience with AWS!</p><p><strong>The knowledge gained from being AWS certified has tremendously benefited me at AWS. </strong>The reality is that I was able to onboard and become a (hopefully!) productive member of my team much quicker because of the certifications I achieved. Many teams at Amazon (including mine) leverage AWS services extensively. Services/tools such as CloudFormation, EC2, CDK, DynamoDB are very important to know. I would go as far to say that SDEs at AWS who don&#8217;t learn the core services that their team use <em>will struggle</em> to be effective members of their team.</p><h3>Miscellaneous Confessions</h3><p>These are fun.</p><p><strong>You might be able to pass some exams with &#8220;minimal prep&#8221;. </strong>AWS used to have an &#8220;Alexa Certified Skill Builder&#8221; exam. A few of my friends and I signed up for it on the first data of its beta. Instead of doing extensive prep for it, we crammed for it the night before and shared notes before taking it. </p><p>We all passed.</p><p>In reality, the &#8220;Alexa Skill Builder&#8221; certification could have been called the &#8220;Serverless&#8221; certification + Alexa. We passed because we used Serverless at work extensively. So you could say that our work experience was the true prep.</p><p>I tried doing the same thing with the Machine Learning AWS exam. That didn&#8217;t go so well, but fortunately Amazon gives a free retake if you fail a beta exam :D (or at least they did at the time).</p><p><strong>Adding a certification badge to your Outlook signature might make people respect you more</strong>. <em>Or it might not</em>. I did this after getting my first few certifications, and I feel like I got less pushback whenever asking engineers to tighten up their IAM permissions. However, I also was in a meeting where someone rolled their eyes at this, so some people might find it obnoxious. I guess just know your company culture before adding the signature.</p><p><strong>I usually think I failed at the end of every exam.</strong> I don&#8217;t know how this can be since I usually get pretty good scores. But the moment I hit the &#8220;submit&#8221; or &#8220;end test&#8221; button, this moment of dread fills my soul. <em>Did I just waste $300 of my employer&#8217;s cash</em>? <em>What if I fail and someone asks me how it went?</em> And speaking of which&#8230;</p><p><strong>Surveys at the end of exams </strong><em><strong>before scores are shown </strong></em><strong>are HELL</strong>. Please stop doing this test administrators! I know people are more likely to take the survey if they can&#8217;t see their score without it. However, my heart rate is faster while taking those surveys than during the <a href="https://www.espn.com/college-football/game/_/gameId/401403868">final minute of Bama&#8217;s football game vs the Texas Longhorns</a> a couple weeks go.</p><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>This is a joke! Please do not be offended if you are one of these people!</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-2" href="#footnote-anchor-2" class="footnote-number" contenteditable="false" target="_self">2</a><div class="footnote-content"><p>AWS has discontinued the Big Data certification and replaced it with an Analytics exam that covers roughly the same material.</p></div></div>]]></content:encoded></item></channel></rss>