<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Adam Hammond</title>
    <description>The latest articles on DEV Community by Adam Hammond (@hammotime).</description>
    <link>https://dev.to/hammotime</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F172883%2F0c63425f-253a-4966-97fa-f20a82851c5f.jpeg</url>
      <title>DEV Community: Adam Hammond</title>
      <link>https://dev.to/hammotime</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hammotime"/>
    <language>en</language>
    <item>
      <title>Error Budgets and their Dependencies</title>
      <dc:creator>Adam Hammond</dc:creator>
      <pubDate>Thu, 25 Feb 2021 11:40:46 +0000</pubDate>
      <link>https://dev.to/squadcast/error-budgets-and-their-dependencies-1871</link>
      <guid>https://dev.to/squadcast/error-budgets-and-their-dependencies-1871</guid>
      <description>&lt;p&gt;&lt;em&gt;Does your team struggle with not having balanced error budget, that impacts your reliabilty &amp;amp; pace of innovation? &lt;a href="https://www.linkedin.com/in/adamhammondqld/" rel="noopener noreferrer"&gt;Adam Hammond&lt;/a&gt; in his latest blog talks about error budget - accountable for planned &amp;amp; unplanned outages that your systems may encounter &amp;amp; how teams can calculate error budget efficiently.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In our last few articles, we’ve &lt;a href="https://www.squadcast.com/blog/choosing-slos-that-users-need-not-the-ones-you-want-to-provide" rel="noopener noreferrer"&gt;discussed SLOs&lt;/a&gt; and how important &lt;a href="https://www.squadcast.com/blog/how-small-changes-to-your-slos-can-be-smart-for-your-business-a-narrative-case-study" rel="noopener noreferrer"&gt;picking them correctly&lt;/a&gt; can make or break for your application’s performance. Today we’re going to cover error budgets, which are used to account for planned and unplanned outages that your systems may encounter. In essence, error budgets exist to cover you when your systems fail and to allow time for upgrades and feature improvement. No system can be expected to be 100% performant, and even if it were, you need to have time available for maintenance. Activity like database major version upgrades can cause significant downtime &lt;strong&gt;when&lt;/strong&gt; they occur. Error budgets allow you to plan ahead and put aside time for your team to manage their services while providing customers with lead time so that they can plan for the downstream impacts of your service going offline.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;An introduction to service calculations&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;There is an easy trap to fall into when it comes to determining your error budgets. Calculating your error budgets - as with everything in regards to process improvement - is a journey. Most people would usually say “well, my error budget is simply the left-over time once my SLO is taken away” and that formula for them might look like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Error Budget = 100% - Service SLO&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, this is incorrect and is “starting at the end”. This is definitely your aspirational error budget, but it doesn’t take into account your service’s current performance and what the current state of your service’s error budget is. The initial equation for your error budget is as follows:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Error Budget = Projected Downtime + Projected Maintenance&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you remember from our previous article on SLOs, we need to do a lot of research into understanding factors like how performant our customers expect our system to be, but another part of that is, understanding maintenance and existing application error rates. The projections will most likely track very closely to your past performance, unless your service’s performance has been widely variable in the past. When you first define your error budget, it is acceptable to baseline it against what your service can currently provide. If you can only deliver an SLO of 85%, there is no point promising 90%. However, once you have established your baseline error budget, you must never allow it to move below your starting point. Error budgets decrease, they do not increase. The first port of call for most organisations when implementing their error budget is to focus on maintenance as you usually get the best “bang for buck”; there are usually processes that can be improved or better software versions to be installed. This is where your SRE teams come in to help deliver streamlined, automated, and focused software pipelines that minimise application downtime. Move away from manual, labour intensive processes and single-click developer experiences to minimise intentional error budget usage.&lt;/p&gt;

&lt;p&gt;The point of error budgets it to allow you to focus on where your product improvement hours are spent. New features can be implemented if you have not utilised your error budget, consider service improvement if it is nearly consumed, and you absolutely must focus all resources on stabilizing your service if your error budget is in deficit. Ultimately, an error budget is designed to help you understand where you should focus your engineering resources to ensure your SLOs are met. The final stage of our error budget baseline is to compare it against the SLO that we intend to maintain for our service. We can do this by simply reverting to our calculation from the beginning:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Expected Service SLO = 100% - Error Budget&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is at this point, that you can determine the immediate direction you need to take in regards to service improvement. If your error budget is running higher than expected, you should focus on reducing it. Once you’ve completed your initial service improvements to bring your error budget into line (if any was required), you can then finally use the “simple” calculation to determine your error budgets:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Error Budget = 100% - Service SLO&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The important thing to note is that things like customer expectations serve as minimums in terms of SLOs, so we don’t include them in our initial calculations. At the beginning of our error budget journey, we are understanding our current state and in a lot of cases, it is probably less than the desired target. Another key aspect to keep in mind is that if our SLO performance is ever less than the minimum, then we need to reduce our &lt;strong&gt;actual&lt;/strong&gt; error budget via service improvement as soon as possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What is downtime, really?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In our calculations, we separated our downtimes into two categories: unexpected and maintenance. To properly calculate our error budgets, we need definitions for what “downtime” is, in general, and then we also need to differentiate between the two categories. For our purposes, a suitable definition for downtime is “systems are not in a state to meet the required metric”. This specifically targets the SLO and it’s associated metric.&lt;/p&gt;

&lt;p&gt;We then further define our two categories, with “maintenance downtime” being “downtime caused by an intentional disruption due to system maintenance” and “unexpected downtime” simply being “all other downtime”. We differentiate between these two types of downtime not specifically to build the error budget, but to provide us with guidance on how we can improve them. For example, if we want to reduce maintenance we need process improvement, but if we want to reduce unexpected downtime we probably need to fix bugs or errors within our services. These categories provide strategic guidance on where we need to look for potential error budget savings when we need to deliver better service to our customers.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Calculating our error budgets&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now that we have all of our required definitions and formulas, now it’s a simple process to actually calculate our error budgets. In fact, a quick visit to our maintenance procedures and our metrics dashboard should suffice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Determine our total downtime by retrieving our current monthly error rates from our metric dashboards.&lt;/li&gt;
&lt;li&gt;Find out how much downtime is scheduled for our maintenance each month.&lt;/li&gt;
&lt;li&gt;Calculate our unexpected downtime amount by subtracting scheduled downtime from actual error rates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now we have our three metrics: total downtime, maintenance downtime, and unexpected downtime. Now, let’s return to Bill Palmer at Acme Interfaces, Inc for a practical look at how effective error budgets can be, and how we can use all of this information to calculate them appropriately.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;“Help, Bill! The system is too slow!”&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Bill Palmer sat at his desk, exasperated. Acme Interfaces had been putting off their database upgrade for years. He received an email from their cloud provider today, advising that the database would be upgraded forcibly if no action was taken in the next four months. Coming in at 15TBs and feeding into over 500 interfaces, their database was at the heart of the business. As part of the upgrade, everything would need to be tested along with the actual upgrade itself. Bill required hours for the upgrade, but it actually looked like Acme Interfaces was going over their error budget by a few minutes every month. Now that their cloud provider had forced their hand, something needed to be done.&lt;/p&gt;

&lt;p&gt;He pulled up an excel spreadsheet with service metrics and began looking for places for a quick win.&lt;/p&gt;

&lt;p&gt;Within a few minutes, he’d found what looked like the root of their error budget deficit. Looking at the error reporting for HTTP requests over the last year at Acme Interfaces, relatively simple requests were returning HTTP 50X errors at quite large volumes and for unknown reasons. He’d made a promise to Dan that he’d get the error rate lower than 10% to get the error budget back in surplus for the upgrade; it was time to get to work. He looked at the detailed statistics and noticed that about half of the errors were 503s and 504s, and the other half were 500s. He just didn’t understand how there could be so many transport errors.&lt;/p&gt;

&lt;p&gt;He picked up his phone and dialed the NOC.&lt;/p&gt;

&lt;p&gt;“&lt;em&gt;Ring, Ring…. Ring, Ring….&lt;/em&gt; Hello, Acme NOC, this is Charlie.”&lt;/p&gt;

&lt;p&gt;“G’day Charlie, this is Bill, the CTO, do you have a few minutes to discuss some statistics I’m reviewing.”&lt;/p&gt;

&lt;p&gt;“Sure, Bill.”&lt;/p&gt;

&lt;p&gt;“Excellent. I’m just taking a look at our HTTP error codes  for the past year and for some reason we return a lot of bad gateway and service unavailable errors, do you know why that would be the case?”&lt;/p&gt;

&lt;p&gt;“Sure do, Bill. Our load balancer software is on a really old version. It’s got a bug, where it hits a memory leak and won’t be able to parse requests back from the backend servers. That’s what throws the 502s. After a few minutes, the server will restart but because it is our load balancer we can’t easily take it out of service so we return 503s. We used to have to manually restart the servers, but we implemented a script that checks for health and can reboot within a few minutes.”&lt;/p&gt;

&lt;p&gt;Bill paused for a few moments. “...Is there a reason why the infrastructure team hasn’t upgraded to a new version of the load balancer?”&lt;/p&gt;

&lt;p&gt;“Well, that’s the problem, we don’t really have anyone dedicated to the load balancers. They were setup up a few years ago as part of a project, and now the NOC just fixes them up when they go a bit crazy. The vendor has confirmed that the newer version of the software doesn’t have the bug but we just don’t have the expertise to manage that at the moment. We also restart them all at night which takes about an hour which would cause 503s.”&lt;/p&gt;

&lt;p&gt;“Okay, well thanks for the information, Charlie. I’ll see what we can do. &lt;em&gt;click&lt;/em&gt;”&lt;/p&gt;

&lt;p&gt;Bill started to write up all the information he had gained from the phone call with Charlie.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F601a608ac5fc8353a0f3d71f_image1%2520%281%29.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuploads-ssl.webflow.com%2F5c9200c49b1194323aff7304%2F601a608ac5fc8353a0f3d71f_image1%2520%281%29.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After he was done, he called Jenny.&lt;/p&gt;

&lt;p&gt;“Jenny, can you please do me a favour and find out how much a System Administration course for our Load Balancing software would be, please?”&lt;/p&gt;

&lt;p&gt;“Sure, is this about those HTTP errors?”&lt;/p&gt;

&lt;p&gt;“You know it!”&lt;/p&gt;

&lt;p&gt;Bill continued to look at the whiteboard, and just knew the fastest way to improve performance would be to bring the load balancer up to scratch, and get the NOC team up-skilled to handle these systems. They’ve been improving these systems in spite of not having any official training, so they definitely are great operators.&lt;/p&gt;

&lt;p&gt;Bill’s phone rang, “Bill, it’s Jenny. I just got off the phone with them and they said they could do a 20% discount on the training with a group larger than 10 people and that it would be $10,000 a head.”&lt;/p&gt;

&lt;p&gt;“Okay, get back to them and book in two sessions of 15 people each. I want the whole NOC to be up-skilled on the Load Balancer immediately. Draw up a project proposal for shift-left knowledge transfer from some of the application teams as well as SRE development for the NOC team. Their skills are wasted waiting for fires to break out, I know they can get this environment up to where it needs to be.”&lt;/p&gt;

&lt;p&gt;“Sounds good, I’ll get onto it now!”&lt;/p&gt;




&lt;p&gt;Bill surveyed the room, taking in the hundreds of leaders from across Acme Interfaces, as he prepared to talk about his team’s development over the last six months.&lt;/p&gt;

&lt;p&gt;“Hi everyone, I’m sure most of you know me by now, but I’m Bill, the new-ish CTO. Today I’m going to be talking about how we were able to eliminate a major barrier to our database upgrade by analysing and refining the error budgets for our HTTP requests.”&lt;/p&gt;

&lt;p&gt;“Six months ago, we were seeing an error rate on HTTP requests of up to 15% per month which was well above our expected error budget of 10%. About 5% of these were caused by application errors, but 8.5% of these errors were being seen at the load balancer and were due to availability issues. We wanted our error budget to be 10% or less request errors, but we were tracking 5% above that. We had to improve something if we wanted to meet that target.”&lt;/p&gt;

&lt;p&gt;“I got onto the NOC and spoke with Charlie who enlightened me to some issues we were having with our load balancer: it hadn’t been updated for a few years and a bug was causing all these errors. Further exacerbating the issue, no one with the skills to actually upgrade the load balancer worked at the company so that wasn’t an immediate option.”&lt;/p&gt;

&lt;p&gt;“Jenny got onto the vendor and arranged training for the entire NOC. Within three weeks they were all skilled up, then we began our project to upgrade the load balancers. With everyone skilled up, it only took us two weeks to upgrade all of the servers and we were able to do this during downtime that was previously reserved for maintenance (otherwise known as restarting servers due to the bug). We’ve also begun transitioning all of the existing NOC operators to new SRE-based roles that will allow them to assume greater responsibility for the improvement of our core infrastructure.”&lt;/p&gt;

&lt;p&gt;“Within two months of defining our current state error budget, we had used them to identify where our issues were coming from, resolved those issues, and, now we’ve been able to meet (and exceed) our target of less than 10% HTTP request errors. We’ve also used the experience to refine our NOC and give our staff greater responsibility.”&lt;/p&gt;

&lt;p&gt;“I’d heartily recommend everyone has a look at the internal error budgets that you are responsible for, as I am very sure that it can only have positive outcomes for the business. Thanks for attending my session, and I hope the rest of the retreat goes well.”&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://www.squadcast.com/" rel="noopener noreferrer"&gt;Squadcast&lt;/a&gt; is an incident management tool that’s purpose-built for SRE. Your team can get rid of unwanted alerts, receive relevant notifications, work in collaboration using the virtual incident war rooms, and use automated tools like runbooks to eliminate toil.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://app.squadcast.com/register/" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuploads-ssl.webflow.com%2F5c51758c58939b30a6fd3d73%2F5e16013f80ad26b00925d758_image--5--1.png"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>slo</category>
      <category>bestpractices</category>
    </item>
    <item>
      <title>How small changes to your SLOs can be SMART for your business - A narrative case study</title>
      <dc:creator>Adam Hammond</dc:creator>
      <pubDate>Wed, 25 Nov 2020 11:08:07 +0000</pubDate>
      <link>https://dev.to/squadcast/how-small-changes-to-your-slos-can-be-smart-for-your-business-a-narrative-case-study-2dje</link>
      <guid>https://dev.to/squadcast/how-small-changes-to-your-slos-can-be-smart-for-your-business-a-narrative-case-study-2dje</guid>
      <description>&lt;p&gt;&lt;em&gt;In the second part of his "&lt;a href="https://www.squadcast.com/blog/choosing-slos-that-users-need-not-the-ones-you-want-to-provide" rel="noopener noreferrer"&gt;Choosing SLOs that are appropriate for our customers&lt;/a&gt;" blog, Adam Hammond, narrates a fictional case study through Bill Palmer, one of the protagonists of &lt;a href="https://www.squadcast.com/blog/must-read-devops-sre-books-for-all-engineers" rel="noopener noreferrer"&gt;The Phoenix Project&lt;/a&gt; and shows "How small changes to your SLOs can be SMART for your business"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In our previous blog, we discussed why you need to choose SLOs that are appropriate for your customers. We don’t always write out S M A R T and list our SLOs immediately. The process is organic, and it may take a while. Most business have a rigorous reporting and metric gathering regime, and in most situations, you will just need to tweak this to get the desired results.&lt;/p&gt;

&lt;p&gt;To elaborate more, in this blog, we will focus on a fictional company named “Acme Interfaces, Inc” (Acme) who already have &lt;strong&gt;M&lt;/strong&gt;easurable, &lt;strong&gt;A&lt;/strong&gt;chievable, and &lt;strong&gt;T&lt;/strong&gt;imebound SLOs. Bill Palmer, one of the protagonists of The Phoenix Project, is jumping into the newly formed role of CTO. He is going to help Acme reform their SLOs so that they’re &lt;strong&gt;S&lt;/strong&gt;pecific and &lt;strong&gt;Relevant&lt;/strong&gt; for their customer’s needs and their business strategy. Despite consistently met internal and external service levels and fantastic feedback scores, customers are rushing away from Acme. It’s Bill’s job to figure out why and restore Acme to its previous glory.&lt;/p&gt;




&lt;p&gt;“Bill, we’ve got a problem here but I’m not sure what it is. Steve said you were great at fixing difficult problems; I’m hoping you can do that here. Our sales are down, and our long term customers are getting ready to leave. We need help fast.” Dan looked across at me, a grim expression on his face, negative analyst briefings were strewn across his desk.&lt;/p&gt;

&lt;p&gt;“I’ve had a bit of experience with this. It’s extraordinary - I’ve looked through the service level reports for the last two years: reported internal metrics have been stable.” I put a report from my hand onto the table. “No breaches of external SLAs.”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--T6X3Bjg5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/5fab8128613db684bd4dc455_image5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--T6X3Bjg5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/5fab8128613db684bd4dc455_image5.png" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;
All requests with a Status Code of 2XX and total volume of requests



&lt;p&gt;I put down another stack of paper. “...and customer satisfaction looks great.” I top the stack off with a print of the customer satisfaction dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ySzOTKSj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/5fab81618d1411676119d9be_image1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ySzOTKSj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/5fab81618d1411676119d9be_image1.png" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;
NPS for Acme Interfaces, Inc of customers with spending higher than US$250,000



&lt;p&gt;Dan looks at me and exhales heavily “you’ve found the same things as we have. Everything looks fine, but everything is not fine. The company was going great under our previous CEO, Nick, but as soon as we diversified our customer base, we started having problems. Our customers want our product until they use it and we can’t close long-term contracts. When we were a one customer company, we didn’t have these problems.”&lt;/p&gt;

&lt;p&gt;He pulls a paper from the stack I placed on the table and pulls out the twelve-month rolling satisfaction report and a second customer churn report with it as well. “What I don’t understand is how we can have an NPS score of 8.2, but our churn is close to 80% after a year of using our product. I need your help.”&lt;/p&gt;

&lt;p&gt;I sat and thought about the situation for a little bit. It was definitely a unique situation. “Look, I’ve got some ideas. I need a pre-sales business analyst to help me understand the current business profile and what our history a bit better.”&lt;/p&gt;

&lt;p&gt;Looking back at me with a bemused expression, Dan picks up the phone “John, send in Jenny.” He put the phone down. “Well, you’re definitely on the right track. Jenny is our business engagement lead. She can help you out with at least a third of what you’re after. She knows everyone; Jenny can sort you out.”&lt;/p&gt;

&lt;p&gt;Jenny opened the doors and walked in, nodded at Dan and then looked at me. “Bill, I take it?”&lt;/p&gt;

&lt;p&gt;“That’s me, ready to jump into it?” I asked. She nodded back at me.&lt;/p&gt;




&lt;p&gt;“Bill, I’ll be honest. Our biggest problem is Globex Corporation.”&lt;/p&gt;

&lt;p&gt;“You’re saying that our largest customer is our biggest problem?” Bill looked slightly quizzically at Jenny as she sipped her coffee.&lt;/p&gt;

&lt;p&gt;“Frankly, yes. As our first customer; Nick always prioritised what they wanted. But that’s the problem: they’re large and cumbersome. What they want is not what the market wants. They’ve had decreasing sales year-on-year, and, all of their feature requests have been perceived negatively by new customers in direct user surveys.”&lt;/p&gt;

&lt;p&gt;Bill scratched his chin. “I’m not saying I don’t believe you, but how do you explain all of our metrics that look great.”&lt;/p&gt;

&lt;p&gt;Jenny smiled grimly at Bill. “That’s an easy answer: all of our SLAs have been designed to look after Globex and no one else. Take a look here.” Jenny pulled out a stack of paper that looked very similar to the one that Bill gave to Dan. “Customers over $250,000, we only have one of those: Globex. All of our other customers pull out before larger contracts, or they never go further with our product. Nick tailored every single SLA to Globex; they don’t care about latency because they predominantly use our interfaces for driving their reporting engine. Their reports take a week to run each quarter. All of our metrics are around volume, but none focus on service quality.”&lt;/p&gt;

&lt;p&gt;Bill flicked through the papers Jenny had put in front of him, eyeing each one closely. “Well... You’re right, how has this not been picked up before?”&lt;/p&gt;

&lt;p&gt;“Nick had a strict ‘clean dashboard’ policy. He didn’t want to see raw data; he just wanted dashboard views. He was unequivocal that as far as he was concerned, data would confuse industry analysts and that they just needed to provide positive results. Coupled with his intense focus on Globex, it just ended up that everything focuses on them and the market responds because they are a significant source of revenue for us. Of course, that has had problems now that Dan has been trying to diversify our client base.”&lt;/p&gt;

&lt;p&gt;Bill sat quietly for a few minutes. “So… I think I have a way out of this. Can you please get me some data?”&lt;/p&gt;

&lt;p&gt;“Sure, what do you need?” Jenny pulled up a document on her iPad.&lt;/p&gt;

&lt;p&gt;“Please send me the engagement reports we have for all of our leads and clients. I want to specifically focus on what problems our customers are trying to solve with our products. Please also have the BI team send me the raw data for customer surveys and a separate data set which shows NPS of customers that exited our platform. Also have the SRE team send me the stats on response times for requests, as well as the status code breakup for a rolling twelve-month period.”&lt;/p&gt;

&lt;p&gt;Jenny finished typing out the list of statistics and looked back to Bill. “I’ll have these back to you by tomorrow morning.”&lt;/p&gt;




&lt;p&gt;“Well Dan, we’ve discovered the problem.”&lt;/p&gt;

&lt;p&gt;Dan’s face lit up as Bill sat down in front of him. “You what!? How did you do that? It’s only been two weeks.”&lt;/p&gt;

&lt;p&gt;Bill sighed heavily. “Well, we’ve found the problems, but I’m afraid it’s going to require substantial work to fix them.”&lt;/p&gt;

&lt;p&gt;Dan’s smile faltered slightly. “How bad is it?”&lt;/p&gt;

&lt;p&gt;“It’s quite bad, Dan. All of the stats our commercial team use for our Service Level Objectives are not suited to the market and our template SLA only satisfies the needs of Globex Corporation. I sincerely doubt if anyone except Globex has had a good time using our platform.”&lt;/p&gt;

&lt;p&gt;Dan leaned back in his chair. “Don’t pull any punches, Bill. Tell me how bad it is.”&lt;/p&gt;

&lt;p&gt;“Our NPS across our entire customer base is four. On average, 11.5% of our requests fail per month, which can be up to 23%. Anyone using our platform APIs for real-time activity has found it to be non-functional under load.”&lt;/p&gt;

&lt;p&gt;“...But, how can this be? All of our data has been so good. We’re still making our revenue targets. How have we missed this?”&lt;/p&gt;

&lt;p&gt;“I said it before; our reporting focuses on Globex corporation. They use our platform for their extensive quarterly reporting, so all of our SLO reporting has targeted this use case. The problem is our market is not interested in using our product for reporting - they want to use our real-time APIs for generic use cases so they can focus on their core development tasks. Diversifying is not working because our platform is not built for the markets we’re trying to break into.&lt;/p&gt;

&lt;p&gt;“Here’s the most prominent example we could find of reporting that looks really great but isn’t. Nick had these SLAs determined based on Globex using the system for reporting.” Bill picks up a sheet and places it in front of Dan.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0puh8Pir--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/5fab831f188e4d4f906bbb47_image4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0puh8Pir--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/5fab831f188e4d4f906bbb47_image4.png" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;
Percentage Breakdown of Major Status Codes



&lt;p&gt;“This looks good, but look what happens when we remove the ‘202’ status codes, which just means the system is processing a request.”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QY9xO076--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/5fab83467fa4390b49890ae6_image2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QY9xO076--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/5fab83467fa4390b49890ae6_image2.png" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;
Percentage Breakdown of Major Status Codes excluding 202s



&lt;p&gt;“As you can see, in reality, we’re barely meeting what would be considered a proper SLO for our systems. If we want to increase our market, we need to make some drastic technology changes now and update our SLOs to meet the expectations of potential customers.”&lt;/p&gt;

&lt;p&gt;“Well, Bill. You’ve done this before, what do you suggest?”&lt;/p&gt;

&lt;p&gt;“Dan, with the help of the SRE Team and Jenny, we’ve been able to build a plan.” Bills pulls out his phone and sends&lt;/p&gt;

&lt;p&gt;We investigated the cause of most of the errors, and it seems like there are issues with IOPS on the database. The first step is to migrate our storage to at least 5000 provisioned IOPS so we can meet the real-time request demand. The SRE team has already upgraded that. Here’s the rest of our plan to normalise our performance and track our progress. Here is our planned SLA, with both internal and external SLOs to help us meet our customer expectations.”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--t1TZtosA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/5fab83b23e5e928acd5d1fcb_image3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--t1TZtosA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/5fab83b23e5e928acd5d1fcb_image3.png" width="502" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;“Our most obvious problem was our reporting metrics for request failures. We’ve added more specific wording so that reporting requests do not dilute our metrics. To support this, we’ve added an internal SLO for IOPS to be monitored by the SRE Team. We found that after waiting 5 seconds, our software would error when a result wasn’t returned. Increasing IOPS eliminated most of our request failures.”&lt;/p&gt;

&lt;p&gt;Dan looked over at Bill, surprised. “What do you mean most?”&lt;/p&gt;

&lt;p&gt;“I mean, we only had an average 1.2% failure rate. We’ve also changed up our NPS reporting to include all paying customers, and we’ve also lowered our targets because we cannot possibly meet an NPS target of 8, given the reality of the situation.”&lt;/p&gt;

&lt;p&gt;“That’s fair enough; I’m fine with explaining the difference to industry analysts.” Dan motioned for Bill to continue.&lt;/p&gt;

&lt;p&gt;“Finally, we have a new internal SLO for new customer NPS average of 8. That might sound crazy, but we found that almost all of our customers that failed to contract predominantly complained of slow request response times. We think that by ensuring our request times are lower than 250 milliseconds, we can retain most of our new customers and they will be promoters.”&lt;/p&gt;

&lt;p&gt;Dan was silent for a few moments as his eyes rolled over the documents that Bill had placed in front of him.&lt;/p&gt;

&lt;p&gt;“Okay Bill, I like the look of all these changes, what can you guarantee me in terms of customer retention? After all, that’s the biggest problem. I don’t want to move focus away from Globex if it’s not going to increase our operating performance.”&lt;/p&gt;

&lt;p&gt;“Well, that’s the thing, Dan. After working with Jenny, we think we can get 80% customer retention on new sales if we implement these targets. Almost all of our customers said they loved the system when it worked. They just need it to be performant, and they will come. Jenny thinks she’ll be able to reach out to some former customers and get them to sign back up with us for a new trial, too. We went out and met the customers, understood what they wanted, and we made sure that these new SLOs were specific and attainable. These aren’t numbers we’ve picked from a hat; this is science. We already had a great system in place for metric measurement and monthly reporting; we just needed to tune it correctly.”&lt;/p&gt;

&lt;p&gt;“Okay, you’ve got six months. I want to see all of these SLOs met and the customer retention numbers. If it all works, out we can announce our results the month after and make our new SLA public at the same time.”&lt;/p&gt;




&lt;p&gt;Bill stood up in the boardroom, buttoned his coat and walked up to the lectern.&lt;/p&gt;

&lt;p&gt;“Thank you all for the opportunity to demonstrate our progress before we announce our results tomorrow.”&lt;/p&gt;

&lt;p&gt;“Six months ago, everyone here believed we had rock-solid SLOs, a great SLA with our target clients, and a great reporting system. That was true for our old market, but not for the new. Dan came to me looking to transform our business so that we could diversify our client base and grow as a business.”&lt;/p&gt;

&lt;p&gt;“Our first step in solving this problem was to look at the data we’d been using and look for any discrepancies; there were a few. Our main problems were our focus on a single client, and some issues with what we considered to be a successful client request. After changing the parameters of our reporting to match what we wanted our company to be delivering, it was immediately clear that our system was failing a lot more than we thought, and our customers were not having their expectations met.”&lt;/p&gt;

&lt;p&gt;“The first thing we did was resolve the root cause of our system failures, which was rather simple. This hadn’t been caught earlier because our SRE team was focused on another set of goals that aligned with assisting Globex Corporation, our primary customer. Simply, our storage was not keeping up with our systems, and we just needed to upgrade it which was relatively straight forward.”&lt;/p&gt;

&lt;p&gt;“Our second issue, which was our primary focus, took a little longer to resolve fully. Over the past six months, we’ve moved resources away from supporting predominantly reporting interfaces to real-time interfaces, and we’ve adjusted our SLOs to focus on non-reporting response times. With the great work of our developers tuning their code, and the SRE team tuning our web servers, we’ve seen our response time drop below our target of 250ms, in the last two months.”&lt;/p&gt;

&lt;p&gt;“These two issues were not our only problem, and we made sure to include all of our paying customers in our NPS surveys. We also put an internal focus on making sure our new customers were fully satisfied with the product, and any small issues they had were prioritised on the development pipeline. This increased our overall NPS on paper to 8.75, but six months ago our NPS was only 6 in our first all-customer survey.”&lt;/p&gt;

&lt;p&gt;“Overall, a strong focus on our vision for where we wanted to be, making sure our goals were aligned with that vision, and then re-focusing our existing SLO and SLA reporting has seen us expand our revenue by 35% and see 85% of new customers stay with our product. We understood our market, listened to our customers, and responded accordingly.”&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;PRESS RELEASE FOR IMMEDIATE CIRCULATION&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Acme Interfaces, Inc sees explosive growth over the last half, attributes success to Know-Your-Customer approaches and SMART Service Level development.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;After implementing a significant change that empowered our SRE and Sales Teams, we’ve been able to drive 85% new customer retention and see a 35% increase in revenue. Our average Net Promoter Score (NPS) has increased by 0.5 to 8.75, even though we’ve expanded our survey base to all our paying customers. We’re also introducing a new customer-focused SLA today that should provide a performant base for all of our customers to depend on as we move into the future.&lt;/p&gt;

&lt;p&gt;A big thanks to our CTO Bill Palmer and our new Head of Business Development Jenny Masters who spearheaded the internal development of our new SLO and SLA offering.&lt;/p&gt;

&lt;p&gt;Did you enjoy this piece of content written in a narrative case study format? We would love to hear your thoughts! Leave us a comment or reach out over a DM via &lt;a href="https://twitter.com/squadcasthq?lang=en" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://www.squadcast.com/" rel="noopener noreferrer"&gt;Squadcast&lt;/a&gt; is an incident management tool that’s purpose-built for SRE. Your team can get rid of unwanted alerts, receive relevant notifications, work in collaboration using the virtual incident war rooms, and use automated tools like runbooks to eliminate toil.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://app.squadcast.com/register/" rel="noopener noreferrer"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cj1VUnAS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c51758c58939b30a6fd3d73/5e16013f80ad26b00925d758_image--5--1.png" width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>sre</category>
      <category>slo</category>
      <category>bestpractices</category>
    </item>
    <item>
      <title>Choosing SLOs that users need, not the ones you want to provide</title>
      <dc:creator>Adam Hammond</dc:creator>
      <pubDate>Wed, 18 Nov 2020 10:52:46 +0000</pubDate>
      <link>https://dev.to/squadcast/choosing-slos-that-users-need-not-the-ones-you-want-to-provide-59eh</link>
      <guid>https://dev.to/squadcast/choosing-slos-that-users-need-not-the-ones-you-want-to-provide-59eh</guid>
      <description>&lt;p&gt;&lt;em&gt;In our latest two-part series blog, Adam Hammond, talks about how you can build sustainable SLOs that are appropriate for your users, your technology platform, and your business which in turn will help you make your systems robust, your customers happy, and your business boom.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Service Level Objectives (SLOs) are a powerful operational tool that uses metric-based targets to constrain activities that may have a negative impact on users (such as maintenance or failed deployments). Traditionally, you may have heard it being used in contractual terms within Service Level Agreements (SLAs), where SLOs are used to identify guarantees for IT platforms (SaaS, IaaS, PaaS, etc.). However, they are far more than that: SLOs are a powerful tool that can be used not only by the “business people” but also by technical staff to drive process improvement and technological advancement. SLOs have a formidable use as metric-based indicators that show you what needs to be improved in your systems, its capabilities, and where you can get your best “bang for buck” when it comes to focusing your work efforts. However, SLOs must be influenced by data, and that data can only come from your customers. A lot of IT professionals tend to think that they know the best metrics, and they do; the only problem is that they are the best metrics for monitoring systems, not for improving customer satisfaction. Today, we’re going to help you build sustainable SLOs that are appropriate for your users, your technology platform, and your business that will help you make your systems robust, your customers happy, and your business boom.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Asking the right questions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now that we have an idea of what SLOs are, we need to go about establishing a data-based approach that will result in positive user outcomes. This is a two-stage process that involves data gathering and then using that data to build your SLOs. The source data for these questions come from three main places: your users, your system, and your business processes. Prepare to go out and talk to clients on zoom calls, trawl through logs, and understand the maintenance and support lifecycle of your system. There is no prescription for these questions, they are subjective, and everyone’s scenario will be different. It is also important to remember the Pareto Principle: 80% of your users use about 20% of your system. Therefore you will get the best value out of this exercise by targeting and providing SLOs for the most commonly used parts of your system.&lt;/p&gt;

&lt;pre&gt;

  &lt;b&gt;Example Questions&lt;/b&gt;

  - When do my users actively or passively use my system?

  - How much maintenance do I need to perform and how regularly does
    it need to be?

  - What tolerance would my users have for outages?

  - Would your users consider your application critical to your 
    business?

  - How well is my system performing at the moment?

  - What levels of performance do my users require?

&lt;/pre&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Determining SLOs&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When you have finished your data gathering exercise, it is time to focus on actually setting your SLOs. SLOs will generally - but not always - fall into the following categories:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6I7xYByQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/5f7435b4ddda8d6bfa5fd6b1_article_2_infographic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6I7xYByQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/5f7435b4ddda8d6bfa5fd6b1_article_2_infographic.png" width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These categories cover most of the things that people consider to be aspects of quality. They also translate easily into metrics that you can use to objectively measure your system against the requirements of your SLOs. Finally, when you define your SLOs, remember that a good SLO should be &lt;strong&gt;S.M.A.R.T.&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;S&lt;/strong&gt;pecific: an SLO should expressly state what it measures (e.g. we want to measure availability by testing whether a request can be made to the server, not we want the server to be up).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;M&lt;/strong&gt;easurable: the SLO should be something that can be measured (e.g. disk latency should be less than 5ms, not the disk should be quick).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A&lt;/strong&gt;chievable: you should be able to meet your SLOs (e.g. if an underlying service has an SLO of 95%, you cannot guarantee 100%).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;R&lt;/strong&gt;elevant: your SLO should reflect the user experience (e.g. an appropriate metric for a web server is response time, not CPU activity).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;T&lt;/strong&gt;imebound: an SLO should cover a period that is appropriate for how your system is used (e.g. if your users only use your system between 9 AM and 5 PM, a 24-hour SLO will only dilute your actual metrics and hide issues).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, let’s get down to creating an SLO. Whether an SLO is achievable or relevant is not pertinent to the specific wording required, but it dictates whether a particular SLO should be set. For example, if the average time to retrieve a file is five minutes, you would not guarantee that the file can be delivered faster than that (because on average, it won’t). Alternatively, if your users only care that files are consistently, but eventually delivered to them then a retrieval time-based SLO is probably not for you. In this case, the best SLO would be one that guarantees that a proportion of files are always delivered to users, regardless of time to retrieve and deliver (i.e. percentage of successful retrievals).&lt;/p&gt;

&lt;p&gt;Once we’ve determined that an SLO is appropriate, let’s get the SLO down on paper. Remember, we need to make sure that the wording is &lt;strong&gt;S&lt;/strong&gt;pecific, &lt;strong&gt;T&lt;/strong&gt;imebound, and that it is &lt;strong&gt;M&lt;/strong&gt;easurable. If it is not all of these things, then it simply cannot be used as an SLO. Let’s consider an example. A system processes stock trades and all requests need to be finalised within 300ms as dictated by a regulatory body. The company running the system wants to offer an SLO that requests, on average, over 30 days are completed faster than 250ms. The system currently responds to 98% requests within 232ms on a 30-day rolling average. The SLO text would look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ug6hpGsU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/5f743660ca1ae1091756f591_article_2_paragraph_breakdown_image.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ug6hpGsU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c9200c49b1194323aff7304/5f743660ca1ae1091756f591_article_2_paragraph_breakdown_image.png" width="800" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Is this a good SLO? Yes. The system already exceeds the SLO, so it is &lt;strong&gt;A&lt;/strong&gt;chievable. There is a legal requirement that requests are finalised within the SLO limits, so it is &lt;strong&gt;R&lt;/strong&gt;elevant. We are &lt;strong&gt;S&lt;/strong&gt;pecific with the metric we want to guarantee our performance against, which is the request response rate. We have limited our SLO to a 30-day period, which allows us to run reporting that is &lt;strong&gt;T&lt;/strong&gt;imebound. Finally, our metric is &lt;strong&gt;M&lt;/strong&gt;easurable via a Prometheus metric. We have met all the requirements for a SMART SLO that has been tailored to the user experience.&lt;/p&gt;

&lt;pre&gt;

  &lt;b&gt;How to account for maintenance and scheduled downtime in your SLOs&lt;/b&gt;

  Everyone needs to maintain their systems; some are highly available
  and have no downtime, while others need some downtime. The simple
  answer is to bake your maintenance into the SLO. If you know you
  can provide 97% availability for a system over a month, but you
  need 14 hours of maintenance (2%), then only offer 95%. It is
  better to underpromise and overdeliver than be red-faced (and out
  of pocket) because your system has been offline (and you expected
  it).

&lt;/pre&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Providing Better Service (and Increasing your SLO guarantees)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now that we have our SLOs, they’re SMART, but… we are just not meeting our targets (or want to exceed them). What do we do? We need to make our systems performant enough to overcome this challenge. While demanding in terms of effort, this is right in the SRE wheelhouse, and will predominantly rely on your expertise and knowledge to improve your system performance. If users require faster requests, streamline your proxy config. If disk reads are too slow, consider high IOPS or higher throughput alternatives. If batch jobs are taking too long, right-size the instances so that they process in the correct amount of time. Some more difficult approaches may include changing your operating system, database platforms, or, even development frameworks. It entirely depends on your ability to analyse and understand the factors in your system that affect your SLOs and mitigating those issues through proper SRE practice.&lt;/p&gt;

&lt;p&gt;There are also other options aside from the more technical approach: improved monitoring and disaster recovery. By improving your monitoring, you can ensure that problems are caught before they affect your SLOs. Your disaster recovery plan is key to managing and maintaining your SLOs. Disasters come when we least expect them, so practising and improving DR procedures means that if disaster strikes, you are able to restore service as quickly as possible. This will limit the overall impact to SLOs by ensuring that any disaster downtime is limited to only that which is strictly necessary to recover your systems.&lt;/p&gt;

&lt;p&gt;Using these processes, you can deliver SLOs that will please your users and make their experience with your systems a delight. By meeting (and hopefully, exceeding) their expectations, you will build lifelong customers that will evangelise your business and products.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;To be Continued...&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In the second part of this blog, we will be looking at an example based on Bill from &lt;a href="https://www.amazon.com.au/Phoenix-Project-DevOps-Helping-Business-ebook/dp/B078Y98RG8" rel="noopener noreferrer"&gt;The Phoenix Project&lt;/a&gt; that will highlight how “achieving SLOs” is not always good for business if those SLOs aren’t derived from customer needs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.squadcast.com/" rel="noopener noreferrer"&gt;Squadcast&lt;/a&gt; is an incident management tool that’s purpose-built for SRE. Your team can get rid of unwanted alerts, receive relevant notifications, work in collaboration using the virtual incident war rooms, and use automated tools like runbooks to eliminate toil.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://app.squadcast.com/register/" rel="noopener noreferrer"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cj1VUnAS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://uploads-ssl.webflow.com/5c51758c58939b30a6fd3d73/5e16013f80ad26b00925d758_image--5--1.png" width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>sre</category>
      <category>slo</category>
      <category>bestpractices</category>
    </item>
    <item>
      <title>Don't Let ICANN Increase the Wholesale Domain Name Price</title>
      <dc:creator>Adam Hammond</dc:creator>
      <pubDate>Tue, 11 Feb 2020 01:28:57 +0000</pubDate>
      <link>https://dev.to/hammotime/don-t-let-icann-increase-the-wholesale-domain-name-price-la4</link>
      <guid>https://dev.to/hammotime/don-t-let-icann-increase-the-wholesale-domain-name-price-la4</guid>
      <description>&lt;p&gt;ICANN is considering letting Verisign increase the wholesale costs of Domain Names by up to 70% over the next 10 year period. For me, Domain Names (especially .COM) are an easy way for anyone to build an online brand or business. While this price increase is negligible for a lot of people, this impacts entrepreneurs in developing nations looking to establish a brand for their online business.&lt;/p&gt;

&lt;p&gt;Everyone should be angry and upset over this, as the continued corporatisation of the internet threatens it's openness and core foundations. Please, go and send an &lt;a href="//mailto:comments-com-amendment-3-03jan20@icann.org"&gt;Email to ICANN&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I've written a letter to them already to encourage them to not proceed with this change that will limit innovation. It's below. For more information, see the &lt;a href="https://www.namecheap.com/blog/icann-allows-com-price-increases-gets-more-money/"&gt;Namecheap Article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To Whom It May Concern&lt;/p&gt;

&lt;p&gt;I am both a customer of the .COM domain system and a seller as a wholesaler through my Hosting Business.&lt;/p&gt;

&lt;p&gt;The .COM domain name enjoys a de facto "default" status that encourages most new domain names to flow through to the .COM registrar, even after the introduction of the new gTLDs and country-specific TLDs. In the same way that the .ORG domain name should be managed and reserved for the enrichment of public organisations, .COM domain name should be made freely available to all people at a relatively cheap price. As we see an ever increasing amount of entrepreneurship, we see a massive decrease in the cost of compute; if anything we should see the wholesale prices for domain names lower. This should be done to make the internet more free and open, and encourage everyone to get domain names. I love domain names, and for me I would love it if domain names proliferated to the same extent as email addresses.&lt;/p&gt;

&lt;p&gt;I make a note of ICANN's vision which is "To be a champion of the single, open, and globally interoperable Internet". I do not see how increasing the price of Domain Names, which will only increase the operating costs of small business and individuals and not affect incumbent players in all markets (which the price increase will not even be noticeable). This action is completely in opposition of this vision. Please also refer to one of ICANN's Strategic Goals: "Sustain and improve openness, inclusivity, accountability, and transparency". How are you making the system more inclusive if the cost of a .COM domain name is about eight times more than what one third of the world's population makes per day? If anything, ICANN should be focusing on reducing the wholesale .COM domain price to make it more open and available.&lt;/p&gt;

&lt;p&gt;I wholeheartedly disagree with this move to make obtaining .COM domains harder. ICANN should reconsider this decision.&lt;/p&gt;

&lt;p&gt;Regards,&lt;/p&gt;

&lt;p&gt;Adam Hammond&lt;/p&gt;

</description>
      <category>inclusion</category>
      <category>startup</category>
    </item>
    <item>
      <title>What's Your Favourite tools?</title>
      <dc:creator>Adam Hammond</dc:creator>
      <pubDate>Fri, 07 Feb 2020 12:58:47 +0000</pubDate>
      <link>https://dev.to/hammotime/what-s-your-favourite-tools-3n8f</link>
      <guid>https://dev.to/hammotime/what-s-your-favourite-tools-3n8f</guid>
      <description>&lt;p&gt;I've worked a lot of places over the 10 years. In that time I've worked in big corporate, small business, and all sizes of Government, and I've come across a lot of tools. I've got a bit of a list going of my current favourites, which I'll drop below.&lt;/p&gt;

&lt;p&gt;What's your favourite tools? Share in the comments below then come back for a read of mine!&lt;/p&gt;

&lt;h2&gt;
  
  
  Web Servers
&lt;/h2&gt;

&lt;h4&gt;
  
  
  SSL Certificates: &lt;a href="https://letsencrypt.org/"&gt;Let's Encrypt&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Free SSL certificates? Yes please! If you want a free SSL certificate for your website, I'd recommend using Let's Encrypt. If you're on Kubernetes, use &lt;a href="https://github.com/jetstack/cert-manager"&gt;Jetstack's Cert Mananger&lt;/a&gt; or if you're on a server, use &lt;a href="https://certbot.eff.org/"&gt;EFF's CertBot&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  SSL Testing: &lt;a href="https://www.ssllabs.com/ssltest/"&gt;SSL Lab's SSL Test&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;I LOVE SSL. &lt;a href="https://engi.fyi/establishing-trust-why-tls-should-be-important-to-you/"&gt;If you've read my article on TLS&lt;/a&gt; (which I'd recommend), you'd see that it's something I'm passionate about. The folks over at SSL Labs have done a GREAT job of providing a tool that will compare your TLS settings against a set of baselines and give you an A to E grade based on the outcome. They test supported TLS versions, Ciphers, vulnerabilities, and heaps of other things. I check every site I set up with SSL Labs so I can be sure it's as hardened as possible. This is my favourite tool on the list to use (Let's Encrypt would be, but I don't "use" it enough - they make it too easy to get certificates).&lt;/p&gt;

&lt;h4&gt;
  
  
  CDN: &lt;a href="https://www.cloudflare.com/"&gt;Cloudflare&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Cloudflare are probably the most well-known CDN available. They provide a quality service and protect some of the largest websites in the world. That's why you should use Cloudflare: they know what they're doing and they're product is CDN, they do it well. They also provide a free plan that is very generous and will suit the needs of almost all small-to-medium users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mail
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Provider: &lt;a href="https://protonmail.com/"&gt;ProtonMail&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;I use ProtonMail for two reasons: they're privacy focused and secure. They do a great job of protecting customers and their communications. In most of my Ops roles, I've needed to communicate secure information with people. ProtonMail does the best job of providing a secure method for communication. You can get a 250 MB mailbox for free with a @protonmail.com/ch email address that includes all of the security features they're known for.&lt;/p&gt;

&lt;h4&gt;
  
  
  Forwarding: &lt;a href="https://forwardemail.net/"&gt;ForwardEmail&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;A lot of companies have multiple domains. If you have addon domains that you want to maintain a mail presence for, but don't want to manage as part of your normal email administration, ForwardEmail is for you. You set up your DNS records to point to ForwardEmail's servers and your emails will be sent to the email address you specify. ForwardEmail provide a great free tier, but you need to expose a public email address on your DNS (I'd suggest only using this for public-facing mailboxes).&lt;/p&gt;

&lt;h4&gt;
  
  
  Mail-related DNS Checkers: &lt;a href="https://www.dmarcanalyzer.com/"&gt;DMARCAnalyzer&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;I am a big nerd when it comes to configuring DNS. DMARCAnalyzer provides three tools for troubleshooting your mail-based DNS settings. They have tools for checking your &lt;a href="https://www.dmarcanalyzer.com/spf/checker/"&gt;SPF&lt;/a&gt;, &lt;a href="https://www.dmarcanalyzer.com/dkim/dkim-check/"&gt;DKIM&lt;/a&gt;, and &lt;a href="https://www.dmarcanalyzer.com/dmarc/dmarc-record-check/"&gt;DMARC&lt;/a&gt; records. I've used this multiple times to troubleshoot SPF and DMARC records. It's a great service.&lt;/p&gt;

&lt;h2&gt;
  
  
  DNS
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Provider: &lt;a href="https://1.1.1.1/"&gt;1.1.1.1&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Unlike most other Tech companies, Cloudflare doesn't have an advertising sales department. They have made a solid promise to provide secure DNS services, and have done a great job with 1.1.1.1. They have the traditional provider available, but also have a set of apps to configure your phone to work with their service. They make secure DNS easy. I'd recommend anyone using Google DNS move to 1.1.1.1, because you just can't trust an advertising company with data about your browsing habits.&lt;/p&gt;

&lt;h4&gt;
  
  
  Propagation Checker: &lt;a href="https://dnschecker.org/"&gt;DNS Checker&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;If you need to check whether your DNS changes have propagated, head here. This tool connects to multiple DNS servers around the globe and reports the current value of records.&lt;/p&gt;

&lt;h4&gt;
  
  
  DNS Cache Clearers: &lt;a href="https://1.1.1.1/purge-cache/"&gt;1.1.1.1&lt;/a&gt; and &lt;a href="https://developers.google.com/speed/public-dns/cache"&gt;Google DNS&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;If you deploy new DNS records and want them to propagate quickly, you can head to both the tools for Cloudflare's 1.1.1.1 and Google's DNS service and purge their caches. You just need to enter your website's domain name and the record type, and these services will refresh their records across their networks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Logging
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Uptime Monitoring: &lt;a href="https://uptimerobot.com/"&gt;Uptime Robot&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;If you love getting woken up in the middle of the night by emails indicating your site is down, Uptime Robot is great. They provide all of the standard features of uptime monitoring, with a generous free plans. They also provide a hosted status page service. It's a lot better than other competitors, while providing way better value for money. If you choose to pay for Uptime Robot, their plans are cheap and are great value for money.&lt;/p&gt;

&lt;h4&gt;
  
  
  Logging and Metrics: &lt;a href="https://cloud.google.com/stackdriver/"&gt;Stackdriver&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Google's Stackdriver is fantastic. It has a great interface for logs and metrics, provides an incident response interface, and just works. It is far superior to most other cloud-provider logging offerings, and is much cheaper than most premium logging solutions. I would recommend Stackdriver to anyone with a small-to-medium project because it has so much functionality and is so cheap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automation
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Workflow Automation: &lt;a href="https://zapier.com/"&gt;Zapier&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Zapier is really expensive, and if you want to automate a lot of things I'd definitely recommend going with one of the multitude of serverless solutions out there and rolling your own. However, if your use falls within the 100 executions/month in the free plan, Zapier has a lot of great integrations with services and is easy to use. You can link it up to almost any system and get going immediately with very low touch. They have a lot of example "zaps", and they provide a lot of tools for how to extend and configure your own.&lt;/p&gt;

&lt;h2&gt;
  
  
  VPN
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Managed: &lt;a href="https://protonvpn.com/"&gt;ProtonVPN&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;ProtonVPN does something that most other VPN companies do: they're open. Most VPN companies are very shady and cagey about their data access and logging practices. They make bold claims about their services without provide any real substantive evidence. However, ProtonVPN goes against the crowd: not only have they had their service &lt;a href="https://blog.mozilla.org/futurereleases/2018/10/22/testing-new-ways-to-keep-you-safe-online/"&gt;audited by the likes of Mozilla&lt;/a&gt;, they have also &lt;a href="https://protonvpn.com/blog/open-source/"&gt;open-sourced all of their apps&lt;/a&gt;, so you can see how their service works. If you want a VPN, there is no decision to make - just use ProtonVPN.&lt;/p&gt;

&lt;h4&gt;
  
  
  Roll-Your-Own: &lt;a href="https://getoutline.org/"&gt;Outline&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;If you're in a super sensitive environment, you still might not trust a company to manage your VPN service. If this is the case, I'd highly recommend Outline, which is a VPN product that has been developed by Jigsaw, Alphabet's emerging threats research subsidiary. Outline provides a simple-to-use interface that connects to your choice of cloud provider and automatically builds a secure VPN server. Once the server is ready, a set of credentials are provided which you can distribute to users. That's it, it's really that easy.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>productivity</category>
      <category>security</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Let's Embark! Securing our Internet Treasures (Part 3)</title>
      <dc:creator>Adam Hammond</dc:creator>
      <pubDate>Thu, 30 Jan 2020 16:22:28 +0000</pubDate>
      <link>https://dev.to/hammotime/let-s-embark-securing-our-internet-treasures-part-3-n87</link>
      <guid>https://dev.to/hammotime/let-s-embark-securing-our-internet-treasures-part-3-n87</guid>
      <description>&lt;p&gt;&lt;em&gt;Today we secure our Ingress! Security is one of the most important parts of any modern software installation. Let's see how easy it is to get 'er done on Kubernetes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It's that time of the day... You sit down at your computer to access your application you're running on Kubernetes. You navigate to your site, and what's this!? Someone has defaced it! Oh no, looks like you didn't have your ingress secured and someone has sniffed all your traffic and gotten your admin password. This of course, is what &lt;em&gt;could&lt;/em&gt; happen, but we're smart SysAdmins - we're going to secure our ingress controllers using &lt;a href="https://letsencrypt.org/"&gt;Let's Encrypt&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6d1SDnLI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3kmp7ggialxqrw885ry5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6d1SDnLI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3kmp7ggialxqrw885ry5.png" alt="Let's Encrypt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  But what is Let's Encrypt?
&lt;/h2&gt;

&lt;p&gt;If you've read my &lt;a href="https://engi.fyi/establishing-trust-why-tls-should-be-important-to-you/"&gt;Article on TLS&lt;/a&gt; (which you should), you know that securing a website is important because it allows each party to trust that they are the only ones participating in their conversation. A few years ago, the ability to provide encryption on a website was hampered by the fact all Certificate Authorities (CAs) issued SSL Certificates for cash. This meant that for most hobbyists or smaller websites, securing their stuff was expensive. Enter Let's Encrypt, a service run by the non-profit &lt;a href="https://www.abetterinternet.org/"&gt;Internet Security Research Group&lt;/a&gt;. Let's Encrypt effectively has democratised access to secure communications by maintaining a CA that issues Certificates for free. That's right, &lt;em&gt;free&lt;/em&gt; as in &lt;strong&gt;free beer&lt;/strong&gt;. This means that you can setup TLS on your website for free, and anyone who access your site does so with the knowledge and comfort that your communication is secure. A vitally important, yet criminally underrated privilege that a lot of people take for granted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the Door
&lt;/h2&gt;

&lt;p&gt;This process for configuring Let's Encrypt is relatively straight forward thanks to &lt;code&gt;cert-manager&lt;/code&gt;, a project by &lt;a href="https://www.jetstack.io/"&gt;Jetstack&lt;/a&gt;. We're going to use &lt;code&gt;cert-manager&lt;/code&gt; and Digital Ocean DNS to provision our certificates. Let's get started by jumping into &lt;code&gt;kubectl&lt;/code&gt; and installing our components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Creates Namespace
kubectl create namespace cert-manager

# Installs Custom Resource Definitions and the cert-manager Services
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.12.0/cert-manager.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This setups up the basic pods and configuration required to run &lt;code&gt;cert-manager&lt;/code&gt;. The main configuration items we need to take care of, is setting up our Digital Ocean API Key, and creating our Cluster Issuers. Before we creating our Digital Ocean Secret, we need to go to the Digital Ocean Control Panel and &lt;a href="https://www.digitalocean.com/docs/api/create-personal-access-token/"&gt;Generate an API Key&lt;/a&gt; (here's a &lt;a href="https://m.do.co/c/f250f695871e"&gt;referral link&lt;/a&gt;, although DNS is free with Digital Ocean). Once this is done, let's create the Secret:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# dns_secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: digitalocean-dns
  namespace: cert-manger-issuer
data:
  access-token: &amp;lt;DIGITAL_OCEAN_API_KEY&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f dns_secret.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now we've got all our configuration in place, we just need to tell &lt;code&gt;cert-manager&lt;/code&gt; how to issue certificates for our Cluster. We do this using ClusterIssuers which can issue Certificates across all Ingress in our Cluster. The cluster issuer consists of two pieces of configuration: your email address (for notifications) and solver configuration (so that Let's Encrypt can prove you own your domain). With these in place, we can get to the part where we &lt;em&gt;actually&lt;/em&gt; secure our Ingress!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# production_do_dns_issuer.yaml
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: do-issuer-production
  namespace: cert-manger-issuer
spec:
  acme:
    # The ACME server URL
    server: https://acme-v02.api.letsencrypt.org/directory
    # Email address used for ACME registration
    email: &amp;lt;YOUR_EMAIL_ADDRESS&amp;gt;
    # Name of a secret used to store the ACME account private key
    privateKeySecretRef:
      name: letsencrypt-production
    # Enable the DNS-01 challenge provider
    solvers:
    - dns01:
        digitalocean:
          tokenSecretRef:
            name: digitalocean-dns
            key: access-token
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f production_do_dns_issuer.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Installing the Lock
&lt;/h2&gt;

&lt;p&gt;We're finally on the home stretch! The final step is to apply our TLS configuration to our Ingress. This involves:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Adding a &lt;code&gt;cert-manager.io/cluster-issuer&lt;/code&gt; annotation which tells &lt;code&gt;cert-manager&lt;/code&gt; that we want a Certificate issued by the listed ClusterIssuer.&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;tls&lt;/code&gt; block under the spec that lists the host names we want the Certificate to provide TLS for, as well as the name of the Secret where the Certificate should be stored.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# production_ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
    [...]
    annotations:
        # Add our annotation
        cert-manager.io/cluster-issuer: letsencrypt-production
spec:
  # Add our host and Secret configuration
  tls:
  - hosts:
    - www.example.com
    - example.com
    secretName: wp-example-com-tls-production
[...]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f production_ingress.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once this changes have been applied to the ingress, the following will occur:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;a TXT record will be placed into your DNS Zone by the dns01 solver.&lt;/li&gt;
&lt;li&gt;a secret will be created in the same namespace as the ingress with the name listed at &lt;code&gt;spec &amp;gt; tls &amp;gt; secretName&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Within about five minutes, your Certificate will be issued and if you refresh your site it will now be secured.&lt;/p&gt;

&lt;h2&gt;
  
  
  See, Totally Easy!
&lt;/h2&gt;

&lt;p&gt;As you can see, it is &lt;em&gt;very&lt;/em&gt; easy to setup TLS on our Ingress on Kubernetes. &lt;strong&gt;No one&lt;/strong&gt; could possibly have any excuse to let their own and their customers private communications be snooped on by third party actors. I love TLS and this is probably my favourite article of the series. Security is really important, and it is easy to forget that given how ubiquitous and easy it is to use in our modern day. However, we can't let our guard down because threats and bad actors take a high baseline of security into account. Don't be easy pickings.&lt;/p&gt;

&lt;p&gt;If you liked this article, consider giving &lt;a href="https://letsencrypt.org/donate/"&gt;Let's Encrypt a donation&lt;/a&gt;, or you could just follow me on Twitter &lt;a href="https://twitter.com/stophammotime"&gt;@stophammotime&lt;/a&gt;. Thanks for reading, and see you for the next installment where we setup backups on our Cluster.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>tutorial</category>
      <category>kubernetes</category>
      <category>security</category>
    </item>
    <item>
      <title>The Secret: Kubernetes Secrets and AWS SSM</title>
      <dc:creator>Adam Hammond</dc:creator>
      <pubDate>Tue, 28 Jan 2020 10:36:13 +0000</pubDate>
      <link>https://dev.to/hammotime/the-secret-kubernetes-secrets-and-aws-ssm-9fl</link>
      <guid>https://dev.to/hammotime/the-secret-kubernetes-secrets-and-aws-ssm-9fl</guid>
      <description>&lt;p&gt;Kubernetes and secrets is always a difficult problem. I've got a super simple solution using AWS SSM today that we can use during our CI/CD pipeline to inject our secrets into our services. This is so simple and quick, that you might miss it, so I'll get to it.&lt;/p&gt;

&lt;p&gt;First, log into AWS and open up Systems Manager. Go to Parameter Store, and create a new Parameter. The parameter type needs to be &lt;code&gt;SecureString&lt;/code&gt;, feel free to name it whatever you like; I like to go with &lt;code&gt;/&amp;lt;cloud_provider&amp;gt;/k8s/&amp;lt;application&amp;gt;/&amp;lt;environment&amp;gt;&lt;/code&gt;. Add the contents of &lt;code&gt;secret.yaml&lt;/code&gt; as the parameter's value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Secret
metadata:
  name: wp-secrets
  namespace: wp-custom-domain
data:
  wordpress_db_password: QXdm .. mRUg=
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Secondly, jump into your CI configuration and add the following as a step prior to creating your Kubernetes Deployment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# create secrets
# /do/k8s/$APP_TYPE/$CI_ENVIRONMENT_NAME
aws ssm get-parameters-by-path \
  --path "/${CLOUD_PROVIDER}/k8s/${APP_TYPE}/" \
  --query "Parameters[?Name==\`/do/k8s/${APP_TYPE}/${CI_ENVIRONMENT_NAME}\`].Value" \
  --with-decryption --output text | kubectl apply -f -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, configure your Deployment spec to include the value of the secret using the &lt;code&gt;valueFrom&lt;/code&gt; directive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spec:
  containers:
  - name: wordpress
    image: _/wordpress:5.3.2
    env:
    - name: WORDPRESS_DB_PASSWORD
      valueFrom:
         secretKeyRef:
           name: wp-secrets
           key:  wordpress_db_password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The only thing you need to do now is run your CI Deployment and your secrets will be available in Kubernetes! See, I told you it was simple! This is a simple, yet effective way to deploy secrets into your environment while keeping them out of source code.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>security</category>
      <category>tutorial</category>
      <category>aws</category>
    </item>
    <item>
      <title>Docker Hub: Automatically Building Images</title>
      <dc:creator>Adam Hammond</dc:creator>
      <pubDate>Thu, 23 Jan 2020 15:18:42 +0000</pubDate>
      <link>https://dev.to/hammotime/docker-hub-automatically-building-images-73h</link>
      <guid>https://dev.to/hammotime/docker-hub-automatically-building-images-73h</guid>
      <description>&lt;p&gt;&lt;em&gt;Ever wanted to build and distribute a tool on Docker Hub? Well, it's easy to automatically build an image. Let's get started!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Docker has become one of those ubiquitous technologies, that follows us everywhere. I myself use docker every single day without fail, building a lot of images on my machine for all sorts of utility tasks. However, what if we have a great idea and we want to share it with the world? That's where &lt;a href="https://hub.docker.com/"&gt;Docker Hub&lt;/a&gt; comes in. If we have a cool tool or idea we want to distribute using Docker, we only need to build a Dockerfile, connect our GitHub account to our Docker Hub account, and set up some configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before continuing, please make sure you have &lt;a href="https://github.com/join"&gt;GitHub&lt;/a&gt; and &lt;a href="https://hub.docker.com/signup"&gt;Docker Hub Accounts&lt;/a&gt;. If you don't, they will only take a few minutes to create. You will also need &lt;a href="https://www.docker.com/products/docker-desktop"&gt;Docker Desktop&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up our Source Repository
&lt;/h2&gt;

&lt;p&gt;Today, we're going to be setting up Docker Builds for my cool repository called "My Task List". This is a super simple app that displays my task list when I run it via Docker. If I want to update my task list, I just push an update to my GitHub repository and then voilà, my image will be updated on my next &lt;code&gt;docker pull&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To get started, go to &lt;a href="https://github.com/HammoTime/my-task-list"&gt;my-task-list&lt;/a&gt;. On the top right-hand corner, click the Fork button. A prompt will come up saying "Where should we work my-task list?". Click your GitHub username. Once you click your username, you will be taken to a new copy that has been created under your user name!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--11XORT-A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/3t9wto2lfhttey4zlkvv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--11XORT-A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/3t9wto2lfhttey4zlkvv.png" alt="Forked From"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting our GitHub Account to Docker Hub
&lt;/h2&gt;

&lt;p&gt;Open up &lt;a href="https://hub.docker.com/settings/linked-accounts"&gt;Docker Hub Linked Accounts&lt;/a&gt;. Click Connect on the GitHub line.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8IIKspLK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/qyllzrn43bx5ayj12cui.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8IIKspLK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/qyllzrn43bx5ayj12cui.png" alt="Docker Hub Linked Accounts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An authorisation page will come requesting access to your GitHub account. Review the settings, and when you're happy to proceed click &lt;strong&gt;Authorize docker&lt;/strong&gt;. Enter in your GitHub password when prompted.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z98Fvt1F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/aup8h6tgnuwdyza3a7d4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z98Fvt1F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/aup8h6tgnuwdyza3a7d4.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the authorisation process has been successful, you will be returned to Docker Hub. If everything has gone well, your Account name will be shown in the Linked Accounts section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1zq4wvS9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/glphw5n22mdq3h3cnzaq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1zq4wvS9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/glphw5n22mdq3h3cnzaq.png" alt="Now Linked"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up our Docker Builds
&lt;/h2&gt;

&lt;p&gt;Sweet! Now we have a GitHub Repository and our Docker Hub account linked. Where to from here? We want to setup our own repository within Docker Hub; this is where all of our images will be deployed when they build. We configure these settings when we create the repository.&lt;/p&gt;

&lt;p&gt;On Docker Hub, click on &lt;strong&gt;Repositories&lt;/strong&gt;. You should see an empty list of repositories with your name in the right-hand corner of the page. Click &lt;em&gt;Create Repository&lt;/em&gt;. Give your repository a name of "my-task-list", and select &lt;em&gt;Private&lt;/em&gt; for the Visibility setting (this is our personal task list afterall).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ERhtmfWp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/t8nto8ha1wszjla08opb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ERhtmfWp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/t8nto8ha1wszjla08opb.png" alt="Create Repository"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We've got our settings for our repository all added, now we just need to setup our builds. Click on the GitHub logo under &lt;strong&gt;Build Settings&lt;/strong&gt; (it should be labelled &lt;strong&gt;Connected&lt;/strong&gt;). From the dropdown &lt;strong&gt;Select organisation&lt;/strong&gt; dropdown select your GitHub username and select "my-task-list" from the Select &lt;strong&gt;repository dropdown&lt;/strong&gt;. Click the &lt;strong&gt;+&lt;/strong&gt; next to &lt;strong&gt;Build Rules&lt;/strong&gt;, leaving the defaults.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6X78diwG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/igofxj0c8xrqef5qf9ms.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6X78diwG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/igofxj0c8xrqef5qf9ms.png" alt="Link Repo to Build"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it, let's click &lt;strong&gt;Create &amp;amp; Build&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building and Running our Image
&lt;/h2&gt;

&lt;p&gt;Now, we'll be taken to our repository's landing page. Well done, you've created a new Docker repository, and our image is building as we speak! We should see our new build on the &lt;strong&gt;Recent builds&lt;/strong&gt; list; click on it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L3ceDUI8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/4eg13z4a9bw8yf9bow3u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L3ceDUI8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/4eg13z4a9bw8yf9bow3u.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The build should be running and should show as "Pending", wait until the build completes and it flags as "Successful". Once that is done, let's open up our Terminal and enter the following commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker-login --username &amp;lt;docker_hub_username&amp;gt; --password &amp;lt;docker_hub_password&amp;gt;
WARNING: login credentials saved in /home/username/.docker/config.json
Login Succeeded

$ docker run --name task-list -p 8080:80 &amp;lt;docker_hub_username&amp;gt;/my-task-list:latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once that's done, open up a browser and go to &lt;code&gt;localhost:8080&lt;/code&gt;. You should see the current task list displayed. Behold, your first docker image running in all it's glory! Once you're done marvelling at your great work, hit &lt;code&gt;CTRL-C&lt;/code&gt; on the terminal to kill the container.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0NO7gxqb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/6uxm7m4dr2qi4wxq0by1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0NO7gxqb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/6uxm7m4dr2qi4wxq0by1.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Editing our Image
&lt;/h2&gt;

&lt;p&gt;Let's update our task list to add a new item. To do this, we need to update our GitHub repository. Go back to GitHub, and open up the main repository screen for your fork of &lt;code&gt;my-task-list&lt;/code&gt;. Click on the &lt;code&gt;my-task-list.html&lt;/code&gt; file and when it opens, click the &lt;strong&gt;Pencil&lt;/strong&gt; to edit the file. Add a new item to the list, and click &lt;strong&gt;Commit Changes&lt;/strong&gt; down the bottom of the editor.&lt;/p&gt;

&lt;p&gt;Let's head back to Docker Hub and view the repository. If our commit has been successful, we should see a new build pending which is tagged with a new commit hash. Wait for the build to complete like before.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2yy3S1Y6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/pt4id6ri5q7lpsfsnxr0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2yy3S1Y6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/pt4id6ri5q7lpsfsnxr0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now to test our final edits. Run the following on your local machine and then once it's running, browse to &lt;code&gt;localhost:8080&lt;/code&gt; again. If you're successful you should see the new item you added to the task list!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker run --name task-list-v2 -p 8080:80 &amp;lt;docker_hub_username&amp;gt;/my-task-list:latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Jyk_rq2J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/rijx5rvja28rj3a591zp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Jyk_rq2J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/rijx5rvja28rj3a591zp.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Writing and building a Docker image via CI/CD using Docker Hub and GitHub is a great way to build and distribute tools. As you can see, it's super easy to get up and running within 15 minutes, and if you're pushing public images the it's all &lt;em&gt;free&lt;/em&gt;. So, what are you waiting for? Write a Dockerfile and push a repo, what have you got to lose?&lt;/p&gt;

&lt;p&gt;If you'd like to contact me, please send me a message on Twitter &lt;a href="https://twitter.com/stophammotime"&gt;@stophammotime&lt;/a&gt;. Thanks for reading and thanks to &lt;a href="https://unsplash.com/@hojipago?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;EJ Yao&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/construction?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt; for the header picture! Please also check out my blog at &lt;a href="https://engi.fyi/"&gt;engi.fyi&lt;/a&gt; where I have a bunch of DevOps and Engineering related blog posts.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>tutorial</category>
      <category>devops</category>
      <category>github</category>
    </item>
    <item>
      <title>Let's Embark! Setting up Ingress (Part 2)</title>
      <dc:creator>Adam Hammond</dc:creator>
      <pubDate>Wed, 22 Jan 2020 14:16:52 +0000</pubDate>
      <link>https://dev.to/hammotime/let-s-embark-setting-up-ingress-part-2-4idn</link>
      <guid>https://dev.to/hammotime/let-s-embark-setting-up-ingress-part-2-4idn</guid>
      <description>&lt;p&gt;&lt;em&gt;In this article of the "Let's Embark!" series, we cover how to setup nginx-ingress using the offical nginxinc/nginx-ingress images and getting your cluster connected to the internet. To find out how to setup a Cluster on Digital Ocean, see &lt;a href="https://engi.fyi/lets-embark-setting-up-kubernetes-part-1/"&gt;Part 1&lt;/a&gt; and use my &lt;a href="https://m.do.co/c/f250f695871e"&gt;Referral Code&lt;/a&gt; for $100 credit to get you up and running.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Well, we have a cluster. What now? We need to get our Cluster connected to the internet so that it can receive connections to our services. By the end of this article, you will have &lt;code&gt;nginx-ingress&lt;/code&gt; setup and configured, and a demo app reachable from the internet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing nginx-ingress
&lt;/h2&gt;

&lt;p&gt;I prefer to use the offical &lt;code&gt;nginx-ingress&lt;/code&gt; images from Nginx, Inc. We will be setting up our Ingress controllers as a DaemonSet, so each pod will run on a node within our Cluster. Let's clone the source repository for our configuration and get our basic configuration items setup on our Cluster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone git@github.com:nginxinc/kubernetes-ingress.git
cd deployments/
kubectl apply -f common/ns-and-sa.yaml
kubectl apply -f rbac/rbac.yaml
kubectl apply -f common/custom_resource_definitions.yaml
kubectl apply -f common/nginx-config.yaml
kubectl apply -f daemon-set/nginx-ingress.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Within about five minutes, you should see a DaemonSet on each node you have active. For the final part of our installation, we need to configure our domain name to point to our IP address, so run the following command and the value available under &lt;code&gt;EXTERNAL-IP&lt;/code&gt; should be created as an A record in your DNS settings. I would recommend using &lt;a href="https://www.digitalocean.com/docs/networking/dns/quickstart/"&gt;Digital Ocean's DNS Service&lt;/a&gt; for this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get service nginx-ingress -n nginx-ingress
NAME           TYPE          CLUSTER-IP     EXTERNAL-IP  PORT(S)        AGE
nginx-ingress  LoadBalancer  10.245.114.32  1.1.1.1      80:31908/TCP   3d1h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Exposing Services
&lt;/h2&gt;

&lt;p&gt;On Kubernetes, when we talk about "Services" we are talking about the endpoint that gets exposed via a Cluster's external IP Address. There are three things that go into creating and running a service on Kubernetes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deployment: this creates the template for the pods, including container and replica configuration which includes image, network, and metadata information.&lt;/li&gt;
&lt;li&gt;Service: this defines the port that the item created by the Deployment (ReplicaSet, DaemonSet, etc) wil be exposed on in the cluster. Once you've created a Service, you can access it within the cluster at &lt;code&gt;&amp;lt;deployment_name&amp;gt;.&amp;lt;namespace&amp;gt;.svc.cluster.local&lt;/code&gt; at the port you have exposed in the Service configuration.&lt;/li&gt;
&lt;li&gt;Ingress: This defines the domain name that we expose the service as on the external IP. Ingress within Kubernetes generally uses &lt;a href="https://en.wikipedia.org/wiki/Server_Name_Indication"&gt;Server Name Indication (SNI)&lt;/a&gt; which means without a domain name, it will be impossible to get to your Service.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For us to get our service up and running, we need to run five scripts which will setup everything we need and expose our service on our &lt;code&gt;nginx-ingress&lt;/code&gt;. Prior to continuing, you will have needed to setup your domain name, as we will use it in the configuration below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl apply -f echo_namespace.yaml

# echo_namespace.yaml
kind: Namespace
apiVersion: v1
metadata:
  name: echo
  labels:
    name: echo
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
$ kubectl apply -f echo_deployment.yaml

# echo_deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo
  namespace: echo
spec:
  selector:
    matchLabels:
      app: echo
  replicas: 2
  template:
    metadata:
      labels:
        app: echo
    spec:
      containers:
      - name: echo
        image: hashicorp/http-echo
        args:
        - "-text=Default HTTP Service"
        ports:
        - containerPort: 5678
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl apply -f echo_service.yaml

# echo_service.yaml
apiVersion: v1
kind: Service
metadata:
  name: echo
  namespace: echo
spec:
  ports:
  - port: 80
    targetPort: 5678
  selector:
    app: echo
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f echo_ingress.yaml

# echo_ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: echo-ingress
  namespace: echo
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: &amp;lt;YOUR_DOMAIN_NAME&amp;gt;
    http:
      paths:
      - backend:
          serviceName: echo
          servicePort: 80
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once all of these templates have been applied to your cluster, your new service will be available at the domain name you specified. The way that &lt;code&gt;nginx-ingress&lt;/code&gt; knows to expose your service is through the annotation on the Ingress template: &lt;code&gt;kubernetes.io/ingress.class: nginx&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;Okay, so we've successfully got our cluster up and running, and we've exposed a service to the internet. Next up, we have details on how to secure our service using TLS via Jetstack's &lt;code&gt;cert-manager&lt;/code&gt; and Let's Encrypt. For more information on the series, please visit the &lt;a href="https://engi.fyi/lets-embark-setting-up-kubernetes/"&gt;series page&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Let's Embark! Setting up Kubernetes (Part 1)</title>
      <dc:creator>Adam Hammond</dc:creator>
      <pubDate>Tue, 21 Jan 2020 07:16:39 +0000</pubDate>
      <link>https://dev.to/hammotime/let-s-embark-setting-up-kubernetes-part-1-3l6j</link>
      <guid>https://dev.to/hammotime/let-s-embark-setting-up-kubernetes-part-1-3l6j</guid>
      <description>&lt;p&gt;&lt;em&gt;Ever wanted to build a Kubernetes Cluster? Well, you can. It's easy. Cross-posted from &lt;a href="https://engi.fyi/lets-embark-setting-up-kubernetes-part-1/"&gt;engi.fyi&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I just went through the process of setting up my Kubernetes Cluster, and it was pretty easy the third time around! So, I thought I'd put up a series of tutorials that focus on getting a Kubernetes Cluster up and running with Ingress, Certificates, and a basic Service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up your Account
&lt;/h2&gt;

&lt;p&gt;First thing is first. Head over to Digital Ocean using my &lt;a href="https://m.do.co/c/f250f695871e"&gt;Referral Code&lt;/a&gt;. I run my personal clusters on Digital Ocean and they are the cheapest and also one of the most featureful Hosted Kubernetes providers.&lt;/p&gt;

&lt;p&gt;On top of this, they also provide an excellent cluster base using the best-in-class Kubernetes networking solution &lt;a href="https://cilium.io"&gt;Cilium&lt;/a&gt;. They also provide a hosted dashboard that you can access via a link on the Digital Ocean Control Panel, and doesn't need to be installed on your cluster itself (unlike other providers, I'm looking at you AWS).&lt;/p&gt;

&lt;p&gt;If you don't want to test this on a real cluster, feel free to install &lt;a href="https://www.docker.com/products/docker-desktop"&gt;Docker Desktop&lt;/a&gt; and enable the Kubernetes feature which comes with a local cluster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up your Cluster
&lt;/h2&gt;

&lt;p&gt;Once you're logged in and ready to go, open the Kubernetes Control Panel. On the top-right corner of the screen is the &lt;strong&gt;Create button&lt;/strong&gt;. Click it, and select &lt;strong&gt;Clusters&lt;/strong&gt; &lt;em&gt;Create Kubernetes Clusters&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RIm2GJLS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/u8zhrjih1mrdbnbveo7u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RIm2GJLS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/u8zhrjih1mrdbnbveo7u.png" alt="Create Cluster"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select your Region (I like to go to Singapore, as I'm in Australia), name your Node Pool, select &lt;strong&gt;Standard Nodes&lt;/strong&gt; (2GB Memory / 1 vCPU), with &lt;strong&gt;1 node&lt;/strong&gt;. There is no need for any more nodes at the moment, but when we get to setting up nginx we will scale up this to demonstrate Daemon Sets.&lt;/p&gt;

&lt;p&gt;The cost for your cluster should be below, at $10 a month. That means the credit you got from my referral link should last 10 months! Yay! Name and tag (optional) your cluster, then click &lt;strong&gt;Create Cluster&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xdUF246R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/39f1arw8h6o2u1xiehge.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xdUF246R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/39f1arw8h6o2u1xiehge.png" alt="Pending Cluster"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessing our Cluster
&lt;/h2&gt;

&lt;p&gt;While we're waiting for the cluster to provision, let's get our CLI access up. Click &lt;strong&gt;Download Config File&lt;/strong&gt;. After this is downloaded, fire up a terminal and install &lt;code&gt;kubectl&lt;/code&gt;. This can be done with either Choco (kubernetes-cli) on Windows or Brew on macOS (kubectl). Once this is installed, move your confg file to &lt;code&gt;~/.kube/config&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once you're configured, run &lt;code&gt;kubectl get pods -n kube-system&lt;/code&gt;. If you've suceessfully installed &lt;code&gt;kubectl&lt;/code&gt; and the put the configuration file in the right place, it should list a bunch of pods including &lt;code&gt;kube-proxy&lt;/code&gt;, &lt;code&gt;cilium&lt;/code&gt;, &lt;code&gt;do-node-agent&lt;/code&gt;, and &lt;code&gt;kube-state-metrics&lt;/code&gt;. If it doesn't work, your cluster is still being configured. Try again in a few minutes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;adam.hammond@adam-laptop k8s-config % kubectl get pods -n kube-system
NAME                                    READY   STATUS    RESTARTS  AGE
cilium-7vd9t                            1/1     Running   0         5m
cilium-operator-d5cd7d758-stsqw         1/1     Running   0         5m
coredns-84c79f5fb4-m9snd                1/1     Running   0         5m
csi-do-node-zc5w8                       2/2     Running   0         5m
do-node-agent-mhc88                     1/1     Running   0         5m
kube-proxy-4nm5b                        1/1     Running   0         5m
kube-state-metrics-7fd44b48b5-jgmz4     1/1     Running   0         5m
kubelet-rubber-stamp-7f966c6779-ztb5s   1/1     Running   0         5m
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once your cluster is ready, a little green light will show on the Kubernetes Dashboard and the &lt;strong&gt;Kubernetes Dashboard&lt;/strong&gt; button should be available. Click it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ue9VfPFK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/5zi5iwbbip7enyobtik3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ue9VfPFK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/5zi5iwbbip7enyobtik3.png" alt="Cluster Ready"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If your cluster is up-and-running, you should see three green circles and a bunch of green Daemon Sets. Congratulations, you're up and running with a Kubernetes Cluster. It's that easy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tew6K2NG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/74yd6wka34dkalgn8syb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tew6K2NG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/74yd6wka34dkalgn8syb.png" alt="Kubernetes Dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Time
&lt;/h2&gt;

&lt;p&gt;Now that we've got a cluster up and running, we'll be getting into setting up our Ingress Controllers with plain ol' HTTP so we can access workloads!&lt;/p&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Good Monitoring Answers Questions</title>
      <dc:creator>Adam Hammond</dc:creator>
      <pubDate>Thu, 16 Jan 2020 04:34:35 +0000</pubDate>
      <link>https://dev.to/hammotime/good-monitoring-answers-questions-1lkl</link>
      <guid>https://dev.to/hammotime/good-monitoring-answers-questions-1lkl</guid>
      <description>&lt;p&gt;I recently had to do a proposal for our Kubernetes monitoring solution. Kubernetes is a tricky beast, especially with Prometheus because there is &lt;em&gt;so much information&lt;/em&gt;. I was daunted by the amount of effort and understanding I'd need to begin on the task, and it took me a few days to actually open the ticket.&lt;/p&gt;

&lt;p&gt;After reading through a lot of articles on Kubernetes monitoring, I knew the answer to my question wasn't going to be a simple one. As I stared at the space above my monitor, pondering the question, a thought struck me. It was simple, but what if I just wrote down all the questions I needed answered by my monitoring and &lt;em&gt;then&lt;/em&gt; got all the appropriate metrics. In every job I've ever had, it's always been "monitor x, y, and z", but never "tell me when this isn't working properly."&lt;/p&gt;

&lt;p&gt;I started off my question chain as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Can my pods be scheduled?&lt;/li&gt;
&lt;li&gt;Are there nodes available to schedule pods?&lt;/li&gt;
&lt;li&gt;Are there resources available on my nodes?&lt;/li&gt;
&lt;li&gt;Are my pods running as expected?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If I can answer each of these questions in the affirmative, then I can generally expect that a service is running correctly. Likewise if I ask questions for each layer (hardware, control plane, nodes, services, ingress, etc) and those answers are in the negative, I can understand cascading dependencies on my compute, advising customers and mitigating an outage as much as possible.&lt;/p&gt;

&lt;p&gt;Actually getting the metrics to answer these questions was super easy. I just opened up the Kubernetes Dashboard and checked the places where I could check if I was manually fixing the issues. Then, I simply noted them and created Prometheus Alarms for them. It's that easy.&lt;/p&gt;

&lt;p&gt;Have a good process, and good results will follow.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>management</category>
      <category>productivity</category>
      <category>codequality</category>
    </item>
    <item>
      <title>DevOps: Culture vs. Tooling</title>
      <dc:creator>Adam Hammond</dc:creator>
      <pubDate>Mon, 09 Dec 2019 01:46:13 +0000</pubDate>
      <link>https://dev.to/hammotime/devops-culture-vs-tooling-1o35</link>
      <guid>https://dev.to/hammotime/devops-culture-vs-tooling-1o35</guid>
      <description>&lt;p&gt;One of the last questions asked in a DevOps interview is usually "so, what does DevOps mean to you?" I think this is a smart question, because DevOps is wildly misunderstood by the greater IT community. Some may answer that it's Continuous Integration and Releases, another may say it's having everything in Git, and the last might say that it's having tests available. All of these technical solutions do represent a key aspect of DevOps which is the tool chain, but it is the least important. Primarily, it is the least important because underlying the implementation of these tools is a make-or-break attitude into implementing them. For example, I may have a build but it might break or deployments may be manual. I may also have everything in git but I might only commit once a year. Or, I may have tests but all of them pass even if errors are thrown. As you can see, just because a team has these things, don't mean they are truly living the DevOps way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Improving Toxic Team Culture
&lt;/h2&gt;

&lt;p&gt;If you think that your team's culture is toxic or work is limited for some reason, there are ways you can go about improving it. Fundamentally, DevOps is about empowering individuals to do the work they need to do. There are a few immediate things you can do to get started on this journey:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Change your KPIs from "tickets resolved" to "problems fixed": this will allow your team to distinguish between the "busy work" of resolving repeated failures, and the real work of &lt;strong&gt;actually&lt;/strong&gt; fixing the problem.&lt;/li&gt;
&lt;li&gt;Begin code reviews: code reviews are important, not only because they may prevent bugs slipping into your code, but they also ensure that multiple members of your team understand and can work on your codebase. If code isn't reviewed, there is probably only a single person who understands it. The more of this code that is added your codebase, the further you embed single points of failure into your business. If a team member leaves and their code breaks for some reason, it may take days or weeks to resolve a problem that will inevitably come along.&lt;/li&gt;
&lt;li&gt;Introduce a CI pipeline: if your team does work on production servers, this is an indication that the your work environment is in a precarious position. Introducing a CI pipeline will force your team to standardise their deployment processes and make sure rigour is applied to deployments. This should also reduce rework as failed production deployments should be a thing of the past.&lt;/li&gt;
&lt;li&gt;Introduce automated testing: If you have a CI pipeline, good work. Now that you've got processes in place to reduce production impairing incidents, let's get started on introducing testing into the CI pipeline. Automated tests are great bang-for-buck as they only need to be defined once and are an immediate indicator if buggy code has been committed onto a branch.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These are just a few suggestions, but they at least give you an idea of simple things you can do to start to introduce your team to DevOps culture. The one thing that is important, is that if you decide to actually implement one of these things, you need to make sure you follow through. A half-implemented practice is worse than nothing because it allows you to operate with a false sense of security.&lt;/p&gt;

&lt;p&gt;If you'd like to read more articles like this, please check out my blog &lt;a href="//engi.fyi"&gt;engi.fyi&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>codequality</category>
      <category>management</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
