<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Christian Melendez</title><link href="https://cmelendeztech.com/" rel="alternate"/><link href="https://cmelendeztech.com/atom.xml" rel="self"/><id>https://cmelendeztech.com/</id><updated>2025-09-01T00:00:00+02:00</updated><entry><title>Kubernetes Autoscaling: Building Efficient and Cost-Optimized Clusters with KEDA and Karpenter</title><link href="https://cmelendeztech.com/posts/2025/09/kubernetes-autoscaling-book-karpenter-keda.html" rel="alternate"/><published>2025-09-01T00:00:00+02:00</published><updated>2025-09-01T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2025-09-01:/posts/2025/09/kubernetes-autoscaling-book-karpenter-keda.html</id><summary type="html">&lt;p&gt;I'm excited to share the news about my first upcoming book: "Kubernetes Autoscaling: Building Efficient and Cost-Optimized Clusters with KEDA and Karpenter" 🤩 ... this book reflects all the lessons learned after working with many, many customers around the world to build efficient Kubernetes clusters with Karpenter and KEDA. I can't count …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I'm excited to share the news about my first upcoming book: "Kubernetes Autoscaling: Building Efficient and Cost-Optimized Clusters with KEDA and Karpenter" 🤩 ... this book reflects all the lessons learned after working with many, many customers around the world to build efficient Kubernetes clusters with Karpenter and KEDA. I can't count how many times I've talked about Karpenter already, but all those customer conversations have helped shape the content for this book.&lt;/p&gt;
&lt;p&gt;The idea started as a focus only on Karpenter, but if we're honest, that's only one piece of the puzzle when we talk about autoscaling in Kubernetes. Therefore, I took on the mission to start with the basics so that we all understand why such tools exist today, and why it's important to know what impacts the performance of your application, its application patterns, and that rightsizing has a massive impact on efficiency. Moreover, as I really love getting hands-on, the book is packed with dozens of hands-on tutorials to help you learn by doing. So, if you're up with me in the mission of "saving the planet, one pod at a time," make sure you give this book an opportunity.&lt;/p&gt;
&lt;p&gt;That being said, the book is soon to be published and it's ready for pre-order on Amazon and Packt. Also, if there's something you'd like to see in the book, there's still time to give me your feedback. So, please let me know either in the comments or message me; I'd be very interested to know what you'd expect to learn.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Kubernetes Autoscaling Book - Building Efficient and Cost-Optimized Clusters with KEDA and Karpenter" src="/images/kubernetesautoscalingbook.jpg"&gt;&lt;/p&gt;
&lt;h3&gt;Where tu buy it?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.packtpub.com/en-at/product/kubernetes-autoscaling-9781836643838"&gt;packet.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Kubernetes-Autoscaling-Efficient-Cost-Optimized-Karpenter/dp/1836643837/"&gt;amazon.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.es/Kubernetes-Autoscaling-Efficient-Cost-Optimized-Karpenter-ebook/dp/B0FL259BX3"&gt;amazon.es&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.co.uk/Kubernetes-Autoscaling-Efficient-Cost-Optimized-Karpenter/dp/1836643837/"&gt;amazon.co.uk&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the link is broken, just search for "Kubernetes Autoscaling book", and you should find it. Otherwise, let me know. &lt;/p&gt;
&lt;p&gt;Have a nice day!! I'll keep you posted about the official release date.&lt;/p&gt;</content><category term="misc"/><category term="karpenter"/></entry><entry><title>What is site reliability engineering (SRE) and how is it different from DevOps?</title><link href="https://cmelendeztech.com/posts/2019/04/site-reliability-engineering.html" rel="alternate"/><published>2019-04-05T00:00:00+02:00</published><updated>2019-04-05T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2019-04-05:/posts/2019/04/site-reliability-engineering.html</id><summary type="html">&lt;p&gt;Site reliability engineering (SRE) is Google’s model of service management where software engineers run production systems using a software engineering approach. It’s clear that Google is unique, and they usually need to tackle &lt;a href="https://raygun.com/blog/errors-and-exceptions/"&gt;software bugs and errors&lt;/a&gt; in different and non-conventional ways. But having software engineers doing a …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Site reliability engineering (SRE) is Google’s model of service management where software engineers run production systems using a software engineering approach. It’s clear that Google is unique, and they usually need to tackle &lt;a href="https://raygun.com/blog/errors-and-exceptions/"&gt;software bugs and errors&lt;/a&gt; in different and non-conventional ways. But having software engineers doing a job that is traditionally done by professionals with a systems administration background sounds impractical. Well, it was good enough to succeed, so Google decided to share their wisdom in a &lt;a href="https://landing.google.com/sre/books/"&gt;book format&lt;/a&gt; a few years ago.&lt;/p&gt;
&lt;p&gt;After the book was released, SRE roles were embraced across the board by modern software teams like Atlassian.&lt;/p&gt;
&lt;p&gt;In today’s post, I’m going to explain what SRE is and why SRE helps maintain software quality in production systems. You might notice that SRE looks like DevOps, so I’ll also explain how these two concepts relate to each other. Finally, I’ll share a few tips on how the hiring process changes with the SRE approach. Let’s get into it.&lt;/p&gt;
&lt;h2&gt;A software engineering approach to run production systems&lt;/h2&gt;
&lt;p&gt;Benjamin Treynor is the founder of Google’s SRE, and &lt;a href="https://landing.google.com/sre/sre-book/chapters/introduction/"&gt;he explains&lt;/a&gt; that “SRE is what happens when you ask a software engineer to design an operations team.” Treynor’s background has always been software engineering, so it wasn’t a surprise that he decided to design an operations team with mostly development skills. Traditionally, operations tasks don’t scale well when they rely too heavily on humans doing things manually. Google’s SRE team ended up automating their tedious manual tasks, even if they were complex.&lt;/p&gt;
&lt;p&gt;Just because the team was bored doing the same manual tasks every day wasn’t the only reason for adding automation. A common challenge when operating a production system is to keep it both up and running and as performant as possible. Usually, systems go down because we need to release new features or because the system infrastructure is running out of capacity. The latter can be automated. But the first one is more difficult because something is always going to go wrong.&lt;/p&gt;
&lt;p&gt;That’s why SRE accepts failure and will try to fail in a controlled manner. One way SRE achieves this is by using an error budget.&lt;/p&gt;
&lt;h3&gt;Error budgets&lt;/h3&gt;
&lt;p&gt;An error budget tells you the minimum amount of reliability required. A system that is reliable 100 percent of the time is expensive, and users might not even notice if the system goes down for one minute. But users &lt;em&gt;will&lt;/em&gt; notice when the system is down for an extended period, even if you don’t. Then what should you do?&lt;/p&gt;
&lt;p&gt;Well, start by defining what level of reliability is acceptable for the system. This level will become the target you shouldn’t violate, but it should be achievable enough that it doesn’t lower the pace of change or affect innovation. When a deployment fails, you’ll be able to decide when to stop it and when to keep it going—and you’ll be able to do it in a controlled manner.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reliability is the most important feature of an SRE team.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now let’s talk about what the team does to be reliable.&lt;/p&gt;
&lt;h2&gt;What does a site reliability engineer do?&lt;/h2&gt;
&lt;p&gt;How do SREs keep to the error budget &lt;em&gt;and&lt;/em&gt; have a reliable system? To answer this question, let me talk about the four core SRE principles an engineer will implement on a daily basis.&lt;/p&gt;
&lt;h3&gt;1. Ensuring an engineering focus&lt;/h3&gt;
&lt;p&gt;SREs intentionally spend a certain amount of time on reducing human labor, sharing knowledge among teams, and &lt;a href="https://raygun.com/blog/design-on-call-schedule/"&gt;creating a blameless culture&lt;/a&gt;. Keeping track of system’s reliability. Knowing &lt;a href="https://raygun.com/blog/crash-reporting-and-apm/"&gt;what’s happening inside the systems&lt;/a&gt; error reporting software is crucial. Engineers design the software to automate routine tasks results in a self-healing system. Humans will be notified only when their decision criteria are needed.&lt;/p&gt;
&lt;h3&gt;2. Bringing the system back online&lt;/h3&gt;
&lt;p&gt;How the team responds to emergencies is what allows them to keep on error budget when something goes wrong. Software engineering removes the human factor and helps to alleviate the pain of failing by recovering rapidly.&lt;/p&gt;
&lt;h3&gt;3. Maintaining compliance with change management&lt;/h3&gt;
&lt;p&gt;When removing the human factor from the equation, change management needs to have automation. By leaving a trail, this not only increases confidence that company rules aren’t ignored, but it also increases the deploy and release velocity by removing the time needed to make a decision.&lt;/p&gt;
&lt;h3&gt;4. Forecasting and provisioning the capacity of the system&lt;/h3&gt;
&lt;p&gt;SRE teams will provide the capacity when it’s needed and optimize the resources when they’re not required. Ensuring the capacity the system will need when there’s a demand for it is vital to maintaining the system’s availability.&lt;/p&gt;
&lt;p&gt;The above list of practices and principles will not be a surprise for an operations team—it’s what they traditionally do. What’s different about the software engineering approach is that it’s working to keep a system reliable under the limits of its availability. The team will be less bored performing manual tasks, they’ll be interrupted less, and as a result, the team will become more creative in finding solutions to complex problems.&lt;/p&gt;
&lt;h2&gt;How does site reliability engineering relate to DevOps?&lt;/h2&gt;
&lt;p&gt;At this point, you’ve probably noticed some similarities in SRE with DevOps. {Link} DevOps isn’t a detailed guide on how to run production systems, which is why everyone has their own way of doing DevOps. Some people even say that DevOps is mainly a cultural mindset. Therefore, SRE looks like DevOps because of the similarity in the practices and principles. But as Google’s engineer says, &lt;a href="https://www.youtube.com/watch?v=uTEL8Ff1Zvk"&gt;SRE is the implementation of DevOps with a clear set of practices.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let’s look at that idea a little more closely. The DevOps movement began with the goal of closing gaps between development and operations but without giving any detailed information on how to do it. That’s one reason why DevOps looks different in every company that decides to implement it. Whereas in SRE, the gap between teams is mostly closed by having the same set of tools and practices.&lt;/p&gt;
&lt;p&gt;At Google, an SRE acts initially as a consultant for a developer’s team, working together with the developers to build the service. Then, developers can hand over managing the system to the SRE when there’s a clear understanding of what to do when something goes wrong—and by this time the system will be quite fault-tolerant and self-healing.&lt;/p&gt;
&lt;p&gt;So SRE is not just another way of saying DevOps, but it’s also not a competitor trying to get rid of DevOps.&lt;/p&gt;
&lt;h2&gt;How to hire a site reliability engineer?&lt;/h2&gt;
&lt;p&gt;By now, an SRE team might look like a good fit for your company.&lt;/p&gt;
&lt;p&gt;So how do you hire a site reliability engineer? Like Benjamin Treynor, that person should have a solid background in software engineering with experience in Unix system internals and networking.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In an SRE role, the engineer will be in charge of running production systems and automating &amp;gt;human labor through software.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;An SRE needs to not only understand code but also be good at creating something from scratch. They should have experience with at least one programming language like Go, Python, or Ruby. An SRE who knows these languages will be able to extend tools like Ansible, Chef, Kubernetes, &lt;a href="https://raygun.com/blog/what-is-docker/"&gt;Docker&lt;/a&gt;, and Terraform.&lt;/p&gt;
&lt;p&gt;A traditional sysadmin is still a good candidate for this role if they are willing to spend significant time figuring out how to reduce toil. (Toil is a term &lt;a href="https://landing.google.com/sre/sre-book/chapters/eliminating-toil/"&gt;explained in the SRE book&lt;/a&gt;—it’s all that repetitive manual work that can be automated but is still being done by a human.) As the system grows, toil grows linearly, demanding more humans for the job. An SRE’s main function will be to reduce toil as much as possible.&lt;/p&gt;
&lt;p&gt;An SRE will also have excellent troubleshooting skills to find solutions to issues and prevent them from happening again. Therefore, an SRE will use meaningful metrics to trigger automatic remediations and start troubleshooting when there’s a new problem, or if automation didn’t solve the problem. An SRE engineer might like to lean on an error monitoring tool.&lt;/p&gt;
&lt;p&gt;Regarding infrastructure, an SRE needs to have experience with infrastructure as code, immutable infrastructure, distributed systems, configuration management, continuous integration, and continuous delivery. In other words, they need the expertise to build a resilient system that is easy to change and evolve over time.&lt;/p&gt;
&lt;p&gt;In a nutshell, if you’re looking to build an SRE team, you should be looking for software engineers with infrastructure experience.&lt;/p&gt;
&lt;h2&gt;SRE isn’t just for Google&lt;/h2&gt;
&lt;p&gt;There’s a lot more to talk about regarding error budgets and SRE practices. I didn’t get into that many details, but hopefully, SRE is more clear now. Even though this way of working was born in Google, it’s not just for the giants of the software world. SREs are now employed by modern software teams to ensure their software is reliable for their customers.&lt;/p&gt;
&lt;p&gt;As software developers take increased responsibility in SRE, there will be an increased reliance on software monitoring tools like &lt;a href="https://raygun.com/"&gt;crash reporting, APM, and real user monitoring&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you want to learn more about SRE, there’s a &lt;a href="https://www.youtube.com/watch?v=uTEL8Ff1Zvk&amp;amp;list=PLIivdWyY5sqJrKl7D2u-gmis8h9K66qoj"&gt;video series from Google&lt;/a&gt; that’s worth watching it. The first SRE book is also available for free, and the latest one is an &lt;a href="https://books.google.es/books?id=fElmDwAAQBAJ&amp;amp;redir_esc=y"&gt;SRE workbook.&lt;/a&gt; More and more companies are already starting to implement SRE, which means that it will only continue to be adopted.&lt;/p&gt;</content><category term="misc"/><category term="sre"/></entry><entry><title>Why Transformational Leadership Is Needed in Every DevOps Initiative</title><link href="https://cmelendeztech.com/posts/2019/02/transformational-devops-leadership.html" rel="alternate"/><published>2019-02-04T00:00:00+01:00</published><updated>2019-02-04T00:00:00+01:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2019-02-04:/posts/2019/02/transformational-devops-leadership.html</id><summary type="html">&lt;p&gt;&lt;img alt="Why Transformational Leadership Is Needed in Every DevOps Initiative" src="/images/Meeting_in_sunny_room_with_figurehead_signifying_transformational_leadership.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Every DevOps initiative needs support from leadership. Without DevOps leadership support, teams won&amp;#8217;t be able to move forward smoothly. Leaders have a significant impact on results—not just with DevOps, but with every change initiative in an organization.&lt;/p&gt;
&lt;p&gt;This time we won&amp;#8217;t talk about DevOps as a tool …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="Why Transformational Leadership Is Needed in Every DevOps Initiative" src="/images/Meeting_in_sunny_room_with_figurehead_signifying_transformational_leadership.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Every DevOps initiative needs support from leadership. Without DevOps leadership support, teams won&amp;#8217;t be able to move forward smoothly. Leaders have a significant impact on results—not just with DevOps, but with every change initiative in an organization.&lt;/p&gt;
&lt;p&gt;This time we won&amp;#8217;t talk about DevOps as a tool or from a cultural perspective—although leaders very much influence culture. There are a few foundations in leadership that guarantee the success of a DevOps initiative, so that&amp;#8217;s what we&amp;#8217;ll be looking at in this post.&lt;/p&gt;
&lt;p&gt;So let&amp;#8217;s start by properly defining what transformational leadership is.&lt;/p&gt;
&lt;p&gt;&lt;span id="more-1293"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;What Is Transformational Leadership?&lt;/h2&gt;
&lt;p&gt;Leadership is about showing your group the way toward its goals. A team is guided by its leader, but that&amp;#8217;s not because the leader demands they follow.&lt;/p&gt;
&lt;p&gt;Good leaders are the types of people that others follow because they identify with them. But only a few leaders have the power to truly transform the team. &lt;a href="https://en.wikipedia.org/wiki/Transformational_leadership"&gt;Wikipedia&lt;/a&gt; defines transformational leadership as:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;A style of &lt;a title="Leadership" href="https://en.wikipedia.org/wiki/Leadership"&gt;leadership&lt;/a&gt; where a leader works with teams to identify needed change, creating a &lt;a class="mw-redirect mw-disambig" title="Vision (disambiguation)" href="https://en.wikipedia.org/wiki/Vision_(disambiguation)"&gt;vision&lt;/a&gt; to guide the change through inspiration, and executing the change in tandem with committed members of a group.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;This type of leadership is focused on leaders inspiring and motivating the team to achieve its goals. Leaders will make sure to create the environment so the team feels safe to work with new things, like DevOps. Every DevOps initiative needs support from leaders, who in turn need to understand the value and the outcomes of implementing DevOps.&lt;/p&gt;
&lt;p&gt;But more importantly, leaders need to be clear that DevOps is not something that has a finish date. DevOps is about continuously improving how we deliver software.&lt;/p&gt;
&lt;p&gt;Some aspects of leadership are essential in every DevOps initiative. According to &lt;a href="https://www.sciencedirect.com/science/article/pii/S1048984304000207"&gt;&lt;span class="title-text"&gt;this study&lt;/span&gt;&lt;/a&gt; on transformational leadership theory, there are five dimensions that explain transformational leadership. Keep reading to find out what they are and how you can include them in your DevOps initiative.&lt;/p&gt;
&lt;h2&gt;Vision&lt;/h2&gt;
&lt;p&gt;Leaders need to know and understand the organization&amp;#8217;s vision so that they can align the team&amp;#8217;s initiatives with the company&amp;#8217;s goals. There are some initiatives that leaders don&amp;#8217;t think add value to the organization. And the team might think that leaders just don&amp;#8217;t like to try new things because, like an old dog that can&amp;#8217;t learn new tricks, they&amp;#8217;ve always done things a certain way.&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s why both leaders and the team need to understand why DevOps leadership is important. It&amp;#8217;s so they&amp;#8217;ll be able to stick to the initiative even when it seems easier to go back to old ways. When there&amp;#8217;s a clear vision of where the company is heading, all DevOps efforts must be aligned with that. For example, if the company&amp;#8217;s goal is to be 100% cloud-based, then you need to consider that in every decision you make about automating deployments. Integrating things like packaging and configuration management and creating resilient applications will become a must.&lt;/p&gt;
&lt;p&gt;Vision is what will keep the DevOps initiative alive, so make sure you&amp;#8217;re clear why you decided to start the journey. But more importantly, every member of the team needs to be on the same page, including the leader.&lt;/p&gt;
&lt;h2&gt;Intellectual Stimulation&lt;/h2&gt;
&lt;p&gt;There will be times the team won&amp;#8217;t feel the need to change. They&amp;#8217;ve been doing things the same way for a long time, so why change it if it&amp;#8217;s working? The problem is that the team might not be aware of a critical fact: if they don&amp;#8217;t innovate, they&amp;#8217;ll take too much time to deliver a change, and the company could be losing a portion of the market share.&lt;/p&gt;
&lt;p&gt;Leaders must challenge the team and not let them settle for practices that have become a comfortable habit. Always ask your team why they&amp;#8217;re doing things a certain way.&lt;/p&gt;
&lt;p&gt;The biggest trap a team can fall into is thinking that things will remain static. This is especially true in our industry, where new technologies and new ways of doing things constantly arise. A good leader will break the status quo and try to get the most from everyone. For example, my boss is always challenging us and creating competition inside the team to get the most from us.&lt;/p&gt;
&lt;p&gt;Or to take another example, in a DevOps initiative, the leader could convince the team that doing manual deployments will continue to be frustrating. Instead (the leader may argue), they should automate deployments so that they can do more interesting things—things like re-architecting and decoupling portions of the system so they can easily achieve continuous delivery.&lt;/p&gt;
&lt;h2&gt;Inspirational Communication&lt;/h2&gt;
&lt;p&gt;Good leaders inspire and motivate the team by being aware of the team&amp;#8217;s morale and then appealing to their emotions. As a leader, you should pay attention to what the team is complaining about &lt;em&gt;and&lt;/em&gt; what they get excited about. Find ways to always keep emotions up. It&amp;#8217;s impossible to be positive all the time, but at least make an effort to create an environment where the team feels motivated.&lt;/p&gt;
&lt;p&gt;And motivation isn&amp;#8217;t always about money. A developer is way more motivated when they feel they can have career advancement and increased autonomy in what they&amp;#8217;re doing.&lt;/p&gt;
&lt;p&gt;When you get to know your team, you&amp;#8217;ll know how to help them to do awesome things.&lt;/p&gt;
&lt;p&gt;The team needs to understand that change is good. And they need to know that they won&amp;#8217;t lose their jobs if they automate the things they&amp;#8217;re doing manually. As a leader, you&amp;#8217;ll want to help them understand that what they&amp;#8217;re doing has an impact in the overall system. Say things like &amp;#8220;If we automate the release pipeline of this system, marketing will be able to run A/B tests to figure out how to increase sales.&amp;#8221;&lt;/p&gt;
&lt;p&gt;Things are going to continue to go wrong sometimes when a team implements DevOps. That means the team will need someone that&amp;#8217;s supportive and constantly motivating them to keep pushing through, which bring us to the next dimension.&lt;/p&gt;
&lt;h2&gt;Supportive Leadership&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://twitter.com/simonsinek"&gt;Simon Sinek&lt;/a&gt; has a &lt;a href="https://www.ted.com/talks"&gt;TED&lt;/a&gt; talk about supportive leadership called &lt;a href="https://www.ted.com/talks/simon_sinek_why_good_leaders_make_you_feel_safe#t-18422"&gt;&amp;#8220;Why Good Leaders Make You Feel Safe,&amp;#8221;&lt;/a&gt; and I highly recommend you watch it. He noted that &amp;#8220;in the military, they give medals to people who are willing to sacrifice themselves so others might gain&amp;#8221; to make the point that leaders make you feel safe. When people feel safe, they start doing things they know the leader would do for them too.&lt;/p&gt;
&lt;p&gt;Instilling fear is never a good way to manage your team. &lt;strong&gt;&lt;a href="https://rollout.io/blog/building-trust-with-your-team/"&gt;Trust is key&lt;/a&gt;. &lt;/strong&gt;You don&amp;#8217;t hire people to follow your orders—you can program a machine to do that. You hire people so that they can solve problems in the best way possible. Sometimes they&amp;#8217;re going to make mistakes, but they shouldn&amp;#8217;t be punished for that. When they&amp;#8217;re punished, they become afraid to try new things and innovation stops.&lt;/p&gt;
&lt;p&gt;As a leader, you should expect and embrace failure. A team will do interesting things in an environment where they can practice without the fear of doing things wrong. They know the leader trusts them. DevOps fosters innovation because it&amp;#8217;s built on the notion that you can &lt;a href="https://rollout.io/blog/devops-metrics/"&gt;recover from failure quickly.&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Personal Recognition&lt;/h2&gt;
&lt;p&gt;Who doesn&amp;#8217;t like to hear a &amp;#8220;thanks, well done!&amp;#8221; when they&amp;#8217;ve just finished their work? Everyone wants to know that their efforts are successful and appreciated.&lt;/p&gt;
&lt;p&gt;When the team feels that the work they&amp;#8217;re doing is being noticed, they&amp;#8217;ll continue doing what leaders reward. If the team is staying late or coming in on weekends to do deployments, always be thankful for it.&lt;/p&gt;
&lt;p&gt;To help your team avoid frustration and burnout, you should apply inspirational communication and intellectual stimulation to challenge them. That way they don&amp;#8217;t have to work extra time and the company will be able to deliver changes more often.&lt;/p&gt;
&lt;p&gt;If a person is proud to work with your team, they&amp;#8217;ll highly recommend the company to others. That&amp;#8217;s a good sign that the environment is the proper one. One way Google was able to make teams do a post-mortem analysis after every incident was to give a &lt;a href="https://landing.google.com/sre/book/chapters/postmortem-culture.html"&gt;visible recognition in the all-hands meeting&lt;/a&gt; from the CEO. Just imagine how proud a person would be if what they did had such an impact that even the CEO was informed.&lt;/p&gt;
&lt;p&gt;In your DevOps initiative, you need to recognize all milestones of improvement. Implementing DevOps will require a lot of discipline and will not be easily achieved. Celebrate your team&amp;#8217;s accomplishments along the way!&lt;/p&gt;
&lt;h2&gt;Once You&amp;#8217;ve Done It, Just Keep Doing It&lt;/h2&gt;
&lt;p&gt;There&amp;#8217;s never, ever going to be enough transformational leadership—once you&amp;#8217;ve done it, you need to keep doing it. Good leaders need to keep pushing the team to achieve new goals. Sharing the company vision with the team will help keep you focused because everyone knows where they&amp;#8217;re heading.&lt;/p&gt;
&lt;p&gt;Try to get the most out of your people. Always challenge them to do better. The worst thing you could think is that there&amp;#8217;s nothing left to improve—things will always change. You easily get the maximum performance from a team if they&amp;#8217;re motivated and you inspire them to take action.&lt;/p&gt;
&lt;p&gt;Lastly, support your team. Things are going to continue to go wrong, but don&amp;#8217;t punish them. Instead, learn from mistakes. Whether you resolve to do better training or you enforce automatic validations, above all, let your team know that mistakes are an opportunity to improve.&lt;/p&gt;</content><category term="misc"/><category term="devops"/></entry><entry><title>Pitfalls with DevOps at Scale</title><link href="https://cmelendeztech.com/posts/2019/01/pitfalls-with-devops-at-scale.html" rel="alternate"/><published>2019-01-28T00:00:00+01:00</published><updated>2019-01-28T00:00:00+01:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2019-01-28:/posts/2019/01/pitfalls-with-devops-at-scale.html</id><summary type="html">&lt;p&gt;Let's get started by defining what DevOps is.&lt;/p&gt;
&lt;p&gt;I know, I know; there are tons of definitions. But the one I like most is from &lt;a href="https://www.skytap.com/blog/gene-kim-on-the-need-for-automated-environment-creation/"&gt;Gene Kim&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;DevOps is those set of cultural norms and technology practices that enable the fast flow of planned work from, among others, development, through …&lt;/p&gt;&lt;/blockquote&gt;</summary><content type="html">&lt;p&gt;Let's get started by defining what DevOps is.&lt;/p&gt;
&lt;p&gt;I know, I know; there are tons of definitions. But the one I like most is from &lt;a href="https://www.skytap.com/blog/gene-kim-on-the-need-for-automated-environment-creation/"&gt;Gene Kim&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;DevOps is those set of cultural norms and technology practices that enable the fast flow of planned work from, among others, development, through tests into operations while preserving world-class reliability, operation and security. &lt;strong&gt;DevOps is not about what you do, but what your outcomes are.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Some might think that because DevOps is hard to implement, it’s not for everyone, especially not large organizations. That’s not true. Outcomes are what really matter, not how you get there. That’s why I like this definition; it shows that DevOps really is for everyone.&lt;/p&gt;
&lt;p&gt;As with almost everything in IT, there are pitfalls that can keep you from reaching your expected outcomes. But before we get into them, remember that for the purposes of this article, we’re looking at DevOps at scale. So first, let’s define our terms.&lt;/p&gt;
&lt;h1&gt;What Does “At Scale” Mean?&lt;/h1&gt;
&lt;p&gt;An organization that’s operating at scale is able to grow to meet greater demand without too much hassle.&lt;/p&gt;
&lt;p&gt;In a small startup, disruptive actions aren’t that difficult to implement—there’s not much to lose, and you need to meet deliverables fast in order to get more funds. With only a few people, it’s easier to communicate and reach agreements. But when more people are involved and the application becomes more critical, things start to change.&lt;/p&gt;
&lt;p&gt;Organizations that run at scale have a whole host of issues to consider that small startups do not. They usually need to deal with compliance and auditors. They have to coordinate many developers, each with a different mindset and knowledge base. And sometimes, they depend on partners in order to solve problems faster, no matter that doing so costs more money in the short term.&lt;/p&gt;
&lt;p&gt;Big, scaled-up organizations also like to make longterm plans and infrequently release app changes because the impact of things going wrong would mean losing tons of money. It’s understandable, then, why these organizations are very cautious of anything that might speed up their work (like &lt;a href="https://www.enov8.com/blog/sand-castles-and-devops-at-scale/"&gt;DevOps&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;So yes, things are different at scale. And at scale, DevOps has some specific pitfalls that you need to take care of.&lt;/p&gt;
&lt;h1&gt;Difficult Coordination Between Teams&lt;/h1&gt;
&lt;p&gt;The more people are involved, the more difficult it is to coordinate teams. That’s not just because as humans we’re not great communicators. It’s also because having more people means that there are more dependencies and applications are more complex.&lt;/p&gt;
&lt;p&gt;Not knowing the application’s dependencies is a big pitfall that can keep you from being able to confidently release code. If you don’t know how parts of your application relate to each other, you might end up fixing one thing while breaking another. It’s necessary to have a shared understanding of the impact of each component in the system.&lt;/p&gt;
&lt;p&gt;I’ve heard that at Netflix there’s no single person that knows every part of the system in detail. That’s problematic, and that’s why &lt;a href="https://apievangelist.com/2012/01/12/the-secret-to-amazons-success-internal-apis/"&gt;Jeff Bezos says&lt;/a&gt; that, at Amazon, developers should always think about exposing services through APIs. Doing so means that every interaction between different teams is clearly documented, and everyone works in a culture that values knowledge-sharing.&lt;/p&gt;
&lt;h1&gt;Picking the Wrong Projects&lt;/h1&gt;
&lt;p&gt;You can’t &lt;a href="https://www.barrypopik.com/index.php/new_york_city/entry/how_do_you_eat_an_elephant"&gt;eat an elephant&lt;/a&gt; in one piece; you need to eat it in small chunks. And you can’t apply DevOps to the organization all at once; you need to do it little by little. Every time you choose a project, you need to know all its dependencies, its impact, and how stable it is. This is especially crucial for the first project.&lt;/p&gt;
&lt;p&gt;You first need to establish some base knowledge and start simple. Don’t get overwhelmed because everyone is talking about cool things like infrastructure as code, containers, or microservices. Sure, those things can help, but you don’t need all of that to improve the outcomes of DevOps. Why don’t you simply start by getting rid of manual changes like deployments and leaving a trace to make changes visible?&lt;/p&gt;
&lt;p&gt;Find out what aspects of your application are not adding value and focus on those. Automation is just one example.&lt;/p&gt;
&lt;p&gt;When starting out, pick a project that is complex enough to do interesting things and that has a low enough impact on revenue so as not to make too big a mess things don’t go well. You can then scale and replicate what you learn in the process. Soon you’ll see better outcomes as an organization, not just by project.&lt;/p&gt;
&lt;p&gt;Picking the wrong projects could make everyone think that DevOps is making things worse.&lt;/p&gt;
&lt;h1&gt;Lack of a Well-Established Framework&lt;/h1&gt;
&lt;p&gt;Employees last an average of &lt;a href="http://www.businessinsider.com/employee-retention-rate-top-tech-companies-2017-8"&gt;two years in the big tech companies&lt;/a&gt;. Make sure you’ve established a framework that works for you before scaling DevOps. This will help with both onboarding new employees and ensuring that when someone leaves, his or her knowledge will be retained.&lt;/p&gt;
&lt;p&gt;Just make sure you don’t create strict rules that are too difficult to change. For instance, you could make practices like infrastructure as code mandatory because you’ve noticed that the labor of maintaining infrastructure is not adding value. But you could let the team choose which tool to use to implement infrastructure as code.&lt;/p&gt;
&lt;p&gt;Other practices you build into your framework could include trunk-based development, feature flags, test-driven development (TDD), not SSH’ing to servers and using centralized logging, among others.&lt;/p&gt;
&lt;p&gt;Let’s take the Google example. Google runs production systems at scale by having site reliability engineers (&lt;a href="https://landing.google.com/sre/"&gt;SREs&lt;/a&gt;) that sometimes function as temporal consultants. SREs make sure that the team stabilizes the project such that it gets more reliable. They have a checklist of things that the team needs to do to make sure ensuing changes comply with Google’s standards.&lt;/p&gt;
&lt;p&gt;Large organizations need a standardized way of working; otherwise, the turnover will be too problematic.&lt;/p&gt;
&lt;h1&gt;Lack of Production-Like Environments&lt;/h1&gt;
&lt;p&gt;Production-like environments could be difficult and expensive if you don’t start out with the mindset of working with homogeneous environments when creating the systems.&lt;/p&gt;
&lt;p&gt;Preparing test environments is no easy task; preparing production-like environments is even trickier. But if this process is not automated as self-service, the path to deploying in production could be painful.&lt;/p&gt;
&lt;p&gt;Having a production-like environment doesn’t mean you’ll have an exact copy of the environment for development or testing. It means that if in production you have, say, a load balancer, you also have a load balancer everywhere else.&lt;/p&gt;
&lt;p&gt;Your production-like environments do not have to be at the same scale as those in production. But quantity and capacity of the resources should be your only difference—unless you need to do performance testing, but that should be a matter of scaling out the infrastructure.&lt;/p&gt;
&lt;p&gt;Why is having homogeneous environments important? Well, they’ll let you do deployments the same way in all environments and run experiments before you go live. You don’t want any surprises when you make changes available to your users.&lt;/p&gt;
&lt;h1&gt;Lack of Meaningful Metrics&lt;/h1&gt;
&lt;p&gt;How sure are you that the things you’re doing are adding value? What’s the impact of automating certain manual processes? If you’re automating something that’s rarely used, the effort may not be worth it. If you’re using trunk-based development and spending too much time resolving merge conflicts, maybe you should switch to short-lived branches instead.&lt;/p&gt;
&lt;p&gt;It’s important that every decision you make is based on data, not assumptions or because everyone is doing it. According to the &lt;a href="https://puppet.com/resources/whitepaper/state-of-devops-report"&gt;state of DevOps report from last year&lt;/a&gt;, these are the key metrics you should be measuring:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Deployment frequency. Small batches are less risky.&lt;/li&gt;
&lt;li&gt;Time it takes to do deployments. It should be a deterministic and boring task.&lt;/li&gt;
&lt;li&gt;Number of times a deployment has failed. There might be things you didn’t consider before going live.&lt;/li&gt;
&lt;li&gt;Time it takes to recover from a failure. Things like rollbacks or self-healing architectures could help.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Measure meaningful things. Otherwise, you won’t know what’s working to improve the outcomes of DevOps.&lt;/p&gt;
&lt;h1&gt;Know Your Weakness and Get Stronger&lt;/h1&gt;
&lt;p&gt;DevOps outcomes take time to be seen. That’s to be expected—you need cultural change before you can make real progress with different processes like DevOps. And changing people’s mindsets is usually hard to do. It’s in our nature as humans to avoid the feeling of discomfort that accompanies change.&lt;/p&gt;
&lt;p&gt;In your continuous DevOps journey, measurement is crucial. You need to know what and where your weaknesses are in order to get stronger and achieve better outcomes for the organization. All industries and organizations are different. Some will encounter all the pitfalls I mentioned in this list; others, only a few.&lt;/p&gt;
&lt;p&gt;Remember: DevOps can benefit your organization only as long as you set yourself up for success. If you’re putting time and effort into improving outcomes but aren’t adding value, you aren’t serving the organization. Check to make sure you aren’t falling prey to one of these pitfalls before applying DevOps at scale.&lt;/p&gt;</content><category term="misc"/><category term="devops"/></entry><entry><title>Getting Started Quickly With Go Logging</title><link href="https://cmelendeztech.com/posts/2019/01/go-logging.html" rel="alternate"/><published>2019-01-21T00:00:00+01:00</published><updated>2019-01-21T00:00:00+01:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2019-01-21:/posts/2019/01/go-logging.html</id><summary type="html">&lt;p&gt;It's time to talk about how to get started with logging again. The languages we've covered so far are &lt;a href="http://blog.scalyr.com/2017/12/get-started-quickly-c-logging/"&gt;C#&lt;/a&gt;, &lt;a href="http://blog.scalyr.com/2018/01/get-started-quickly-java-logging/"&gt;Java&lt;/a&gt;, &lt;a href="https://blog.scalyr.com/2018/02/started-quickly-python-logging/"&gt;Python&lt;/a&gt;, &lt;a href="http://blog.scalyr.com/2018/03/getting-started-quickly-ruby-logging/"&gt;Ruby&lt;/a&gt;, &lt;a href="http://blog.scalyr.com/2018/04/getting-started-quickly-node-js-logging/"&gt;Node.js&lt;/a&gt;, and &lt;a href="https://blog.scalyr.com/2018/05/get-started-quickly-javascript-logging/"&gt;JavaScript&lt;/a&gt;. Today, we're going to be talking about the &lt;a href="https://golang.org/"&gt;Go&lt;/a&gt; programming language, also known as Golang. Go is a statically compiled, &lt;a href="https://github.com/golang/go"&gt;open-source&lt;/a&gt; programming language …&lt;/p&gt;</summary><content type="html">&lt;p&gt;It's time to talk about how to get started with logging again. The languages we've covered so far are &lt;a href="http://blog.scalyr.com/2017/12/get-started-quickly-c-logging/"&gt;C#&lt;/a&gt;, &lt;a href="http://blog.scalyr.com/2018/01/get-started-quickly-java-logging/"&gt;Java&lt;/a&gt;, &lt;a href="https://blog.scalyr.com/2018/02/started-quickly-python-logging/"&gt;Python&lt;/a&gt;, &lt;a href="http://blog.scalyr.com/2018/03/getting-started-quickly-ruby-logging/"&gt;Ruby&lt;/a&gt;, &lt;a href="http://blog.scalyr.com/2018/04/getting-started-quickly-node-js-logging/"&gt;Node.js&lt;/a&gt;, and &lt;a href="https://blog.scalyr.com/2018/05/get-started-quickly-javascript-logging/"&gt;JavaScript&lt;/a&gt;. Today, we're going to be talking about the &lt;a href="https://golang.org/"&gt;Go&lt;/a&gt; programming language, also known as Golang. Go is a statically compiled, &lt;a href="https://github.com/golang/go"&gt;open-source&lt;/a&gt; programming language created by Google in 2009. It runs on Windows, Linux, and Mac and has been increasingly adopted in the last couple of years because of its simplicity and concurrency mechanisms. And in case you didn't know, &lt;a href="https://github.com/moby/moby"&gt;Docker&lt;/a&gt; and &lt;a href="https://github.com/kubernetes/kubernetes"&gt;Kubernetes&lt;/a&gt; were written in Go. Go is quite an interesting language when we talk about logging. Why? For one thing, it includes a really simple native library for logging. But the most interesting thing is that in Go there are no &lt;a href="https://dave.cheney.net/2012/01/18/why-go-gets-exceptions-right"&gt;exceptions&lt;/a&gt;—only errors. That means when you want to log application errors, things get interesting. We'll cover that later in this post. But let's start by taking a look at how easily you can get started logging in Go.&lt;/p&gt;
&lt;p&gt;&lt;img alt="gopher scalyr" src="/images/Go-Beaver-With-Scalyr-Colors.png"&gt;&lt;/p&gt;
&lt;h1&gt;The Simplest Go Logging That Could Possibly Work&lt;/h1&gt;
&lt;p&gt;Personally, I prefer to use the &lt;a href="https://www.jetbrains.com/go/"&gt;JetBrains &lt;/a&gt;offer for Go, but in this tutorial, I'm going to use &lt;a href="https://github.com/Microsoft/vscode-go"&gt;VS Code&lt;/a&gt; because it's free. Let's start by creating an empty folder. In my case, I created the folder at &lt;strong&gt;C:\Projects\go\go-logging&lt;/strong&gt;. Open VS Code. Then, click on &lt;strong&gt;File &amp;gt; Open Folder&lt;/strong&gt;. &lt;img alt="" src="/images/go-logging/golog-vs-new-folder.jpg"&gt; Go to the location of the folder you just created and select it by clicking on the &lt;strong&gt;Select Folder&lt;/strong&gt; button: &lt;img alt="" src="/images/go-logging/golog-vs-select-folder.jpg"&gt; In the left panel of VS Code, click on the icon indicated below to create a new file. &lt;img alt="" src="/images/go-logging/golog-vs-create-file.png"&gt; Name the new file &lt;strong&gt;console.go&lt;/strong&gt;. The left panel should look like this now: &lt;img alt="" src="/images/go-logging/golog-vs-console-file.jpg"&gt; As I mentioned before, Go has a simple native logging library that you can use. By default, the output goes to the standard error of printing the date and time of the messages logged in the application. The simplest &lt;a href="https://github.com/christianhxc/go-logging/blob/master/console/console.go"&gt;code&lt;/a&gt; that you can use to write logs is the following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;log&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Logging in Go!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In order to easily test the code without leaving VS Code, let's enable the terminal by clicking on &lt;strong&gt;View &amp;gt; Integrated Terminal&lt;/strong&gt;. &lt;img alt="" src="/images/go-logging/golog-vs-enable-terminal.jpg"&gt; Because Go is a compiled language, we need to compile it by running the following command in the terminal:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There shouldn't be any errors when running this command—the absence of a message means it succeeded. &lt;img alt="" src="/images/go-logging/golog-vs-build-console.jpg"&gt; In the same terminal, run the following command to execute the compiled program:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;.\\console.exe
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The terminal will display the date, time, and message logged, like this: &lt;img alt="" src="/images/go-logging/golog-vs-run-console.jpg"&gt; Great—it works! But what if we need to store the logged messages in files? For that, you need to create a new file (or open an existing file), then set that file as the output of the log, like the following &lt;a href="https://github.com/christianhxc/go-logging/blob/master/file/file.go"&gt;code&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;log&amp;quot;&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;os&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OpenFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;info.log&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;O&lt;/span&gt;\&lt;span class="n"&gt;_CREATE&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;O&lt;/span&gt;\&lt;span class="n"&gt;_APPEND&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0644&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetOutput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Logging to a file in Go!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now go back to the terminal and build and run the program. This time, no output will appear in the terminal because it was written to the file. &lt;img alt="" src="/images/go-logging/golog-vs-log-file.jpg"&gt; In the left panel, you'll see the &lt;strong&gt;info.log&lt;/strong&gt; file. Open it, and the same message you saw in the terminal should appear here: &lt;img alt="" src="/images/go-logging/golog-vs-log-message-file.jpg"&gt; And that's it! You just created your first Go logger. But as simple and easy as this could be, hello-world examples are not enough. Log messages could get messy and difficult to read if we continue logging manually like we just did. We need to know a few other things before we can seriously integrate logging into our applications.&lt;/p&gt;
&lt;h1&gt;What Is Application Logging?&lt;/h1&gt;
&lt;p&gt;Let's take Erik's definition from the &lt;a href="http://blog.scalyr.com/2017/12/get-started-quickly-c-logging/"&gt;first logging series post&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Application logging involves recording information about your application’s runtime behavior to a more persistent medium.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So what exactly does that mean? When problems arise, we want to know what caused the issue. I wish I could be physically inside the server to watch what's happening in real time to spot the problem. But as far as I know, humans can't be inside a server physically or virtually. Right? But seriously, in a world where containers are getting more attention every day and the cloud is becoming de facto, instances of our application are very volatile. One day you could have access to logs on a server, and the next day the server could be gone. Even if you stored your logs in files locally, you lose valuable information when things like this happen. You need to have a persistent medium so that you can do post-mortem analysis more accurately.&lt;/p&gt;
&lt;h1&gt;Why Bother Logging? What’s the Motivation?&lt;/h1&gt;
&lt;p&gt;I remember my first days at a new job several years ago. I was learning how the application worked, and one day I decided to pair-troubleshoot in production with one of the original programmers. At that time, the company was a startup, so developers had access to production servers. In order to know what was wrong with the application, we needed to scratch the log files. But the application depended on several microservices, and there were times that one of those services was down. The problem wasn't really that one service was down. The problem was that we had to go through several files before we knew what was happening. So we decided to change the approach and started sending the log files to a centralized logging platform—a more persistent medium. When you have application logging in place, you'll be able to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Resolve problems faster because you won't need to go to each server to read logs.&lt;/li&gt;
&lt;li&gt;Have a standard format to quickly spot issues. (If you read logs on a server, log formats can vary greatly from one application to another.)&lt;/li&gt;
&lt;li&gt;Enable visibility to everyone that needs it. When you move logs to a centralized place, you can easily give access to developers so they can see for themselves what's happening with the application without having access to the servers. It also helps you avoid the temptation to implement a fixhr inside the servers that could make things worse.&lt;/li&gt;
&lt;li&gt;Automate notifications so you know when problems are happening. You might be able to catch and fix problems before your users notice it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In a nutshell, you need application logs to go back in time and understand how the application behaves in the real world.&lt;/p&gt;
&lt;h1&gt;What Should You Log?&lt;/h1&gt;
&lt;p&gt;The data that companies are storing with applications are becoming more relevant each day. Want proof? Think of the companies going to court to explain what they're doing with the data they collect. Or consider compliance initiatives like GDPR, SOX, or HIPAA. We need to be careful about what we put on those log files. And let's be honest—there's a lot of data we'll never need. Let me give you a short list of what I've found useful to log:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Date and time of the event in a standard timezone like UTC.&lt;/li&gt;
&lt;li&gt;In distributed systems, a tracking flag to replicate the request across all the different points of the system.&lt;/li&gt;
&lt;li&gt;Data that will help you to understand and make diagnostics of the application—things like error stacks, the external service name, header's request, the URL path and its parameters, and similar kinds of data that will help you to reproduce the error and understand what happened.&lt;/li&gt;
&lt;li&gt;Context data that you might need for all events like the ones I mentioned before so logging doesn't get bulky in code.&lt;/li&gt;
&lt;li&gt;The environment where the application is running—you could easily ignore anything else that's not production.&lt;/li&gt;
&lt;li&gt;The IP address of the server so you'll know where the problem is.&lt;/li&gt;
&lt;li&gt;Log levels such as panic, fatal, debug, or informational logs to give more context.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With the above data, I've been able to spot problems quickly and easily. Now, let's take a look at how you can easily log in Go by using a logging framework. With the simple approach we saw before, we might have some spaghetti code that will be hard to maintain and extend.&lt;/p&gt;
&lt;h1&gt;Enter the Logging Framework&lt;/h1&gt;
&lt;p&gt;Logging is an already-solved problem, and there are &lt;a href="http://blog.scalyr.com/2017/09/logging-framework/"&gt;logging frameworks&lt;/a&gt; that will help you log easily. A framework will let you do the same things we did at the beginning of this guide but with fewer lines of code and a standard way of logging. Logging frameworks cover almost all common scenarios, so it's better that you choose a framework rather than do everything manually like in my first example. (The only case where I'd say you need to think twice about which framework you use is if your application's performance is crucial.) In the Go ecosystem, there are actually a lot of logging frameworks. You can see them listed on the &lt;a href="https://github.com/avelino/awesome-go#logging"&gt;Awesome Go page on GitHub&lt;/a&gt;. The two most popular logging frameworks are &lt;a href="https://github.com/golang/glog"&gt;Glog&lt;/a&gt; and &lt;a href="https://github.com/Sirupsen/logrus"&gt;Logrus&lt;/a&gt;. Google is the author of Glog. It keeps the simple style from Go, but no one has updated the GitHub repository for two years now. On the other hand, Logrus has been constantly supported by the community. In this guide, I'm going to use Logrus. Now, even though I like Glog's simplicity, there are valuable things from Logrus that might be worth taking a look.&lt;/p&gt;
&lt;h1&gt;Getting Started With Logrus&lt;/h1&gt;
&lt;p&gt;Let's start by installing the Logrus module by running the following command in the terminal of your computer:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;github.com/Sirupsen/logrus&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We'll keep updating the code that we used before just to demonstrate how easily you could introduce logging frameworks in Go without having to change too many things in the code. So let's replace the &lt;strong&gt;log&lt;/strong&gt; import with the Logrus import, like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;os&amp;quot;&lt;/span&gt;

    &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;github.com/sirupsen/logrus&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Keep everything as it's now in the code and run it. The output of the log will look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;2018&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;05&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;22&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;17&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;02&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;43&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Log&lt;/span&gt;&lt;span class="n"&gt;ging&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;Go&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt;
&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;2018-05-22T17:33:03-06:00&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Logging to a file in Go!&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A new line was added but in a different format: the default Logrus format. We're still seeing the timestamp and the messages logged, but we're also seeing the &lt;strong&gt;info&lt;/strong&gt; level. What does "level=info" mean? It's the category of a message in the log. And &lt;strong&gt;why would you need levels in logs?&lt;/strong&gt; Well, let's explain that with some readable code from &lt;a href="https://github.com/sirupsen/logrus"&gt;logrus GitHub&lt;/a&gt; page:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;log&lt;/span&gt;.&lt;span class="nv"&gt;Debug&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Useful debugging information.&amp;quot;&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;log&lt;/span&gt;.&lt;span class="nv"&gt;Info&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Something noteworthy happened!&amp;quot;&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;log&lt;/span&gt;.&lt;span class="nv"&gt;Warn&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;You should probably take a look at this.&amp;quot;&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;log&lt;/span&gt;.&lt;span class="nv"&gt;Error&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Something failed but I&amp;#39;m not quitting.&amp;quot;&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Calls&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;os&lt;/span&gt;.&lt;span class="k"&gt;Exit&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;after&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;logging&lt;/span&gt;
&lt;span class="nv"&gt;log&lt;/span&gt;.&lt;span class="nv"&gt;Fatal&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Bye.&amp;quot;&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Calls&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;panic&lt;/span&gt;&lt;span class="ss"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;after&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;logging&lt;/span&gt;
&lt;span class="nv"&gt;log&lt;/span&gt;.&lt;span class="nv"&gt;Panic&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;I&amp;#39;m bailing.&amp;quot;&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Order lines here are very important. I'll explain why later in this guide. Log levels don't just give more context to the logged message by categorizing in groups. Log levels are also useful when you don't need to have too much information about the application's behavior. And vice-versa, there will be times when you'll need to have all the information available to make a better analysis. This will also help you make better use of the storage or data transfer in your infrastructure. Let's add some &lt;a href="https://github.com/christianhxc/go-logging/blob/master/logrus/logrus.go"&gt;interesting code&lt;/a&gt; here. Then I'll explain the lines that are adding something different to the application that we've been coding.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;os&amp;quot;&lt;/span&gt;

    &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;github.com/sirupsen/logrus&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OpenFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;info.log&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;O_WRONLY&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;O_CREATE&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;O_APPEND&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0644&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetOutput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSONFormatter&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WarnLevel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithFields&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fields&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;animal&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;walrus&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;size&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;A group of walrus emerges from the ocean&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithFields&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fields&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;omg&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;number&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;122&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;The group&amp;#39;s number increased tremendously!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithFields&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fields&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;omg&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;number&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;The ice breaks!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Let's start with this line:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;log.SetFormatter(&amp;amp;log.JSONFormatter{})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;One of the main purposes of using a framework is to have log data standardized. This is not only because it will be easy to read and understand; it's also because the idea should be to move this log data to a &lt;a href="https://www.scalyr.com/product/centralized-log-management"&gt;centralized logging platform &lt;/a&gt;so that you can read logs from several sources in one place. JSON is the standard format when you want to move logs somewhere else. That's because JSON's key/value style will make it easier to parse the data.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;log.SetLevel(log.WarnLevel)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This line sets the log level we talked about before. Remember when I said earlier that the order of lines is important? The reason is that the log level also sets the importance of the logged message. The first level, &lt;strong&gt;debug&lt;/strong&gt;, is the least important. And the last level, &lt;strong&gt;panic&lt;/strong&gt;, is the most important. When you set a level in the code, as the line above does, you're saying that all the log messages from that level down will be logged. In this case, all debug and info messages won't be written to the log.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;log.WithFields(log.Fields{
    &amp;quot;omg&amp;quot;:    true,
    &amp;quot;number&amp;quot;: 100,
}).Fatal(&amp;quot;The ice breaks!&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I also mentioned that it's important to include some context to the logged messages. In this line, we're doing it by using the &lt;strong&gt;WithFields&lt;/strong&gt; and &lt;strong&gt;Fields&lt;/strong&gt; functions. That's dummy data, but in the real world, you could use a data structure like the request parameters so that you can reproduce the problem. Let's compile and run the application. The log will look like this now:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;2018&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;05&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;22&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;17&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;02&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;43&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Log&lt;/span&gt;&lt;span class="n"&gt;ging&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;Go&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt;
&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;2018-05-22T17:33:03-06:00&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Logging to a file in Go!&amp;quot;&lt;/span&gt;
&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;level&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;warning&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;msg&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;The group&amp;#39;s number increased tremendously!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;number&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;122&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;omg&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;time&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;2018-05-22T17:52:47-06:00&amp;quot;&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;level&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;fatal&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;msg&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;The ice breaks!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;number&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;omg&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;time&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;2018-05-22T17:52:47-06:00&amp;quot;&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can now see the difference between this and other approaches we took in this guide. Only the &lt;strong&gt;warning&lt;/strong&gt; and &lt;strong&gt;fatal&lt;/strong&gt; log messages were written. If you want to take a look at the code, you can check out the &lt;a href="https://github.com/christianhxc/go-logging"&gt;different approaches&lt;/a&gt; I've uploaded to GitHub as examples. I can't stress enough that you need to move these log files to a centralized logging platform. Even though you now have a standard format and it's easy to add logging to your applications, you can't keep going to the servers to read logs. It will be time-consuming as the application keeps growing.&lt;/p&gt;
&lt;h1&gt;Where Do You Go Now?&lt;/h1&gt;
&lt;p&gt;Logging frameworks are there to help you add logs to the application with just a few lines of code. What I really like about these frameworks is that you can guarantee that important data (such as timestamps, context, and log levels) is logged. Log levels can become your best friend when problems arise and you need to troubleshoot. By using log levels, you avoid being ashamed in demos with &lt;a href="https://www.intertech.com/Blog/funny-computer-error-messages/"&gt;funny&lt;/a&gt; log messages that you might accidentally leave in the code. Go's native library for logging is really simple, but if you want to know more about it, you can take a look at the &lt;a href="https://golang.org/pkg/log/"&gt;docs site&lt;/a&gt;. In this post, I only just scratched the surface of Logrus logging framework. You can find useful information and examples by just going to the home page of the project on &lt;a href="https://github.com/Sirupsen/logrus"&gt;GitHub&lt;/a&gt;. You can configure hooks, log messages according to the environment, use formatters, and a lot of other things as per the &lt;a href="https://godoc.org/github.com/sirupsen/logrus"&gt;docs site&lt;/a&gt;. Since we just learned how easy it is to add logs to your applications, there's no reason why you shouldn't! If you're worried about performance, just make sure you can turn off logging or easily change log levels. Trust me, you won't regret it—you'll need logs when you want to find out what's wrong.&lt;/p&gt;</content><category term="misc"/><category term="golang"/></entry><entry><title>Deployment Smells: The 5 Most Common Deployment Mistakes</title><link href="https://cmelendeztech.com/posts/2019/01/deployment-smells-5-most-common-deployment-mistakes.html" rel="alternate"/><published>2019-01-14T00:00:00+01:00</published><updated>2019-01-14T00:00:00+01:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2019-01-14:/posts/2019/01/deployment-smells-5-most-common-deployment-mistakes.html</id><summary type="html">&lt;p&gt;&lt;img alt="Deployment Smells" src="/images/mask.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Deployment shouldn't be the most nerve-racking task for sysadmins when releasing software, but many times it is.&lt;/p&gt;
&lt;p&gt;If we’re deploying application changes to a beta system, we don’t care that much if the system goes down. Neither will your users—they know that beta means “expect problems from …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="Deployment Smells" src="/images/mask.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Deployment shouldn't be the most nerve-racking task for sysadmins when releasing software, but many times it is.&lt;/p&gt;
&lt;p&gt;If we’re deploying application changes to a beta system, we don’t care that much if the system goes down. Neither will your users—they know that beta means “expect problems from time to time.” The same thing applies to new systems that don’t have a large user base yet.&lt;/p&gt;
&lt;p&gt;But what if we’re talking about bigger systems, like those used by a major online retailer or a bank? Users might get frustrated if they have problems shopping online. They may choose to buy from a different store as a result. And they’ll be furious if they aren’t able to access their bank account to make a withdrawal. Even if it’s just for a small fraction of time, companies lose credibility every time their systems are down or malfunctioning.&lt;/p&gt;
&lt;p&gt;Deployments tend to get really difficult. Just &lt;em&gt;how&lt;/em&gt; difficult is proportional to the complexity of the system you’re working with. The more dependencies the system has, the riskier and more problematic deployments get. But what are the common mistakes that we’ve all made?&lt;/p&gt;
&lt;h1&gt;1 Not Enough Automation&lt;/h1&gt;
&lt;p&gt;Manual deployments &lt;strong&gt;lack consistency&lt;/strong&gt;. So, when a significant portion of your procedures are manual, you wind up with a big ball of mud. I have suffered the consequences of doing deployments manually. I vividly remember one time when the site was down intermittently because I forgot to upload the binary files to 1/4 of the servers in the farm.&lt;/p&gt;
&lt;p&gt;With the rise of DevOps, automation is becoming de facto. But don’t get overwhelmed if your process is still largely manual. You don’t need to stop what you’re doing and automate everything. I’ve always loved the &lt;a href="https://medium.com/@biratkirat/step-8-the-boy-scout-rule-robert-c-martin-uncle-bob-9ac839778385"&gt;boy scout rule&lt;/a&gt; to leave things better than you found them. It’s OK to start manually because it’ll help you understand how everything works. But &lt;strong&gt;do&lt;/strong&gt; identify where automation can be used_._ You might want to be able to go from 0 to 100 to declare the task of automating your process “complete,” but &lt;strong&gt;automation should be done progressively and continuously&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The only manual thing you might want to have is someone approving the release, but even that should be a matter of just clicking a button. So, it’s not just about copying and pasting things; it’s also about configuration management, infrastructure, on-demand environments, and so on.&lt;/p&gt;
&lt;p&gt;When you automate, you &lt;strong&gt;foster communication&lt;/strong&gt;. If there’s only one way to make changes in deployment, everyone will know the what, why, and how of things. And if everyone is in the know, the guy or gal that solved a complex deployment problem can go on vacation without having their mai-tai-at-the-beach time interrupted by a clueless colleague back at the office.&lt;/p&gt;
&lt;h1&gt;2 Different Environment, Different Way&lt;/h1&gt;
&lt;p&gt;I once fell into the trap of automating deployments by environment. In my case, there were four environments: dev, QA, staging, and production. I took my time to finish with the dev environment. Then I needed to replicate those changes in the other environments. The problem was that the deployment process for each environment was completely different in most cases.&lt;/p&gt;
&lt;p&gt;I’m a big fan of the &lt;a href="https://12factor.net/"&gt;twelve-factor app methodology.&lt;/a&gt; Regarding deployments, it says that you need to keep &lt;a href="https://12factor.net/config"&gt;config values in the environment&lt;/a&gt;, not in the application or any file. It also says that &lt;a href="https://12factor.net/dev-prod-parity"&gt;environments should be as similar as possible&lt;/a&gt;—not in size, but in style.&lt;/p&gt;
&lt;p&gt;In other words, if you lack production-like environments, you’ll be lying when you say you’re ready to deploy to production. I’ve seen it, I’ve suffered it, and I stopped treating production as some sacred environment to be feared.&lt;/p&gt;
&lt;p&gt;When I was part of a project where we Dockerized the system, I understood this very clearly. I used concepts like immutable infrastructure, infrastructure as code, &lt;a href="https://b64dfcc9be0841a304a4b791-ktdx9ecoa3h.netdna-ssl.com/wp-content/uploads/Test-Environment-Management-Datasheet.pdf"&gt;environment configuration management&lt;/a&gt;, cloud, and deployment definition files with Kubernetes as pieces of the deployment puzzle to make things easier.&lt;/p&gt;
&lt;h1&gt;3 Waiting for Low-Traffic Time Slots&lt;/h1&gt;
&lt;p&gt;Any time you hear (or say) “Let’s wait for the weekend to make this deployment,” it’s a sign the deployment pipeline isn’t trustworthy. You’re still treating production significantly differently from other environments.&lt;/p&gt;
&lt;p&gt;Netflix and the other “unicorns” in the industry say they actually do deployments during regular work hours. After all, that’s when everyone is together and ready to react properly if there’s an incident. I know you might not be as big as the unicorns, but there’s nothing special about them aside from one thing: they experience problems at a really large scale. That forces them to change the way they’re doing things.&lt;/p&gt;
&lt;p&gt;As I said before, you probably do deployments during low-traffic hours or over the weekends because you want to prevent any downtime in the system. But instead of living in fear of screwing things up, why don’t you set the foundation to experiment?&lt;/p&gt;
&lt;p&gt;Do deployment strategies like feature flags, canary releases, blue/green deployments, or rolling updates ring a bell? Maybe, maybe not. Either way, these are great strategies that help you make deployments without users noticing it. And it’s a way to avoid stealing family time away from the staff.&lt;/p&gt;
&lt;h1&gt;4 Waiting Until Enough Changes Accumulate&lt;/h1&gt;
&lt;p&gt;Do you have changes that are ready to be deployed? Why wait? To take one out of Nike’s book, just do it!&lt;/p&gt;
&lt;p&gt;OK, so maybe something official is delaying you. Maybe you’re waiting for the change advisory board (CAB) to approve the changes based on the risk. I’ve been there too. But maybe you just need to improve communication by automating some steps in the process. These changes don’t come overnight—it takes time for the CAB to trust the process.&lt;/p&gt;
&lt;p&gt;Another reason why organizations wait to do deployments until enough changes have been accumulated is, again, to reduce downtime. Downtime usually happens because you’re changing something. It rarely happens because of nightmarish things like the cloud provider going down, fires, earthquakes, and so on.&lt;/p&gt;
&lt;p&gt;But I’ll say it again: don’t wait! Work to build a culture that deploys frequently and in small batches. If it hurts, do it more often. Every sprint, you can deploy something that can easily be disabled with a feature flag. Once you decide it’s ready to be used by everyone, turn the feature on to release the changes.&lt;/p&gt;
&lt;p&gt;When you deploy too many things at once, you don’t know which of those things might be causing problems. And when you don’t know what’s causing problems, you have to roll back &lt;em&gt;everything&lt;/em&gt;, including perfectly functional features that may have been really critical for the system.&lt;/p&gt;
&lt;h1&gt;5 A Lack of Subsequent Feedback&lt;/h1&gt;
&lt;p&gt;You might have good monitoring and observability for your systems, but how sure are you that problems are being caused by a recent deployment and not by something else? There are lots of possible factors, such as internet problems, cloud provider issues, and an increase in traffic.&lt;/p&gt;
&lt;p&gt;Another problem is that after a deployment, we tend to monitor changes for a while and then forget about it. But if you end up working with feature flags, it can take some time to activate or release a change. For that reason, it’s important that you have a smart way to correlate events, logs, and any other information you’ve found useful as you’ve learned the system’s behavior.&lt;/p&gt;
&lt;p&gt;It’s also important that you have feedback after deployments because that’s how you’ll know if something needs to be rolled back. Without reliable feedback, any issues will just continue to affect your users. Let your team know when a deployment and release happen. It could be as simple as a Slack message in a channel. That way, people can “subscribe” to get notified, ask questions, and learn how the team solves problems.&lt;/p&gt;
&lt;h1&gt;Shift Deployments to the Left&lt;/h1&gt;
&lt;p&gt;In a nutshell, don't treat production differently from your other environments. If you want to have a high rate of successful deployments, practice them before going live. I've even been in the situation of announcing a release to the CAB for a certain date and then having to delay release dates because we found problems when we were launching the B side of our blue/green deployment.&lt;/p&gt;
&lt;p&gt;I've also come to the conclusion that most of the things I've written here are more of a cultural change than anything else—a mindset that has to be adopted by the team that's involved in building the software, not just developers and operations.&lt;/p&gt;
&lt;p&gt;Start small and keep analyzing areas where you're consistently struggling during deployment. Then improve. The end goal should be that, at some point, you might leave releases to marketing or management because you already took care of doing deployments with almost no downtime.&lt;/p&gt;
&lt;p&gt;And how do you get there? Practice until you've mastered deployments.&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="deployment"/></entry><entry><title>A Detailed Guide to Canary Deployments</title><link href="https://cmelendeztech.com/posts/2018/10/canary-deployments.html" rel="alternate"/><published>2018-10-22T00:00:00+02:00</published><updated>2018-10-22T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-10-22:/posts/2018/10/canary-deployments.html</id><summary type="html">&lt;p&gt;&lt;img alt="A Detailed Guide to Canary Deployments" src="/images/A-Detailed-Guide-to-Canary-Deployments-881x441.png"&gt;&lt;/p&gt;
&lt;p&gt;Every time we need to deploy to production, we worry about how changes will affect the user experience. No matter what &lt;a href="https://thenewstack.io/deployment-strategies/"&gt;technique or strategy&lt;/a&gt; you use to make deployments, there are going to be times when the things that &lt;em&gt;can&lt;/em&gt; go wrong &lt;em&gt;will&lt;/em&gt; go wrong. It’s &lt;a href="https://en.wikipedia.org/wiki/Murphy%27s_law"&gt;Murphy’s law …&lt;/a&gt;&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="A Detailed Guide to Canary Deployments" src="/images/A-Detailed-Guide-to-Canary-Deployments-881x441.png"&gt;&lt;/p&gt;
&lt;p&gt;Every time we need to deploy to production, we worry about how changes will affect the user experience. No matter what &lt;a href="https://thenewstack.io/deployment-strategies/"&gt;technique or strategy&lt;/a&gt; you use to make deployments, there are going to be times when the things that &lt;em&gt;can&lt;/em&gt; go wrong &lt;em&gt;will&lt;/em&gt; go wrong. It’s &lt;a href="https://en.wikipedia.org/wiki/Murphy%27s_law"&gt;Murphy’s law&lt;/a&gt;. The fact of the matter is you can’t always prevent errors when deploying changes. But what you can do is prevent downtime after a deployment from becoming the norm. One way you can minimize downtime is by implementing canary deployments.&lt;/p&gt;
&lt;p&gt;It doesn’t matter what type of application you have—canary deployments can be applied whether it’s a website, desktop, or mobile app. They also work with on-premises, cloud, or hybrid infrastructures. Containers? You bet. In this post, I’ll be demonstrating how to do canary deployments using &lt;a href="https://stackify.com/kubernetes-docker-deployments/"&gt;Docker and Kubernetes&lt;/a&gt; as a hands-on example.&lt;/p&gt;
&lt;h3&gt;What is a canary deployment?&lt;/h3&gt;
&lt;p&gt;Let’s start with the origin of the name canary deployment, which comes from an old British mining practice. It’s a little bit cruel. According to &lt;a href="https://www.smithsonianmag.com/smart-news/story-real-canary-coal-mine-180961570/"&gt;Kat Eschner at The Smithsonian&lt;/a&gt;, this practice consisted of using “canaries in coal mines to detect carbon monoxide and other toxic gases before they hurt humans.” To make sure mines were safe for them to enter, miners would send canaries in first; if something bad happened to the canary, it was a warning for the miners to abandon the mine.&lt;/p&gt;
&lt;p&gt;So how is this comparable to software development and deployments?&lt;/p&gt;
&lt;p&gt;Well, when you want to release a new version of an application, you’ll use a canary to make sure the new changes can survive for a broader public. It’s just a matter of defining who the proverbial canary will be. For simplicity, some organizations decide that the canary will be five percent of the traffic. So if something goes wrong with the new changes, only five percent of users will be affected. You can also use more canaries of different colors and sizes in order to increase your confidence in the new changes.&lt;/p&gt;
&lt;p&gt;After you feel confident that the new changes are good to go, you roll out the changes to the rest of users. You can now get rid of the canary since it was only used to make sure the miners (your broader audience) wouldn’t be negatively affected by the new changes.&lt;/p&gt;
&lt;h3&gt;How do you do canary deployments?&lt;/h3&gt;
&lt;p&gt;As I said before, if you want to do canary deployments, the type of application or infrastructure you’re working on isn’t too important—canary deployments are pretty versatile. Let me give you some specific examples of how to do canary deployments on different infrastructures using only one canary.&lt;/p&gt;
&lt;h4&gt;Load balancers&lt;/h4&gt;
&lt;p&gt;If you want to do canary deployments with load balancers, you’ll start by having two of them. Load balancer A will receive 95 percent of the traffic, and load balancer B will get the remaining five percent. We’ll use load balancer B for canary deployments, which means we’ll update the servers behind it first. It doesn’t really matter how many servers are behind each load balancer—the important thing is that traffic is split between the load balancers, not the servers.&lt;/p&gt;
&lt;p&gt;(Note that you can do canary deployments without load balancers, but it’s easier with them because you can take the server you’re updating out of the rotation.)&lt;/p&gt;
&lt;p&gt;When you’re done updating the servers, you monitor and test for a while. If you don’t like the results in load balancer B, you can roll back and finish the release. But if the new changes are good to go, you can proceed to update the servers that are behind load balancer A.&lt;/p&gt;
&lt;h4&gt;Amazon Web Services (AWS)&lt;/h4&gt;
&lt;p&gt;If you want to do canary deployments with AWS, you’ll use their service called &lt;a href="https://aws.amazon.com/route53/"&gt;Route 53&lt;/a&gt;, which lets you use weighted records to split the traffic 95/5, like we did before. Or you can use auto-scaling groups, if you don’t want to mess with DNS TTLs.&lt;/p&gt;
&lt;p&gt;But if you don’t care that much about having a strict split like that, you can get the same results using &lt;a href="https://docs.aws.amazon.com/autoscaling/ec2/userguide/AutoScalingGroup.html"&gt;Auto Scaling groups&lt;/a&gt; (ASG). The magic of ASG is that, even if you have more than one ASG, you only need one &lt;a href="https://aws.amazon.com/elasticloadbalancing/"&gt;Elastic Load Balancer&lt;/a&gt; (ELB) because you’ll be attaching all the ASGs to the same ELB. This balances the load between ASGs. So let’s say that one ASG has nine instances (three for each availability zone). A second ASG has only one instance. This gives you a total of ten instances. Then, if we use the second ASG as a canary, you’ll have 1/10 instances for that purpose.&lt;/p&gt;
&lt;p&gt;To do canary deployments with ASGs, you apply the same technique as with load balancers but modify it slightly. You update the ASG with the new &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html"&gt;Amazon Machine Image&lt;/a&gt; (AMI)—which has the new changes—and replace the current instance with the new one. You don’t have to worry about downtime because you can launch the new instance first. Once it’s registered in the load balancer, you can drain connections with the old instance and terminate it.&lt;/p&gt;
&lt;p&gt;With this technique, rollback is as easy as updating the ASG with the previous AMI and then rotating instances. If you decide to continue with the deployment as is, you just do the same procedure with the other ASG that has nine instances.&lt;/p&gt;
&lt;h4&gt;Kubernetes&lt;/h4&gt;
&lt;p&gt;Now with Kubernetes, the approach to doing canary deployments is similar to the one used in AWS, but we use different terminology.&lt;/p&gt;
&lt;p&gt;You have a service that could act as a load balancer for pods that are “registered” to the service. You also have “deployments,” which act like ASGs. So in theory, you apply the same techniques. But instead of just explaining it like I did above, let’s learn by practicing.&lt;/p&gt;
&lt;h4&gt;Containers and Docker&lt;/h4&gt;
&lt;p&gt;&lt;img alt="Containers and Dockers Canary Deployments" src="/images/canary-deployments-containers-18786.png"&gt;&lt;/p&gt;
&lt;p&gt;Now, let’s talk about how to do canary deployments with containers and Docker.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://stackify.com/microservices-containers/"&gt;Containers&lt;/a&gt; are what you use to pack the application code and its dependencies so that you can move your application without too much hassle.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://stackify.com/docker-tutorial/"&gt;Docker&lt;/a&gt; is the company that made containers popular. When someone talks about containers, there’s a good chance they’re referring to the containerized technology that Docker created. Containers are pretty easy to use; all you need to have is a file called Dockerfile, where you define how you build the app and what dependencies it needs. This file is used to create what is called a Docker image, which is later used to instantiate a container.&lt;/p&gt;
&lt;p&gt;Since all you need to do to use Docker containers is have the Docker daemon installed, you can move the application through all the environments without fear. Everything that’s needed for your app to run is right there in the container image that you built.&lt;/p&gt;
&lt;h3&gt;Kubernetes basic theory&lt;/h3&gt;
&lt;p&gt;Now that we’ve covered how to do canary deployments on different infrastructures, let’s talk about the Kubernetes theory you’ll need to know in order to do a canary deployment.&lt;/p&gt;
&lt;h4&gt;Deployments&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/"&gt;Deployments&lt;/a&gt; are the desired state definitions for &lt;a href="https://kubernetes.io/docs/concepts/workloads/pods/pod/"&gt;pods&lt;/a&gt; and &lt;a href="https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/"&gt;replica sets&lt;/a&gt;. A pod is a group of one or more containers that you run together. Think of a pod like a virtual machine where you “install” and “configure” the application and its dependencies—we both know it’s not actually a virtual machine, but bear with me. A replica set is used to define the number of pods that are running. If for some reason a pod is stopped or destroyed, Kubernetes will create a new one to maintain the desired state.&lt;/p&gt;
&lt;p&gt;Deployments then define which container images and versions will run in pods, how many of them will run, what strategy will be used to update pods, and what metadata can be used to interact with other resources.&lt;/p&gt;
&lt;h4&gt;Services&lt;/h4&gt;
&lt;p&gt;You can think of &lt;a href="https://kubernetes.io/docs/concepts/services-networking/service/"&gt;services&lt;/a&gt; as load balancers for pods. Let me explain: each pod has its own IP address, but if the pod is recreated or there’s more than one, consumers of those pods will need to keep track of those IP addresses. Instead of doing this manually, you could use a service. Services also provide an IP address that consumers can use, but the real benefit is that the service will balance the requests among the pods that are under it.&lt;/p&gt;
&lt;p&gt;There are other use cases for services, but for this time, let’s leave it at that since we’ll be using services in our practice example.&lt;/p&gt;
&lt;h4&gt;Labels and Selectors&lt;/h4&gt;
&lt;p&gt;Finally, &lt;a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/"&gt;labels and selectors&lt;/a&gt; are the metadata that other resources need in order to interact with each other. Labels are key/value pairs that you can define as you want—they’re used to identify objects. Because you can define as many labels as you need, some objects won’t need to have the same labels. So a label selector is needed to select objects using one or more labels.&lt;/p&gt;
&lt;p&gt;Labels and selectors are how everything we’ve just discussed is connected. When you define the pods in a deployment, you describe a set of labels that a service will use to balance the load. This is how pods are “registered” into a service.&lt;/p&gt;
&lt;h3&gt;Canary Deployment Step by Step&lt;/h3&gt;
&lt;p&gt;&lt;img alt="Canary Deployments Step by Step" src="/images/canary-deployments-steps-18787.png"&gt;&lt;/p&gt;
&lt;p&gt;Enough theory; let’s get started. Let’s mimic what a developer’s day-to-day work will look like when using &lt;a href="https://stackify.com/kubernetes-docker-deployments/"&gt;Docker and Kubernetes&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;0. Prerequisites&lt;/h4&gt;
&lt;p&gt;Before we start, you need to have the following installed on your computer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/install/"&gt;Docker Edge&lt;/a&gt;. If you’ve already installed Docker, you need to uninstall it and then install the Edge version. Why Edge? Simply because it includes a local Kubernetes installation that will make your life easier. It’s supported on &lt;a href="https://blog.docker.com/2018/01/docker-windows-desktop-now-kubernetes/"&gt;Windows&lt;/a&gt; and &lt;a href="https://blog.docker.com/2018/01/docker-mac-kubernetes/"&gt;Mac&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kubernetes/minikube"&gt;Minikube&lt;/a&gt; if you’re using Linux. It’s also supported on Windows, but then Docker needs to be installed in a non-native fashion.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/tasks/tools/install-kubectl/"&gt;kubectl&lt;/a&gt; is a must because this is how you interact with Kubernetes using the command line. It’s supported on Windows and Mac, too.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once you have Docker, Kubernetes, and kubectl in your local environment, you’re ready to get started.&lt;/p&gt;
&lt;h4&gt;1. Create the Docker image for the application&lt;/h4&gt;
&lt;p&gt;You need an application to deploy in Kubernetes. In my case, I’ll use a .NET Core API template, but you can use an existing application.&lt;/p&gt;
&lt;p&gt;If you want to use mine, the code is on &lt;a href="https://github.com/christianhxc/k8s-canary-deployment-guide"&gt;GitHub&lt;/a&gt;. You simply need to clone it in the root folder of the repository and run a few commands to create the initial Docker image version. &lt;strong&gt;Replace my username “christianhxc” with your username.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Run the following command to create the Docker image version 1.0:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker build -f HelloWorld/Dockerfile -t christianhxc/helloworld:1.0 .
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Next, run the following command to push the Docker image version 1.0 (this is optional since our case is running locally):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker push christianhxc/helloworld:1.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You’ll see that the image is now visible in the &lt;a href="https://hub.docker.com/"&gt;Docker Hub&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Canary Deployments Docker Hub" src="/images/canary-deployments-helloworld-v1-18788.png"&gt;&lt;/p&gt;
&lt;h4&gt;2. Deploy version one to Kubernetes&lt;/h4&gt;
&lt;p&gt;Now that we have an initial version of the application, we can deploy it to Kubernetes.&lt;/p&gt;
&lt;p&gt;Let’s start by creating the service definition file &lt;a href="https://github.com/christianhxc/k8s-canary-deployment-guide/blob/master/k8s-service.yaml"&gt;k8s-service.yaml&lt;/a&gt;. It should look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;apiVersion&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;
&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Service&lt;/span&gt;
&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;helloworld&lt;/span&gt;
&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LoadBalancer&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;selector&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;helloworld&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you can see in line 8, this service will run in port 80. Note how the service is going to select pods in lines 9–10. It will use the label “app: helloworld” as the selector. The pods that have that label will be included in the service.&lt;/p&gt;
&lt;p&gt;Now run the following command to create the service. If the service already exists, it will be updated:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl apply -f k8s-service.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now it’s time to create the deployment. Let’s create the deployment definition file &lt;a href="https://github.com/christianhxc/k8s-canary-deployment-guide/blob/master/k8s-deployment.yaml"&gt;k8s-deployment.yaml&lt;/a&gt;, which should look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;apiVersion&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;apps&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1beta1&lt;/span&gt;
&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Deployment&lt;/span&gt;
&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;helloworld&lt;/span&gt;
&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;replicas&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;rollingUpdate&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;maxSurge&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;maxUnavailable&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;minReadySeconds&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;labels&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;helloworld&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;track&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;stable&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;containers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;helloworld&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;christianhxc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;helloworld&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;containerPort&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;cpu&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;limits&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;cpu&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this deployment definition file, you see that in lines 15–16 there are two labels: app and track. This is where the magic happens. Pods in this deployment will have the “app:helloworld” label that the service is looking for. The service will balance the load to the two pods (line 6) created by this deployment.&lt;/p&gt;
&lt;p&gt;Let’s create the deployment in Kubernetes by running the following command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl apply -f k8s-deployment.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can check that pods are running with the following command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl get pods
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Run this command to get the “EXTERNAL-IP” address of the service:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl get service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is where you will get a static IP address if you’re running on the cloud, but in this case, we’re running a local Kubernetes so the “EXTERNAL-IP” is localhost.&lt;/p&gt;
&lt;p&gt;Go to &lt;a href="http://localhost/api/values"&gt;http://localhost/api/values&lt;/a&gt; and you should see API Version 1.0 running:&lt;/p&gt;
&lt;p&gt;&lt;img alt="https://www.hitsubscribe.com/wp-content/uploads/2018/05/canary-k8s-version-one.jpg" src="/images/canary-deployments-api-values-v1-18789.png"&gt;&lt;/p&gt;
&lt;h4&gt;3. Create the Docker image for version two of the application&lt;/h4&gt;
&lt;p&gt;If you decided to use my application, go to the &lt;a href="https://github.com/christianhxc/k8s-canary-deployment-guide/blob/master/HelloWorld/Controllers/ValuesController.cs"&gt;HelloWorld/Controllers/ValuesController.cs&lt;/a&gt; file and change the version in the first method so it looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Canary Deployments Docker Image" src="/images/canary-deployments-values-controller-18790.png"&gt;&lt;/p&gt;
&lt;p&gt;Run the following command to create the Docker image version 2.0:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker build -f HelloWorld/Dockerfile -t christianhxc/helloworld:2.0 .
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then, run the following command to push the Docker image version 2.0 (again, this is optional as our case is running locally):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker push christianhxc/helloworld:2.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;img alt="https://www.hitsubscribe.com/wp-content/uploads/2018/05/canary-k8s-docker-version-2.jpg" src="/images/canary-deployments-helloworld-v2-18791.png"&gt;&lt;/p&gt;
&lt;h4&gt;4. Deploy version two to Kubernetes using a canary&lt;/h4&gt;
&lt;p&gt;Version 2.0 is ready, but we want to deploy it safely.&lt;/p&gt;
&lt;p&gt;Let’s create the canary deployment file definition &lt;a href="https://github.com/christianhxc/k8s-canary-deployment-guide/blob/master/k8s-deployment-canary.yaml"&gt;k8s-deployment-canary.yaml&lt;/a&gt;. It should look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;apiVersion&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;apps&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1beta1&lt;/span&gt;
&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Deployment&lt;/span&gt;
&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;helloworld&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;canary&lt;/span&gt;
&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;replicas&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;rollingUpdate&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;maxSurge&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;maxUnavailable&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;minReadySeconds&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;labels&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;helloworld&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;track&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;canary&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;containers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;helloworld&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;christianhxc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;helloworld&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;containerPort&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;cpu&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;limits&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;cpu&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In line 6, you can see that this deployment file is saying that it will create only one pod. As we saw in the “stable” deployment file, you now have two pods running. That means that the canary version will now receive 33 percent (1/3) of all traffic. In line 20, the new Docker version 2.0 is defined, so the new pod will run the version we just created.&lt;/p&gt;
&lt;h4&gt;5. Monitor version two for a while&lt;/h4&gt;
&lt;p&gt;It’s time to monitor the new version for a while. You need to have some &lt;a href="https://stackify.com/retrace-apm-for-net-core-released/"&gt;visibility about performance&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If there are no errors, you’re ready to deploy (see step 6). But if something goes wrong (Murphy’s Law, people), jump ahead to step 7. Even if there were some errors, you don’t need to worry because only 33 percent of the users will be affected by the errors. (If you want to have a lower percentage, you need to add more pods to the stable version. For example, if the stable version created nine pods and the canary version created one, only 10% of the users would be affected.)&lt;/p&gt;
&lt;h4&gt;6. Roll out version two to the stable&lt;/h4&gt;
&lt;p&gt;Congratulations! If you’re here, it’s because you decided it’s time to deploy the new version. Now you can get rid of the canary and deploy to your entire audience.&lt;/p&gt;
&lt;p&gt;Let’s update the &lt;a href="https://github.com/christianhxc/k8s-canary-deployment-guide/blob/master/k8s-deployment.yaml"&gt;k8s-deployment.yaml&lt;/a&gt; file in line 20 to use the Docker image version 2.0, which should look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;christianhxc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;helloworld&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Run the following command to apply the update:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl apply -f k8s-deployment.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Verify that everything is still running well. You should see the version 2.0 running for all pods.&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="/images/canary-deployments-api-values-v2-18792.png"&gt;&lt;/p&gt;
&lt;h4&gt;7. Remove the canary version&lt;/h4&gt;
&lt;p&gt;If you’re here, it’s because something went wrong. You need to roll back, or maybe you just need to clean up. Remember, we’re only using the canary deployment to reduce the impact on our users.&lt;/p&gt;
&lt;p&gt;Run the following command to delete the canary deployment:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl delete -f k8s-deployment-canary.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4&gt;8. Go back to step 3 to deploy a new version&lt;/h4&gt;
&lt;p&gt;And that’s it. Every time you have a change that you want to deploy, you need to create a new Docker image version.&lt;/p&gt;
&lt;p&gt;Go back to step 3 and make the changes you need, then deploy. Steps 4-7 don’t need to change. A nice thing here is that we’re running everything locally, so you can practice deployments before going to the production environment. You can automate which Docker image version gets deployed. Or you can pass it on as a parameter so that you just replace the new version with a placeholder in the deployment file.&lt;/p&gt;
&lt;h3&gt;It’s Not as Difficult as You Might Think&lt;/h3&gt;
&lt;p&gt;Canary deployments can be done in &lt;a href="https://martinfowler.com/bliki/CanaryRelease.html"&gt;different ways&lt;/a&gt; with different platforms. But to me, the Docker and Kubernetes way feels more native. And as you saw, it’s not as difficult as you might think. Following these simple and sequential steps will help make your deployments more predictable. Of course, there’s no way to predict application errors, but that’s why you also need to have information about how the application is performing.&lt;/p&gt;
&lt;p&gt;You’re not just going to deploy more rapidly as you automate these steps—you’re also going to deploy with more confidence. You’ll always have a chance to test the new version with a small fraction of the users. And if something goes wrong, you can easily roll back. If nothing goes wrong, you can proceed with the full rollout. Then you just shut down the canary version and repeat.&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="canary"/><category term="kubernetes"/><category term="docker"/></entry><entry><title>Amplify Feedback with Continuous Performance</title><link href="https://cmelendeztech.com/posts/2018/10/amplify-feedback-with-continuous-performance.html" rel="alternate"/><published>2018-10-16T00:00:00+02:00</published><updated>2018-10-16T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-10-16:/posts/2018/10/amplify-feedback-with-continuous-performance.html</id><summary type="html">&lt;p&gt;&lt;img alt="Amplify Feedback with Continuous Performance" src="/images/amplify-feedback-for-continuous-performance-881x441.png"&gt;&lt;/p&gt;
&lt;p&gt;As cloud becomes the norm, we’re letting others manage much of our infrastructures for us. Cloud providers offer common metrics like CPU, memory, storage, and networking so that you can stay up to date on the health of your system. And we worry less and less about those metrics …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="Amplify Feedback with Continuous Performance" src="/images/amplify-feedback-for-continuous-performance-881x441.png"&gt;&lt;/p&gt;
&lt;p&gt;As cloud becomes the norm, we’re letting others manage much of our infrastructures for us. Cloud providers offer common metrics like CPU, memory, storage, and networking so that you can stay up to date on the health of your system. And we worry less and less about those metrics with &lt;a href="https://stackify.com/function-as-a-service-serverless-architecture/"&gt;serverless&lt;/a&gt; architectures. But there remains a major concern that we can’t just trust to the cloud provider, and that’s our applications. We need our applications accompanied by a good set of internal metrics that will tell us about their health, and no one else can take care of that for us.&lt;/p&gt;
&lt;p&gt;It doesn’t matter where our applications are hosted. If we don’t know how well things are running, we’ll continue to add features to the point that some users won’t be able to use them.&lt;/p&gt;
&lt;p&gt;And performance issues usually aren’t evident until it’s too late. After the code has been released, problems start popping up. That’s why it’s important that we amplify feedback by assessing performance continuously. Shifting performance to the left will help you to think about performance early. It won’t just be an afterthought; rather, performance will be a &lt;a href="https://blog.codinghorror.com/performance-is-a-feature/"&gt;feature&lt;/a&gt; of the application.&lt;/p&gt;
&lt;p&gt;But what does all this mean? Let’s start by figuring out why we need to optimize application performance.&lt;/p&gt;
&lt;h3&gt;Why Is Performance Important?&lt;/h3&gt;
&lt;p&gt;&lt;img alt="Amplify Feedback with Continuous Performance" src="/images/amplify-feedback-why-is-performance-important-18598.png"&gt;&lt;br&gt;
When you’re visiting a webpage, if it doesn’t load fast, you just leave. If an app is taking to long to work, you just close it. If applications are making users struggle to satisfy their needs, they’ll go somewhere else. &lt;strong&gt;We don’t usually think about performance until we need to&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;We might not think that our application will be the next Facebook or Twitter—two applications that receive millions of visits per hour or minute. But it shouldn’t matter how many people use our applications. We should always be looking to have an application that performs well.&lt;/p&gt;
&lt;p&gt;If we do this, we’ll realize the benefit of continuously adding features to the application because we won’t constantly have to fix performance issues in production. Some people claim they don’t have to worry about performance because “&lt;a href="http://joeduffyblog.com/2010/09/06/the-premature-optimization-is-evil-myth/"&gt;premature optimization is the root of all evil&lt;/a&gt;.” On the other side, there are the people who obsessively try to improve performance, thinking that &lt;a href="https://blog.codinghorror.com/performance-is-a-feature/"&gt;performance is a feature&lt;/a&gt;. Which way of thinking is the correct one? It depends. There are always trade-offs.&lt;/p&gt;
&lt;p&gt;Performance is not a new focus. As an industry, we’ve always had to worry about it. Several years ago, we needed to make sure that our code could function with limited resources. Languages weren’t as mature as they are now, so a common issue was to have stack overflow memory issues. Modern languages hide all of that complexity for us, but that comes at a cost.&lt;/p&gt;
&lt;p&gt;As someone who’s been on both sides of the fence, I’ve found that premature optimization isn’t worth it—but that doesn’t mean that it isn’t important. It’s cheaper and easier to apply a fix if any problems are visible at the very beginning of the workflow.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Create a Culture of Continuous Improvement&lt;/strong&gt;&lt;/h3&gt;
&lt;h3&gt;&lt;strong&gt;&lt;img alt="Amplify Feedback with Continuous Performance" src="/images/amplify-feedback-continuous-improvement-18599.png"&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;When we talk about culture, it all starts with management. If the people at the top don’t understand the impact of having applications with low performance, they’ll see it as a waste of time. To fully grasp the problems, they’ll need to see the numbers and have feedback. We’ll come back to that later—the importance of performance should be visible and supported by data.&lt;/p&gt;
&lt;p&gt;Once management buys in, a performance-valuing culture needs to be spread everywhere. It’s not enough to say it’s important. You need to motivate developers by rewarding them when they do something to improve application performance. And I’m not even necessarily talking about a financial incentive. Sometimes a simple “Well done, thank you!” will give them recognition within the team and will make them feel that performance really matters. As Joe Duffy says in his &lt;a href="http://joeduffyblog.com/2016/04/10/performance-culture/"&gt;performance culture&lt;/a&gt; post, “You get what you reward.”&lt;/p&gt;
&lt;p&gt;In this regard, everyone should be clear about what success means. Do you need to optimize latency of an API to the lowest number possible? No. As long as that number is within the acceptable range, latency can still be considered successful. Performance needs to be constantly evaluated because if it isn’t, progress will be interrupted when the team needs to pay down some of the accumulated technical debt. This leads to the sometimes counterproductive idea that the team should throw everything out and start over with a greenfield project.&lt;/p&gt;
&lt;p&gt;Only having a few people who truly care about performance isn’t a good idea. Folks think, “It’s not my problem. I’m not the performance-focused team member.” It can create a culture of blame. Performance should be everyone’s responsibility, and it should be a part of our day-to-day processes.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Start by Shifting Performance to the Left&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;When I say you should shift development to the left, I simply mean you need to think about performance from the very beginning of the development process. We usually think about delivering first. When it comes to performance, we buy into one of the biggest lies we in IT tell ourselves: that we’ll do it later. In a way, this makes sense. You won’t know if what you’re building will be successful when it’s live. But if it &lt;em&gt;is&lt;/em&gt; successful, you’ll have to be quick about fixing performance issues, or else you’ll lose the opportunity to get more customers. It’s tricky, I know.&lt;/p&gt;
&lt;p&gt;So, what if we deliver quickly, and we continuously work on doing everything we can to make our applications better?&lt;/p&gt;
&lt;p&gt;First, you need to build the machinery to deploy live changes quickly. If you deliver in small batches, you’ll be able to iterate more often and fix performance issues within hours instead of days or weeks because it’s easier to identify where the problem is. There will be fewer interruptions for the team because everyone will be taking care of issues as they arise; whereas normally developers would get interrupted immediately if there are problems in production—I’ve been there, and it’s frustrating.&lt;/p&gt;
&lt;p&gt;You should start with your continuous integration (CI) pipeline. Don’t assume that the things you’re changing won’t affect performance. Measure performance all the time. Start by &lt;a href="https://stackify.com/application-profiling-tools-to-find-bugs-before-production/"&gt;profiling&lt;/a&gt; the application on your machine. A good CI practitioner will not push untested code to master. Load testing should become part of your CI pipeline. You also need to include load tests for each environment in your continuous delivery (CD) pipeline. By simply making your different types of tests (unit, integration, smoke, etc.) run in parallel, you’ll be stressing the application. If you don’t automate it, you might only think about performance again when a problem arises.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Get Feedback on Each Deployment&lt;/strong&gt;&lt;/h3&gt;
&lt;h3&gt;&lt;strong&gt;&lt;img alt="Amplify Feedback with Continuous Performance" src="/images/amplify-feedback-on-each-deployment-18600.png"&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;You don’t need to wait until users start noticing performance issues to do something about it. Here’s how feedback should work.&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;Feedback Should be Accessible to Everyone&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;After the application has been updated, you need to have feedback. Developers need feedback, but they don’t usually have access to production servers. So it’s operations folks’ job to help them to get visibility. One way of achieving that is by having a centralized &lt;a href="https://stackify.com/application-logging-apm-strategy/"&gt;logging&lt;/a&gt; tool everyone can access. There, people will be able to spot not only performance issues, but problems in general.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://stackify.com/web-performance-monitoring-guide-developers/"&gt;Application performance monitoring&lt;/a&gt; is key because you need to get more information about what’s really going on. For example, you might share context error information that will help your team spot issues in a database.&lt;/p&gt;
&lt;p&gt;Or what about alerts? Without those, it’s hard to be proactive about fixing problems. Of course, I’m not talking about having noisy alerts. Rather, you should set up alerts based on error rates, latency issues, networking issues, page abandon rates—things that will tell you if something’s wrong.&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;…and it Should be Useful&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;When you have feedback not only after doing deployments to production but also in other similar environments, you reduce the chances of releasing features with poor performance. Collect everything you can get, like syslog events. There are tools like &lt;a href="https://www.webpagetest.org/"&gt;webpagetest.org&lt;/a&gt; that give you a decent context of a site. I’ve been a huge fan of that service, and just recently I learned that you can have those same tools in your &lt;a href="https://github.com/WPO-Foundation/webpagetest-docs/blob/master/user/Private%20Instances/README.md"&gt;own environment&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can also get performance feedback when monitoring the applications from a different perspective—namely, from a business perspective. Sometimes problems aren’t evident when we look at the infrastructure or error logs, so we need to keep an eye on things like the number of orders made in the application. I once helped a team that had an automated process not just to validate deployments but also to collect application metrics that were important, from a revenue perspective.&lt;/p&gt;
&lt;p&gt;Once you have good quality feedback, the solution to a problem becomes quite obvious. This allows you to act sooner rather than later. Let’s say that after analyzing your site, you notice that you need a content delivery network (CDN) to reduce page load time. Or if the database is now a bottleneck that needs more and more time to give data back, you might add a cache layer to reduce the load in the database.&lt;/p&gt;
&lt;p&gt;Without having intentional feedback on each deployment, users will complain. And they don’t always complain right after you released something, when it’s convenient for you to fix it. They might complain at a moment when fixing performance problems is not only difficult, but also costly.&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;Learn and Experiment Because Things Will Still Go Wrong&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;After you’ve been deploying constantly in small batches, including a certain type of performance testing in your pipeline, and getting feedback constantly so that it’s easier and cheaper to fix things, you might think that you’re covered. But things will still go wrong. It’s better if you’re prepared.&lt;/p&gt;
&lt;p&gt;No production environment can beat the experience of real users. You might practice having a similar traffic load in previous environments, but you can’t predict tomorrow’s users. Even if you design and code the application in a way that can support 10 times the amount of users you typically have, things will always fail. Expect failure and embrace it.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://opensource.com/article/17/8/testing-production"&gt;Testing in production&lt;/a&gt; should be part of the process, not a phase that should be avoided and feared. It’s okay to wait for things to go live to really see how the application performs when receiving real usage. It will be hard and costly to have a copy of production where you can test changes. Quite frankly, you have other things to worry about. For example, you’ll be preparing the application to be resilient to failures. If the database is down, you should depend on the cache, a local copy, or default data. When something goes wrong, you learn. It’s okay to make mistakes; what’s not okay is failing to learn from them.&lt;/p&gt;
&lt;p&gt;You’re not always going to be prepared to react when something goes wrong, and it might not be your fault. That’s why it’s important to be able to deploy quickly, and get feedback constantly. Implementing things like a &lt;a href="https://en.wikipedia.org/wiki/Circuit_breaker_design_pattern"&gt;circuit-breaker&lt;/a&gt; with &lt;a href="https://github.com/Netflix/Hystrix"&gt;Hystrix&lt;/a&gt;, doing canary releases, or using feature flags in the application will help you to be more resilient. As a bonus, only a fraction of your users will notice that something’s happening. Rollbacks should be quick, easy, and expected.&lt;/p&gt;
&lt;p&gt;Everyone, not just operations folks, should know what a healthy system looks like. And more importantly, everyone should know what to do when it’s not healthy.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Performance is Not Static—It Continuously Changes&lt;/strong&gt;&lt;/h3&gt;
&lt;h3&gt;&lt;strong&gt;&lt;img alt="" src="/images/amplify-feedback-perfomance-continuously-changes-18601.png"&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;In order to have applications with good performance, you need to constantly work on your awareness, culture, and a good set of practices.&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;Start by Setting Up the Basics&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;To amplify feedback with continuous performance, it’s necessary to know why performance is important. That will help everyone to understand why you need to load test, even if the belief is that the recent change won’t have any significant impact. Then, you need to make performance everyone’s job, not just something for a few people to handle. Spread the news that performance should not be an afterthought or only something you think about when doing big refactors.&lt;/p&gt;
&lt;p&gt;When you have the basics down, you’re ready to include performance feedback from the very beginning of the process: things like developers profiling to locally spot bugs. You can start by reserving a time for doing load tests, but eventually, as the set of test cases grows, it could be a matter of running all of them in parallel.&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;…and Then Keep Monitoring&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Having feedback before releasing to production is important because you can fix things quickly and effortlessly. But feedback from production will tell you the real story, all the time. For that reason, everyone needs to have that visibility. Knowing &lt;em&gt;where&lt;/em&gt; things are wrong instead of just knowing &lt;em&gt;that&lt;/em&gt; things are wrong will make the difference in how much time you’ll need to fix problems. This is especially true for performance problems—those that the user might only understand as “the site is slow.”&lt;/p&gt;
&lt;p&gt;Expecting failure will foster resiliency in the application code. Don’t get discouraged when things are still going wrong. Use those failures to learn and constantly experiment with how the application will react under duress. That will give you the feedback you need to be prepared for unintentional failures.&lt;/p&gt;
&lt;p&gt;Performance is not something that you should take care of only when it’s needed, but it also shouldn’t be the only thing you care about. There should be a balance. But what you can’t have enough of is feedback. Work to get it, and get it continuously.&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="performance"/></entry><entry><title>Why You Need an Error Budget and How to Make It Work</title><link href="https://cmelendeztech.com/posts/2018/09/why-you-need-error-budget-how-make-it-work.html" rel="alternate"/><published>2018-09-26T00:00:00+02:00</published><updated>2018-09-26T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-09-26:/posts/2018/09/why-you-need-error-budget-how-make-it-work.html</id><summary type="html">&lt;p&gt;&lt;img alt="Why You Need an Error Budget and How to Make It Work" src="/images/error-budget.jpg"&gt;&lt;/p&gt;
&lt;p&gt;How many times have you seen Google go down? Not many, I bet. You might not even notice it if it happened. If you did, you’d probably assume it’s an internet connection problem.&lt;/p&gt;
&lt;p&gt;But Google isn’t perfect. As &lt;a href="https://twitter.com/Werner"&gt;Werner Vogels&lt;/a&gt; says, “Everything fails, all the time.” If …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="Why You Need an Error Budget and How to Make It Work" src="/images/error-budget.jpg"&gt;&lt;/p&gt;
&lt;p&gt;How many times have you seen Google go down? Not many, I bet. You might not even notice it if it happened. If you did, you’d probably assume it’s an internet connection problem.&lt;/p&gt;
&lt;p&gt;But Google isn’t perfect. As &lt;a href="https://twitter.com/Werner"&gt;Werner Vogels&lt;/a&gt; says, “Everything fails, all the time.” If even Google doesn’t have 100% uptime, maybe we should accept we won’t either. Shouldn’t we instead focus on how to recover from failure? It’s been proven that systems fail when they change, but your customers probably wouldn’t like it too much if you simply never updated your software. So since we &lt;em&gt;have&lt;/em&gt; to change, how do we know &lt;em&gt;when&lt;/em&gt; to change?&lt;/p&gt;
&lt;p&gt;Maybe you’ve had good uptime recently, and a small fail won’t hurt you so much. But you have to know whether that’s the case or not. You need metrics that tell you if it’s a good idea to freeze changes for a time or if having some errors is still acceptable.&lt;/p&gt;
&lt;h1&gt;Why You Need an Error Budget&lt;/h1&gt;
&lt;p&gt;If you’ve compared cloud services, you may have heard about the &lt;a href="https://en.wikipedia.org/wiki/High_availability#%22Nines%22"&gt;nines of availability&lt;/a&gt;. It’s basically a number that tells you how much of the time systems are going to be down. When someone talks about having four nines (99.99%) of availability for a system, that person is saying the system will be down only 52 minutes and 35 seconds a year. The more decimals, the more uptime. For instance, let’s say that you defined a rule specifying that the system has to respond in under 500 ms 99.99 times out of 100. If latency goes up, then your system is considered down because it’s above the 500 ms threshold.&lt;/p&gt;
&lt;p&gt;This number is used to define the service level agreement (SLA) or service level objective (SLO). The error budget is how much time you’re willing to allow your systems to be down, and it will depend heavily on the SLA that you’ve defined with the product team. Everyone would like to have systems with 100% uptime, but you need to be realistic. How much availability are you willing to provide, based on how much your customers care? Are your users going to notice that your system is up 100% of the time? What about 99.99%? Or even 99%? They might not.&lt;/p&gt;
&lt;p&gt;It’s important that you have an SLA and SLO that works for you so that, at the moment a deployment fails, you’ll think twice before trying to fix something in production or go back to a stable environment. Having an error budget helps support the plan of not pushing changes if people lack trust in those new changes.&lt;/p&gt;
&lt;h1&gt;Uptime vs Innovation: Should I Pick One?&lt;/h1&gt;
&lt;p&gt;High uptime has risk beyond financial costs and complexity. It’ll also put you in the position of worrying too much when deploying changes. Some might use error budgets to support their theory that every time a change happens, the stability of the system is affected. That means no more changes, in their mind. But I’d advise against having that mindset. It’s better to avoid risking stability in other ways.&lt;/p&gt;
&lt;p&gt;Operations will always seek to have systems that are highly available by putting in place replication, redundancy, auto-scaling, backups, and everything that makes systems more robust. On the other hand, developers will try to write code that satisfies the requirements that came from the business. That’s how the DevOps movement started: people wanted to create a culture where these frictions are minimal.&lt;/p&gt;
&lt;p&gt;If you care more about having several nines of availability than releasing new features, the result will be that innovation will stop. Sure, it might be better to be conservative than to take the risk, right? But let’s face it. No one will care very much about your reliability if your system doesn’t provide any value. Successful systems are those that solve a problem users have. There are always trade-offs, but keeping systems static won’t allow you to keep your customers happy.&lt;/p&gt;
&lt;h1&gt;How Do We Keep the Budget Positive?&lt;/h1&gt;
&lt;p&gt;It’s important to have room in your error budget in case something happens that’s external to deployments—something like internet connection issues, fires in the data center, cloud providers being down, and any problem that’s not in our hands to fix (and that complaining on Twitter won’t solve).&lt;/p&gt;
&lt;p&gt;When you push changes gradually, you’re more in control of the error budget. If something starts to affect uptime, you can roll back immediately before it consumes the budget. Also, you might soar over your error budget if you don’t release in small batches. Deployment strategies like blue/green deployments or canary releases are a good option to keep numbers positive. Automation becomes your best friend here. Every second counts, especially when you need to do a rollback.&lt;/p&gt;
&lt;p&gt;You can also start with the code. How does your code respond if the database has problems? Or what about Redis? Problems with dependencies will always happen, so it’s better if your application can support that. Let’s say your system is composed of several microservices. If one of those microservices is down, instead of failing, the client should have a default response or take data from the local cache. For example, Netflix has a really good library called &lt;a href="https://github.com/Netflix/Hystrix/wiki/How-it-Works"&gt;Hystrix&lt;/a&gt;. If you’re not in the Java world, you can still internalize the principles behind other companies’ level of support for problems.&lt;/p&gt;
&lt;h1&gt;Fail, But Don’t Get Caught&lt;/h1&gt;
&lt;p&gt;Failure &lt;em&gt;is&lt;/em&gt; an option, but the trick here is how you manage it. Netflix actually practices failure all the time with their &lt;a href="https://github.com/Netflix/chaosmonkey"&gt;chaos monkeys&lt;/a&gt;. They go to the extreme of bringing down entire clusters in production several times, all the time. Now, let’s be clear about this. If Netflix is down, users might get mad, but no one will die. They won’t lose money, either, because of their monthly plans system. But their reputation could be affected if the system is constantly down, impacting revenue months later through lost users.&lt;/p&gt;
&lt;p&gt;So, should you start bringing servers down? What will be the business’s reaction when you tell them? They’ll probably freak out and respond with a solid no. It’ll depend on the impact downtime has on the users. But even if you don’t put your systems in failure situations in production, like Netflix, you should at least practice it in a testing environment. Doing that shows you care about reliability and are prepared for common failure scenarios.&lt;/p&gt;
&lt;p&gt;When AWS went down some years ago, Netflix was one of the few that survived that failure. They failed but didn’t get caught.&lt;/p&gt;
&lt;h1&gt;Keep Innovating While Staying Up&lt;/h1&gt;
&lt;p&gt;With DevOps, some organizations are so focused on delivering fast that they sometimes don’t adequately assess risk. And if that’s you, developing an error budget can help you to be aware and respond properly. Most businesses prefer to be conservative, so you need to learn how to sell DevOps or even automation to management while accounting for risk. At the same time, you need to keep innovating without affecting reliability.&lt;/p&gt;
&lt;p&gt;Having an error budget will force you to have metrics in place to know if you’re meeting expectations or not, and it will help you take action to reduce the chances of being unreliable.&lt;/p&gt;
&lt;p&gt;Error budgets give you more than just a number. They’ll change your thinking when you’re delivering software. You’ll want to shift to the left everything that will make your systems more reliable.&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="sre"/></entry><entry><title>Choosing a Deployment Strategy: A Manager’s Guide</title><link href="https://cmelendeztech.com/posts/2018/08/deployment-strategy.html" rel="alternate"/><published>2018-08-27T00:00:00+02:00</published><updated>2018-08-27T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-08-27:/posts/2018/08/deployment-strategy.html</id><summary type="html">&lt;p&gt;&lt;img alt="Choosing a Deployment Strategy" src="/images/bigstock-210537436.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Some time ago, I was in charge of deploying to the main system in the company I was working at. Back in those days, I had the bad habit of doing deployments manually by copying/pasting assemblies and then RDPing into the servers to update it with the latest changes …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="Choosing a Deployment Strategy" src="/images/bigstock-210537436.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Some time ago, I was in charge of deploying to the main system in the company I was working at. Back in those days, I had the bad habit of doing deployments manually by copying/pasting assemblies and then RDPing into the servers to update it with the latest changes. One. Server. At. A. Time. Luckily for me, that system only needed four servers.&lt;/p&gt;
&lt;p&gt;Those were bad days because something always went wrong—files were in the incorrect folder, configuration values or file permissions were missing, or I was so tired that I forgot to update one of the servers.&lt;/p&gt;
&lt;p&gt;Things are way different now; there are more good days than bad days. For example, what I call a “bad” day now is because of something as simple as a missing test case.&lt;/p&gt;
&lt;p&gt;Now that we live in the DevOps era, deployments are also different in the industry. Some organizations do several deployments per day. There are some strategies to increase the frequency of deployments that help to reduce the risks of downtime without customers noticing that something changed.&lt;/p&gt;
&lt;h2&gt;All or Nothing With Blue/Green Deployments&lt;/h2&gt;
&lt;p&gt;The &lt;a href="https://rollout.io/blog/blue-green-deployment/"&gt;blue/green deployment strategy&lt;/a&gt; consists of having &lt;strong&gt;two production versions&lt;/strong&gt; of a particular system &lt;strong&gt;running at the same time&lt;/strong&gt;. The catch is that only one is receiving live traffic. This means that the new version doesn’t necessarily have to be backward compatible because the blue and green deployments won’t be live at the same time. It represents a challenge for app dependencies like databases, but you can use the blue/green strategy for them too.&lt;/p&gt;
&lt;p&gt;Let’s say for example that your blue side is the running version. The new version with the changes you want to deploy then is the green side. Because the green side isn’t receiving live traffic yet, you have the chance to perform real testing in a production environment before pushing it live.&lt;/p&gt;
&lt;p&gt;When the green side is ready to be released, you just need to change the router that’s pointing to the blue side so that it points to the green side instead.&lt;/p&gt;
&lt;p&gt;If something goes wrong for some reason, you can just &lt;strong&gt;switch the router back&lt;/strong&gt; and diagnose what went wrong calmly. Rollback speed depends on how quickly you can switch versions, but it’s usually fast. The downside is that you’re duplicating infrastructure, which has an impact on cost—although this might get reduced with containers. But the more important thing is that you’re reducing risk by having a production version that you can test before deploying to real users.&lt;/p&gt;
&lt;h2&gt;Little by Little With Rolling Update Deployments&lt;/h2&gt;
&lt;p&gt;The rolling update strategy consists of &lt;strong&gt;pushing the new version little by little&lt;/strong&gt;. You won’t be replacing everything at once, as you do with blue/green deployments, so &lt;strong&gt;backward compatibility is a must&lt;/strong&gt;. This challenges developers because they need to make sure that the new version can keep working with the previous version for some period of time. But this will also give them a sense of how things actually work in production and, as a bonus, &lt;a href="https://rollout.io/blog/testing-strategies-delivery-pipeline/"&gt;it fosters the habit of practicing deployments early in the workflow—which will shift deployments to the left.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Similar to the blue/green strategy, you start by spinning up the new version first &lt;strong&gt;when it’s ready to go live&lt;/strong&gt;. Then, connections from the now-previous version start draining to be rolled out gracefully. The cool thing about this is that you do &lt;strong&gt;deployments gently&lt;/strong&gt;. You also get to define whether you want to spin up and replace one or several instances at a time. The downside is that you aren’t able to run a set of tests on the new version before going live. Or rather, it’s not that you &lt;em&gt;can’t&lt;/em&gt;, but it will make the deployment slower and more complex.&lt;/p&gt;
&lt;p&gt;Before deployment finishes, you might see some problems with the new version. It will take some time to do rollbacks depending on how far along the update is. (It’s usually slow because you need to spin up new instances of the previous version again and then do the rotation.) An alternative that will help you reduce deployment and rollback time is to use containers—as long as there’s enough capacity do the rollout.&lt;/p&gt;
&lt;p&gt;The benefit of this method is that costs stay low because you’re just creating copies of the new version in small portions, not a full copy every time you deploy.&lt;/p&gt;
&lt;h2&gt;Start Small With Canary Deployments&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://rollout.io/blog/canary-deployment/"&gt;Canary deployments&lt;/a&gt; make &lt;strong&gt;the new version live&lt;/strong&gt; for just a &lt;strong&gt;small fraction of the users&lt;/strong&gt;. Technically, you decide which users will see the new version first, and you can always change the decision of which users to have in your test group. It’s usually as simple as redirecting a small portion of user traffic to the new version and the rest to the current version. When deployment is finished, both versions will be the same. But the good thing is that &lt;strong&gt;you get the chance to test changes&lt;/strong&gt; with a portion of the real traffic before a full rollout.&lt;/p&gt;
&lt;p&gt;Deployment could be done either with a blue/green deployment or a rolling update, as long as you only release the new version to a control group of users at a time. You also define how you want to split the traffic. It could be 5/95, meaning that, initially, only five percent of users will see the change. You could also use more than two groups, like 5/15/80. Or you can even start with a group of beta testers who are willing to look for problems and provide feedback.&lt;/p&gt;
&lt;p&gt;You can keep the new version for some time (minutes, hours, or even days) to see how it goes when receiving real traffic. Again, it depends on how you want to do it. If nothing goes wrong, you can continue by making the new version available to the rest of the users. Or you can roll back to the previous version. The good thing is that only the few users who tested the new version will notice it.&lt;/p&gt;
&lt;p&gt;The benefits and risks, rollback time, and costs (besides the ones that I just mentioned) will depend on whether you choose the blue/green or rolling update strategy.&lt;/p&gt;
&lt;h2&gt;Compete For Revenue With A/B Testing Deployments&lt;/h2&gt;
&lt;p&gt;A/B testing is similar to the canary release, but how you split the traffic is a &lt;strong&gt;business decision&lt;/strong&gt; and is usually &lt;strong&gt;more complex&lt;/strong&gt;. This strategy is commonly used for experimentation—when you want to try something that you’re not sure will work. You define groups based on user preferences, location, age, gender, or other factors that will tell you which version had the biggest positive impact on revenue. You can then decide if A or B is ready for all your users.&lt;/p&gt;
&lt;p&gt;With this deployment strategy, two versions of the system compete with each other. It could be new vs old or A vs B. Whoever is responsible for making executive decisions in your company could choose which version converted the user to a customer the most, and that’s the version you keep. For that reason, it’s important that you have data to support your theory rather than make a decision simply because you think a certain version will work better.&lt;/p&gt;
&lt;p&gt;Implementing this strategy is usually complex, but if you make use of &lt;a href="https://rollout.io/blog/ultimate-feature-flag-guide/"&gt;feature flags&lt;/a&gt;, it gets simpler. You can be as creative as you want when testing your hypothesis. For example, you might start by &lt;a href="https://rollout.io/blog/dark-launch-directors-new-best-friend/"&gt;dark launching&lt;/a&gt; using any of the previous strategies. Then, you’d turn on the feature flag to make only version A available. After some time, you’d turn it off and then turn on version B for the same amount of time as A. From there, you’d collect metrics and decide which version to leave running.&lt;/p&gt;
&lt;h2&gt;What Outcomes Are You Expecting To Have?&lt;/h2&gt;
&lt;p&gt;It doesn’t matter much which strategy (or a mix of strategies) you choose for your deployments. It depends on the outcomes you want. The key thing here is that you stop doing deployments manually and you have as little human interaction as possible. You also need to stay consistent, meaning that you’ll have to apply the chosen deployment strategy for development and any other environment in your workflow. It might be challenging to have production-like environments, but you need to practice deployment before updating the environment where your real users interact. Don’t treat your production environment any differently.&lt;/p&gt;
&lt;p&gt;Every strategy has its trade-offs. But one benefit common to all of them is that, if you implement the strategy well, you’ll have zero downtime. You won’t have to wait for specific times when your users won’t notice that you’re changing something. Now, it won’t be easy to get to that point; your staff will have to put in some extra effort to achieve it. But they’ll appreciate not having deployments cut into their nights, weekends, or family time.&lt;/p&gt;
&lt;p&gt;Last but not least, practice doing deployments frequently. If it hurts, do it more.&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="deployments"/></entry><entry><title>Which DevOps Metrics Matter?</title><link href="https://cmelendeztech.com/posts/2018/08/devops-metrics.html" rel="alternate"/><published>2018-08-20T00:00:00+02:00</published><updated>2018-08-20T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-08-20:/posts/2018/08/devops-metrics.html</id><summary type="html">&lt;p&gt;&lt;img alt="DevOps Metrics" src="/images/Tape-measure-signifing-DevOps-metrics.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Some time ago, I decided to start dieting for the millionth time. All previous tries were a complete failure. But this last time was different.&lt;/p&gt;
&lt;p&gt;It was different because not only was I going to a nutritionist, but also every time I visited her, she took my measurements. That way …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="DevOps Metrics" src="/images/Tape-measure-signifing-DevOps-metrics.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Some time ago, I decided to start dieting for the millionth time. All previous tries were a complete failure. But this last time was different.&lt;/p&gt;
&lt;p&gt;It was different because not only was I going to a nutritionist, but also every time I visited her, she took my measurements. That way, she knew if I was following the recommended diet and exercise, and if I was, she knew what changes she needed to suggest based on the results. I was seeing a small amount of progress every week. It didn’t matter if I lost only one pound; it was something.&lt;/p&gt;
&lt;p&gt;When building a product, we should always try to find ways of improving what we’re doing to produce—to deliver faster, cheaper and on time. There are practices and processes that help us, especially in software development. But when you implement something new in your process, you also need to know if it’s working or not. Even if everyone else says it works for them, you might be doing something a different way…maybe even the wrong way. How can you know if what you’re doing is adding value or not? Well, you need to measure.&lt;/p&gt;
&lt;p&gt;When you start practicing DevOps, it’s very helpful to have numbers that tell you how good or bad it’s going. But which metrics would you use? Well, let’s explore the what, why, and how of some important metrics in DevOps.&lt;/p&gt;
&lt;h2&gt;How Many Times Are You Doing Deployments?&lt;/h2&gt;
&lt;p&gt;Organizations usually do deployments quarterly or monthly—or with the rise of Scrum, every two weeks, if user stories are complete.&lt;/p&gt;
&lt;p&gt;You need a deployment frequency metric. That means counting the times you do deployments of the applications under your DevOps implementation. The more deployments you do (or can do), the better. You don’t necessarily need to do frequent deployments if you’re not changing the system very often. In other words, deployment frequency correlates to the times you complete changes in the code.&lt;/p&gt;
&lt;p&gt;Is your change ready to be deployed? Go ahead, do it! Or maybe you’re good enough that you have it ready to go on the date that marketing set for a campaign. Awesome! But it doesn’t matter if you deploy when coding is done or not. You can use feature flags to &lt;a href="https://rollout.io/blog/dark-launch-directors-new-best-friend/"&gt;deploy anytime you want&lt;/a&gt; with the feature turned off and then turn it on when you’re prepared to release.&lt;/p&gt;
&lt;p&gt;It’s important that you know how many times you’re doing deployments because it’s a sign of how fast and easy a deployment is to do. If they’re not easy and you don’t deploy very often, your next task is to find out why and improve. It might be because your developers’ confidence in deployments is broken. Or maybe testing quality isn’t good enough. Don’t let these issues stand; you have to address them.&lt;/p&gt;
&lt;p&gt;You don’t have to be Amazon, &lt;a href="https://rollout.io/blog/dont-facebook-ship-software-like-facebook/"&gt;Facebook&lt;/a&gt;, or Flickr to do ten deployments a day. It should be possible when you need to.&lt;/p&gt;
&lt;p&gt;Now, how to keep track of this? Well, every time you do a deployment, save a record in a database or any other service you use for logging, like &lt;a href="https://www.elastic.co/elk-stack"&gt;ELK&lt;/a&gt;. Then, build dashboards to have a better view of the past. You’ll know if you’re improving or getting worse at a glance.&lt;/p&gt;
&lt;h2&gt;How Much Time Does It Take From Code Commit to Release?&lt;/h2&gt;
&lt;p&gt;The DevOps movement started because after developers finish coding, moving to production tends to be problematic. I’ve experienced this struggle in my job. Basically, we would spend two weeks coding and another two weeks trying to release. It didn’t always take that long, but the time to deploy after development delivered certainly wasn’t consistent. Add to that the pressure of management asking why it was taking so long to deliver, and you have one stressed-out team.&lt;/p&gt;
&lt;p&gt;My second suggested DevOps metric measures the time between a developer saying “OK, I’m ready to have this change in production” to actually &lt;em&gt;putting&lt;/em&gt; that change in production. If you don’t measure that time, you might not improve upon it—or it will be too hard to identify why it’s taking too long. In this case, the less time it takes, the better. So this metric number should be low, and as low as you can possibly make it because you need to consider compiling, publishing and testing.&lt;/p&gt;
&lt;p&gt;Knowing that you take too long to deliver will incentivize you to identify where you’re spending most of that time. It could be that you’re wasting too much time fixing merge conflicts. If that’s the case, then the solution is to have a trunk-base development with &lt;a href="https://rollout.io/blog/top-5-use-cases-feature-flags/"&gt;feature flags&lt;/a&gt;. It could be that you’re doing things differently in each environment, so there’s always something new to fix. The solution is to have production-like environments.&lt;/p&gt;
&lt;p&gt;The idea is to know you have a problem and that you need to do something to fix it.&lt;/p&gt;
&lt;p&gt;So, how can you keep track of this? Well, because the time between delivery and deployment could be due to many things, start by recording that time in a database or app. Save the date and time the change was validated in a dev environment and ready to be released. Then, when that change is deployed, record the date and time again, do the math, and store the total time it took.&lt;/p&gt;
&lt;h2&gt;How Many Times Do Deployments Fail?&lt;/h2&gt;
&lt;p&gt;The metric I’ll speak about measures how many times you’re in need of rolling back or turning a feature off because of the increase in errors. The closer to zero this number is, the better. Measuring this will tell you about the quality of your process before the release. It can also tell you how many times you’ve practiced putting things in a production environment.&lt;/p&gt;
&lt;p&gt;It’s important to have this metric because it will tell your customers or upper management how good or bad your DevOps efforts are going.&lt;/p&gt;
&lt;p&gt;You need to measure this if you want to worry less about deployments. I know some organizations that reserve Christmas Eve to do high-risk deployments. Why? Users are too busy spending time with family, eating, and celebrating to care if the system is down. But you shouldn’t have to wait for a time when your users won’t notice you’ve failed.&lt;/p&gt;
&lt;p&gt;How can you keep track of this? For this metric, it’s not about measuring time. And you might be already measuring what you need to, but not for the purpose of DevOps metrics. I’m talking about knowing how many 5XX and 4XX errors you have or how high latency is after a deployment. Even if your system isn’t a web app, it doesn’t matter: you need to keep track of system errors.&lt;/p&gt;
&lt;p&gt;An even better metric is to have key performance indicators (KPIs). These will vary from one industry to other. Retailers may measure sales while banks may measure transactions, for instance. So your KPIs could be something like the amount of failed purchases, the number of times the user has to abandon the page—you get the idea. As long as you have a way of knowing the system is failing, you should use that information to know the number of times a deployment has failed.&lt;/p&gt;
&lt;h2&gt;How Much Time Does It Take To Recover?&lt;/h2&gt;
&lt;p&gt;The next metric I’ll mention requires you to measure the time it takes you to recover from a failed deployment. It’s also known as “mean time to recover” (MTTR). The less time it takes, the better.&lt;/p&gt;
&lt;p&gt;You need to measure this because it will tell you how good you are at recovering the state of the system. If you’re putting stability above all else, your response to seeing a deployment fail will be to immediately roll back. And you don’t have to build a rollback process. It could be as simple as turning a feature flag off. If you read this blog, you’re already aware of &lt;a href="https://rollout.io/blog/feature-flag-management-technical-debt/"&gt;how powerful&lt;/a&gt; &lt;a href="https://rollout.io/blog/large-companies-use-feature-flag-management-system/"&gt;feature flags&lt;/a&gt; can be. And they’re especially useful in these types of scenarios.&lt;/p&gt;
&lt;p&gt;How can we keep track of how we’re doing on recovery time? It’s as easy as having a record of the time it takes you to roll back to a stable version. If you have one-click deployments, going to a stable state of the system shouldn’t take that much time. How much automation you have here will help you, definitely.&lt;/p&gt;
&lt;h2&gt;How Are Your Metrics Doing?&lt;/h2&gt;
&lt;p&gt;Correlate all metrics and you’ll have a better understanding of what’s happening with your DevOps implementation. You don’t need to have good numbers when you start, but make sure you know your initial state—like the before/after photos you see when someone succeeded in losing weight.&lt;/p&gt;
&lt;p&gt;In the end, what you should seek to have is&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A significantly higher number of deployments per day or per week. The more, the better.&lt;/li&gt;
&lt;li&gt;A decrease in the amount of time you take to deploy a change after the code is finished. The less time, the better.&lt;/li&gt;
&lt;li&gt;A smaller number of failures after doing a deployment. The fewer, the better.&lt;/li&gt;
&lt;li&gt;A decrease in the amount of time you take to recover from a failure. The less time, the better.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can start by having simple measurements of each of the above metrics—a simple number that includes the concept. Or you can have detailed metrics. You’ll need them when trying to improve the numbers. Either way, don’t make guesses about your progress with DevOps—use metrics to prove it with data.&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="metrics"/></entry><entry><title>Introducing Different Testing Strategies Into Your Delivery Pipeline</title><link href="https://cmelendeztech.com/posts/2018/08/testing-strategies-delivery-pipeline.html" rel="alternate"/><published>2018-08-14T00:00:00+02:00</published><updated>2018-08-14T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-08-14:/posts/2018/08/testing-strategies-delivery-pipeline.html</id><summary type="html">&lt;p&gt;&lt;img alt="Testing Strategies" src="/images/large-pipeline.jpg"&gt;&lt;/p&gt;
&lt;p&gt;With the rise of DevOps, everyone’s talking about delivering quickly. But while speed is important, so is confidence. Testing will help you increase confidence, and without tests, you can’t trust the deployment pipeline. Just like divers won’t explore the ocean without oxygen tanks they can trust, ops …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="Testing Strategies" src="/images/large-pipeline.jpg"&gt;&lt;/p&gt;
&lt;p&gt;With the rise of DevOps, everyone’s talking about delivering quickly. But while speed is important, so is confidence. Testing will help you increase confidence, and without tests, you can’t trust the deployment pipeline. Just like divers won’t explore the ocean without oxygen tanks they can trust, ops folks shouldn’t dive into the deployment process without having tests of good quality. You need something to protect you from creating a mess when you go live.&lt;/p&gt;
&lt;p&gt;That’s why it’s important to include a good testing strategy in your delivery pipeline. There’s no need to introduce another silo by testing your code changes at the end of the workflow. &lt;a href="https://devops.com/devops-shift-left-avoid-failure/"&gt;Shift tests to the left&lt;/a&gt; because you need to test early, often, and with confidence. You need a way to certify that what you’re shipping satisfies the needs of the users.&lt;/p&gt;
&lt;p&gt;But what’s a good way of introducing tests into your delivery pipeline without increasing the delivery time? Let’s explore some ideas.&lt;/p&gt;
&lt;h2&gt;Creating Tests That Run Quickly Even If the System Grows&lt;/h2&gt;
&lt;p&gt;How fast should the tests be? Well, how much time are developers willing to wait after pushing code changes? If tests take more than one hour, developers won’t be willing to test early and often, especially if we’re talking about the first set of tests that your application will be running against.&lt;/p&gt;
&lt;p&gt;Tests should be integrated into your continuous integration (CI) workflow, but not just after a developer pushes the code changes into the master branch. One of the critical benefits of CI is that developers have rapid feedback before integrating their code with the rest of the changes from the team. That means that these tests should run fast—in a matter of minutes—and they should run locally. They also need to have a constant running time, even if the application keeps growing.&lt;/p&gt;
&lt;p&gt;One way of keeping a steady time for tests is to parallelize. But don’t parallelize in code. Parallelization should be something external. Tests should be able to scale by running multiple groups at the same time—say, for example, a Jenkins job that triggers tests simultaneously by calling different JAR files at the same time. Or now that we’re in the era of containers, you can spin up a group of containers that will run several tests at the same time, optimizing resources and reducing run time.&lt;/p&gt;
&lt;h2&gt;Including a Minimum Set of Use Cases&lt;/h2&gt;
&lt;p&gt;A strategy that will help you be more confident is to include &lt;a href="http://softwaretestingfundamentals.com/smoke-testing/"&gt;smoke tests&lt;/a&gt;. These give you the minimum amount of use cases you need to approve a change.&lt;/p&gt;
&lt;p&gt;As you progress, tests can take longer per phase, and that’s alright. The closer you are to deploying to production, the more confident you need to be that a change isn’t breaking something. In the final production phase, you’d like to do more—add more real data—so it’s not a bad thing to take longer.&lt;/p&gt;
&lt;p&gt;If you find a significant bug, make sure you translate that issue into a test that runs fast. That way you can check to make sure you’ve fixed the bug. Also, make sure it’s included at the very beginning of the pipeline. It could be something like converting a manual test to a unit test that will run fast. This doesn’t just apply to unit tests—it can be a more complex integrated test that runs quickly using real data. These complex tests can run while the rest of the unit tests are running.&lt;/p&gt;
&lt;p&gt;You also may have heard about the &lt;a href="https://martinfowler.com/bliki/TestPyramid.html"&gt;testing pyramid&lt;/a&gt;, where you include a certain number of different test types in the pipeline. The idea is to have more unit than integration tests and to use unit tests to test locally. While that works, there are times when mocking (that’s why they run so fast) an object is more difficult than just using real data objects. So you can also include some integration tests at the beginning of the delivery pipeline. They won’t depend on certain data existing—they’ll create it and then remove it once they’re done. By doing this, these integration tests could also be testing other parts of the system, increasing test coverage.&lt;/p&gt;
&lt;p&gt;So it’s not about which type of tests should go in each step. Rather, it’s a combination of speed and the importance of tests.&lt;/p&gt;
&lt;h2&gt;Using Acceptance Criteria, Not Just Code Coverage&lt;/h2&gt;
&lt;p&gt;I’ve heard that people sometimes add tests that assert to a static “true” value just for the sake of increasing code coverage. But is that the real purpose of the code coverage metric? No. The idea is that you have a test for each portion of the code. It’s really costly to have 100% test coverage, and it’s not worth it. Why? Because every time you need to make a change, most likely you’ll also need to change something in the tests.&lt;/p&gt;
&lt;p&gt;Why don’t we focus on how many use cases we’re covering rather than just code coverage? Taking this approach will you avoid the temptation to create silly and useless tests. Practices like &lt;a href="http://testobsessed.com/2008/12/acceptance-test-driven-development-atdd-an-overview/"&gt;ATDD&lt;/a&gt; or &lt;a href="https://en.wikipedia.org/wiki/Behavior-driven_development"&gt;BDD&lt;/a&gt; could be helpful because you’re focusing on the use of the system. These practices will also help you be more confident when doing refactors because you’ll be changing code, not behavior. So the code is being adapted to the tests, not the other way around.&lt;/p&gt;
&lt;p&gt;Make sure the tests you’re including in the pipeline are providing value. When they stop doing that, evolve them or get rid of them. A good sign that a test needs to be retired is how much time you invest in fixing or adapting it to new changes.&lt;/p&gt;
&lt;h2&gt;Constructing Tests In Parallel With Code&lt;/h2&gt;
&lt;p&gt;Tests should be treated the same way as the application code. You might construct them using a different source code or even a different language. You can also benefit by using versioning and packaging them (i.e., JARs, containers, etc).&lt;/p&gt;
&lt;p&gt;What else should you do with the application code? Put it in version control. Don’t use long-lived feature branches. Push frequently to master and use feature flags. The same principles that apply to the code apply to construct tests.&lt;/p&gt;
&lt;p&gt;Was a test ready before the application code but now it’s causing failures in CI? No problem. Just make use of the same feature flag you’ll use in the application code and turn it on when the changes are pushed.&lt;/p&gt;
&lt;p&gt;It’s not necessary to add another silo, like a separate team that constructs the tests. Testing should be a developer’s job. It doesn’t mean that the same developer that wrote the code writes all tests. It’s about having different roles during development sprints. If Developer A writes the code and some unit tests, then Developer B should write another set of tests that will increase confidence in the code. Next time, those developers will exchange roles. And if for some reason in your organization there’s a testing team, then it’s important that sometimes they pair program together.&lt;/p&gt;
&lt;p&gt;Testing shouldn’t be an afterthought when a developer finishes coding. It must be integrated into your delivery pipeline, in the same way you integrate code. You might not run all tests in all stages, but it’s important that they’re built together.&lt;/p&gt;
&lt;h2&gt;Continuously Adjust Based On Results&lt;/h2&gt;
&lt;p&gt;Avoid keeping your testing strategy static. It must be evolving continuously.&lt;/p&gt;
&lt;p&gt;You’ll always have bugs by missing tests. Get used to it and expect it. Your main job after this happens is to reproduce the bugs by including a new set of tests in the pipeline. This will break something, but that’s the idea. It should be evident that the problem exists before you even start coding the fix.&lt;/p&gt;
&lt;p&gt;In the end, it doesn’t matter how many tests you have before going live. There’s nothing like real users for testing, and that’s why you need to continuously adjust, adapt, and evolve your testing strategy. But with the ideas above, you’re amplifying feedback and becoming aware of any bugs early.&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="testing"/></entry><entry><title>How Does DevOps Help You Make Database Changes?</title><link href="https://cmelendeztech.com/posts/2018/08/how-does-devops-help-make-database-changes.html" rel="alternate"/><published>2018-08-08T00:00:00+02:00</published><updated>2018-08-08T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-08-08:/posts/2018/08/how-does-devops-help-make-database-changes.html</id><summary type="html">&lt;p&gt;Databases have always been treated with a certain level of respect---sometimes to the point that when we want to make a change to the database, we have to create scripts that contain all the commands that need to be executed in the destination environment. Of course, these sets of commands …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Databases have always been treated with a certain level of respect---sometimes to the point that when we want to make a change to the database, we have to create scripts that contain all the commands that need to be executed in the destination environment. Of course, these sets of commands need to be reviewed first by someone else (usually a DBA team).&lt;/p&gt;
&lt;p&gt;We need to be this careful because if something goes wrong, data could be lost. The life of a company could go down the drain. Sure, there are always backups, but let's be honest: how many of us have tried to recover from those backups recently? And how many of us do it periodically? Not that many of us can proudly say that we do.&lt;/p&gt;
&lt;p&gt;I know I'm not alone in thinking that working with databases can turn complicated, especially as they grow. We've all suffered this pain, or at least have heard of or seen someone else deal with it. But what about if we could apply some DevOps principles to databases? It's worked so well with application code. Why don't we give it a try?&lt;/p&gt;
&lt;h1&gt;&lt;strong&gt;Why Database Changes Are So Hard&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;Usually, database changes are not an automated task because each change is different. And tools can help you to manage them by creating scripts, but there are some tools that will include sentences that will first delete a table and then create it, as if it's always about a greenfield project. This is why DBAs like to take a final review before proceeding with the deployment to production.&lt;/p&gt;
&lt;p&gt;Another reason database changes are hard is that databases tend to be really big, especially now that we're storing all sorts of information just for the sake of it. Everyone knows &lt;strong&gt;big databases are problematic&lt;/strong&gt;. When we do a change in these databases, it could take hours to finish. And what about if we don't get the results we expected? Rollbacks could take twice the time.&lt;/p&gt;
&lt;p&gt;And it's not just that. Because of the nature of how changes are promoted, &lt;strong&gt;it's probable that the different database environments are not alike&lt;/strong&gt;. This causes problems for the DBAs when running the scripts in production. Developers get informed of it, but they have no idea what could have happened because it always worked. So they spend some more time troubleshooting.&lt;/p&gt;
&lt;p&gt;We all get it. Changes in databases are really hard to promote...but what if they weren't?&lt;/p&gt;
&lt;h1&gt;&lt;strong&gt;Treat Your Database Like Code&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;There must be a better way, right? I mean, how are companies able to do several deployments a day without considering databases? Everyone has to interact with a database---no exceptions. It doesn't matter if it has good architecture or not. Systems are there to collect information, process it, and then produce a result. That result can't just be sporadic. It needs to be preserved.&lt;/p&gt;
&lt;p&gt;The good news is that there &lt;em&gt;is&lt;/em&gt; a better way. What we need is to start treating our databases like code. You might have heard this before with &lt;a href="http://techtowntraining.com/resources/blog/infrastructure-as-code-iac-benefits"&gt;infrastructure as code&lt;/a&gt;, where we define infrastructure by using a descriptive language. The scripts we've been talking about could go under version control. But it's more than that---it's about changing your mindset. If we want this to succeed, we should avoid promoting database changes manually.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;All database changes need to be scripted, pushed into version control, and introduced in your current delivery pipeline.&lt;/strong&gt; These scripts need to have a special characteristic. They should be idempotent, meaning that it doesn't matter how many times that script is run---it should always produce the same result. It's as simple as adding an "if," just to check if the field the script is about to add already exists.&lt;/p&gt;
&lt;p&gt;But you don't have to create your own script. There are &lt;a href="https://www.red-gate.com/solutions/database-devops/"&gt;tools&lt;/a&gt; and &lt;a href="https://docs.microsoft.com/en-us/ef/core/"&gt;frameworks&lt;/a&gt; out there that help you to treat your databases like code.&lt;/p&gt;
&lt;h1&gt;&lt;strong&gt;Treat Every Database Change Like a Migration&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;There's a wonderful project that I love in the .NET stack called &lt;a href="https://docs.microsoft.com/en-us/ef/core/"&gt;Entity Framework Core&lt;/a&gt; (EFC). When you use this framework, it doesn't really matter what database vendor you're using. You interact with the database by using objects, because it's an object-relational mapper (ORM). Although this is incredibly powerful, that's not the point of this post.&lt;/p&gt;
&lt;p&gt;Still, what I like about EFC is that you can use migrations to promote changes. It's as easy as running a set of commands. For example, say you need to start with the following to create the initial migration script, including the initial table structure like columns, indexes, and keys:&lt;/p&gt;
&lt;p&gt;dotnet ef migrations add InitialCreate&lt;/p&gt;
&lt;p&gt;It will translate all the objects you've defined in the code to a SQL format. When you need to promote changes to another environment, you just run the following command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;dotnet ef database update
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That command will check if the change was already applied to the database. If it wasn't, it applies the change.&lt;/p&gt;
&lt;p&gt;When you keep iterating and doing changes, you can continue doing them in the code. Then it's just a matter of creating a new migration by running the first command you ran when you started. To promote, you just run the update command again.&lt;/p&gt;
&lt;p&gt;Those commands are repeatable, which makes it easy to introduce them into your delivery pipeline. EFC will take care of making sure that those migrations are idempotent. Does this mean that DBAs will be out of the equation? No, there are sentences that DBAs might want to review before proceeding. The difference now is that they'll be happy because there will be a standard format in scripts. And they'll be involved early in the process, not just before a release.&lt;/p&gt;
&lt;h1&gt;&lt;strong&gt;But...What About Rollbacks?&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;It's really important to be able to manage rollbacks in databases easily. Let's keep using the EFC example. EFC creates a migration history table when you start using it. So every time you run a migration, it adds a tuple to that table to keep track of what migrations it applied to the database. Having this process is really helpful because you can also roll back the last migration. You can keep rolling back until the database is in the desired state.&lt;/p&gt;
&lt;p&gt;Another important aspect for rollbacks is that your application needs to be able to live with new and previous versions of the database. Changes need to be backward and forward compatible. This will help you to decouple database changes from code changes. The idea is that it shouldn't matter which goes first, the code or database changes---you shouldn't have any downtime. There might be occasions when this won't be possible because a change is too complex and existing data is too big. But try to make that the exception and not the rule.&lt;/p&gt;
&lt;h1&gt;&lt;strong&gt;It's Not Just Automation&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;Tools are important. Honestly, they make our jobs easier. Automation will be easier to implement. But it's about more than tools; it's about a change in mindset for developers, testers, DBAs, managers, and everyone else involved.&lt;/p&gt;
&lt;p&gt;It's possible to introduce database changes in DevOps. It won't be as easy as with code, but it's definitely doable. My recommendation will be, as always, to start small. Pick a non-critical or new project where you can apply these principles. It will help your team to get used to this new way of working. As one manager once told me, "I'm not sure if what you're suggesting will work, but I'm willing to be proven wrong."&lt;/p&gt;
&lt;p&gt;So prove to your boss or the blockers that they're wrong about how DevOps principles can help you make database changes. Treat your changes as if they were code and use migrations as a way to promote them. It will amplify feedback and visibility for the team. The result will be that you can iterate your product faster, and you can go back and forth as needed.&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="databases"/></entry><entry><title>Test Data Management and Its Role in DevOps</title><link href="https://cmelendeztech.com/posts/2018/07/test-data-management-and-its-role-devops.html" rel="alternate"/><published>2018-07-24T00:00:00+02:00</published><updated>2018-07-24T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-07-24:/posts/2018/07/test-data-management-and-its-role-devops.html</id><summary type="html">&lt;p&gt;In my career, there've been many times when I've experienced the false joy of my code change being ready to be released to production. I say false joy because everything worked as expected on my computer, in dev, in testing and also staging. But in production, my recent code changes …&lt;/p&gt;</summary><content type="html">&lt;p&gt;In my career, there've been many times when I've experienced the false joy of my code change being ready to be released to production. I say false joy because everything worked as expected on my computer, in dev, in testing and also staging. But in production, my recent code changes were causing intermittent problems.&lt;/p&gt;
&lt;p&gt;You know the types of problems. It's always something little, like data being longer than expected for certain fields. No matter how careful I was when testing my change, there was a scenario that I forgot or I didn't know existed. If only I could have good data that helped me to do my job better! My joy wouldn't be diluted by those errors.&lt;/p&gt;
&lt;p&gt;Having data for good quality testing is key. And that's where test data management (TDM) comes into play. But what's its role in DevOps? Is it possible to integrate TDM? And how would we go about it?&lt;/p&gt;
&lt;p&gt;Let's find out.&lt;/p&gt;
&lt;h1&gt;&lt;strong&gt;What Is Test Data Management?&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;Missing a use case of our app: it's a common problem in all types of organizations that develop software. No matter how we think our app will be used, users tend to exceed our expectations for creativity when using it. And production is production. It serves as a reminder to us that our test cases aren't invincible. If only we could test our changes in production.&lt;/p&gt;
&lt;p&gt;But what if we could have production-like environments? And what if these could be production-like environments not just in terms of infrastructure, but also in terms of data?&lt;/p&gt;
&lt;p&gt;TDM is the process of creating production-like data for testing purposes. In some cases, there's no difference. But when there's sensitive data, things change. That sensitive data needs to be masked; then, if it's compromised, the impact will be low.&lt;/p&gt;
&lt;p&gt;Tests are important in DevOps. Without tests, it's easy to lose confidence in our applications, and deployments tend to be scary. You need data for good tests. TDM won't prevent you from introducing bugs, but it will help you to reduce the chances by giving you the ability to build data of good quality. That's because if you're able to reproduce an error in production, you'll be able to fix it and make sure it won't happen again. Bugs will continue emerging, but they won't be the same ones over and over. Thus, it's important that anyone in the team can access the data they need when they need it.&lt;/p&gt;
&lt;h1&gt;&lt;strong&gt;Test Data Management Should Be Self-Service For Everyone&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;Well, we know now that there's a process to prepare data and there are tools for the job. The next obvious thought then will be to automate it and give access to the team. That way, operations and DBAs stop being the bottleneck.&lt;/p&gt;
&lt;p&gt;When you're building this process, everyone should be involved. You should agree on what data can and should be used, what data will be masked, and how much data will be needed---much like a data discovery phase, if you will. But after there's an agreement, the team should work on having this process automated so that everyone can create, update, or duplicate data for testing. DBAs will appreciate it; it's one less thing to worry about.&lt;/p&gt;
&lt;p&gt;You don't have to reinvent the wheel. There are already some &lt;a href="http://www.softwaretestinghelp.com/tools/14-test-data-management-tools/"&gt;tools&lt;/a&gt; for this job.&lt;/p&gt;
&lt;p&gt;People shouldn't have to wait too long to get the data they need---and, in fact, they won't wait. They'll find ways to get around things that take time and will shift testing to the right. That's why it's key that you choose the proper tool and plan ahead what data will be needed.&lt;/p&gt;
&lt;h1&gt;&lt;strong&gt;Test Data Management Should Help You Keep Healthy Data&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;It's also important to keep in mind that we're talking about having production-like data in other environments. Initially, that might not be a problem. But as the data grows, it could be costly. This process will also force you to keep your data healthy, not bloated.&lt;/p&gt;
&lt;p&gt;My recommendation is that you start by having all the data you need, but as you grow, start generating the data for each test case. Or you can even have a mix of pre-populated data and static data that you generate in the code for each test case. Look forward to having more static data because it will be cheaper and you'll have more control over it!&lt;/p&gt;
&lt;p&gt;It will always depend on the use case, but I've seen databases with tables that have data from years, not months or days. It affects not only costs by using more storage but also performance when writing. When this happens, why don't we consider keeping just the data that's needed and then moving historical data for reporting somewhere else? Or what about working with tables per day, week, or month? It's complex, but as with everything, there are always tradeoffs you need to consider.&lt;/p&gt;
&lt;p&gt;The plan is to include TDM in your delivery pipeline. So always keep an eye on the time it takes to prepare data, and make sure to optimize. It's key to reduce lead time to deliver your software, so the less time it takes for TDM, the better.&lt;/p&gt;
&lt;h1&gt;&lt;strong&gt;It Should Be Part of CI/CD Processes&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;Once TDM is a self-service process that testers and developers can use when they need it (and once it runs fast), it's time to implement it in your continuous integration and delivery process.&lt;/p&gt;
&lt;p&gt;In DevOps, every process or task that increases silos are shifted to the left. Shifting to left means that you take to doing it at the very beginning of the workflow. We've seen this happen with deployments, security, testing, and basically everything we need to develop and deliver software.&lt;/p&gt;
&lt;p&gt;If we're talking about shifting to the left, it means that we should even start including TDM on a developer's machine. Same for testers and any other team member involved in the process. Some argue that developers and testers should generate static data for testing and that they should invest heavily in unit testing, mocks, and stubs. Some even say you should even use &lt;a href="https://thenewstack.io/microsoft-uses-linux-containers-test-sql-server-2017/"&gt;containers&lt;/a&gt;. It's not just cheaper to go this route---it's also faster. I get it, and actually, I'm an advocate for that. But I won't lie; doing that is not an easy task.&lt;/p&gt;
&lt;p&gt;So while you work on increasing test coverage with unit tests, the easiest way to start is by integrating TDM into your workflow. It's better that your process become reliable first. Then you can optimize and improve it.&lt;/p&gt;
&lt;h1&gt;&lt;strong&gt;Good Testing Data Increases Reliability&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;Want to increase deployment reliability and at the same time reduce the lead time? Invest in TDM and make it part of your process. Shift it to the left. Don't let testing become an afterthought. A sign that you're not shifting to the left enough is when development is finished and you still need to wait for tests to validate those changes.&lt;/p&gt;
&lt;p&gt;Automate your tests. It's OK that you started testing manually, but try to take the time to automate as much as possible---even the process of preparing the data. After that, include it in your DevOps implementation. Make it part of your delivery process. But you also need to pay attention to the time it takes to generate testing data. This will force you in some way to think constantly in your data architecture.&lt;/p&gt;
&lt;p&gt;And it's good to be thinking. If you do so, you'll always improve, and you'll decouple things that are not just hard to change but also to test.&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="tdm"/><category term="testing"/></entry><entry><title>7 Container Design Patterns You Need to Know</title><link href="https://cmelendeztech.com/posts/2018/07/7-container-design-patterns-you-need-know.html" rel="alternate"/><published>2018-07-04T00:00:00+02:00</published><updated>2018-07-04T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-07-04:/posts/2018/07/7-container-design-patterns-you-need-know.html</id><summary type="html">&lt;p&gt;&lt;img alt="Container Design Patterns" src="/images/container-design-patterns.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Containers are popular right now because they &lt;a href="https://techbeacon.com/one-year-using-kubernetes-production-lessons-learned"&gt;help move applications forward&lt;/a&gt; in a consistent, repeatable, and predictable manner, reducing labor and making app management simpler. &lt;/p&gt;
&lt;p&gt;But how do you know if you're &lt;a href="https://techbeacon.com/essential-guide-software-containers-application-development"&gt;using containers properly&lt;/a&gt;? That's where container design patterns come into play. Here's what you need to know about …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="Container Design Patterns" src="/images/container-design-patterns.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Containers are popular right now because they &lt;a href="https://techbeacon.com/one-year-using-kubernetes-production-lessons-learned"&gt;help move applications forward&lt;/a&gt; in a consistent, repeatable, and predictable manner, reducing labor and making app management simpler. &lt;/p&gt;
&lt;p&gt;But how do you know if you're &lt;a href="https://techbeacon.com/essential-guide-software-containers-application-development"&gt;using containers properly&lt;/a&gt;? That's where container design patterns come into play. Here's what you need to know about container design patterns and why you need them, along with seven common design patterns to consider and how to choose the right one for your needs.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://techbeacon.com/building-software-its-all-about-thinking-acting-effective-communication"&gt;Design patterns&lt;/a&gt; exist to help you solve common problems with containers. They also provide a common language when communicating about the architecture of the applications. That way, everyone can understand what's going on.&lt;/p&gt;
&lt;p&gt;Design patterns ultimately help make containers reusable. Users of those containers will give each their own purpose. There are times when I don't need to have a complex configuration to test locally, but at the same time, I don't want to modify the architecture so much that I lose consistency when testing. That's why having a baseline is helpful: to reuse containers and make things simpler to test.&lt;/p&gt;
&lt;h3&gt;1. The Single-Container Design Pattern&lt;/h3&gt;
&lt;p&gt;Employing the single-container pattern means just putting your application into a container. It's how you usually start your container journey. But it's important to keep in mind that this pattern is all about simplicity, meaning that the container must have only one responsibility. That means it's an anti-pattern to have a web server and a log processor in the same container.&lt;/p&gt;
&lt;p&gt;Containers are commonly used for web apps, where you expose an HTTP endpoint. But they can be used for many different things.&lt;/p&gt;
&lt;p&gt;In Docker, you have the ability to change the behavior of a container at runtime, thanks to the &lt;a href="https://docs.docker.com/engine/reference/builder/#cmd"&gt;CMD&lt;/a&gt; and &lt;a href="https://docs.docker.com/engine/reference/builder/#entrypoint"&gt;ENTRYPOINT&lt;/a&gt; instructions. So I'm not limited to using containers for HTTP services. I can also use them for any bash script that accepts some parameters at runtime.&lt;/p&gt;
&lt;p&gt;By letting containers change behavior at runtime, you can create a base container that can be reused in different contexts. So you'd use the single-container pattern to expose an HTTP service or to reuse a script for which you don't want to worry about its dependencies. And it would be a good choice, as long as you keep in mind that containers should solve only one problem.&lt;/p&gt;
&lt;h3&gt;2. The Sidecar Design Pattern&lt;/h3&gt;
&lt;p&gt;So containers should have only one responsibility. But what about the use case I mentioned before, where you have a web server with a log processor? Actually, that's one of the exact problems that the sidecar pattern aims to resolve.&lt;/p&gt;
&lt;p&gt;Using the sidecar pattern means extending the behavior of a container. In our example of the log processor for the web server, the log processor could be a different container reading logs from the web server.&lt;/p&gt;
&lt;p&gt;The web server will need to write those logs to a volume. In Docker, &lt;a href="https://docs.docker.com/storage/volumes/"&gt;volumes&lt;/a&gt; can be shared with other containers. It's preferable to have this separation because it makes packaging, deployment, resiliency, and reuse easy—and also because not all containers will need or use the same resources.&lt;/p&gt;
&lt;p&gt;With this pattern, you're decoupling your system in different parts. Each part has its own responsibilities, and each solves a different problem. You're &lt;a href="https://www.brainyquote.com/quotes/creighton_abrams_207381"&gt;eating the elephant in small chunks&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;3. The Ambassador Design Pattern&lt;/h3&gt;
&lt;p&gt;If you're using the ambassador pattern, it means you have a proxy for other parts of the system. It transfers the responsibility to distribute the network load, retries, or monitoring to something else. A container should have one responsibility and be as simple as possible. For a container, the communication to the outside world will simply be an endpoint. It won't know (or care) if what's out there is a set of servers or just one server.&lt;/p&gt;
&lt;p&gt;This is the pattern you'd use when you want microservices to interact with one another. They don't know exactly where other microservices are; they just know they can find them by name. And for that, they need a service discovery. This discovery could be at the DNS level, or it could be at an application level, where microservices register. Service discovery will be in charge of keeping only healthy services.&lt;/p&gt;
&lt;p&gt;In Docker, this is possible because containers can live on the same virtual network. When you use &lt;a href="https://docs.docker.com/compose/"&gt;Docker Compose&lt;/a&gt; and you link containers, it basically modifies just the "hosts" file so the call to a service is by name, not by IP address. Also, Docker supports &lt;a href="https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables--e---env---env-file"&gt;environment variables&lt;/a&gt; to inject values such as subdomains for a proxy server that you can change depending on the environment.&lt;/p&gt;
&lt;h3&gt;4. The Adapter Design Pattern&lt;/h3&gt;
&lt;p&gt;Using the adapter pattern means keeping communication between containers consistent. Having a standard way of communicating via a set of contracts helps you to always make requests in the same way, and lets you expect the same response format. It also helps you easily replace an existing container without the consumer or client noticing because the contract won't change—just the implementation changes. You can also reuse this container somewhere else without having to worry about managing other application logs.&lt;/p&gt;
&lt;p&gt;Analyzing logs from different sources can be a pain if you don't have a standard format. When you have a container that works as an adapter, it will receive raw logs. It will standardize and store data in a centralized place. The next time you need to consume the logs, you'll have a consistent format, and so it will be easier to understand, correlate, and analyze logs.&lt;/p&gt;
&lt;p&gt;The main premise here is that the adapter pattern allows a container to reuse a solution for a common problem in the system.&lt;/p&gt;
&lt;h3&gt;5. The Leader Election Design Pattern&lt;/h3&gt;
&lt;p&gt;If you're using the leader election pattern, it means you're providing redundancy for consumers of containers that need to have highly available systems. You can see this pattern in tools such as &lt;a href="https://www.elastic.co/"&gt;Elasticsearch&lt;/a&gt;, an open-source stack. Elasticsearch's architecture consists of more than one node, and each node will have chunks of data (shard) for replication and redundancy purposes.&lt;/p&gt;
&lt;p&gt;When the service starts, a node is elected as the leader. If the service goes down, the rest of the nodes elect a leader based on certain criteria, keeping the cluster healthy.&lt;/p&gt;
&lt;p&gt;So how is this related to containers?&lt;/p&gt;
&lt;p&gt;Well, you can spin up a bunch of containers that communicate with one another without needing service discovery. Elasticsearch containers will elect a new leader, and then you can spin up a new one in just seconds, either manually or automatically, by using an orchestrator such as &lt;a href="https://kubernetes.io/"&gt;Kubernetes&lt;/a&gt;. Doing the same thing with virtual machines or physical servers could take minutes or even hours.&lt;/p&gt;
&lt;h3&gt;6. The Work Queue Design Pattern&lt;/h3&gt;
&lt;p&gt;The work queue pattern dictates that you split up a big task into smaller tasks to reduce running time. You can think of this as the &lt;a href="https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem"&gt;producer-consumer&lt;/a&gt; problem. Say a user requests that you transform 1 million records. This will take a lot of time. So to speed up the process, you'd employ the work queue pattern and transform the data into smaller chunks of 100 records each. The code that does the processing work can be packed into a container, and then you can spin up 10 containers at the same time.&lt;/p&gt;
&lt;p&gt;Containers are really useful for batch processes. You might need to worry about resources being able to support concurrency, but if you don't, there are tools or services such as &lt;a href="https://aws.amazon.com/batch/"&gt;AWS Batch&lt;/a&gt; that help you manage resources. You just need to provide a container and launch a set of execution jobs.&lt;/p&gt;
&lt;p&gt;Containers will help you make the code reusable and portable. But coordination is a problem better solved by container orchestrators.&lt;/p&gt;
&lt;h3&gt;7. The Scatter/Gather Design Pattern&lt;/h3&gt;
&lt;p&gt;The scatter/gather pattern is quite similar to the work queue pattern in the sense that it splits a big task into smaller ones. But there's one difference. Containers will immediately give a response back to the user. So instead of launching a bunch of tasks and forgetting for a moment about the actual response, in this pattern, you'd need to combine all small responses into just one. A really good example of this pattern is the &lt;a href="https://en.wikipedia.org/wiki/MapReduce"&gt;MapReduce&lt;/a&gt; algorithm.&lt;/p&gt;
&lt;p&gt;To implement this pattern, you need two containers. The first will do the partial computation that returns all small chunks needed (map), usually not in an ordered way. This container will then do a request to the second container you need, the one in charge of merging all parts, to return data that makes sense to the user.&lt;/p&gt;
&lt;p&gt;With this pattern, you're only focusing on developing each part independently, and you can spin up and use as many containers as needed.&lt;/p&gt;
&lt;h3&gt;Which Design Pattern to Choose?&lt;/h3&gt;
&lt;p&gt;Which pattern you should pick out of these seven depends on several factors. There's no silver bullet. Each design pattern has its own purpose and solves a different type of problem. Actually, you might want to apply more than one at the same time in the same system.&lt;/p&gt;
&lt;p&gt;These design patterns for &lt;a href="https://techbeacon.com/units/tb-learn-containers-containers-microservices-modernizing-legacy-applications"&gt;containers&lt;/a&gt; let you focus on developing the mindset to comprehend distributed systems. They give you the ability to reuse code and have fault-tolerant and high-availability architectures with optimized resources.&lt;/p&gt;
&lt;p&gt;I've just scratched the surface of each pattern. Hopefully, you've learned enough to know which ones may be right for your application. I encourage you to further explore the patterns you think will best target the problems you face.&lt;/p&gt;</content><category term="misc"/><category term="containers"/></entry><entry><title>AWS Batch: A Detailed Guide to Kicking Off Your First Job</title><link href="https://cmelendeztech.com/posts/2018/06/aws-batch-guide.html" rel="alternate"/><published>2018-06-29T00:00:00+02:00</published><updated>2018-06-29T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-06-29:/posts/2018/06/aws-batch-guide.html</id><summary type="html">&lt;p&gt;&lt;img alt="AWS Batch Guide" src="/images/aws-batch-guide/AWS-Batch_-A-Detailed-Guide-to-Kicking-Off-Your-First-Job-881x441.png"&gt;&lt;/p&gt;
&lt;p&gt;There are always the kind of tasks that need to run periodically, either to analyze and process information (like fraud detection), or to simply do things like send email reports. But for that, we need to have a tool to schedule computer resources and, of course, the script.&lt;/p&gt;
&lt;p&gt;But what …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="AWS Batch Guide" src="/images/aws-batch-guide/AWS-Batch_-A-Detailed-Guide-to-Kicking-Off-Your-First-Job-881x441.png"&gt;&lt;/p&gt;
&lt;p&gt;There are always the kind of tasks that need to run periodically, either to analyze and process information (like fraud detection), or to simply do things like send email reports. But for that, we need to have a tool to schedule computer resources and, of course, the script.&lt;/p&gt;
&lt;p&gt;But what if we only need to worry about coding the script?&lt;/p&gt;
&lt;p&gt;Introducing &lt;a href="https://aws.amazon.com/batch/"&gt;AWS Batch.&lt;/a&gt; It’s a free service that takes care of batch jobs you might need to run periodically or on-demand. And you only pay for the resources you use.&lt;/p&gt;
&lt;p&gt;In this tutorial, you’ll learn how to kick off your first AWS Batch job by using a &lt;a href="https://stackify.com/complete-docker-toolkit/"&gt;Docker&lt;/a&gt; container.&lt;/p&gt;
&lt;h2&gt;What Is AWS Batch? A Quick Overview&lt;/h2&gt;
&lt;p&gt;Before we dive in, let’s do a quick overview of the subject at hand. AWS Batch is a service that lets you run batch jobs in AWS. You don’t have to worry about installing a tool to manage your jobs. AWS Batch will do that for you.&lt;/p&gt;
&lt;p&gt;There are a lot of features you might not need when you’re first starting out, but let’s explore a few of them anyway:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Instances will run only for the time that’s needed&lt;/strong&gt;, taking advantage of the per-second billing. You can also lower your costs by using &lt;a href="https://aws.amazon.com/ec2/spot/"&gt;spot instances&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;It’s possible to configure how many &lt;strong&gt;retries&lt;/strong&gt; you’d like for any job.&lt;/li&gt;
&lt;li&gt;It offers &lt;strong&gt;queues&lt;/strong&gt; where you send the jobs. Each queue could be configured with a certain priority so you can configure which jobs will run first. You can also have queues that use better resources to speed up the process.&lt;/li&gt;
&lt;li&gt;It supports &lt;strong&gt;Docker containers&lt;/strong&gt; so that you can focus only on your code.&lt;/li&gt;
&lt;li&gt;And &lt;a href="https://aws.amazon.com/batch/details/"&gt;more&lt;/a&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, enough theory. Let’s get our hands dirty.&lt;/p&gt;
&lt;h2&gt;Kick Off Your First Job&lt;/h2&gt;
&lt;p&gt;Before we start, there are some prerequisites that will make this tutorial easy to follow, and it will include some good practices in regards to security. If you think you need more details, you can check the &lt;a href="https://docs.aws.amazon.com/batch/latest/userguide/get-set-up-for-aws-batch.html"&gt;setup&lt;/a&gt; page in AWS’s official docs.&lt;/p&gt;
&lt;h3&gt;Prerequisites&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Have an AWS account.&lt;/li&gt;
&lt;li&gt;Create an IAM user with administrator permissions. To do this, you can just follow this tutorial. I recommend you give granular permissions to the user that will do the provisioning.&lt;/li&gt;
&lt;li&gt;Install and configure &lt;a href="https://stackify.com/what-is-aws-cli/"&gt;AWS CLI&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If something from the above doesn’t work, it might be because a permission is missing, or the CLI is not configured properly. I’ll let you know exactly what’s needed in the following steps.&lt;/p&gt;
&lt;h3&gt;Go to AWS Batch&lt;/h3&gt;
&lt;p&gt;Log in to your AWS account and look for AWS Batch in the initial screen, or you can go directly by using &lt;a href="https://console.aws.amazon.com/batch/home?region=us-east-1#/first-run"&gt;this link&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You’ll see a screen like the following:&lt;/p&gt;
&lt;p&gt;&lt;img alt="AWS Batch guide " src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201.png"&gt;&lt;/p&gt;
&lt;p&gt;Click the “Get started” button. Then, this next screen will appear:&lt;/p&gt;
&lt;p&gt;&lt;img alt="AWS Batch guide " src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-1.png"&gt;&lt;/p&gt;
&lt;p&gt;Click the “Skip wizard” button. We’re not going to follow this wizard because I want to explain each step to you. Also, after this, you’ll probably use AWS CloudFormation or something else to provision, not the wizard.&lt;/p&gt;
&lt;h3&gt;Create a compute environment&lt;/h3&gt;
&lt;p&gt;The jobs will run on a compute environment. Here, you’ll configure the instance type, family, and some other things that we’ll see in a bit.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It’s important that you know we’re not going to create any instances now.&lt;/strong&gt; AWS Batch will create one when it’s needed. You can also configure things to create instances right away, speeding up job scheduling, but we won’t tackle that in this post.&lt;/p&gt;
&lt;p&gt;Click the “Compute environments” link that appears in the left menu. You’ll see the following screen:&lt;/p&gt;
&lt;p&gt;&lt;img alt="AWS Batch guide instances" src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-2.png"&gt;&lt;/p&gt;
&lt;h4&gt;Instance type and permissions&lt;/h4&gt;
&lt;p&gt;Now click the “Create environment” blue button so you can start defining the compute environment. You’ll start configuring the environment in the following screen:&lt;/p&gt;
&lt;p&gt;&lt;img alt="AWS Batch guide  create environment" src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-3.png"&gt;&lt;/p&gt;
&lt;p&gt;For simplicity, we’re going to choose all default values. You just need to name the environment. I called it “first-compute-environment.”&lt;/p&gt;
&lt;p&gt;You don’t have to worry about creating a service or instance role right now. Just choose the option “Create new role” for both, and AWS will create them for you with the proper permissions. It will help you see which permissions are needed and adjust them if you want to.&lt;/p&gt;
&lt;p&gt;Leave the EC2 key pair blank because we don’t need to access the servers for now.&lt;/p&gt;
&lt;h4&gt;Compute resources&lt;/h4&gt;
&lt;p&gt;Scroll down a little bit, and let’s talk about the compute resources section. You’ll see the following screen:&lt;/p&gt;
&lt;p&gt;&lt;img alt="AWS Batch guide compute resources" src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-4.png"&gt;&lt;/p&gt;
&lt;p&gt;This is where you get to choose if you want to use on-demand or spot instances. For simplicity, let’s choose “On-demand.”&lt;/p&gt;
&lt;p&gt;The “Allowed instance types” field is where you define which family type you’d like these environments to create. This is where things get fun because you can create compute environments that are CPU-intensive and choose between C family instance types. Or if there are jobs that are memory intensive, you can choose M family instance types. You’re limiting which instance types can be created. I chose “optimal,” so AWS decides for me which instance is better based on the configuration of job queues.&lt;/p&gt;
&lt;p&gt;Now, &lt;strong&gt;vCPUs are one of the most important things&lt;/strong&gt; here in order for your first job to run.&lt;/p&gt;
&lt;p&gt;If you’re familiar with running workloads using ECS, you might get confused here. You might configure so many vCPUs that AWS won’t be able to create the environment. And even if there are a few instances running, jobs won’t run until the environment is ready. So keep in mind that &lt;strong&gt;vCPUs are virtual CPUs, not CPU units&lt;/strong&gt; that you configure in a container when running in ECS.&lt;/p&gt;
&lt;p&gt;I configured a maximum of four vCPUs. It means that if at some point the cluster has four vCPUs among all instances, it won’t create more. Jobs will run slowly, but your costs will remain controlled. I also put one vCPU as desired, just so it starts creating an instance right now. AWS will adjust this later if needed, and you can change it when submitting a job if you’re in a hurry.&lt;/p&gt;
&lt;h4&gt;Networking&lt;/h4&gt;
&lt;p&gt;Scroll down a little bit, and you’ll now configure the networking section and tags. You’ll see a screen like this:&lt;/p&gt;
&lt;p&gt;&lt;img alt="AWS Batch guide networking" src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-5.png"&gt;&lt;/p&gt;
&lt;p&gt;Leave the VPC and subnets as default for now. Click the “Create” blue button and wait a bit while the environment is created.&lt;/p&gt;
&lt;p&gt;&lt;img alt="AWS Batch guide  compute environments" src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-6.png"&gt;&lt;/p&gt;
&lt;h3&gt;Create a job queue&lt;/h3&gt;
&lt;p&gt;Now you need a queue where you’ll send the jobs to get executed. This queue will be attached to a compute environment so the AWS Batch service will create the resources needed based on the load of the queue. It will use the min, max, and desired vCPUs configuration to know how many instances to create.&lt;/p&gt;
&lt;p&gt;Click the “Job queues” link in the left menu and you’ll see the following screen:&lt;/p&gt;
&lt;p&gt;&lt;img alt="AWS Batch guide jon queues" src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-7.png"&gt;&lt;/p&gt;
&lt;p&gt;Then, you can click the “Create queue” blue button. You’ll see this:&lt;/p&gt;
&lt;p&gt;&lt;img alt="AWS Batch guide create job queue" src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-8.png"&gt;&lt;/p&gt;
&lt;p&gt;Let’s put a name to the queue so it’s easy to identify. I called it “first-job-queue.”&lt;/p&gt;
&lt;p&gt;In the priority, make sure you type a value that lets you play with lower priority queues later. I put “100” in case I need to create a lower priority queue later—say, for example, one with 50.&lt;/p&gt;
&lt;p&gt;Enable the job queue. By default, this checkbox will be checked. You should leave it that way.&lt;/p&gt;
&lt;p&gt;You now need to connect this queue to one or more compute environments. I chose the one I just created, the “first-compute-environment” one. If there were any other environment, this is where you’d choose it.&lt;/p&gt;
&lt;p&gt;Why would I like to have more than one compute environment?  Well, it’s useful if you want to speed up a job’s processing time by creating more instances using the spot market. You can have an &lt;strong&gt;on-demand&lt;/strong&gt; compute environment where you always have resources available. And if the load increases, you can create &lt;strong&gt;spot instances&lt;/strong&gt; if there are any available, based on the bid you configured.&lt;/p&gt;
&lt;p&gt;Click the “Create queue” blue button.&lt;/p&gt;
&lt;p&gt;&lt;img alt="http://www.hitsubscribe.com/wp-content/uploads/2018/03/Screen-Shot-2018-03-13-at-2.24.36-PM.png" src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-9.png"&gt;&lt;/p&gt;
&lt;h3&gt;Create a job using Docker&lt;/h3&gt;
&lt;p&gt;We’re going to use a “hello world” job that AWS evangelists have &lt;a href="https://github.com/awslabs/aws-batch-helpers"&gt;used&lt;/a&gt; for &lt;a href="https://youtu.be/H8bmHU_z8Ac?t=1696"&gt;demo&lt;/a&gt; purposes. I couldn’t find a repository with all the files they’ve used, so I created one with all the files we’re going to need. You can find it on GitHub &lt;a href="https://github.com/christianhxc/aws-batch-101"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let’s explore what’s in there, as well as why and how to use those files to create our first job in AWS Batch.&lt;/p&gt;
&lt;h4&gt;Docker image&lt;/h4&gt;
&lt;p&gt;We’re going to create a simple job that will pull a Bash script from S3 and execute it. The Dockerfile and the script that does what I just described is located in the “job” folder of the repository.&lt;/p&gt;
&lt;p&gt;&lt;img alt="AWS Batch guide create job" src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-10.png"&gt;&lt;/p&gt;
&lt;p&gt;I won’t explain either the script or the Dockerfile just yet—we’ll just use it. So let’s build the Docker image and push it to the &lt;a href="https://hub.docker.com/"&gt;Docker hub&lt;/a&gt;. You need to have Docker installed on your machine, a Docker hub account, and a login for your computer.&lt;/p&gt;
&lt;p&gt;Let’s build the Docker image. You can skip this step and use my image located &lt;a href="https://hub.docker.com/r/christianhxc/aws-batch-101/"&gt;here&lt;/a&gt;, or you can run the following command and tag the image using your username instead of mine:&lt;/p&gt;
&lt;p&gt;docker build -t christianhxc/aws-batch-101:latest .&lt;/p&gt;
&lt;p&gt;Now, let’s push the image. You need to be logged in with your user ID. And make sure you push the image that has your username in the tag. Run the following command:&lt;/p&gt;
&lt;p&gt;docker push christianhxc/aws-batch-101:latest&lt;/p&gt;
&lt;p&gt;That’s it! You now have the Docker image that will download a Bash script from S3 and run it.&lt;/p&gt;
&lt;h4&gt;A Bash script&lt;/h4&gt;
&lt;p&gt;Let’s create the Bash script. You can use the one I have in the repo. That script simply puts a Fibonacci sequence in a DynamoDB table. It uses an environment variable called FOO to create the series of numbers, and it uses an argument just to print it in the console.&lt;/p&gt;
&lt;p&gt;This script is in the root of the GitHub repository I linked before, and it’s called mapjob.sh&lt;/p&gt;
&lt;p&gt;&lt;img alt="AWS Batch guide bash script" src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-11.png"&gt;&lt;/p&gt;
&lt;p&gt;Now, because this is outside the scope of AWS Batch, I’m just going to list the actions you’ll need for this guide to work. We’ll need to do the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Create a DynamoDB table&lt;/strong&gt; in the Virginia region. Mine is called “fetch_and_run.” If you decide to enter a different name, make sure you change it at the end in the mapjob.sh script.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Create an S3 bucket&lt;/strong&gt; in the Virginia region. Mine is called “cm-aws-batch-101.” Don’t make it public.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Upload the mapjob.sh&lt;/strong&gt; script in the bucket you just created.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Create an IAM role&lt;/strong&gt; for an ECS service task with permissions to the S3 bucket and the DynamoDB table. If you don’t know how to do that, follow &lt;a href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html#create_task_iam_policy_and_role"&gt;these&lt;/a&gt; instructions. I called my IAM role “aws-batch-101.” We’ll use this one next.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You’re almost ready to kick off your first job. You already have a script and a Docker image to use.&lt;/p&gt;
&lt;p&gt;Let’s create the job definition in AWS and then submit a job.&lt;/p&gt;
&lt;h3&gt;Create a job definition&lt;/h3&gt;
&lt;p&gt;At this point, you’ve defined the environment where your jobs will run and the queue, which means AWS takes care of creating resources only when they’re needed. Now you need to run the job definition. And this is where things get more interesting.&lt;/p&gt;
&lt;p&gt;Click the “Job definitions” link in the left menu and you’ll see the following screen:&lt;/p&gt;
&lt;p&gt;&lt;img alt="AWS Batch guide job definitions" src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-12.png"&gt;&lt;/p&gt;
&lt;p&gt;Click the “Create” blue button and let’s start defining the job.&lt;/p&gt;
&lt;p&gt;&lt;img alt="AWS Batch guide create job definition" src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-13.png"&gt;&lt;/p&gt;
&lt;p&gt;Enter any name you’d like. I put “first-job.” Next, choose the IAM role you created previously; mine is “aws-batch-101.” Now pick a name for the container image. Like I said before, for simplicity, you can use mine. I called it “christianhxc/aws-batch-101:latest.” These values can’t be changed when submitting a job, but the ones we’re about to explore can be changed.&lt;/p&gt;
&lt;p&gt;Scroll down a bit and let me explain what’s there:&lt;/p&gt;
&lt;p&gt;&lt;img alt="AWS Batch guide environment" src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-14.png"&gt;&lt;/p&gt;
&lt;p&gt;The command field describes the command passed to the container. It maps to the &lt;em&gt;COMMAND&lt;/em&gt; parameter to &lt;em&gt;docker run&lt;/em&gt;. Here, we’ll type the name of the script that will run the container and its parameters. Because we can override this value, we’ll leave it as it is right now.&lt;/p&gt;
&lt;p&gt;Now, here’s another trick to be able to run a job. Unfortunately, &lt;strong&gt;you can’t configure CPU units to a container&lt;/strong&gt;, only vCPUs. It means that, at minimum, the container will have 1024 CPU units because that’s the equivalent to one vCPU. You can configure the CPU, then, in blocks of 1024. This is important because I entered 256, thinking that this was CPU units, and the job never started. &lt;strong&gt;It sticks in the RUNNABLE state if there’s nowhere to run it.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Configure how much memory this container will need. I put 256. Leave the rest as it is.&lt;/p&gt;
&lt;h3&gt;Submit a job&lt;/h3&gt;
&lt;p&gt;You’re now, finally, able to submit a job.&lt;/p&gt;
&lt;p&gt;Click the “Jobs” link in the left menu, and you’ll see the following screen:&lt;/p&gt;
&lt;p&gt;&lt;img alt="AWS Batch guide jobs" src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-15.png"&gt;&lt;/p&gt;
&lt;p&gt;Click the “Submit job” blue button. Let’s submit one!&lt;/p&gt;
&lt;p&gt;&lt;img alt="AWS Batch guide submit batch job" src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-16.png"&gt;&lt;/p&gt;
&lt;p&gt;Next, name your job submission. I called it “first-attempt.” Choose the job definition and the queue we just created, and choose “Single” as a job type.&lt;/p&gt;
&lt;p&gt;Scroll down a little and let’s override some values here:&lt;/p&gt;
&lt;p&gt;&lt;img alt="http://www.hitsubscribe.com/wp-content/uploads/2018/03/Screen-Shot-2018-03-13-at-3.39.53-PM.png" src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-17.png"&gt;&lt;/p&gt;
&lt;p&gt;In here, you’ll need to put the name of the script in the S3 bucket and the Fibonacci number as parameter. But these are only for reference. I used “mapjob.sh 60.” Type in “1” for vCPU and “256” for memory. As for job attempts, 1 is fine.&lt;/p&gt;
&lt;p&gt;Scroll down some because our scripts need environment variables in order to work. Let’s add the corresponding values:&lt;/p&gt;
&lt;p&gt;&lt;img alt="http://www.hitsubscribe.com/wp-content/uploads/2018/03/Screen-Shot-2018-03-13-at-3.46.47-PM.png" src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-18.png"&gt;&lt;/p&gt;
&lt;p&gt;Let’s add the environment variables. For FOO, enter the Fibonacci number. I used 60. For BATCH_FILE_TYPE, put “script”, and for BATCH_FILE_S3_URL, put the S3 URL of the script that will fetch and run.&lt;/p&gt;
&lt;p&gt;Click the “Submit job” blue button and wait a while. You can go to the computer environment and changed the desired vCPUs to 1 to speed up the process.&lt;/p&gt;
&lt;p&gt;&lt;img alt="http://www.hitsubscribe.com/wp-content/uploads/2018/03/Screen-Shot-2018-03-13-at-3.52.53-PM.png" src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-19.png"&gt;&lt;/p&gt;
&lt;p&gt;It will start creating one instance. When the instance is ready to process a job, the job will transition from RUNNABLE to SUCCEEDED.&lt;/p&gt;
&lt;p&gt;&lt;img alt="http://www.hitsubscribe.com/wp-content/uploads/2018/03/Screen-Shot-2018-03-13-at-3.54.01-PM.png" src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-20.png"&gt;&lt;/p&gt;
&lt;p&gt;And you’ll see a new entry in the DynamoDB table.&lt;/p&gt;
&lt;p&gt;&lt;img alt="http://www.hitsubscribe.com/wp-content/uploads/2018/03/Screen-Shot-2018-03-13-at-3.55.38-PM.png" src="/images/aws-batch-guide/http-www-hitsubscribe-com-wp-content-uploads-201-21.png"&gt;&lt;/p&gt;
&lt;p&gt;You can keep submitting jobs and change the FOO var to generate a different sequence of numbers. When you don’t submit any other job, AWS Batch will terminate the instance it created.&lt;/p&gt;
&lt;h2&gt;It’s Your Turn Now&lt;/h2&gt;
&lt;p&gt;You now have the basics to kick off a job in AWS Batch. Once you’ve finished this guide, it’s up to you which scripts or code you’ll put in a container. AWS Batch will manage all the infrastructure, scheduling, and retries for you.&lt;/p&gt;
&lt;p&gt;Now the challenge is in how to code your application so that you can submit several instances of a job. AWS Batch will run them as you submit them and will scale out/in when it’s needed, saving you some money. You can start by migrating any existing cronjob, but don’t stop there. Let’s be creative!&lt;/p&gt;</content><category term="misc"/><category term="aws"/><category term="docker"/><category term="awsbatch"/></entry><entry><title>Growing a High-Performance DevOps Culture</title><link href="https://cmelendeztech.com/posts/2018/06/growing-high-performance-devops-culture.html" rel="alternate"/><published>2018-06-08T00:00:00+02:00</published><updated>2018-06-08T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-06-08:/posts/2018/06/growing-high-performance-devops-culture.html</id><summary type="html">&lt;p&gt;Culture is one of those things where we all know what it is but can’t explain it. Well, according to &lt;a href="https://en.wikipedia.org/wiki/Culture"&gt;Wikipedia&lt;/a&gt;, culture is “the social behavior and norms found in human societies.” But in simple words, it’s all about people: how they interact, how they behave, how they …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Culture is one of those things where we all know what it is but can’t explain it. Well, according to &lt;a href="https://en.wikipedia.org/wiki/Culture"&gt;Wikipedia&lt;/a&gt;, culture is “the social behavior and norms found in human societies.” But in simple words, it’s all about people: how they interact, how they behave, how they talk, and what they practice. And culture is the foundation of a successful implementation of DevOps.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.linkedin.com/in/johnwillisatlanta/"&gt;John Willis&lt;/a&gt;, an established speaker and writer on the subject of DevOps, coined the term &lt;a href="http://itrevolution.com/devops-culture-part-1/"&gt;CAMS&lt;/a&gt; (culture, automation, measurement, sharing) at a talk where he explained that DevOps culture is about breaking down silos. But what I find most striking about his discussion of culture, as summarized in the &lt;a href="http://devopsdictionary.com/wiki/CAMS"&gt;DevOps Dictionary&lt;/a&gt;, is the observation that “fostering a &lt;strong&gt;safe environment for innovation and productivity&lt;/strong&gt; is a key challenge for leadership and directly opposes our tribal managerial instincts.” So the starting point for your DevOps journey is good leadership. After that, it’s just about how to grow your team to become a high-performing one.&lt;/p&gt;
&lt;p&gt;A high-performing team in DevOps, according to &lt;a href="https://puppet.com/resources/whitepaper/state-of-devops-report"&gt;recent research&lt;/a&gt;, is one that&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Does deployments often, meaning several times a day.&lt;/li&gt;
&lt;li&gt;Delivers a change with a fast lead time (minutes) after it’s been pushed to a shared repository.&lt;/li&gt;
&lt;li&gt;Has a short (again, minutes) mean time to recover (MTTR).&lt;/li&gt;
&lt;li&gt;Has a small change failure rate (described &lt;a href="https://devops.com/metrics-devops/"&gt;here&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So how do you grow a high-performance DevOps culture? You create a culture that will produce a team that delivers on time with confidence in a predictable manner. Here are the things that will help you get there.&lt;/p&gt;
&lt;h2&gt;Increase Deployment Frequency&lt;/h2&gt;
&lt;p&gt;Increasing deployment frequency could be seen as a contradiction to delivering in a reliable manner. But working in small batches isn’t anything new. &lt;a href="https://en.wikipedia.org/wiki/Scrum_(software_development)"&gt;Scrum&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Extreme_programming"&gt;Extreme Programming&lt;/a&gt; are two management systems for software development that emphasize delivering in short cycles. While deployment frequency varies from one user to the next, people who practice Scrum typically deploy biweekly. And sure, that may seem fast if you’re new to agile. But there are some companies that would find it laughable to call two weeks a “short cycle.”&lt;/p&gt;
&lt;p&gt;High performers are known for doing several deployments per day. The average high-performance team does four daily deployments, and some do way more than that. Etsy does eighty, and Amazon and Netflix deploy thousands of times every day, according to &lt;a href="https://puppet.com/resources/whitepaper/state-of-devops-report"&gt;this study&lt;/a&gt;. That seems crazy, but doing so increases delivery throughput and lets organizations get feedback all the time. Customers or stakeholders don’t have to wait for the sprint to finish. As soon as development has finished coding and verified that the change adds value (and doesn’t break anything), there’s no reason to keep waiting to deploy.&lt;/p&gt;
&lt;p&gt;Working in small batches is more than a practice. It’s a mindset. It requires that all members of the organization—developers, operators, businesspeople, and most importantly, leaders—think about it all the time. The result will be that you’ll increase customer collaboration because they’ll have something to try every day.&lt;/p&gt;
&lt;p&gt;When you incubate an idea for too long, it becomes obsolete and useless. Deliver, and do it often.&lt;/p&gt;
&lt;h2&gt;Find Countermeasures to Increase Speed&lt;/h2&gt;
&lt;p&gt;How will you know if something’s working or not if you don’t measure it?&lt;/p&gt;
&lt;p&gt;Measuring plays a big role in building a high-performance team. It’s important that you identify what’s stopping you from delivering on time. High performers have all sort of metrics in place to help them do that.&lt;/p&gt;
&lt;p&gt;One very important metric is lead time. Lead time is how long it takes to implement a change in a production environment after the code has been committed in version control. Basically, it’s how much time it takes to deploy and test code changes. This is important because it won’t matter how fast the developer codes; a change could take weeks to be delivered.&lt;/p&gt;
&lt;p&gt;Do you know what’s causing big lead times in your workflow? You might not.&lt;/p&gt;
&lt;p&gt;For example, you might be working with long-lived feature branches. Are you measuring the time it takes to merge the feature into the master branch? If you’re spending too much time on this task that doesn’t have much value, it’s time to find a countermeasure.&lt;/p&gt;
&lt;p&gt;According to lean training company &lt;a href="http://www.velaction.com/countermeasures/"&gt;Velaction&lt;/a&gt;, countermeasures are “the actions taken to reduce or eliminate the root causes of problems that are preventing you from reaching your goals.” So a good countermeasure in the above example is to use trunk-base development. You’ll always commit to the master branch, reducing the issue of having to spend too much time fixing merge conflicts.&lt;/p&gt;
&lt;p&gt;After you’ve applied a countermeasure, you might need to apply another one somewhere else. But it will be hard to identify which if you’re not measuring everything you’re doing.&lt;/p&gt;
&lt;p&gt;Having a culture of continuous learning in your organization will help you become better across the board. You won’t stop improving once you’ve made the transition from doing deployments once a month to two weeks. You’ll continue working to identify what’s preventing you from doing daily deployments. And deployments are just one example. What about code coverage? Manual testing? Immutable infrastructure? The list goes on. But the idea is that you’ll always have a chance to improve what remains.&lt;/p&gt;
&lt;h2&gt;Stop Pointing Fingers&lt;/h2&gt;
&lt;p&gt;There’s nothing more harmful in a culture than pointing fingers when something goes wrong. No one that provoked a downtime said, “I’m bored. Let’s bring the system down, just for fun.” (Well, unless they’re hackers.) And if colleagues make someone feel guilty after causing a downtime, will that person admit fault the next time? Not likely.&lt;/p&gt;
&lt;p&gt;Failure is inevitable, so organizations should embrace it. It’s better to find mechanisms to reduce the time it takes to recover from failure than to try to avoid mistakes. One way to avoid failure is to do deployments less frequently, but that stops innovation.&lt;/p&gt;
&lt;p&gt;What you need in your organization is a &lt;strong&gt;blameless culture&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This is a culture that accepts that we all make mistakes sometimes. Being able to say, “I screwed up. I’m sorry. Can someone help me fix it?” will help your organization focus on a solution rather than the problem. And if there’s no stigma associated with guilt, the team can be honest about who else contributed to the problem.&lt;/p&gt;
&lt;p&gt;It’s important to build trust in your team. Making mistakes shouldn’t be a punishable offense. Instead, you should anticipate failure and then fail on purpose. Netflix does it all the time—they bring servers down just to test their fault-tolerant architecture.&lt;/p&gt;
&lt;p&gt;Now, telling management that you want to intentionally cause problems doesn’t sound good. But what if you did it in an environment other than production? What if it only affected certain users? These are ways that you can enable experimentation and build trust in the team.&lt;/p&gt;
&lt;p&gt;Let your people learn from their mistakes. Find ways to prevent those things from happening again. When something bad happens, it’s not about one person. Stop pointing fingers so everyone accepts responsibility for their mistakes. A healthy organization embraces failure and learns from it.&lt;/p&gt;
&lt;h2&gt;Enable Production-Like Environments&lt;/h2&gt;
&lt;p&gt;High performers have a low failure rate. Deployments don’t usually fail because high-performing teams deploy in small batches, they have practices in place that reduce lead time, and most importantly, they have a way to recover quickly in case of any failure.&lt;/p&gt;
&lt;p&gt;How is that possible?&lt;/p&gt;
&lt;p&gt;Well, one option is to have a production-like environment. It lets everyone experiment with what it’s like to work on a production server. And it lets the team practice deployments as if they were doing it in a production environment.&lt;/p&gt;
&lt;p&gt;For example, if you’re using Jenkins as your CI tool, you can make sure every developer has their own copy of Jenkins installed locally. Why? Having it running locally on their machines will let developers test their code before integrating it into the source control. The flow will be like this: do some changes, pull the latest changes from the repository, fix any conflicts, simulate the integration locally, and if it works, push the changes. By doing this, the practice of continuous integration will have the team always ready to deliver.&lt;/p&gt;
&lt;p&gt;Work on building a culture &lt;strong&gt;that’s always ready&lt;/strong&gt; by practicing before going live. This includes building, packing, testing, deploying, rolling back…you name it. You’ll avoid any surprises when going live, and that will reduce your failure rate, increasing the trust in the team.&lt;/p&gt;
&lt;h2&gt;Do It Again, but Better Every Time&lt;/h2&gt;
&lt;p&gt;You’ll start seeing the benefits of everything I described here once you’ve made it a habit. After all, practice makes perfect. People might not see the value of these initiatives right away, but don’t get frustrated. Just keep pushing until everyone gets it.&lt;/p&gt;
&lt;p&gt;Fostering a safe environment for innovation and productivity should be the main goal in every DevOps implementation. Building trust in the team brings enormous benefits because members will have a feeling of ownership when doing things.&lt;/p&gt;
&lt;p&gt;When you reward certain behaviors, you see that behavior more often. So make sure everything you reward contributes to building a high-performance culture.&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="development"/></entry><entry><title>But I’m a Dev, Not a DevOps!</title><link href="https://cmelendeztech.com/posts/2018/05/im-dev-not-devops.html" rel="alternate"/><published>2018-05-25T00:00:00+02:00</published><updated>2018-05-25T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-05-25:/posts/2018/05/im-dev-not-devops.html</id><summary type="html">&lt;p&gt;My experience with DevOps began before I even knew there was a name for the approach, when my boss asked me for some help in operations. The company I worked for was small at that time, so I always had the opportunity to get my hands dirty in the release …&lt;/p&gt;</summary><content type="html">&lt;p&gt;My experience with DevOps began before I even knew there was a name for the approach, when my boss asked me for some help in operations. The company I worked for was small at that time, so I always had the opportunity to get my hands dirty in the release automation process. I knew a few things about servers and Linux, so I was up for the challenge. To my surprise, I loved it. I knew it wasn’t the classic way of doing operations by manually managing physical servers, firewalls, virtual machines, and the like. We were using a cloud vendor. This meant that to spin up a new server, it wasn’t necessary to know which buttons to click.&lt;/p&gt;
&lt;p&gt;The cloud vendor had his own API and SDKs for several languages, so I never really felt like I stopped programming. Of course, that was just the tip of the iceberg because systems administration is not just about spinning up new servers, adding more storage or rebooting servers. I had to take care of the architecture and which cloud services were needed for the job. But I was sure I could apply some development skills to operations, and I did. I created some scripts that launched a new environment from scratch, made backups, and restored databases.&lt;/p&gt;
&lt;p&gt;Then, I found out about DevOps and all its practices. And because my background was in development, I was able to work with developers and explaining in their language how they could be destroying our log files and why it was important.&lt;/p&gt;
&lt;p&gt;So if you’re a developer new to this DevOps world, trust me. You’ll like this new way of working.&lt;/p&gt;
&lt;h1&gt;You Won’t Be Writing Less Code&lt;/h1&gt;
&lt;p&gt;Because things often go wrong when deploying their latest changes in code, developers get interrupted constantly, keeping them away from the keyboard and writing less code. At first, I thought maybe this just happened to me. But when I found out this was also an issue for Ben Treynor, who created the first Site Reliability Engineering (SRE) team at Google, I didn’t feel alone. In an &lt;a href="https://landing.google.com/sre/interview/ben-treynor.html"&gt;interview&lt;/a&gt;, he described SRE as “what happens when you ask a software engineer to design an operations function.”&lt;/p&gt;
&lt;p&gt;Can you imagine that? A developer tasked with operating a production system? At first, that sounds like a scary thing. (I was scared the first time I did it.) But it turns out that this experiment went amazingly well for Ben Treynor. SREs are now lightening the workload by automating what they can and worrying less and less about the mundane, boring operations tasks.&lt;/p&gt;
&lt;p&gt;If you’re worried about writing less code, you don’t have to be. I think we all know coding is an important skill to have. You’ll actually be interrupted less frequently if you work with the operations team, building all the machinery to do boring deployments. And if you decide to make a DevOps career path switch, you’ll be writing more code as you automate the world’s repetitive tasks.&lt;/p&gt;
&lt;h1&gt;You Won’t Have to Wait Weeks to Push New Changes&lt;/h1&gt;
&lt;p&gt;As developers, one of the things we like the most is seeing our lines of code come to life. But realistically speaking, most of us don’t get to see this every day; deployments are done every two weeks or even more. And those deployments can be really painful. Some are scheduled late at night, on weekends, or when few users are connected. There’ve been times I had to roll back because something went wrong and the maintenance window wasn’t wide enough. That’s frustrating, but it’s the nature of deployments. It’s our reality.&lt;/p&gt;
&lt;p&gt;So…did you buy that? That this has to be our reality?&lt;/p&gt;
&lt;p&gt;I don’t. There’s a better way to do deployments.&lt;/p&gt;
&lt;p&gt;According to the &lt;a href="https://puppet.com/resources/whitepaper/state-of-devops-report"&gt;2017 State of DevOps Report&lt;/a&gt;, some organizations have been able to do four deployments per day. Now, I’m not going to lie to you. It’s not easy to get there. But it’s possible. And no, it’s not just about automation. You’ll need a &lt;a href="https://blog.scalyr.com/2018/01/5-critical-devops-practices/"&gt;critical set of practices&lt;/a&gt; in place to be successful. I’ve had the joy of experiencing fast deployments. In the past, we deployed every two weeks at my company. We created new infrastructure and had to test everything over and over again with a mix of automated and manual testing. One day, we made some changes in our architecture and adopted containers. We now do several deployments per week with a push of a button, and each of them takes five minutes.&lt;/p&gt;
&lt;p&gt;For this to work, you’ll need to make adjustments at every stage of your process. The most critical change will be to increase code coverage with automated testing. It’s not just about speed. It’s also about consistency and reliability.&lt;/p&gt;
&lt;p&gt;There will be some growing pains when you try to reduce your deployment time, but it’s really worth it.&lt;/p&gt;
&lt;h1&gt;You Won’t Have to Keep Waiting for Feedback&lt;/h1&gt;
&lt;p&gt;When you’re able to get your changes to production fast, you can’t just restart the server to solve problems. The old ways won’t work. It’s mandatory to know, in detail, what’s happening every time you do a deployment. What metrics changed? When did problems start? Everyone should have the ability to see the system status all the time. Long gone are the days when only operations had this visibility. It’s not enough to have infrastructure-level metrics; you need metrics that matter to the business, too. What those metrics should be will depend on the purpose of your software. For a site with a shopping cart, for example, you’ll be interested to know the number of orders taking place.&lt;/p&gt;
&lt;p&gt;One of the hardest things to do is to deploy in the same way across all environments, including your local computer. It’s possible most of the time, but it gets complicated when you use PaaS in production because the idea is to have production-like environments everywhere. This doesn’t apply to data, but if you have a load balancer in production, you need it in every environment, too. You can run local VMs or mimic some dependencies. For example, you can use a local NGINX server to represent a load balancer in your cloud provider.&lt;/p&gt;
&lt;p&gt;If you have the chance to work with containers and Kubernetes, you can use &lt;a href="https://github.com/kubernetes/minikube"&gt;Minikube&lt;/a&gt; to run Kubernetes on your computer and do deployments locally. Excuse my excitement here, but I think that’s awesome! Now, it’s of tremendous importance that you can get feedback locally because that’s the fastest feedback possible. And it’s essential you have a production-like environment running on your computer. But with this, developers can truly increase credibility when they say, “It works on my machine.”&lt;/p&gt;
&lt;h1&gt;You Won’t Lose the Opportunity to Experiment&lt;/h1&gt;
&lt;p&gt;A natural effect of deploying faster and getting feedback afterward is that you’ll now be able to experiment. You’ll have the ability to say, “Hmm. What if I do this change? Is revenue going to increase? Let’s run an experiment.” Your changes will be accompanied by a set of reliable, automatic tests, and then you can wait for feedback and make a decision. I know, it sounds simple—and it is! And now that you’ve implemented these other changes, you can easily run A/B tests with your users as well.&lt;/p&gt;
&lt;h1&gt;You Will Deliver Faster&lt;/h1&gt;
&lt;p&gt;I’ve made a career change by moving from development to operations. And because of how operations has evolved now, I don’t regret it. I still love coding, and I do as much of it as I did before—the cool thing is that I’m applying development principles to operations. You’re going to delight in this new way of working, even if you stick with development. When you see how DevOps changes the way of working at an organizational level—not just at a team level—you’ll be smitten. And the way you think about your code will change too. You’ll no longer just stop thinking about your code once you finish because now you know you might be only halfway to getting your code live.&lt;/p&gt;
&lt;p&gt;These are exciting times for a developer. You’ll be writing more code and creating interesting new things every time. More importantly, you’ll be interrupted less frequently, freeing up time for learning and allowing you to have less stress. You’ll see your changes go live rapidly, and you’ll get feedback quickly as well. That means you can remain focused on a task and do less context switching, which kills productivity. And when deployment is so frequent it becomes natural, the doors to experimentation will be wide open to you. It’s not just that bug fixes get done rapidly. The pace of innovation will also be positively impacted. Everyone will be happy.&lt;/p&gt;
&lt;p&gt;Taking the DevOps route won’t be easy, but it’s worth it: for everyone, not just for you.&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="development"/></entry><entry><title>Deploy to Production: 5 Tips to Make It Smoother</title><link href="https://cmelendeztech.com/posts/2018/05/deploy-to-production-5-tips-make-smoother.html" rel="alternate"/><published>2018-05-23T00:00:00+02:00</published><updated>2018-05-23T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-05-23:/posts/2018/05/deploy-to-production-5-tips-make-smoother.html</id><summary type="html">&lt;p&gt;Who hasn’t had issues when deploying a software change to production? No one.&lt;/p&gt;
&lt;p&gt;I once accidentally deleted a bin folder from a .NET application in one of four servers when deploying a change. The site was working intermittently as a consequence, so I had to check all the servers …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Who hasn’t had issues when deploying a software change to production? No one.&lt;/p&gt;
&lt;p&gt;I once accidentally deleted a bin folder from a .NET application in one of four servers when deploying a change. The site was working intermittently as a consequence, so I had to check all the servers again to find the one that was having problems. Luckily for me, there were only four servers.&lt;/p&gt;
&lt;p&gt;Everything that can go wrong in a deployment change to production will go wrong. It’s &lt;a href="https://en.wikipedia.org/wiki/Murphy%27s_law"&gt;Murphy’s law&lt;/a&gt;. For that reason, we have a sort of respect that borders on fear when we think about doing deployments. There’s too much at risk, so sometimes we avoid the struggle. But in reality, &lt;strong&gt;deployments should be the most boring task of the workflow&lt;/strong&gt;. The trick is knowing how to do it.&lt;/p&gt;
&lt;p&gt;With that in mind, let’s talk about some ways to smoothly deploy to production without risking quality.&lt;/p&gt;
&lt;h1&gt;1. Automate As Much As Possible&lt;/h1&gt;
&lt;p&gt;Let computers do the repeatable work for you—they’re better at that than we are. I prefer to invest some hours working on a script to do deployments, like a recipe of commands. Then I test the script locally and in the development environment. That way, next time I want to deploy a change, I won’t have to worry about missing any steps like creating a folder or giving permissions to some files. I’ll just need to run the script again.&lt;/p&gt;
&lt;p&gt;But I’m not talking about just a bash script that can be hard to read and understand. In the last few years, new things have emerged. You have at your disposal tools like &lt;a href="https://www.terraform.io/"&gt;Terraform&lt;/a&gt;, &lt;a href="https://www.ansible.com/"&gt;Ansible&lt;/a&gt;, and &lt;a href="https://jenkins.io/"&gt;Jenkins&lt;/a&gt;, which allow you to use code principles. You can have all your scripts in version control, and that will be the only source of truth. That means everyone will know what changed, as well as when and why it changed, not just in code but also in infrastructure and deployment pipelines.&lt;/p&gt;
&lt;p&gt;All of this means that &lt;strong&gt;deployments can be as easy as clicking a button&lt;/strong&gt;. Even reverting the deployment is a button-click away. You can get to the point where anyone, even non-technical people, can do deployments.&lt;/p&gt;
&lt;p&gt;Automation makes deployments smoother by letting you move forward and backward with ease. The process becomes repeatable and reliable.&lt;/p&gt;
&lt;h1&gt;2. Build and Pack Your Application Only Once&lt;/h1&gt;
&lt;p&gt;The build process usually takes a while, so it will make things run so much more smoothly at deployment time if you only build once. You can keep coding and push changes all the time without worrying about promoting code that’s not ready.&lt;/p&gt;
&lt;p&gt;After you build your app, the next step is to pack it and to make sure the package remains untouchable. That way, you’re constantly taking snapshots of your app. There will be times when the app is packed with errors or incomplete code. But that’s no problem because you get to choose which package will be deployed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You’ll move the same package across all your environments&lt;/strong&gt;. This means that when you generate it for development, you’ll use the exact same version of the app to update the production environment. You can easily achieve this by doing adequate configuration management. Just replace placeholders with the respective values of the environment—like database endpoints, for example.&lt;/p&gt;
&lt;p&gt;You’ll want to practice &lt;strong&gt;continuous integration&lt;/strong&gt; to make packing easier, and one of its fundamental principles is that you build only once. Practices like this allow you to integrate constantly in a shared repository, verify the process with automated tests, and fix things quickly if needed.&lt;/p&gt;
&lt;p&gt;Do all of these things, and you’ll smooth the deployment to production because what you tested in development is the same thing you tested in other environments, including production.&lt;/p&gt;
&lt;h1&gt;3. Deploy the Same Way All the Time&lt;/h1&gt;
&lt;p&gt;There’s no value in applying the previous tips if you don’t deliver the same way in all circumstances. You packed once to deploy the same code everywhere, and you need to deliver the same way. By doing this, you’ll avoid any surprises in production.&lt;/p&gt;
&lt;p&gt;For this, &lt;strong&gt;you need to have production-like environments&lt;/strong&gt;. This doesn’t necessarily mean that you’ll have the same data everywhere—that can be expensive and a possible security risk. It just means that if you have a load balancer in production because you need to be able to scale out/in, you also have to have one in development. If you’re hosting production in the cloud, you need to do the same for development.&lt;/p&gt;
&lt;p&gt;Of course, you can think about how to have cheaper environments. You just need to change configurations when you update an environment.&lt;/p&gt;
&lt;p&gt;This deployment tip will help you to be bold when changing production. You’ll be fearless because you’ve already practiced it several times before actually doing it.&lt;/p&gt;
&lt;h1&gt;4. Deploy Using Feature Flags In Your Application&lt;/h1&gt;
&lt;p&gt;If you only take away one tip from this list, make it this one. Using feature flags will increase your confidence to deploy. And the benefit is even bigger when you combine them with strategies like &lt;a href="https://docs.cloudfoundry.org/devguide/deploy-apps/blue-green.html"&gt;blue/green&lt;/a&gt; and &lt;a href="https://octopus.com/docs/deployment-patterns/canary-deployments"&gt;canary&lt;/a&gt; deployments. These strategies will help you to deploy without customers noticing there was a change.&lt;/p&gt;
&lt;p&gt;It doesn’t matter which strategy you choose—all changes should be backward compatible. I recommend you choose a strategy that works for you. Blue/green deployments tend to be costly, depending on your infrastructure and how small your app is. But they’re the safest way to deploy because you’re duplicating the environment and testing it before pushing it live. In the case of canary deployments, you’re pushing changes little by little. You can do it server by server or by recreating containers one at a time.&lt;/p&gt;
&lt;p&gt;But you can do it better using feature flags.&lt;/p&gt;
&lt;p&gt;In fact, you can do it so much better that you can deploy all changes with the feature flag turned off. Then you can turn on the feature flag for a small fraction of users, monitor their behavior for a while, and keep enabling the feature for more users until you’re sure that the change is good to keep. And you can do this all without worrying about adding more complexity to your code or deployment strategy.&lt;/p&gt;
&lt;p&gt;One good tool that makes feature flags easier to implement is &lt;a href="https://rollout.io/product/feature-flag-management/"&gt;Rollout&lt;/a&gt;. You set up your &lt;a href="https://support.rollout.io/docs/audience"&gt;audience&lt;/a&gt; and roll out your changes little by little.&lt;/p&gt;
&lt;h1&gt;5. Deploy in Small Batches, and Do It Often&lt;/h1&gt;
&lt;p&gt;When you put all the previous tips in practice, deploying in small batches and doing it frequently becomes natural. It will take some time to get there, especially because deployments should be predictable and reliable. But it’ll be worth it.&lt;/p&gt;
&lt;p&gt;Now, automated testing is a prerequisite. It doesn’t matter how much effort you put into automating your deployments—if at the end of the day you spend a lot of time manually testing your application, you won’t see the benefit. So try to spend time automating your test cases. Otherwise, there’s no point in doing automated deployments.&lt;/p&gt;
&lt;p&gt;But back to the subject at hand. How small should your batches be, and how frequently should you deploy them?&lt;/p&gt;
&lt;p&gt;Well, if you’ve ever played the hot potato game, you’ll have a good idea of what “small” and “frequent” mean. As soon as you have something ready to be deployed, do it. It doesn’t have to be complete, so long as you use feature flags. Treat deployments like coding. It’s pretty weird when someone spends many hours coding without testing. Without checking your code as you write it, you won’t know exactly what’s causing an error. And if there aren’t many lines of code, there are fewer things you need to check.&lt;/p&gt;
&lt;p&gt;Amplify feedback by increasing the number of times you deploy. It might sound risky, but it’s not. The fewer changes you make, the easier it will be to know what’s wrong. Don’t wait until you have a lot of changes to deploy. Do it frequently.&lt;/p&gt;
&lt;h1&gt;Make Deployments a Mundane Task&lt;/h1&gt;
&lt;p&gt;When you practice one or all of the above tips, your deployments will become boring. And in this case, boring is a big win. You’ll find more exciting things to do rather than face the same problems over and over again.&lt;/p&gt;
&lt;p&gt;The tools, services, and practices that exist today—especially those I’ve mentioned here—are wonderful. They help you avoid surprises, transforming all those scary nights or long weekends into peaceful, routine workdays. You can do things like automate many of your tasks, especially testing, to make going forward easier and more efficient. Also, you can pack your application; it will help you make deployments consistent. Note, too, that production environments don’t deserve to be treated differently. And make sure you use feature flags. They’ll help you be less stressed when deploying because you know you can always turn off features and everything will continue working. Lastly, work in small batches. It’s easier to spot bugs, and it’s less risky because you’re not changing too many things at the same time.&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="agile"/><category term="development"/></entry><entry><title>The Advantages of Using Kubernetes and Docker Together</title><link href="https://cmelendeztech.com/posts/2018/05/kubernetes-docker-deployments.html" rel="alternate"/><published>2018-05-07T00:00:00+02:00</published><updated>2018-05-07T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-05-07:/posts/2018/05/kubernetes-docker-deployments.html</id><summary type="html">&lt;p&gt;You might be hearing a lot about &lt;a href="https://stackify.com/kubernetes-guide-container-orchestration/"&gt;Kubernetes&lt;/a&gt; and &lt;a href="https://stackify.com/complete-docker-toolkit/"&gt;Docker&lt;/a&gt;—so much that you might be wondering which one is better.&lt;/p&gt;
&lt;p&gt;Well, there is no “better” because these aren’t equivalent things. Docker is like an airplane and Kubernetes is like an airport. You wouldn’t ask “Which should I …&lt;/p&gt;</summary><content type="html">&lt;p&gt;You might be hearing a lot about &lt;a href="https://stackify.com/kubernetes-guide-container-orchestration/"&gt;Kubernetes&lt;/a&gt; and &lt;a href="https://stackify.com/complete-docker-toolkit/"&gt;Docker&lt;/a&gt;—so much that you might be wondering which one is better.&lt;/p&gt;
&lt;p&gt;Well, there is no “better” because these aren’t equivalent things. Docker is like an airplane and Kubernetes is like an airport. You wouldn’t ask “Which should I use to travel—airport versus airplane?” So it goes with Docker and Kubernetes. You need both.&lt;/p&gt;
&lt;p&gt;In this post, we’ll run through a deployment scenario, how containers and orchestrators can help, and how a developer would use them on a daily basis. You’ll walk away from this post with an understanding of how all the pieces of the puzzle fit together.&lt;/p&gt;
&lt;p&gt;&lt;img alt="What containers and orchestrators actually are" src="/images/kubernetes-docker-deployments/docker-vs-kubernetes-881x441.jpg"&gt;&lt;/p&gt;
&lt;h1&gt;Everything Starts With Your Local Environment&lt;/h1&gt;
&lt;p&gt;So let me start with a typical day in the life of someone who struggles through every deployment. Then I’ll explain how these two technologies can help. For practical purposes, we’ll talk about the fictional developer John Smith. John’s a developer working for a startup, and he’s responsible for deploying his code to a live environment.&lt;/p&gt;
&lt;p&gt;John has two apps: one in &lt;a href="https://stackify.com/content/net-core/"&gt;.NET Core&lt;/a&gt; and another in Node.js. He struggles every time a new version of the language, framework, or library comes out and he has to run an upgrade. The problem is when things aren’t compatible with what he’s installed. When something’s not working, he just installs, uninstalls, updates, or removes until finally things get back up and running. The struggle becomes even bigger when he has to push a new change after doing all of that to another environment. It’s kind of hard to remember all the steps when we’re in a rush.&lt;/p&gt;
&lt;p&gt;One solution could be for him to work with virtual machines (VMs). That way, he can isolate all dependencies and avoid affecting any existing apps and their dependencies&lt;/p&gt;
&lt;p&gt;While that could work, it doesn’t scale. Why? Because every time something changes, he has to take a new snapshot. And then he has to somehow organize all the different versions of those VM snapshots. He’ll still need to deploy changes in code and any dependencies to other environments. Now, he can screw things up in other environments too and then fix it, and that’s okay. But when we’re talking about production, things get risky. He has to work with production-like environments to ease deployments and reduce risk. That’s hard to do.&lt;/p&gt;
&lt;p&gt;Even having automation in place, deployments might be too complex or painful. Maybe John even has to spend a whole weekend doing deployments and fixing all sorts of broken things.&lt;/p&gt;
&lt;p&gt;We all wish deployments could be as boring as pushing a button. The good news is that that’s where Docker and Kubernetes come into play.&lt;/p&gt;
&lt;h1&gt;Use Docker to Pack and Ship Your App&lt;/h1&gt;
&lt;p&gt;&lt;img alt="Containers in real world" src="/images/kubernetes-docker-deployments/word-image-1024x668.jpeg"&gt;&lt;/p&gt;
&lt;p&gt;So, what is Docker anyway?&lt;/p&gt;
&lt;p&gt;Docker is a company that provides a container platform. Containers are a way to pack and isolate a piece of software with everything that it needs to run. I mean “isolate” in the sense that containers can assign separate resources from the host where it’s running. You might be thinking this &lt;a href="https://www.docker.com/what-container"&gt;sounds pretty similar to VMs&lt;/a&gt;, but the difference is that containers are more lightweight: they don’t need another OS to make software run. Containers let you be more &lt;a href="https://stackify.com/agile-methodology/"&gt;agile&lt;/a&gt; and build secure and portable apps, which lets you save some costs in infrastructure when done well.&lt;/p&gt;
&lt;p&gt;I know that sounds like a textbook definition, so let’s see how this is beneficial by following the day in the life of John.&lt;/p&gt;
&lt;p&gt;Let’s say John decides to start his containers journey. He learns that Docker containers work with base images as their foundation to run an app. A base image and all its dependencies are described in a file called “Dockerfile.”  A Dockerfile is where you define something like a recipe that you usually have in docs (or in your mind) for anyone who wants to run your app. He starts with the .NET Core app, and the Dockerfile looks like this. Take a look:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;FROM microsoft/aspnetcore-build:2.0 AS build-env
WORKDIR /app

&lt;span class="gh"&gt;#&lt;/span&gt; Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

&lt;span class="gh"&gt;#&lt;/span&gt; Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out

&lt;span class="gh"&gt;#&lt;/span&gt; Build runtime image
FROM microsoft/aspnetcore:2.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT [&amp;quot;dotnet&amp;quot;, &amp;quot;hello.dll&amp;quot;]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you can see, it’s as if you were programming. The only difference is that you’re just defining all dependencies and declaring how to build and run the app.&lt;/p&gt;
&lt;p&gt;John needs to put that file in the root of the source code and run the following command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker build -t dotnetapp .
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This command will create an image with the compiled code and all of its dependencies to run. He’ll only do the “build’ once because the idea is to make the app portable to run anywhere. So when he wants to run the app, only Docker needs to be installed. He just needs to run the following command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker run -d -p 80:80 dotnetapp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This command will start running the app on port 80 of the host. It doesn’t matter where he runs this command. As long as port 80 isn’t in use, the app will work.&lt;/p&gt;
&lt;p&gt;John is now ready to ship the app anywhere because he’s packed it in a Docker container.&lt;/p&gt;
&lt;p&gt;So why is this better? Well, John doesn’t have to worry about forgetting what he installed on his local computer or on any other server. When the team grows, a new developer will rapidly start coding. When John’s company hires an operations guy, the new hire will know what exactly what’s included in the container. And if they want to do an upgrade of the framework or some dependency, they’ll do it without worrying about affecting what’s currently working.&lt;/p&gt;
&lt;p&gt;Use Docker to pack and ship your app without worrying too much about whether the app will work somewhere else after you’ve tested it locally. If it works on your machine, it will work on others’ machines.&lt;/p&gt;
&lt;h1&gt;Use Kubernetes to Deploy and Scale Your App&lt;/h1&gt;
&lt;p&gt;So, John now just needs to go to each of the servers where he wants to ship the app and start a container. Let’s say that, in production, he has ten servers to support the traffic load. He has to run the previous command on all the servers. And if for some reason the container dies, he has to go to that server and run the command to start it again.&lt;/p&gt;
&lt;p&gt;Wait. This doesn’t sound like an improvement, right? It’s not much different than spinning up VMs. When something goes down, he’ll still need to manually go and start containers again. He could automate that task too, but he’ll need to take into consideration things like health checks and available resources. So here’s where Kubernetes comes into play.&lt;/p&gt;
&lt;p&gt;Kubernetes, as their &lt;a href="https://kubernetes.io/"&gt;site says&lt;/a&gt;, “is an open-source system for automating deployment, scaling, and management of containerized applications.” &lt;a href="https://devops.com/characterizing-and-contrasting-container-orchestrators/"&gt;There are more of its type&lt;/a&gt;, but Kubernetes is the most popular one right now. Kubernetes does the container orchestration so you don’t have to script those tasks. It’s the next step after containerizing your application, and its how you’ll run your containers at scale in production.&lt;/p&gt;
&lt;p&gt;Kubernetes will help you to deploy the same way everywhere. Why? Because you just need to say, in a declarative language, how you’d like to run containers. You’ll have a load balancer, a minimum amount of containers running, and the ability to scale up or down only when it’s needed—things that you’d otherwise need to create and configure separately. You’ll have everything you need to run at scale, and you’ll have it all in the same place. But it’s not just that. You can also have the ability now to have your own Kubernetes cluster running locally, thanks to &lt;a href="https://github.com/kubernetes/minikube"&gt;Minikube&lt;/a&gt;. Or you can use Docker, because Docker now &lt;a href="https://blog.docker.com/2018/01/docker-windows-desktop-now-kubernetes/"&gt;officially supports Kubernetes&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So, coming back to John. He can define how he wants to deploy an app called “dotnetapp” at scale.&lt;/p&gt;
&lt;p&gt;Take a look at the “dotnetapp-deployment.yaml” file, where John defines how to do deployments in a Kubernetes cluster, including all its dependencies at a container level. In this case, besides launching the dotnetapp, it’s also launching the database using a container. Here’s how the file looks:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;apiVersion&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;apps&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1beta1&lt;/span&gt;
&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Deployment&lt;/span&gt;
&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dotnetapp&lt;/span&gt;
&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;replicas&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;rollingUpdate&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;maxSurge&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;maxUnavailable&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;minReadySeconds&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;labels&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dotnetapp&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;containers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dotnetapp&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;johndoe&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;dotnetapp&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;containerPort&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;cpu&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;250&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;limits&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;cpu&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DB_ENDPOINT&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;dotnetappdb&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="n"&gt;apiVersion&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;
&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Service&lt;/span&gt;
&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dotnetapp&lt;/span&gt;
&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LoadBalancer&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;selector&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dotnetapp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;John now just needs to run this command to deploy the app in any Kubernetes cluster, locally or in another cluster:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl apply -f .\dotnetapp-deployment.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This command will create everything that’s needed, or it will just apply an update, if there is one.&lt;/p&gt;
&lt;p&gt;He can run the exact same command on this computer or any other environment, including production, and it will work the same way everywhere. But it’s not just that. Kubernetes constantly checks the state of your deployment according to the yaml definition you use. So if a Docker container goes down, Kubernetes will spin up a new one automatically. John no longer has to go to each server where the container failed to start it up again; the orchestrator will take care of that for him. And there will be something monitoring the stake to make sure it’s compliant—meaning it’s running as expected—all the time.&lt;/p&gt;
&lt;p&gt;That’s how you could easily get to doing several deployments a day that take around five minutes.&lt;/p&gt;
&lt;h1&gt;You’ll Deliver Quickly, Consistently, and Predictably&lt;/h1&gt;
&lt;p&gt;Now you know what Docker and Kubernetes are—and not just in concept. You also have a practical perspective. Both technologies use a declarative language to define how they will run and orchestrate an app.&lt;/p&gt;
&lt;p&gt;You’ll be able to deliver faster, but more importantly, you’ll deliver in a consistent and predictable manner. Docker containers will help you to isolate and pack your software with all its dependencies. And Kubernetes will help you to deploy and orchestrate your containers. This lets you focus on developing new features and fixing bugs more rapidly. Then you’ll notice, at some point, your deployments stop being a big ceremony.&lt;/p&gt;
&lt;p&gt;So, the main thing to remember is this: when you combine Docker and Kubernetes, confidence and productivity increase for everyone.&lt;/p&gt;</content><category term="misc"/><category term="docker"/><category term="kubernetes"/></entry><entry><title>Agile and DevOps: Why Are You Keeping Them Separate?</title><link href="https://cmelendeztech.com/posts/2018/04/agile-and-devops-together.html" rel="alternate"/><published>2018-04-09T00:00:00+02:00</published><updated>2018-04-09T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-04-09:/posts/2018/04/agile-and-devops-together.html</id><summary type="html">&lt;p&gt;I first heard about agile many years ago. I learned then that the movement started in 2001 when a group of professionals met and created the &lt;a href="http://agilemanifesto.org/"&gt;Agile Manifesto&lt;/a&gt;. The manifesto describes a way of developing software faster by focusing more on how to provide value than anything else.&lt;/p&gt;
&lt;p&gt;Personally, when …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I first heard about agile many years ago. I learned then that the movement started in 2001 when a group of professionals met and created the &lt;a href="http://agilemanifesto.org/"&gt;Agile Manifesto&lt;/a&gt;. The manifesto describes a way of developing software faster by focusing more on how to provide value than anything else.&lt;/p&gt;
&lt;p&gt;Personally, when I talk about agile, I like to share a video from &lt;a href="https://www.youtube.com/watch?v=p0O1VVqRSK0"&gt;Uncle Bob about demanding professionalism&lt;/a&gt;. Some of his aspirations include inexpensive adaptability and continuous improvement, and he believes we should always be ready deploy or to deliver software changes. The first time I saw the video, I thought, "Wow, this all sounds great. But how do we achieve everything he expects?" I had an idea of how to pursue some of the goals he mentioned, but for the rest, I had no idea.&lt;/p&gt;
&lt;p&gt;That's because some of Bob's aspirations require involvement from operations folks. When I was a developer with practically no knowledge about operations, I believed agile was only for development. At least, that's what I thought until it hit home that my work didn't stop when I finished my code. Although my definition of "done" was "have the software working in a production environment," I had always simply focused on how to develop faster.&lt;/p&gt;
&lt;p&gt;But what about the moment after? The operations team struggled every time developers were ready to deploy. Was it from a lack of communication between these two teams? Maybe, but that's how the DevOps movement got started. It came from the desire to break down silos between developers and operations. Maybe we need something more now. Maybe we need to inject agile into this way of working, too.&lt;/p&gt;
&lt;p&gt;So why keep DevOps separated from agile? Is it worth it? Wouldn't there be a bigger benefit if they're combined? Let's find out.&lt;/p&gt;
&lt;h1&gt;DevOps Was Conceived as Agile Infrastructure&lt;/h1&gt;
&lt;p&gt;The moment developers start adopting agile, operations starts receiving requests for deployments every two weeks or less. And we all know that the production environment becomes unhealthy right after we start making changes. It shouldn't be the case, but it usually happens. I can't imagine the reactions of the crowd when &lt;a href="https://www.youtube.com/watch?v=LdOe18KhtT4"&gt;Flickr announced they were doing 10 deployments a day&lt;/a&gt;. But they were able to pull it off by identifying the real problem. When development and operations start to work together, both teams will be aware of all the steps needed to prepare the software for deployment. It's mainly about communication issues, blockers, and lack of knowledge.&lt;/p&gt;
&lt;p&gt;"Agile," in its shortest definition, means &lt;strong&gt;to be able to move quickly and easily&lt;/strong&gt;. As humans, one of our main problems is interacting with one another in a way that promotes understanding, and this prevents us from moving quickly and easily. The Agile Manifesto starts with individuals and interactions over processes and tools.&lt;/p&gt;
&lt;p&gt;What if we added the concepts from agile to the operations world and called it "agile infrastructure"? Well, we might start by immediately applying some of the concepts that succeeded in agile for the software development industry: things like working in small batches and delivering more frequently---or rather, deploying more frequently. This will help the operations team to pay, little by little, the interest they've accumulated through technical debt.&lt;/p&gt;
&lt;p&gt;When you don't do anything to reduce technical debt, you'll keep feeling the pain of being paged and constantly interrupted during each release. This keeps you stuck in a perpetually stressful, overwhelmed mindset, enabling the excuse of "We don't have time to implement agile or DevOps now."&lt;/p&gt;
&lt;p&gt;That's a shame because, with the amount of APIs that have emerged for infrastructure, it's easier to apply agile practices than ever. As you see, agile isn't only for software developers.&lt;/p&gt;
&lt;h1&gt;"Working Software" Doesn't Stop at Development&lt;/h1&gt;
&lt;p&gt;Agile was popularized in development organizations. Perhaps that's why some people relate agile only to development, forgetting about operations. (Well, to be fair, that's also probably because the Agile Manifesto starts by talking about uncovering new ways of developing software.)&lt;/p&gt;
&lt;p&gt;The result is that when developers say they're done, they're not really done. They have to wait for operations to install and configure the latest changes in a server, with the chance of getting interrupted if something goes wrong. And most of the time, something does, in fact, go wrong. So one of the first things we need to do is define what "done" means in an organization. This will help to determine who's involved in the process and what the outcome will be.&lt;/p&gt;
&lt;p&gt;Customers will expect to have working software in their hands, not in any previous environment, including the developer's machine. So we need to include operations in the workflow. And it's not just that. We should also include security, compliance, databases, management, and everything else that's involved in the process of getting the working software to customers.&lt;/p&gt;
&lt;p&gt;But how can that be achieved? Glad you asked. You can make use of the practices that many of the agile frameworks created, and of course, you can use the practices under the DevOps umbrella.&lt;/p&gt;
&lt;h1&gt;The Practices, Not the Frameworks or Labels&lt;/h1&gt;
&lt;p&gt;When you take the approach of thinking about practices, you get the real benefit, because there are a lot of agile frameworks, and sometimes people tend to mix them up.&lt;/p&gt;
&lt;p&gt;What about labels or definitions? Oh, you'll find a dozen definitions of agile and DevOps. So don't pay too much attention to that. Eventually, you'll have your own too.&lt;/p&gt;
&lt;p&gt;What if instead, we turn our focus to the practices? Practices like TDD, BDD, infrastructure as code (IaC), configuration management, continuous integration (CI), continuous delivery (CD)---the list goes on. Knowing what they are and why they're useful makes a remarkable difference in the way you deliver software to your customers.&lt;/p&gt;
&lt;p&gt;With agile and DevOps practices, you can reduce lead time and get feedback more rapidly and more frequently. That will let you, as the Agile Manifesto states, respond to a change over following a plan. But it's not just that. You can also run experiments once you've mastered the delivery process. So instead of trying to convince someone else (or even yourself) that agile and DevOps are the coolest, hippest things, focus on mastering the practices. I can't recommend just one of them, but I can tell you that when I got the "aha" moment by practicing them, I couldn't go back. It made me say, "If only I'd have known this before."&lt;/p&gt;
&lt;p&gt;In the end, it won't matter too much which practice you choose. What matters is if your performance increases or not. And using practices of both worlds will definitely help you.&lt;/p&gt;
&lt;h1&gt;Combined, They're Stronger&lt;/h1&gt;
&lt;p&gt;Are you still going to keep agile and DevOps separate? You could. But there's a lot of synergy between these two. The IT industry started to change constantly after agile, for the good and the bad. Unfortunately, now we have a lot of frameworks, labels, and definitions around agile. But we also have a ton of practices with the spirit of being able to move quickly and easily. Customers expect value, and they don't care what you did to provide it to them---they only care when something goes wrong.&lt;/p&gt;
&lt;p&gt;So, you start in development with good technical practices to get the software ready for delivery. Then, you continue with DevOps, which helps everyone to have a broader picture of what's needed to take software from "ready" to "working software in the hands of your customers." DevOps is about all the people that are immersed in the process of software development, not just developers and operations. And DevOps acts as the reminder that software development doesn't stop when a developer has finished coding, even if all tests passed. All that learning development has acquired through the years about agile is valuable, and it's applicable to infrastructure nowadays.&lt;/p&gt;
&lt;p&gt;It's important to focus more attention and effort on the practices of agile and DevOps. When you succeed in this, the name of the movement becomes less important.&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="agile"/></entry><entry><title>The Pitfalls of Feature Branching</title><link href="https://cmelendeztech.com/posts/2018/04/pitfalls-feature-branching.html" rel="alternate"/><published>2018-04-02T00:00:00+02:00</published><updated>2018-04-02T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-04-02:/posts/2018/04/pitfalls-feature-branching.html</id><summary type="html">&lt;p&gt;Working with feature branching reminds me of building a house. You don’t see general contractors insisting on making copies of their own houses when remodeling. Working in the house at the same time forces them to talk to each other and come to an agreement over a conflict. Imagine …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Working with feature branching reminds me of building a house. You don’t see general contractors insisting on making copies of their own houses when remodeling. Working in the house at the same time forces them to talk to each other and come to an agreement over a conflict. Imagine that a contractor finishes a room, tries to leave, and finds the door suddenly blocked by another wall. The same thing could happen in the code after you’ve been too focused on your feature changes. That’s why communication needs to be enforced—and with feature branches, that’s a thing that can easily get overlooked.&lt;/p&gt;
&lt;p&gt;There are some situations in which working exclusively with feature branches might make sense. But generally speaking, if this can be avoided, a team’s productivity and confidence in the code will increase by a factor that you never imagined. For that reason, let’s talk about some of the pitfalls of working with feature branches in your development workflow.&lt;/p&gt;
&lt;h1&gt;You’ll Waste Time Fixing Unnecessary Merge Conflicts&lt;/h1&gt;
&lt;p&gt;Merge conflicts are the biggest pitfall of using feature branches. Nothing hurts more than spending unnecessary time fixing merge conflicts, especially when a feature branch has been there for a while. But time is not the only factor. The risk of removing any existing code or introducing new issues increases considerably. In some occasions, you’d also need to freeze any changes in code while you stabilize everything. Everyone on the team that was involved must make sure any code is removed or overridden.&lt;/p&gt;
&lt;p&gt;I felt this pain when working with a remote team. They were always removing my recent changes. Every time they changed something, I had to stop what I was doing and review their work to see if any of my code was altered—or even removed all together. I don’t blame them. We only had one code repository for a big monolithic app. Instead, I blame merge conflicts.&lt;/p&gt;
&lt;p&gt;When there are too many people working in the same source code repository, it could be a smell that you need to decouple your code. Divide your big application into smaller parts to avoid the suffering caused by merge conflicts. Some might call this going from monolith to microservices, although this doesn’t mean you’ll create a git repository for just two or three files. You can pack commonly used code.&lt;/p&gt;
&lt;h1&gt;You’ll Have No Consistency When Generating Artifacts&lt;/h1&gt;
&lt;p&gt;When you generate the artifacts that will be deployed in your environments, it’s recommended that you generate them only once. Building and packing should happen in the first stage of your workflow or delivery pipeline. That first stage is usually dev. You don’t want to get any surprises when releasing a change in a production environment. For that reason, it’s better if you deploy the same way everywhere, including production. A change in configuration is all that you’d expect.&lt;/p&gt;
&lt;p&gt;Branching might sound good. Working this way, you can isolate changes that are ready to go from those that aren’t ready yet. But let’s think about a common scenario:&lt;/p&gt;
&lt;p&gt;You have your “dev,” “master,” and “release-X” branches, and everyone is initially pushing their changes to the “dev” one. Everything that gets there is released in dev and any other test environment. When a change is ready to be released, you create a “release-bugfix” branch and generate the artifacts. After they’ve been released, you integrate changes to “master” because that’s where all stable code exists.&lt;/p&gt;
&lt;p&gt;The problem is that everyone needs to update their branches from “master” and resolve any conflicts. A long time could have passed since their last update. But it’s not just that. They’d need to generate artifacts again, and they’d also need to repass the set of tests. It increases delivery time and risk, and you’ll lose consistency. The release process will begin to inspire a lack of confidence.&lt;/p&gt;
&lt;h1&gt;You Won’t Be Ready To Ship&lt;/h1&gt;
&lt;p&gt;Which feature branch should be released? Is there more than one? Which one should go first? These are the types of questions that you’ll face when working with feature branches. If you don’t know the answer, you’ll need to take some time to investigate. And it’s not only that. You’ll also need to coordinate with the teams that were working on certain branches to make sure no one deleted another’s code.&lt;/p&gt;
&lt;p&gt;What about bug fixes? What if you need to push a change but you’re in the middle of a merge? Or if you have a branch in the middle of the pipeline that’s not ready to be released? Things are about to get complicated.&lt;/p&gt;
&lt;p&gt;To make sure you don’t release anything unexpected, you need to roll back beforehand in order to have a clear path. Only then are you good to go by creating another branch for the fix.&lt;/p&gt;
&lt;p&gt;It might sound too complicated, but I’ve seen this scenario many times. There are also some branching models like &lt;a href="https://github.com/nvie/gitflow"&gt;GitFlow&lt;/a&gt; that help you with this. But sadly, complexity doesn’t go away, and the chance of ruining things is still there. GitFlow can be &lt;a href="http://endoflineblog.com/gitflow-considered-harmful"&gt;harmful to others who work on the code&lt;/a&gt;. And the fact that the branching model needs to be this complicated is a sign that something needs to change in your workflow.&lt;/p&gt;
&lt;p&gt;Release cadence is reduced by these types of problems. That’s something you need to take care of—the sooner the better. You shouldn’t be afraid of releasing new things.&lt;/p&gt;
&lt;h1&gt;Feedback and Collaboration Will Be Complicated&lt;/h1&gt;
&lt;p&gt;When you work with feature branches, the team won’t know what changed until the branch is merged. Feedback doesn’t come quickly. Collaboration is sacrificed because the group focuses only on the piece of code they changed in the feature branch. To avoid any delay, some might even decide not to update their branch until they’ve finished coding. Taking time to decide what code should get mixed in or deleted will also cause delays. All of this adds up to procrastination; people know that fixing a merge conflict will impact their delivery time, so they decide to leave that till the end.&lt;/p&gt;
&lt;p&gt;Another downside here is that, at some point in time, there might be a common problem in two feature branches. Each team will solve it in a different way. And because of this, the code might start getting duplicated. More than one solution to the same problem might start to exist. Which one will you fix when a problem arises? Are you aware of all of them? Or just certain people’s? You’ll never know exactly.&lt;/p&gt;
&lt;p&gt;That’s why pushing your changes to “master” will increase feedback and collaboration in the team. The feedback you receive is immediate. The team is forced to pull the latest changes more frequently. If there’s a conflict, they can easily review what just changed instead of needing to review a big list of changes when the branch is merged.&lt;/p&gt;
&lt;p&gt;It becomes problematic when a long list of files need to be reviewed carefully in each merge request. It’s way better when a developer pushes the latest changes to the main branch and makes sure it didn’t affect anyone else’s work. But that needs to happen as soon as possible.&lt;/p&gt;
&lt;h1&gt;Knowing What Changed Will Be Difficult&lt;/h1&gt;
&lt;p&gt;Many things can happen in a feature branch. If more than one person was working on it, the most likely scenario is that there’s a branch from the feature branch for each one of those people. Most likely, many commit messages will be found when merging the feature branch. You could squash all your commits to make them appear as one, but if the code needs to be reviewed, the folks doing it will need to read an awful lot. And they’ll have questions…too many questions.&lt;/p&gt;
&lt;p&gt;Even though there’s always a way that you can go back in history and see what changes were made, at the moment of deciding which code should be chosen when fixing a merge conflict, it’s better if you have a quick way to understand why that code was added, removed, or changed. Knowing the context will be key.&lt;/p&gt;
&lt;h1&gt;In Short, Avoid Using Long Feature Branches!&lt;/h1&gt;
&lt;p&gt;At this point, you might think, “OK. I understand that there are some pitfalls…but what do you propose then?” Well, I propose to work with &lt;a href="https://cmelendeztech.com/posts/2018/03/top-5-use-cases-feature-flags.html"&gt;feature flags&lt;/a&gt; and short-lived feature branches and to practice continuous integration. The most common reason people have for choosing to work with feature branches is that they want to minimize the risk of releasing incomplete or buggy code. But you shouldn’t be afraid of doing that. As long as a feature is turned off, you should be good to go. You can always toggle it when needed.&lt;/p&gt;
&lt;p&gt;The pitfalls I described here are real, but this doesn’t mean you should go to the extreme of not using feature branches at all. They’re really helpful. But &lt;strong&gt;the key here is how much time they will live&lt;/strong&gt;. The same thing happens when you don’t release frequently. Changes accumulate, and the risk is bigger and bigger the more time you wait. If you make the switch to working in small batches, you might keep using feature branches, but they will live a day at most. The difference is that feedback is amplified, and you can work on fixing things rapidly because there’s not too much to review. That’s the smart way to use feature branches!&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="agile"/><category term="development"/></entry><entry><title>HTTP Monitor: What It Is and Why You Need It</title><link href="https://cmelendeztech.com/posts/2018/03/http-monitor-what-is-why-you-need-it.html" rel="alternate"/><published>2018-03-26T00:00:00+02:00</published><updated>2018-03-26T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-03-26:/posts/2018/03/http-monitor-what-is-why-you-need-it.html</id><summary type="html">&lt;p&gt;One day, one of our main web APIs was down, and the first person that knew it was my boss. We were so worried about bringing the API up that we never paid attention to how he was able to be one step ahead of us. There were times when …&lt;/p&gt;</summary><content type="html">&lt;p&gt;One day, one of our main web APIs was down, and the first person that knew it was my boss. We were so worried about bringing the API up that we never paid attention to how he was able to be one step ahead of us. There were times when we even thought he had nothing else to do than constantly refresh the web page. But the truth is that he wasn’t doing that at all. He was using an HTTP monitor that emailed him every time the API was down, slow, or unresponsive.&lt;/p&gt;
&lt;p&gt;It was actually lucky for us that he had that monitor: it helped everyone fix things before our clients could notice. But what is an HTTP monitor, anyway? And why else would you need it?&lt;/p&gt;
&lt;h1&gt;It’s a Friend Who’s Watching Out For You All the Time&lt;/h1&gt;
&lt;p&gt;Think of an HTTP monitor like it’s a friend you’re paying to constantly check if your HTTP endpoints are working. That friend will hit the endpoints you tell him to, and he’ll follow the exact orders you gave him. Those instructions will be something like, “Hey, I need you to hit this endpoint every five minutes. And only call me if they’re responding with anything other than OK or if you haven’t heard anything back from them in less then a second.”&lt;/p&gt;
&lt;p&gt;You can use an HTTP monitor not just for web APIs but also for any of your websites. All that matters is that the application you want to monitor can be accessed using HTTP. It’s also important that they’re publicly accessed. If they’re not, you can make use of a &lt;a href="https://en.wikipedia.org/wiki/Bastion_hostsx"&gt;bastion host&lt;/a&gt; for critical-no-public endpoints. This is needed because an HTTP monitor is something that’s outside your network. Imagine that you or your provider have massive downtime. Your application will be down, but you also have that good friend who’s supposed to tell that you’re down. People also use HTTP monitors as part of the integration testing suite to validate a deployment.&lt;/p&gt;
&lt;p&gt;HTTP monitors are really simple, but fault tolerance and high availability in these type of systems make them complicated. And I bet you have enough of a time trying to keep your application up and running to want to worry about something else. Scalyr helps you to alleviate the load by offering &lt;a href="https://www.scalyr.com/help/monitors"&gt;HTTP monitors&lt;/a&gt; to probe your servers and measure availability, status, and performance.&lt;/p&gt;
&lt;h1&gt;Some Metrics You Need to Know Before You Start&lt;/h1&gt;
&lt;p&gt;It’s not just about whether it works or it doesn’t work. In order to make better use of HTTP monitors, we need to understand a handful of metrics and codes you can use to know how bad, exactly, your app is behaving.&lt;/p&gt;
&lt;p&gt;Let’s explore these metrics and codes:&lt;/p&gt;
&lt;h2&gt;HTTP Response Codes&lt;/h2&gt;
&lt;p&gt;There are &lt;a href="https://httpstatuses.com/"&gt;several codes&lt;/a&gt; that will give you more information about what happened in a request. But when monitoring HTTP endpoints, the only code that you’ll probably use is the “200 OK.” If you don’t receive this code in the response, something is wrong.&lt;/p&gt;
&lt;p&gt;They are grouped like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1XX is only informational.&lt;/li&gt;
&lt;li&gt;2XX means success.&lt;/li&gt;
&lt;li&gt;3XX means a redirection happened.&lt;/li&gt;
&lt;li&gt;4XX means something in the user’s request is not correct.&lt;/li&gt;
&lt;li&gt;5XX means that something is wrong in your servers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, it doesn’t make sense to tell your monitor to watch for any code other than the “200 OK.” If you get something different than this code, it will be useful to troubleshoot, not to monitor.&lt;/p&gt;
&lt;h2&gt;Response Body&lt;/h2&gt;
&lt;p&gt;This is simply the payload you receive back when hitting the endpoint. It could be in various formats such as JSON, HTML, or even plain text. This is useful because you can configure your monitors to extract, parse, and analyze the text.&lt;/p&gt;
&lt;p&gt;So for example, if the word “error” is found, you can trigger an alert even though you’ve received a 200-status code.&lt;/p&gt;
&lt;p&gt;Or what about when, for example, an endpoint should return data for Ferraris and you’re getting back data for Lamborghinis? That could be caused by a data migration in the database. But it doesn’t really matter what caused it; it matters that you can be notified almost in real time automatically.&lt;/p&gt;
&lt;h2&gt;Response Time&lt;/h2&gt;
&lt;p&gt;The response time is the time the endpoint takes to respond with a status code and a response body. It’s also called latency. Response time will depend on the endpoint you’re monitoring and the SLAs you’ve defined for it. If it’s an API, it usually needs to be in a range of 100 ms to 500 ms, but if it’s a website, the rage varies from 1 s to 2 s. But it depends on your use case.&lt;/p&gt;
&lt;p&gt;There are different metrics that serve different purposes. You can combine them so the monitor will alert you only when something really bad is happening, and not just because there was a temporary problem. And it’s important that your applications are returning the proper code too. I’ve seen cases where the endpoint is returning a 200 code, but when I looked at the response body, it was clear that the application was throwing an error.&lt;/p&gt;
&lt;h1&gt;You Can React When Something’s Wrong&lt;/h1&gt;
&lt;p&gt;After you know what data is important when probing HTTP endpoints, the next step is to configure the monitor so that it can notify the proper people. This part is tricky, but it’s the most important step because you don’t want your monitor to become the boy who cried wolf.&lt;/p&gt;
&lt;p&gt;For this reason, you might want to only be alerted when something can’t be recovered or healed by itself. Otherwise, the next time you receive an alert, you’ll rapidly think, “Nah, I always get these alerts. The recovery notifications will come after—they always do.” But no, after five minutes you start receiving calls from everyone, including your boss, telling you that the site is down.&lt;/p&gt;
&lt;p&gt;So let me give you some examples of HTTP monitor configurations that have worked for me. An alert will be triggered when at least one of the following happens:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The system received a status code that’s different than 200 OK.&lt;/li&gt;
&lt;li&gt;It takes more than 800 ms to respond back.&lt;/li&gt;
&lt;li&gt;The response body size in KBs is zero.&lt;/li&gt;
&lt;li&gt;The response JSON doesn’t include the “success” value in the “status” property.&lt;/li&gt;
&lt;li&gt;A custom header in the response isn’t found.&lt;/li&gt;
&lt;li&gt;The HTTPS endpoint is timing out after 800 ms and the status code is not 200 OK.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The idea is that when you receive an alert, you previously verified all the contexts of the request. Downtime could be caused by a ton of different reasons. It could be something with a server, and you just need to replace it. Or maybe an external dependency like others’ API endpoints are having problems and you just need to disable them temporarily. What happened doesn’t matter too much at the moment of being alerted. What matters is that you can act soon to reduce your system’s downtime.&lt;/p&gt;
&lt;h1&gt;You’ll Always Be One Step Ahead&lt;/h1&gt;
&lt;p&gt;Don’t let your clients be the first in line when reporting a problem in your system. Always be one step ahead of them and find the mechanisms to recover quickly. HTTP monitors will help you to minimize downtime by being aware. They’ll do this boring job for you.&lt;/p&gt;
&lt;p&gt;These type of monitors will inform you about the uptime percentage of your system endpoints. They’ll let you know when endpoints aren’t loading or taking too much time. And it’s not just that. You can do interesting things like parse the response body and look for any unexpected results. So it’s important that the dev team knows what status should be returned depending on the result.&lt;/p&gt;
&lt;p&gt;Know what you have at your disposal, and take advantage of it.&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="development"/><category term="itops"/></entry><entry><title>The Top 5 Use Cases for Feature Flags</title><link href="https://cmelendeztech.com/posts/2018/03/top-5-use-cases-feature-flags.html" rel="alternate"/><published>2018-03-01T00:00:00+01:00</published><updated>2018-03-01T00:00:00+01:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-03-01:/posts/2018/03/top-5-use-cases-feature-flags.html</id><summary type="html">&lt;p&gt;The concept of feature flags is really simple: it’s a conditional block of code that you strategically put somewhere to enable or disable features of your app easily. But knowing the top use cases for feature flags helps you to plan ahead and be more deliberate with their implementation …&lt;/p&gt;</summary><content type="html">&lt;p&gt;The concept of feature flags is really simple: it’s a conditional block of code that you strategically put somewhere to enable or disable features of your app easily. But knowing the top use cases for feature flags helps you to plan ahead and be more deliberate with their implementation. There are some obvious use cases, but there are also some that maybe you haven’t considered before.&lt;/p&gt;
&lt;p&gt;So let’s explore the top feature flag use cases!&lt;/p&gt;
&lt;h1&gt;1. Deployments With Less Hassle&lt;/h1&gt;
&lt;p&gt;Have you ever wondered how some companies release new things just after they’ve announced them at a live conference? Well, with feature flags, that’s possible—they just toggle a switch and enable the new feature. From the moment you start coding, you can wrap the new changes into a conditional block and deploy anytime you want, but with the new code disabled. Thinking of introducing the new change in secret, also known as a &lt;a href="https://rollout.io/blog/dark-launch-directors-new-best-friend/"&gt;dark launch&lt;/a&gt;? No problem—just make sure all your tests are passing with and without the new code.&lt;/p&gt;
&lt;p&gt;It doesn’t matter really which deployment strategy you choose. Whether it’s &lt;a href="https://docs.cloudfoundry.org/devguide/deploy-apps/blue-green.html"&gt;blue/green&lt;/a&gt; (B/G) or &lt;a href="https://octopus.com/docs/deployment-patterns/canary-deployments"&gt;canary&lt;/a&gt; deployment, feature flags fit perfectly. Let’s talk about a B/G scenario in which you have the green version running and the blue version as a candidate to be released. The blue version will have the feature turned off. Blue and green versions will run together for some time. And then you turn on the new feature. If something goes wrong, instead of switching back to the green version (because fixing things could take some time), you can just turn off the new feature immediately. Taking this approach, you’ll know for sure which version has problems, and that will lead to reduced downtime.&lt;/p&gt;
&lt;p&gt;The same thing goes for canary releases, only the benefit here is more evident. Imagine you encounter problems when almost finishing the rolling update. Normally, you’d have to roll back. With feature flags, you don’t have to worry about that. You just turn the feature off. Feature flags enable your apps to be backward compatible, and that’s critical for deployments with less hassle.&lt;/p&gt;
&lt;h1&gt;2. Experimentation Through A/B Testing&lt;/h1&gt;
&lt;p&gt;Most of us have seen the movie The Matrix. What pill would you choose, if you had Morpheus asking you? Red pill for the truth of reality? Or would you pick the blue pill and continue to believe an illusion?&lt;/p&gt;
&lt;p&gt;What if you wanted to try both and then choose?&lt;/p&gt;
&lt;p&gt;Unfortunately, that wasn’t possible in the movie, but in software, with feature flags, it’s possible.&lt;/p&gt;
&lt;p&gt;Facebook, Netflix, and other companies claim that they run experiments all the time. In fact, this is how Amazon launched their recommendations section you see on each product page. A developer had the idea of making recommendations to customers by showing what others had bought when shopping for the same product. They ran the experiment for a while, showing this section to some users and tracking the results, using the A/B testing technique. We all know how it ended because now everyone sees that section.&lt;/p&gt;
&lt;p&gt;But you don’t need to be Amazon to run A/B experiments. Let’s pretend we’re working for Amazon and we need to run the experiment I just mentioned. We’d add the code for a feature flag and decide which percentage of users, with the criteria we define, will see the new feature. Then, we’ll collect metrics to see how many more purchases came from those who saw the “customers who bought” feature versus those that didn’t see it. If the new version proved to be more profitable, we’ll just change the feature flag value to make it available to the rest of users and keep monitoring. The great thing about this is if for some reason we decide we don’t want the feature anymore, we don’t have to redeploy; we just need to turn the feature off.&lt;/p&gt;
&lt;h1&gt;3. Verbose Logging for Troubleshooting&lt;/h1&gt;
&lt;p&gt;There have been times when I wish I’d enabled the verbose logging in my code—especially when I receive reports that some users have been experiencing errors in code. The first thing I do is try to reproduce the error. If I’m lucky enough and succeed, the next step is to see logs. The sad part of the story is that, at this step, there’s nothing more than “something unexpected happened here.”&lt;/p&gt;
&lt;p&gt;It’s understandable if you don’t want to have verbose logging because disks could run out of space. No one wants to be awakened in the middle of the night with this news. But what if you could launch your code with verbose logging turned off and only enabled when you need it? Yes, with feature flags, it’s possible. You could activate all different types of logging that you previously configured but released them deactivated. Everyone will be happy with this approach: you get the information only when you need it, and no one has to worry about being paged about a low space problem or purchasing more space just to avoid it.&lt;/p&gt;
&lt;h1&gt;4. Always Be Ready for Continous Integration&lt;/h1&gt;
&lt;p&gt;You don’t need to worry about integrating &lt;em&gt;unfinished&lt;/em&gt; code with the rest of the team when using feature flags. A common approach is to use feature branches when working on a new change. The problem with this approach is the dreaded “merge conflict hell”—you know, that moment when you’re trying to merge your feature branch to master. The moment you’ll do anything to avoid. Some clever folks might even distract other developers so that they can merge their branch first and avoid this pain. It would be funny if it weren’t true.&lt;/p&gt;
&lt;p&gt;The idea with this, number four in our list of feature flag use cases, is to minimize problems that will steal valuable time from the team. When you code something you know for sure will take more than the rest of your day, you’ll see the benefit of feature flags. That’s because you can always push your code with the feature toggled off. Merge conflicts will be reduced, and it will be much easier and cheaper to fix them because everyone is pushing their changes more frequently.&lt;/p&gt;
&lt;p&gt;You might be afraid of pushing your changes to master; something incomplete could go live or the build could fail. But if that happens, other team members will look at the code to identify which flag was recently turned on. Then, they can simply turn it off and continue working. You’ll realize there’s no need for this fear any longer, thanks to feature flags.&lt;/p&gt;
&lt;h1&gt;5. Customize Behavior Based on User Preferences&lt;/h1&gt;
&lt;p&gt;Have you ever seen a message in a system saying they’re testing a new layout and asking you to opt into the new interface? I have. And in my experience, if I don’t like it, I can just simply opt out. Feature flags can be at the user level too. If users were selected to test a new feature, they could always just turn the new feature off if it didn’t suit them.&lt;/p&gt;
&lt;p&gt;Feature flags can also help you enable certain things for premium users. How easy would it be to upgrade a user? Quite easy. Just turn the premium features on for that user, and you’re done.&lt;/p&gt;
&lt;p&gt;At some point, your app might have a ton of features that your experienced users love. Just remember that you always have to think about your new users, too. They could get confused and stop using your app because they don’t even know where to start. A good solution for this is to turn off non-common features. Learn little by little how they’re using your app, and suggest features to them from time to time. Simplicity is the key. Try to avoid giving the impression that your app is hard to use or hard to learn.&lt;/p&gt;
&lt;h1&gt;Just Turn It On or Off…But Plan Ahead&lt;/h1&gt;
&lt;p&gt;This is how a few more lines in your code can let you experiment more. You’ll also enjoy the peace of mind that comes with just being able to turn things off when the result isn’t what you expected. When you plan ahead and write your code intentionally, good things emerge from it. Everyone’s productivity will increase because it’s not just developers that will be able to push unfinished code; also, the operations team will be able to roll back easily when it’s needed.&lt;/p&gt;
&lt;p&gt;Even if I was able to convince you where and how to use feature flags, until you start practicing using them, all of the above will be just theory. And one last thing—you can use feature flags almost everywhere, and you can use them many times, but eventually, &lt;a href="https://rollout.io/blog/feature-flag-retirement/"&gt;they’ll need to get retired&lt;/a&gt;. But meanwhile, apply the advice in the feature flag use cases listed here, and enjoy watching your stress levels decrease!&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="agile"/><category term="development"/></entry><entry><title>Sexy But Useless DevOps Trends</title><link href="https://cmelendeztech.com/posts/2018/02/sexy-useless-devops-trends.html" rel="alternate"/><published>2018-02-23T00:00:00+01:00</published><updated>2018-02-23T00:00:00+01:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-02-23:/posts/2018/02/sexy-useless-devops-trends.html</id><summary type="html">&lt;p&gt;What’s sexy but useless? A Ferrari in a traffic jam. It’s beautiful, but all that power means nothing. When trapped in traffic, it can’t live up to its full potential.&lt;/p&gt;
&lt;p&gt;Same with DevOps. While there are some &lt;a href="http://cmelendeztech.com/posts/2018/02/5-critical-devops-practices.html"&gt;critical DevOps functions that you absolutely need&lt;/a&gt;, there are some …&lt;/p&gt;</summary><content type="html">&lt;p&gt;What’s sexy but useless? A Ferrari in a traffic jam. It’s beautiful, but all that power means nothing. When trapped in traffic, it can’t live up to its full potential.&lt;/p&gt;
&lt;p&gt;Same with DevOps. While there are some &lt;a href="http://cmelendeztech.com/posts/2018/02/5-critical-devops-practices.html"&gt;critical DevOps functions that you absolutely need&lt;/a&gt;, there are some sexy but useless DevOps trends that are good to be aware of. Truth be told, there’s no recipe that will tell you how to succeed in DevOps. Everyone will have different opinions, and what worked for others might not work for you. But you can trust one thing: there are some actions that will guide you directly to frustration with DevOps.&lt;/p&gt;
&lt;p&gt;With the amount of information out there about DevOps, you might get overwhelmed and think it’s not for you. You also might think the learning curve is too steep—that you need to change too many things before you get started. Maybe you’ll need a new team, new tools, more metrics, more time… you name it.&lt;/p&gt;
&lt;p&gt;My advice is this: don’t get distracted by all things that people say about DevOps. These things I’m going to talk about here, for instance, are all style and no substance.&lt;/p&gt;
&lt;h1&gt;1. Having a Separate DevOps Team&lt;/h1&gt;
&lt;p&gt;The idea of DevOps is to remove silos. It doesn’t make sense then to include another team that will be in charge of handling or easing the communication between developers and operations. Historically, these two teams have had conflicts, so adding a DevOps team is similar to adding therapists for each team. Having a DevOps team might look sexy because now you can tell the world you’re doing DevOps. Your team will hurry to update their LinkedIn profile. But in reality, you’re just adding more complexity.&lt;/p&gt;
&lt;p&gt;What would a potential problem with a DevOps team look like? Well, developers and operations could start saying, “It’s not my job to automate the release; it’s the DevOps team’s responsibility.” And what about accountability and ownership? You’ll lose it.&lt;/p&gt;
&lt;p&gt;Another downside is that you’ll need to have a “full-stack” team that has a background in development, operations, testing, and security. I don’t doubt there are people with these skills, but you lose a lot when someone isn’t specializing in one thing.&lt;/p&gt;
&lt;p&gt;So instead of having a separate team that will create more handoffs, what you can do is identify where the problem really is. It could be as simple as changing a culture that doesn’t share knowledge. Are developers thinking about using a new NoSQL database? Great. The developers should let operations know so they can learn it too. Is operations thinking about adopting containers? Nice. They should let developers know about it—I bet the devs would appreciate a production-like environment.&lt;/p&gt;
&lt;p&gt;So, please, don’t add a new team to your DevOps initiative. Say no to silos. Instead, target the real problems: the ones that made you think you needed a DevOps team in the first place.&lt;/p&gt;
&lt;h1&gt;2. “Going DevOps” By Virtue of Adopting Some Tool&lt;/h1&gt;
&lt;p&gt;As the great &lt;a href="https://twitter.com/Grady_Booch"&gt;Grady Booch&lt;/a&gt; once said, “A fool with a tool is still a fool.” While using the fanciest, most-almighty-seeming tool for DevOps might seem sexy, it’s useless if you’re hoping it will magically make you a practitioner of DevOps. Same for things like cloud, microservices, or containers. You don’t need any of those things to provide value. If you don’t know what problem a tool or technology stack is solving, ask yourself why they even exist.&lt;/p&gt;
&lt;p&gt;This doesn’t mean that tools aren’t important and they can’t be useful. Some of them will help you speed up, but you shouldn’t fully depend on them. They’re always evolving.&lt;/p&gt;
&lt;p&gt;In fact, you can embrace DevOps without tools, and James Shore’s post on how to do &lt;a href="http://www.jamesshore.com/Blog/Continuous-Integration-on-a-Dollar-a-Day.html"&gt;continuous integration with the bare minimum&lt;/a&gt; sets a baseline for what I’d say about tools and DevOps. The post basically says that you only need an old computer that you’re not using anymore, a rubber chicken, a desk bell, a script, and Kool-Aid to do &lt;a href="http://blog.scalyr.com/2017/10/introduction-continuous-integration-tools/"&gt;continuous integration&lt;/a&gt;. Sounds silly, but it helps you understand that you don’t need a tool to start things; you can use what you already have in place. You just need to be creative.&lt;/p&gt;
&lt;h1&gt;3. Having Developers Manage Production Environments&lt;/h1&gt;
&lt;p&gt;You might be tempted to do this, especially after hearing that companies like Netflix and Amazon are letting their developers push changes directly to a production environment several times a day. But you shouldn’t forget that, in order to achieve this, the delivery pipeline needs to be deterministic and accompanied by a trustworthy set of tests. While I believe that DevOps encourages freedom, I don’t think giving the keys to production to everyone will be beneficial. Folks have been fired on their first day of work because they were allowed—and proceeded—to screw things up badly. Imagine giving everyone at a bank a key to the vault. It’s like that.&lt;/p&gt;
&lt;p&gt;I’m not saying that developers shouldn’t be trusted, nor am I saying that companies that give full permissions to developers are nuts. It’s just not for everyone. Giving this type of access could make you ask why you need an operations team.&lt;/p&gt;
&lt;p&gt;Instead, consider giving developers indirect access to production. By indirect access, I’m saying the operations team should provide all the tools developers need to make better decisions. For example, you could give developers read-only access to the system you’re using to administer infrastructure (e.g., AWS or vSphere).&lt;/p&gt;
&lt;p&gt;You could also give developers access to the log management tool or to whatever you use to store infrastructure metrics. If developers have visibility into things like CPU, memory, requests per second, error rates, and other such things, it will help them be accountable. You don’t need to give them full permissions. Just give them the proper tools to make their work easier. And in the end, remember that operations folks have way more to do than just releasing and operating systems, and most people are just trying to help.&lt;/p&gt;
&lt;h1&gt;4. Giving Yourself X Months to Become “DevOps Compliant”&lt;/h1&gt;
&lt;p&gt;Are you looking for a crystal ball that can tell you when you’ll finish with your DevOps initiative? That would be Ferrari-style sexy. You could, in fact, reach the point of doing several deployments per day, being always ready to deliver. That sounds next-level sexy, especially to top-level management. But the ambition to finally have “arrived,” as far as DevOps is concerned, is fool’s gold. This should be something that you constantly improve upon. What if suddenly, for some reason, you’re not delivering quickly, securely, and reliably? Your process might need to change.&lt;/p&gt;
&lt;p&gt;Are you going to stop working on new features? I’d hope not. You should take a more conservative approach initially, but as you progress, know there’s always an opportunity to improve. The architecture will evolve, features will be removed, technology will need to be upgraded, etc. So as the Agile Manifesto says, you should always respond to change over following a plan. Don’t expect that you’ll need X time to be DevOps. It’s a continuous improvement process.&lt;/p&gt;
&lt;h1&gt;What Worked for Others Might Not Work for You&lt;/h1&gt;
&lt;p&gt;In conclusion, your own DevOps path might be easy. Or it might make you suffer a bit. But just as organizations are different, cultures and processes can be different—even in the same industry. So why bother with sexy-but-useless rules that not only may not apply to you but also might hold you back? Just keep learning from others, taking what you think will work for you, and then trying things out. &lt;a href="https://en.wikipedia.org/wiki/Pinky_and_the_Brain"&gt;Pinky and the Brain&lt;/a&gt; were trying to take over the world every night, and they never did it.&lt;/p&gt;
&lt;p&gt;It’s important you’re aware that DevOps trends that are sexy but useless exist. But here’s some things that will help you.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Remove silos instead of adding more of them.&lt;/li&gt;
&lt;li&gt;Know you don’t need a certain tool or technology to provide value to your customers. Some will make your life easier and will improve productivity, but they alone won’t solve all your problems.&lt;/li&gt;
&lt;li&gt;Make sure every person in your organization knows how they are providing value. Doing so will reduce complaints about lack of access.&lt;/li&gt;
&lt;li&gt;And most importantly, know that it’s helpful to take the approach of always improving in small batches.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Experiment, adjust, and don’t forget to enjoy the journey.&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="agile"/></entry><entry><title>5 Critical DevOps Practices</title><link href="https://cmelendeztech.com/posts/2018/02/5-critical-devops-practices.html" rel="alternate"/><published>2018-02-15T00:00:00+01:00</published><updated>2018-02-15T00:00:00+01:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-02-15:/posts/2018/02/5-critical-devops-practices.html</id><summary type="html">&lt;p&gt;DevOps is like pizza. We can’t think of pizza without considering critical ingredients: dough, sauce, cheese, and your preferred choice for vegetables and proteins. Everyone likes different toppings. In my case, I can’t think about pizza without extra cheese and meat. You might choose differently, but I think …&lt;/p&gt;</summary><content type="html">&lt;p&gt;DevOps is like pizza. We can’t think of pizza without considering critical ingredients: dough, sauce, cheese, and your preferred choice for vegetables and proteins. Everyone likes different toppings. In my case, I can’t think about pizza without extra cheese and meat. You might choose differently, but I think we can agree there are some ingredients that are critical for this food to be called pizza. Quality and ingredients will vary, but some things will always remain true.&lt;/p&gt;
&lt;p&gt;Well, it’s the same with DevOps practices. There are some critical practices, and you can’t think about DevOps without considering them. Everyone will have preferred choices regarding the tools and the process, but the practice will remain and each practice complements the other.&lt;/p&gt;
&lt;p&gt;Every critical DevOps practice takes time to get down, but the end result will be magnificent. So, let’s discuss what they are and how to implement them.&lt;/p&gt;
&lt;h1&gt;1. Involvement From Everyone In the Process&lt;/h1&gt;
&lt;p&gt;Group involvement is like the dough of our pizza. It’s the foundation, the base. This is the DevOps practice that you need to start before any other. Gone are the days when you would define DevOps as a collaboration between &lt;strong&gt;just&lt;/strong&gt; development and operations. What about QA? What about &lt;a href="https://www.govloop.com/what-is-secops/"&gt;SecOps&lt;/a&gt;? And more importantly, what about management? In order to get a good base for DevOps, you have to stop thinking about teams or people. Everyone involved in the process of developing the product should have a mindset of collaboration.&lt;/p&gt;
&lt;p&gt;If this doesn’t happen, you’ll constantly have people questioning everything or ignoring important aspects of the project. It’s not like you’re working with saboteurs—no one’s trying to destroy the initiative. But people have to understand the impact of their actions. When you involve everyone in the process, people can grasp the whole picture. And just like that, you’ve laid the foundation for DevOps.&lt;/p&gt;
&lt;h1&gt;2. Trust Only What You Have In Version Control&lt;/h1&gt;
&lt;p&gt;Trusting only what you have in version control is like the sauce of our pizza. It’s the first ingredient you put on it. The flavor will vary, but it’s a critical practice.&lt;/p&gt;
&lt;p&gt;At work, every time someone interrupts me with a question about a certain functionality—especially one that I coded a while back—I answer with what I remember, but I always add, “Don’t trust me, though. Let’s go and see what’s in the repository.” Now it’s not just code. You’ll have to put in version control infrastructure specifications, dependencies, and configuration templates. Some of those configuration values will be &lt;a href="http://blog.scalyr.com/2018/01/visibility-speed/"&gt;visible to everyone&lt;/a&gt;, and others won’t. It becomes critical to have it just for the sake of repetition. Repetition and consistency are key.&lt;/p&gt;
&lt;p&gt;The only source of truth should be what you have in version control. Avoid doing manual changes. If something needs to change, it should be done here. Not anywhere else. The team will then know the “what,” “when,” “why,” and “who” when it comes to changes, and that knowledge is the difference between a team with poor communication and a high-functioning DevOps team. As this practice becomes routine, team confidence will increase. There’s nothing like trusting the process.&lt;/p&gt;
&lt;h1&gt;3. Be Confident With Automated Testing&lt;/h1&gt;
&lt;p&gt;Cheese! Automated testing is like cheese. And there’s no pizza without cheese. You can’t afford to not have the practice of &lt;a href="https://smartbear.com/learn/automated-testing/"&gt;automated testing&lt;/a&gt; in place.&lt;/p&gt;
&lt;p&gt;Forget about DevOps for a moment. This practice is critical now more than ever in our industry. If you want to succeed and deploy with confidence, a good suite of tests you can trust is crucial. You need tests that will fail if the app is not providing the expected output. Otherwise, the team will be slower to call something is done, thanks to manual testing.&lt;/p&gt;
&lt;p&gt;There are several types of tests that you can choose, and today’s not the day to talk about them. But know that the speed of the tests is a critical factor. If it takes too much time to receive feedback, everyone will avoid them. Some people might go to the extreme of commenting them out or removing them. As long as almost no human intervention is needed and they run fast, your tests are good.&lt;/p&gt;
&lt;p&gt;Without the practice of automated testing, all DevOps efforts will be compromised because you’ll instead be dealing with a constant barrage of errors.&lt;/p&gt;
&lt;h1&gt;4. Regularly Integrate Your Codebase&lt;/h1&gt;
&lt;p&gt;The regular integration of your codebase is like our pizza’s vegetables. In order to have a balanced diet, you need to include them. As kids, we didn’t like them that much, but as adults, we realized that we need them. You might not like this practice at the beginning, but you will after time. This practice consists of regularly integrating your codebase into the mainline, trunk or master (depending on the version control tool). &lt;a href="https://blog.newrelic.com/2012/11/14/long-running-branches-considered-harmful/"&gt;Avoid long-lived feature branches&lt;/a&gt;, and &lt;a href="http://blog.scalyr.com/2017/10/introduction-continuous-integration-tools/"&gt;integrate your code&lt;/a&gt; at minimum once a day.  Everyone should always have the same working copy of the codebase each morning.&lt;/p&gt;
&lt;p&gt;Things can go wrong, I know. That’s why, in addition to integrating your codebase, you’ll need to have an automated way to check if everything went well. Compile the code, do your &lt;a href="https://www.owasp.org/index.php/Static_Code_Analysis"&gt;static code analysis&lt;/a&gt;, check that all unit tests passed, and then pack to deploy the same code everywhere. You’ll build only once. If you don’t do this, you’ll add more time to delivery, and you might encounter new problems every time. This practice might sound crazy if it’s the first time you’ve heard of it.&lt;/p&gt;
&lt;p&gt;Architecture plays a big role here. You will need to have a loosely coupled one. Things need to be easy to change and evolve all the time.&lt;/p&gt;
&lt;p&gt;Are you still in doubt that this is necessary? I understand. The first time I read about this practice, I thought, “It’s not for me.” Try it out and see the difference it can make. You can leverage feature flags to always have the option of turning off what you’ve checked in.&lt;/p&gt;
&lt;h1&gt;5. Deterministic Deployments in All Environments&lt;/h1&gt;
&lt;p&gt;Deterministic deployments in all environments are like proteins. A good pizza will have them, and so will a good DevOps implementation. I never get tired of telling people that deployments should become a boring task: predictable, without randomness. You’ll need to have the above practices in place in order to practice this one, though. It’s about having a deployment pipeline. There are gates that require the human skill of critical thinking in order to continue.&lt;/p&gt;
&lt;p&gt;It’s of the utmost importance that the delivery pipeline is the same in every environment. Remember, you don’t want to be surprised on release day. Development, QA, staging, and production should have the same pipeline. For development, you’ll want everything automated without anyone approving. In QA, you’ll want to have a bigger suite of tests approving it. Staging might be the same but with a different suite of tests, usually that take more time to validate. And for production, it should be a business decision.&lt;/p&gt;
&lt;p&gt;Let me tell you also that it’s not just about code. It’s about everything involved in the process of deploying the app in a working state. This means that aspects like infrastructure and configuration should be considered too. Processes like infrastructure as code and configuration management are critical. Of course, automation will always be key because the idea is to provide value to your customers in a timely manner. That’s why this practice is critical. You can’t let fate take care of this. There’s nothing worse than calling things done when developers have delivered.&lt;/p&gt;
&lt;h1&gt;It’s All About Providing Value&lt;/h1&gt;
&lt;p&gt;As I’ve been saying, it’s all about pizza. Wait, sorry. It’s all about providing value with this set of practices.&lt;/p&gt;
&lt;p&gt;It’s important to have at least these five elements in place in order to succeed. Practicing these will help to increase your team’s confidence more and more with each release. Persevere through the pain of implementing something new, because the more you practice these, the better you’ll become. Customers will be impressed when you’re mature enough in DevOps that you deliver value to them — and in a timely fashion — each time they make a request.&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="agile"/></entry><entry><title>Is DevOps Possible in Government Agencies?</title><link href="https://cmelendeztech.com/posts/2018/02/devops-possible-government-agencies.html" rel="alternate"/><published>2018-02-09T00:00:00+01:00</published><updated>2018-02-09T00:00:00+01:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-02-09:/posts/2018/02/devops-possible-government-agencies.html</id><summary type="html">&lt;p&gt;Let’s not beat around the bush. Yes, it’s possible.&lt;/p&gt;
&lt;p&gt;And before you close this tab because you’re not working for the government, let me say that what you’ll read in this post will provide a good example of how big organizations could implement DevOps—organizations where …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Let’s not beat around the bush. Yes, it’s possible.&lt;/p&gt;
&lt;p&gt;And before you close this tab because you’re not working for the government, let me say that what you’ll read in this post will provide a good example of how big organizations could implement DevOps—organizations where several teams have to agree on things and documents have to be filed before anyone can act. That’s usually the case with many big enterprises. Bureaucracy and coordination between teams are often what prevent organizations from providing value at the exact right time.&lt;/p&gt;
&lt;p&gt;But what does this all have to do with DevOps and government? Well, DevOps is about providing value to someone that will benefit from the product the organization is providing. It’s not just about helping organizations to speed up delivery and profit. Governments have a yearly budget, so profit might not be a big win in this case. Instead, they’re interested in a more social cause: improving human life. The software they produce could affect someone’s life to the point of not getting healthcare coverage. We’ll talk about that in a moment. The point is that we all depend on software now, so it’s not just a matter of profitability. It’s also a matter of providing life-enhancing value.&lt;/p&gt;
&lt;p&gt;A common mistake is to think that DevOps is only for certain companies—that you will need to have the smartest people on your team. But that’s not true. I overheard that someone ask &lt;a href="https://twitter.com/adrianco"&gt;Adrian Cockcroft&lt;/a&gt; how Netflix was able to get the team they have. He just answered, “I took them from you.” I’m not pretending DevOps is for everyone, but I will say that I haven’t found any industry of software development where this can’t be applied. It’s applicable even in &lt;a href="https://itrevolution.com/the-amazing-devops-transformation-of-the-hp-laserjet-firmware-team-gary-gruver/"&gt;firmware industry&lt;/a&gt;. So let’s see how we can take the DevOps approach to some of the common problems in government.&lt;/p&gt;
&lt;h1&gt;Culture, Processes, and Architecture Are Too Rigid&lt;/h1&gt;
&lt;p&gt;Government agencies typically have serious silos. That’s because they often work with a waterfall model, and each phase represents a different group. And it’s not just that. They usually have to deal with a series of contractors, and all of them use a different tool to communicate. This especially applies to, say, a ticket system to report bugs. As &lt;a href="http://www.melconway.com/Home/Conways_Law.html"&gt;Conway’s Law&lt;/a&gt; says, “Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure.” Communication is exactly one of the things that DevOps tries to improve.&lt;/p&gt;
&lt;p&gt;The way you introduce DevOps in such a scenario is by working on how teams interact with each other. When you start to understand the needs of the other teams that are also struggling when delivering something, you’ll anticipate those needs and work on removing their hassles.&lt;/p&gt;
&lt;p&gt;Let’s talk about security since it’s a big concern in government. You don’t need to wait until you’re about to deploy a change to recertify the software. Instead, you could start injecting those security checks from the beginning. And that list is pretty big in government. Doing this will not only help you to deliver faster but will also leave tracks as the change is being pushed across the different environments.&lt;/p&gt;
&lt;p&gt;And because you will be &lt;a href="http://cmelendeztech.com/posts/2018/01/devops-change-management.html"&gt;leaving tracks all the way down&lt;/a&gt;, you’ll also have the ability to make sure the software is compliant. Everyone will know how a change got to production. You can even get to a point where no manual intervention will be required. Government agencies have strict regulations about what gets sent to production, as well as where and how it gets sent. Compliance is a big concern in this realm, but DevOps brings the benefits of continuous visibility.&lt;/p&gt;
&lt;h1&gt;Resistance To Change Until It’s Urgently Needed&lt;/h1&gt;
&lt;p&gt;Usually, bureaucratic shops resist change culturally. Most of the time it’s because, in government, many people have lots of years in the same job. Some might be afraid to lose those jobs, and others simply don’t see the need for change. For them, work might be slow, but at least progress is being made. But what about when there’s an external pressure—a political one that you can’t control? You might remember when the &lt;a href="https://rctom.hbs.org/submission/the-failed-launch-of-www-healthcare-gov/"&gt;launch of the healthcare.gov platform failed&lt;/a&gt;. Everybody had something to say about what went wrong and how they should have done things differently.&lt;/p&gt;
&lt;p&gt;The healthcare.gov failure forced the government to change. There are some interesting tales about how they &lt;a href="https://youtu.be/QEfS0z_iPoo?t=7107"&gt;survived during that time&lt;/a&gt; and how things worked &lt;a href="https://www.youtube.com/watch?v=7Vc8sxhy2I4&amp;amp;index=1"&gt;a year&lt;/a&gt; after that failure. There were big struggles with communication. No one really knew exactly the impact and importance of that project. But it’s interesting that after some years, you see that there are platforms like &lt;a href="https://cloud.gov/"&gt;cloud.gov&lt;/a&gt; that take care of all the security checks (a document about 4,000 pages long) that government needs to pass so that people can focus only on software development. That platform is even &lt;a href="https://18f.gsa.gov/2017/02/02/cloud-gov-is-now-fedramp-authorized/"&gt;fedRAMP authorized&lt;/a&gt; now, and AWS has a dedicated region for these type of workloads.&lt;/p&gt;
&lt;p&gt;So it is possible to introduce practices like DevOps in government. Some will resist the change wholeheartedly. Others will say that DevOps is great, but it’s just not for them. They will always put forth a valid argument or excuse, but they often come around to viewing DevOps as the right move when they’re forced to change. It’s exemplified by the &lt;a href="https://itrevolution.com/wp-content/uploads/files/PhoenixProjectExcerpt.pdf"&gt;Bill Palmer storyline in the book The Phoenix Project&lt;/a&gt;: after a big failure in a project, they had to find a way to do things better. They did, but only after the external pressure of outsourcing, IT came.&lt;/p&gt;
&lt;h1&gt;Working With Bureaucracy In Small Batches&lt;/h1&gt;
&lt;p&gt;So, you're in an environment where every little thing requires six levels of approval. Do you want to use Jenkins? Great! You just need 15 committees to approve it over two years, and you're good! So how do you work with this? Startups can easily take the DevOps approach because there are not many people who have to agree. But in government or big enterprises, that’s not the case.&lt;/p&gt;
&lt;p&gt;Some time ago, I had the wrong idea about my boss and his feelings about introducing something new. I thought he didn’t like it when I’d innovate or try new things. In reality, he was concerned about the stability and quality of our product. But then he encouraged me in a different way. He said that it was OK to experiment in another environment that wouldn’t affect anyone else, especially our customers. That way, we were able to try a new technology, architecture, or tool without risking our business. Also, we’d make sure that we weren’t introducing something that wouldn’t work for us.&lt;/p&gt;
&lt;p&gt;That’s the approach you can take when introducing a practice like DevOps. Prove that it’s working, start small, but make sure it will have an impact. Start making your allies and choose wisely. Talk with key team members in each team—those that you know have a voice. Listen carefully to all their concerns, and work on having an anticipated answer. Then, you can offer a few options. And don’t expect that you’ll be implementing DevOps overnight. You’ll have to give in to certain things that you might not necessarily agree with in order to convince the committee that will approve the initiative.&lt;/p&gt;
&lt;h1&gt;Rome Wasn’t Built In a Day&lt;/h1&gt;
&lt;p&gt;It will take time for some organizations to adopt DevOps. And we all can learn about other industries that have needed to do things differently. What worked for some might not work for you and vice versa. Especially in software development, there will always be tradeoffs. The majority of the problems in such bureaucratic industries concern culture and process. It’s not about individuals, per se, nor is it about technology stack or tools. I’ve had problems with my friends when coordinating where to go to dinner. Imagine how complicated it can be with the government, where there are so many people and aspects to take into consideration.&lt;/p&gt;
&lt;p&gt;There will always be resistance to change. We humans don’t like it. Even in our personal lives, we try to avoid it. Change seldom comes until you need it or you’re forced into it. So instead of trying to avoid it, let’s embrace it.&lt;/p&gt;
&lt;p&gt;So yes, DevOps is possible in government agencies. And if it’s possible in this area, chances are that it’s possible everywhere else. The secret is in the strategy we choose to introduce these types of changes into complex organizations.&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="agile"/></entry><entry><title>Why IT and Software Delivery Service Cycles Are Getting So Much Faster?</title><link href="https://cmelendeztech.com/posts/2018/01/why-software-delivery-is-faster.html" rel="alternate"/><published>2018-01-25T00:00:00+01:00</published><updated>2018-01-25T00:00:00+01:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-01-25:/posts/2018/01/why-software-delivery-is-faster.html</id><summary type="html">&lt;p&gt;I had the opportunity to attend Amazon's AWS re:Invent conference this year. The number of new services they launched was amazing. And in November, Microsoft held the virtual conference called Connect(). They, too, announced plenty of new initiatives. But what does this have to do with delivery service cycles …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I had the opportunity to attend Amazon's AWS re:Invent conference this year. The number of new services they launched was amazing. And in November, Microsoft held the virtual conference called Connect(). They, too, announced plenty of new initiatives. But what does this have to do with delivery service cycles? Well, as I watched what Amazon and Microsoft have done, I realized that their end goal is to alleviate the pain companies have when developing and deploying new software. They’re letting everyone focus on what’s really important: delivering value to customers.&lt;/p&gt;
&lt;p&gt;The existence of tools and services is one of the reasons why delivery speed is so fast these days, but it’s not just that. When you let others take care of the things that aren’t your primary business, you can easily innovate and deliver faster. For example, if you need to do a big migration to the cloud but you don’t have enough experience to do it, it’s better if you hire a contractor to help you. This doesn’t mean you aren’t capable of doing it–or even learning how to do it. But it may cost you, both financially and reputation-wise. It’s way more affordable–and more face-saving–in the long term to lean on someone else’s shoulder.&lt;/p&gt;
&lt;p&gt;That’s how our industry is behaving now. There have been so many improvements regarding cultures and disciplines, tools and services, practices and the vast number of resources you can find out there that speed is resulting naturally. It’s letting organizations take software delivery time from months to minutes. So let’s explore some of the things that are making this speed possible.&lt;/p&gt;
&lt;h1&gt;Changes in Culture That Have Resulted in New Disciplines&lt;/h1&gt;
&lt;p&gt;One of the first software development methodologies I encountered was the waterfall approach. At the time, I liked the idea that there was an order and well-defined processes to follow. But when I joined a company where they heavily used this model, I was disappointed. I’d get so excited to work on new assignments, but then they’d take ages to deliver, thanks to the bureaucratic processes involved. It was clear that we needed a change in the process. Everyone needed to be involved. After working in waterfall fashion for some time, I was introduced to Scrum. Everything was different. For example, I noticed that with this model we could be paying more attention to creating working software than having extensive documentation.&lt;/p&gt;
&lt;p&gt;When we switched to Scrum, we were deploying something new to production every two weeks. In the past, we’d deliver a simple change in a month, if we were lucky. Testing is another example of improvements that came with Scrum. Teams became more confident in what they were working on because something or someone was always verifying they were delivering what was expected. And testing opens the door to refactoring and to always be improving the code. That’s contrary to what usually happens: the older the code, the more difficult it is to make a change.&lt;/p&gt;
&lt;p&gt;Now we have test-driven development (TDD), short cycles of development, all sorts of different tests (like unit, acceptance, and integration tests), pair programming, ownership from everyone, continuous integration, continuous delivery, SOLID principles, and even crazy things like &lt;a href="http://principlesofchaos.org/"&gt;chaos engineering&lt;/a&gt;. We’re still learning how to apply all of these principles and disciplines, but it’s good to know they’re there. We should take what makes our delivery service cycles faster and discard what doesn’t.&lt;/p&gt;
&lt;h1&gt;More Tools and Services That Let You Focus On Your Business&lt;/h1&gt;
&lt;p&gt;There’s one main reason you’re seeing tools and services being launched so frequently: those companies or communities are trying to make your life easier and more productive. Proof of that is all the serverless waves you may have been seeing recently. It’s a simple and fast way to get started. From prototyping to validating a concept to creating something new, you don’t need to worry about provisioning a server to host your application. And you just pay for what you use. Cloud providers are launching these types of tools with the sole purpose of helping you to become more productive. If there’s something you need that a cloud provider doesn’t offer, there might be a company already offering a software-as-a-service (SaaS) solution for that. &lt;a href="https://www.twilio.com/"&gt;Twilio&lt;/a&gt; or &lt;a href="https://auth0.com/"&gt;Auth0&lt;/a&gt; are just two companies that specialize in this.&lt;/p&gt;
&lt;p&gt;Also, for any tech stack that you choose, there’s likely to be a powerful IDE available. There are so many IDEs right now that are making people more productive. Features like &lt;a href="https://blogs.msdn.microsoft.com/visualstudio/2017/03/09/live-unit-testing-in-visual-studio-2017-enterprise/"&gt;live unit testing&lt;/a&gt; from Visual Studio or pair programming from &lt;a href="https://code.visualstudio.com/visual-studio-live-share"&gt;Visual Studio Live Share&lt;/a&gt; or &lt;a href="https://docs.c9.io/docs/share-a-workspace"&gt;Cloud9&lt;/a&gt; are good examples of productivity-boosters. Those features are appealing because you can receive feedback instantly, and this certainly improves your speed of development.&lt;/p&gt;
&lt;p&gt;Another important tool is Jenkins, which helps in the field of deployments and code integration. You can have at your fingertips the possibility to deploy a new change to a live environment in minutes. Of course, that’s only after the change has passed a set of tests successfully and after the team knows it isn’t making the application worse, overriding anything, or causing any downtime. While these benefits aren’t 100% attributable to Jenkins, the tool is absolutely helping to achieve them.&lt;/p&gt;
&lt;h1&gt;Better Practices That Enable Ease of Change&lt;/h1&gt;
&lt;p&gt;When you hear that there are some organizations delivering software changes in minutes, your first impression might be that their system must not be that complicated—or that they’re nuts! But in reality, these organizations are leveraging automation. This is by far the more important practice that’s helping everyone to go faster. The rise of DevOps as a movement reinforces this practice of relying on automation more and more each day. Many practices in this area will help you to deliver with confidence: practices like configuration management, continuous integration, automated testing, infrastructure as code, immutable infrastructure, release strategies, and more.&lt;/p&gt;
&lt;p&gt;But architecture also plays a big role here. You’ll need to keep it in mind that things will change. Technology will evolve. We can choose to evolve with it, or, if we wait too long, we’ll be forced to evolve with it. Functionality will change, too. This happens all the time. And if you don’t act wisely, you’ll accumulate technical debt. That technical debt, in the end, can force you to start over. That’s costly.&lt;/p&gt;
&lt;p&gt;Instead, what’s happening right now is the emergence of new patterns that let us be less afraid of change. There are practices like implementing domain-driven design (DDD), using design patterns, building microservice architectures, making use of containers, and taking the serverless approach, just to mention a few. Of these examples, containers are the most acclaimed right now. Everybody is talking about containers and with good reason. Organizations are increasingly adopting them, thanks to the portability and packaging that this technology offers. Containers enable more collaboration between teams and reduce the time taken for deployments—and even for rollbacks. In some way, they enable you to go faster by forcing you to document each change, even at the infrastructure level. This makes everyone aware of what’s being pushed, and potential problems practically identify themselves. Plus, it’s easy to change something; if it’s easy to change, you can deliver fast.&lt;/p&gt;
&lt;h1&gt;Focus On What Your Customers Value Most&lt;/h1&gt;
&lt;p&gt;We’re living in wonderful times. It amazes me how good our industry is becoming at delivering useful things to the world and how collaborative we are right now. We’re not only focusing on delivering fast. We’re also paying more attention to what customers value most.&lt;/p&gt;
&lt;p&gt;We’ve learned from our mistakes. We’re creating tools that make our lives easier and more enjoyable. New practices are becoming the default, thanks to the results they’re giving in return.&lt;/p&gt;
&lt;p&gt;It’s true that things are changing fast, but the good thing is that you can easily tell when something is becoming relevant and useful if it stands out from the rest. You might be practicing some of the things I mentioned here. If you’re not, at least consider trying some of them.&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="agile"/></entry><entry><title>How Does DevOps Handle Change Management?</title><link href="https://cmelendeztech.com/posts/2018/01/devops-change-management.html" rel="alternate"/><published>2018-01-11T00:00:00+01:00</published><updated>2018-01-11T00:00:00+01:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2018-01-11:/posts/2018/01/devops-change-management.html</id><summary type="html">&lt;p&gt;Tools today are wonderful. They help ease your task load, letting you get things done with only a few clicks. I remember reading a potential horror story about a developer promoting a change in the database to a production environment. He was trying to add a column to a table …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Tools today are wonderful. They help ease your task load, letting you get things done with only a few clicks. I remember reading a potential horror story about a developer promoting a change in the database to a production environment. He was trying to add a column to a table, and a tool generated the script with a "drop table" statement at the beginning. The developer didn’t notice it because he tested the script locally. Luckily for him, they had a DBA that always reviewed developer’s scripts. When he discovered that the script was going to recreate the table just to add a new column, he reported that back and no data was lost that day. Phew!&lt;/p&gt;
&lt;p&gt;That’s change management (CM), the process by which you can understand why a change is needed and how to minimize risk as much as possible. My first encounter with CM was horrible. I was used to deploying new changes rapidly, without a formal announcement because the team was small. The problem with that was I didn’t have free time; when something was failing, I was the only one who’d know what was causing the problem. And that meant it was me that had to connect remotely and fix it.&lt;/p&gt;
&lt;p&gt;I always thought that CM was only for big companies, not startups. After all, startups have to stay light and lean! But the idea behind CM isn’t to slow down company initiatives. Instead, one of its main purposes is to reduce risk when releasing new changes, which is something everyone, including startups, can use. A key point of CM is to provide documentation. And CM is also about having a human to review, analyze, and approve changes—to make judgments. After all, people are better able to make decisions than computers. CMs aren’t meant to prevent failure, but what if we can automate the things that can be done by a computer? We can have feedback frequently and rapidly, letting us humans take on fewer—and more interesting—decisions.&lt;/p&gt;
&lt;p&gt;With the speed that DevOps brings, it’s only logical to think that more problems will arise and our systems will become riskier. DevOps isn’t meant to supplant CM. In fact, its purpose is to replace the need for human intervention. So CM and DevOps can live together. When we merge speed with less risk, the results are incredible. So how does DevOps handle change management?&lt;/p&gt;
&lt;h2&gt;Treating Changes Differently&lt;/h2&gt;
&lt;p&gt;Not all changes have the same impact. You can’t measure how risky a change is by counting the lines of code modified. It’s so easy for little things to create big problems, like just changing a font color in a web page. For example, ITIL has three type of changes we can use as a base to classify and, based on that, apply DevOps principles. Those changes are standard, normal, and emergency.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;standard change&lt;/strong&gt; is a low-risk change that’s already well known, and it follows a strict procedure. Everyone loves these types of changes.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;normal change&lt;/strong&gt; is, well, normal. You don’t know how risky these changes are; they’re either new or they’re those changes everyone is afraid to make because there’s always a problem with them. For these type of changes, you usually request approval from a change advisory board (CAB). The CAB analyzes it before going live, trying to deduce the impact on the system. Usually, IT Ops would like to avoid these types of changes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Emergency changes&lt;/strong&gt; are those that need immediate attention. You can’t wait for them to go through the formal approval process. Everyone would like to avoid these, but sometimes they’re inevitable.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Having this knowledge as a base, we’ll need to practice making those changes. In the beginning, you won’t have many standard changes. Most of them will be normal changes. But the end goal is to transform normal changes into standard changes by having automation in place.&lt;/p&gt;
&lt;p&gt;DevOps will start treating your changes differently, with the purpose of improving lead time and reducing blockers by introducing automation all the way down. The CAB could reject a change because there’s missing documentation, and a much-needed fix could be delayed because of this. Next time, you can automate this process by automatically filling in the documentation from the user stories, emails, or whatever you use to document requirements.&lt;/p&gt;
&lt;h2&gt;Integrating With Existing Tools and Processes&lt;/h2&gt;
&lt;p&gt;You don’t need to stop doing what you’re currently doing and drop all your existing tools. Hack them. Find a way that blockers stop being blockers. The problem most of the time is lack of documentation and poor communication. You don’t always remember what steps are needed unless you do it all the time. Humans are awful at at repeatable tasks. Seek to have an improved process in which, after the developer pushes a change in the code, all the machinery is triggered and starts creating requests for changes (RFC) and JIRA tickets, sending emails requesting approval with links or summaries, etc. This will leave humans free to do what they’re best at it: applying judgment.&lt;/p&gt;
&lt;p&gt;The main goal is to prove we have everything we need to make the change operate as expected when published—especially when the business hits the “publish” button. The CAB will appreciate all the effort we went to give them enough information and context for a change. And this new automated process will give them all the proof they want to see before releasing a change to the users.&lt;/p&gt;
&lt;h2&gt;Leaving Tracks All the Way Down&lt;/h2&gt;
&lt;p&gt;When you have automation in place, it becomes a trivial task to incorporate audit trails into the pipeline. This brings big benefits. Anyone who wants to can know how much time went into a recent change going live, why it was needed, who approved it, and whether all checkmarks were ticked off in previous steps. For example, the next time an auditor requests evidence that a change followed your process, it’ll just be a matter of following the trail backward. All information will be available. But along with these big benefits come big challenges. That’s especially true when you need to skip the process and make manual changes for an emergency change, for example.&lt;/p&gt;
&lt;h2&gt;Avoiding Manual Changes&lt;/h2&gt;
&lt;p&gt;When you understand this, you’ll gain so much confidence with deployments that you’ll never want to do manual changes again. In a perfect and immutable world, let’s say you eliminate the temptation to implement manual changes by locking down the doors and forcing everyone to avoid SSH’ing to servers. There may still be times when you will need to break the rules, but you’ll want to make that the exception, not the norm, and automate it. Having problems and need to see logs? Go to the log management tool. Running out of space? Ok, fix it. But next time, add an alert and trigger an automated process to increase storage. See? It’s doable.&lt;/p&gt;
&lt;h2&gt;Transporting From Dramatic to Non-Dramatic Changes&lt;/h2&gt;
&lt;p&gt;Now we’ll have enough information to prove that a pipeline is trustworthy. There’s proof that you’ve had fewer incidents with automation. The CAB will start seeing those types of changes as less risky, and less and less human intervention will be needed, even to approve changes. Why? Because to have a solid deployment pipeline, you have to have all types of evolving tests included. There are some companies that will still want to have the approval gate for business purposes (e.g., a change will go live on the announced date, not before).&lt;/p&gt;
&lt;p&gt;The idea is to transport a normal change to a standard change and make emergency changes need less and less human intervention. This will take time, sure. But be patient and seek to have a green-light pipeline most of the time. Make sure that if it goes red, it’s because a test failed and not because there was something wrong with the automation process.&lt;/p&gt;
&lt;h2&gt;Use Your Weapons Wisely&lt;/h2&gt;
&lt;p&gt;All the things that have been blockers—you’ll transform them in a way that makes them easier to live with. (The “aha” moment for me was when I read &lt;a href="https://www.amazon.com/Phoenix-Project-DevOps-Helping-Business/dp/0988262592"&gt;The Phoenix Project&lt;/a&gt;, and I can’t recommend a better book for understanding why CM is needed and how DevOps helped a company escape the hole they dug themselves into.)&lt;/p&gt;
&lt;p&gt;Meanwhile, relax. DevOps is not trying to remove CM. It’s trying to make it more powerful. You can still use your current processes and tools, but you can do it in a more strategic way. Focus on trying to have more standard changes. Start with one—the least problematic one—and prove the theory. ITIL practices have been in IT for quite a long time, and it’s for a reason. Embrace change management, but do it smartly by having an expected and predictable delivery pipeline.&lt;/p&gt;</content><category term="misc"/><category term="devops"/></entry><entry><title>Integrated Security: DevSecOps 101</title><link href="https://cmelendeztech.com/posts/2017/12/integrated-security-devsecops-101.html" rel="alternate"/><published>2017-12-14T00:00:00+01:00</published><updated>2017-12-14T00:00:00+01:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2017-12-14:/posts/2017/12/integrated-security-devsecops-101.html</id><summary type="html">&lt;p&gt;Everyone at some time or another has received an email from a service saying their password has been &lt;a href="https://motherboard.vice.com/en_us/article/78kevq/dropbox-forces-password-resets-after-user-credentials-exposed"&gt;reset&lt;/a&gt; because data was compromised. Security has always been a big topic in IT, and it’s sad that some companies don’t take security as seriously as others. New vulnerabilities are …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Everyone at some time or another has received an email from a service saying their password has been &lt;a href="https://motherboard.vice.com/en_us/article/78kevq/dropbox-forces-password-resets-after-user-credentials-exposed"&gt;reset&lt;/a&gt; because data was compromised. Security has always been a big topic in IT, and it’s sad that some companies don’t take security as seriously as others. New vulnerabilities are found every day, and most of them are discovered long after they’re introduced. Equifax is currently feeling the pain of a breach, and it's a lesson companies should learn from. Luckily, many IT professionals already are thinking ahead about &lt;a href="https://haveibeenpwned.com/"&gt;security&lt;/a&gt;. But we still have things to overcome.&lt;/p&gt;
&lt;p&gt;Part of the problem is that we’re still using traditional methods. We’re thinking about security only at the final stages of the software development lifecycle (SDLC). But security isn’t something you should consider only at the end. Imagine if car manufacturers started considering security after the car had been designed and assembled. It’s too late by then. Now let’s use the same analogy for testing. In order for a change in code to get to the end user, it has to pass through a set of stages. It’s good practice to start testing at the beginning of the lifecycle of the project—not only because you're addressing security before it’s too late but also because it’s cheaper.&lt;/p&gt;
&lt;p&gt;Just think of it. An application is ready to go live, and we just need to make sure it’s secure. Boom! The potential for a breach was found during testing, and it needs to get fixed in the code. This forces you to start all over again. That change in code needs to be validated to make sure it doesn’t break any existing functionality, meaning the end user will have to wait longer to get the fix or new feature in his/her hand.&lt;/p&gt;
&lt;p&gt;There are other problems, too. What about the frustration of the application needing to be scanned just before the deployment? The security team can become a bottleneck. As the &lt;a href="http://agilemanifesto.org/"&gt;Agile Manifesto’s&lt;/a&gt; first principle says, “Individuals and interactions over processes and tools.” It’s more about a cultural change than just acquiring new tools to make apps more secure. It’s not enough to have leverage only on firewalls. We'll get better results when, instead of being a bottleneck in the process, we work with the team to make security everyone's responsibility. And that’s where &lt;strong&gt;de&lt;/strong&gt;velopment, &lt;strong&gt;sec&lt;/strong&gt;urity, and &lt;strong&gt;op&lt;/strong&gt;eration&lt;strong&gt;s&lt;/strong&gt; (DevSecOps) combine.&lt;/p&gt;
&lt;p&gt;DevSecOps. It’s about feedback and a blameless culture. How will security teams know that someone found a hole in the app’s security? Well, the Ops team is good at this. They can provide the needed feedback by collecting metrics and reviewing logs. This same information can be shared with the development team so they can apply patches in the code.&lt;/p&gt;
&lt;p&gt;Some say that DevSecOps is just a new buzzword. Others say that DevOps and DevSecOps are the same thing. In the end, the name doesn’t matter much. What matters is the intention to shift security to the left of the cycle.&lt;/p&gt;
&lt;p&gt;To help move that shift along, let’s explore several topics worth seeing in more detail.&lt;/p&gt;
&lt;h1&gt;Security As Code&lt;/h1&gt;
&lt;p&gt;In order to innovate by pushing new changes in a timely manner and at the same time minimize risk, we need to pay attention to security right from the beginning. This becomes a no-brainer when you start treating your infrastructure as code (IaC). Think of security as code, like the test cases you’ll be running against the IaC. But don’t stop there. There are some tools out there that perform static application security testing (SAST) and dynamic application security testing (DAST) on the code, and they can help you go the extra mile.&lt;/p&gt;
&lt;p&gt;SAST analyzes the source code by looking for common vulnerabilities—and it does this without needing the application to run. It won’t catch all problems, but it certainly reduces the attack surface. It’s a white-box testing methodology, testing from the inside out. In this regard, it’s similar to unit testing.&lt;/p&gt;
&lt;p&gt;DAST covers scenarios by acting as if it was an external user. It runs against the real application, similar to integration tests. It’s a black-box testing methodology and tests from the outside. When you implement this type of testing in the SDLC, you’re making sure that, for example, SQL injections are not possible or that sensitive information is not being exposed to the end user. You’re also controlling what the user is able to see when there’s a managed and/or unmanaged exception in the code.&lt;/p&gt;
&lt;p&gt;How much test coverage will you be able to get for on-premises? That will depend on if there’s an API you can use to interact with your infrastructure’s security. In the cloud, this can be achieved easily, as every interaction is done through APIs. You can run common checks, like seeing if the SSH port is open to the world, if some servers are in a private network, and if secrets are encrypted, among other things. Basically, you’ll need to make sure you’re giving least privilege and granular access to resources.&lt;/p&gt;
&lt;h1&gt;Injecting Failure Continuously&lt;/h1&gt;
&lt;p&gt;The only way you become better at something is by practicing. No matter how hard or painful it is, you have to do it. It’s just like when you were learning to ride a bike. We need to inject failure into our systems. The best example of this is the well-known &lt;a href="https://github.com/Netflix/SimianArmy"&gt;Simian Army&lt;/a&gt; by Netflix, with its &lt;a href="https://github.com/Netflix/security_monkey"&gt;security monkey&lt;/a&gt; that’s constantly watching the state of the app’s security.&lt;/p&gt;
&lt;p&gt;Don’t chase a final state for security. You can’t make security a project that has an end date. It never ends. New security holes are found every day, so it doesn’t make sense to stop thinking about how our apps can be protected if hackers are constantly trying to find new breaches. Vulnerability scans are not enough in today’s world; consider doing penetration tests as well, which can be performed as soon as you start development. Having exploit testing can bring many benefits. Instead of just relying on security scans, you’re actively monitoring.&lt;/p&gt;
&lt;p&gt;Make use of the information you already have at hand and take actions based on the valuable information you can get from logs. All types of logs. Use log management tools like Splunk or the famous ELK (Elasticsearch + Logstash + Kibana). Gone are the days when you download logs from the servers and analyze them. Thanks to the cloud, it’s common to constantly generate new servers when something happens or when implementing blue/green deployments. You can’t afford to lose the last known state of a server. It can be your chance to find new ways to protect your application or see what the attack did.&lt;/p&gt;
&lt;h1&gt;Automate to Improve Agility&lt;/h1&gt;
&lt;p&gt;The time you take to react when a new vulnerability is found is crucial—especially if you have hundreds of servers (or containers). You need to act rapidly or be ready to face the consequences. You can take the approach of patching each and every server, as normal operations would. But if you’re using immutable infrastructure, you just need to create a new version with the patch applied and replace all servers. This is accomplished when you treat your infrastructure as code. There’s no better way to react in a consistent and predictable manner than with automation.&lt;/p&gt;
&lt;p&gt;You can even protect yourself automatically when an attack is taking place. There’s an excellent example of this that I always like to present when talking about the value of automated protection. A site was constantly having DDoS attacks, and in order to remediate this, the administrator temporarily blocked the attacker’s IP addresses with &lt;a href="https://www.troyhunt.com/azure-functions-in-practice/"&gt;Azure Functions&lt;/a&gt;. After some time, those IPs were again whitelisted, but the administrator was constantly monitoring the process. In other words, he was applying automation that he was actively supervising.&lt;/p&gt;
&lt;p&gt;You can also use AWS Lambda functions to act based on API calls. For example, you can set up an alarm that will alert your team when a security group (like a firewall) changes. This is what the security monkey mentioned above does. You can even get to the point that if something changes in a way that’s outside of your defined parameters, you can revert it. That’s taking security to the next level.&lt;/p&gt;
&lt;h1&gt;Self-Service Reviews&lt;/h1&gt;
&lt;p&gt;Anyone should be able to see the state of security—especially auditors. It’s pretty common for them to request a static snapshot of an app’s security status, but that isn’t a very useful way to demonstrate that you’re applying security practices. This is like a picture. You always see the same thing when you look at it. Plus, it’s taking up someone’s valuable time, as they construct these boring reports. Even recording a video of how security checks are being performed limits you. You’re just watching a recorded period of time, with no idea what’s happening outside that window. And it’s still wasting someone's time. I was pretty disappointed when an auditor requested I simply send a set of screenshots of password policies, active users, groups, and roles for a certain tool. And easily-manipulated image files shouldn’t be the only source of information, should they? In this circumstance, the phrase “trust but verify” makes a lot of sense to me.&lt;/p&gt;
&lt;p&gt;Why don’t you instead invest some time in creating the building blocks that make security visible to anyone? When auditors come around again and start asking you about security, you can just give them access to whatever tool you built and make them do the reviews themselves. This time, we’re not wasting people’s work hours, and we’re gaining so much. We’re demonstrating that security is important to us and that we’re practicing it constantly. And our report becomes more credible because it’s not subject to human error or fraud, intentional or unintentional.&lt;/p&gt;
&lt;h1&gt;Security Is Everyone's Responsibility&lt;/h1&gt;
&lt;p&gt;This is not just about a person or a team. We’ve already learned that isolating development and operations brings conflict. Don’t make the same mistake with an aspect of your application as important as security. DevSecOps is not introducing a new concept. It’s just making the point that we need to think about security for more than just a moment during development. It’s something that we should think about every day, and it’s everyone’s responsibility. It’s about collaboration. And it means that you can’t afford to have a finger-pointing culture, where everyone’s trying save his/her own skin. We all make mistakes, but having a team that supports you makes all the difference. This mindset is an enabler of experimentation, and that opens the door to innovation.&lt;/p&gt;
&lt;p&gt;In the end, if you’re going to take away anything from this post, let it be this. Leverage automation to ensure your applications are secure, and act rapidly when there are potential breaches that could affect you.&lt;/p&gt;
&lt;p&gt;Want to know more? Check out the DevSecOps &lt;a href="http://www.devsecops.org/"&gt;manifesto&lt;/a&gt; and &lt;a href="https://github.com/devsecops/awesome-devsecops"&gt;this&lt;/a&gt; awesome content list in GitHub full of links to tutorials, videos, tools, and more.&lt;/p&gt;</content><category term="misc"/><category term="devops"/><category term="devsecops"/><category term="security"/></entry><entry><title>The Business Case for Container Technology</title><link href="https://cmelendeztech.com/posts/2017/12/business-case-for-container-technology.html" rel="alternate"/><published>2017-12-07T00:00:00+01:00</published><updated>2017-12-07T00:00:00+01:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2017-12-07:/posts/2017/12/business-case-for-container-technology.html</id><summary type="html">&lt;p&gt;When you see the word “containers”, you probably immediately think of Docker. But containers are not a new concept. It dates back to Linux-VServer, initially released in &lt;a href="http://www.solucorp.qc.ca/changes.hc?projet=vserver"&gt;2001&lt;/a&gt;. Then in 2008, containers improved with the release of the Linux Container Project (LXC). &lt;a href="https://www.docker.com/"&gt;Docker&lt;/a&gt; came along in 2013, making things easier …&lt;/p&gt;</summary><content type="html">&lt;p&gt;When you see the word “containers”, you probably immediately think of Docker. But containers are not a new concept. It dates back to Linux-VServer, initially released in &lt;a href="http://www.solucorp.qc.ca/changes.hc?projet=vserver"&gt;2001&lt;/a&gt;. Then in 2008, containers improved with the release of the Linux Container Project (LXC). &lt;a href="https://www.docker.com/"&gt;Docker&lt;/a&gt; came along in 2013, making things easier by using the command line interface to interact with LXC. But you didn’t come here for a history lesson. Even though “container” seems to be a buzzword right now, as you can see, they’re not something new. They've been around for about sixteen years now. And Docker isn't the only container technology, either. There are other projects in the container ecosystem. And &lt;a href="https://coreos.com/rkt/"&gt;rkt&lt;/a&gt; (another flavor) makes a good comparison on its &lt;a href="https://coreos.com/rkt/docs/latest/rkt-vs-other-projects.html"&gt;site&lt;/a&gt;.                           &lt;/p&gt;
&lt;p&gt;I also won’t give you the vendor speech about containers—I’m not a salesman. But let me tell you something: if you want portability, efficiency, and security for your applications, you should consider using containers. With containers, you can deploy the same code through all environments, without any modifications. You can make your database endpoint configurable so that it’s just a matter of configuring it for the environment in which you’d like to run the app. It can be on your computer, in the cloud, on a virtual machine, on bare metal or a mix of everything.&lt;/p&gt;
&lt;p&gt;Before we dive in, you should know that containers are not a silver bullet. Using them requires a change in culture, not just in code. (In fact, you might not even need to change the code). But make sure you’re clear on all the benefits and requirements before adopting the container approach. Don't do it just because everybody is doing it. All that being said, let’s look at the business case for containers. This should give you a clear idea of where and why you’d use containers.&lt;/p&gt;
&lt;h2&gt;Portability as First-Class Citizen&lt;/h2&gt;
&lt;p&gt;One of the first things you’ll hear about containers is that they don't only work on your machine but also on others' machines. You can easily recover from a disaster and move your environment to another place—from on-prem to the cloud or from one cloud provider to another. You avoid vendor lock-in. Your application will continue working, guaranteed…or at least it will work as long as you make sure all dependencies are in place too, as with databases.&lt;/p&gt;
&lt;p&gt;You can also reduce risk by repetition. By the time you’re ready to deploy to production, you’ve proven that the code works by testing it in familiar environments. It doesn’t matter if you don’t have automation in place; you’re just moving the container from one place to another. How can this be achieved, you might be wondering? Well, since you’re isolating the application in its own environment, you can make use of environment variables. That means making it behave differently is just a matter of how you run the container and what values you use.&lt;/p&gt;
&lt;p&gt;You can pass a list of values to your container, like calling a parameterized function in code. Or you can use just one value to define the environment and then have the app grab the values it needs from another location. The compiled code inside the container will remain the same regardless. This way, you’re gaining consistency. You can increase the level of trust because your containers are completely isolated one from another, and they're especially isolated from the host. Gone are the days when you need to reboot a server because your app is having problems. Now, if you’re having issues with your app, you just kill the bad container and create another fresh one in seconds.&lt;/p&gt;
&lt;h2&gt;Be More Responsive to Change&lt;/h2&gt;
&lt;p&gt;How much time do you need to take your application code from a developer machine to a production server? How many validations in different environments do you need to perform before saying, “It’s ready to go"? And how many people are involved in that process? How many manual interventions need to happen? If the answer to these questions is “a lot”, start tracking how much time you actually invest in moving your code around, as opposed to developing new features. In the end, if you’re not an infrastructure company, you shouldn't need to bother with these activities. Make your life easier.&lt;/p&gt;
&lt;p&gt;With containers, you focus on what’s important: providing value to customers. That means less time spent debugging problems and more time spent delivering useful features. When you pack your application code in a container with all its dependencies, you can iterate faster. That’s because you know the code will work in all environments. And you know the build won't fail before going to production since you only have to build once to deploy many times. You’ll get to the point where you won’t be adding more external dependencies or environment configurations. And finally, you'll make more changes in code than anywhere else. See? Fewer and fewer infrastructure headaches.&lt;/p&gt;
&lt;p&gt;One of the nice things about packing the application code and its dependencies is that you can use versioning. Instead of modifying an existing version, you create a new one. It’s making your container immutable by going forward, not backward. But what if something’s wrong with the new release? If you’re practicing continuous integration, you’ll stop everything, make the correction, and deploy again. In the meantime, just use the previous container version image and deploy again to avoid any interruptions. But you have to be able to do this fast. Another way to do this is to just turn off a feature by changing the configuration (a.k.a. feature flags) and then deploy again.&lt;/p&gt;
&lt;h2&gt;It Can Be Adopted to Legacy Systems&lt;/h2&gt;
&lt;p&gt;Maybe you’re thinking that when you adopt containers, you’ll have to make big changes. Or maybe you think you’ll have to adopt a microservices architecture. Save those worries for later because they’re not valid in this case. Don’t believe me? I don’t blame you—I bet you’re thinking of that Windows service you’ve been running forever. Or maybe you’re thinking of that old app that you don't even dare to look at, let alone touch.&lt;/p&gt;
&lt;p&gt;If that Windows case sounds familiar, there’s a Powershell module called &lt;a href="https://github.com/docker/communitytools-image2docker-win"&gt;Image2Docker&lt;/a&gt; where you’ll be porting your application using Docker without making any changes. Is your issue not a Windows one? Don’t worry, Docker likes challenges. They have a program called “Modernize Traditional Applications” (&lt;a href="https://blog.docker.com/2017/04/modernizing-traditional-apps-with-docker/"&gt;MTA&lt;/a&gt;). It won’t force you to modify the code or make other application changes. And the folks at Docker guarantee that they’ll help you in less than five days. If they need more time, it means things will need to be added to the platform.&lt;/p&gt;
&lt;h2&gt;Make Better Use of Infrastructure&lt;/h2&gt;
&lt;p&gt;All enterprises like to reduce cost, whether it be through cutting waste like idle resources or making sure servers aren’t overprovisioned. The cloud gives you a set of server types with predefined characteristics for memory, CPU, and networking. This means you’re more likely to overprovision resources. In the case of on-premises, the chances of idle resources increase. You have to plan ahead of time. But with containers, if you need more capacity, you just spin up more containers on the same host. You don’t have to worry about more infrastructure. Just make sure you have enough resources available. A good, simple example of this is the AWS service called ECS. In ECS, you configure your auto-scaling policies with the "reservation capacity” metric. It doesn’t really matter how many resources you use but rather how much you reserve. In the end, resource usage will serve as a metric to add more containers, whereas reserved capacity will be used to add more hosts.&lt;/p&gt;
&lt;p&gt;Maybe you won’t see big savings at the beginning, but you’ll see a real benefit when you’re in need of scaling. Instead of adding big servers, you can have small servers and add just the blocks you need, little by little. On the other hand, without containers, you might need to buy the same size of server (on-prem or cloud) because that’s the capacity your app is currently needing. But you won’t be able to use all resources, leading to waste.&lt;/p&gt;
&lt;p&gt;You might be asking yourself, “Aren’t we making things more complex?” Maybe. But for the example of on-prem environments, are VMs getting recycled when the app isn’t behaving well? No. At least not automatically. In the cloud, you have self-recovery built in, but on-premises, you need to manage that by yourself. If you’re using vSphere, for example, you can rest assured that if something goes wrong with the host, that VM will be moved quickly to another one without any downtime. That’s cool. But what if the host is OK? What if the VM is OK? What if the problem is inside the application because it’s using so many resources? In vSphere, you &lt;a href="https://blogs.vmware.com/management/2017/06/configure-auto-scaling-private-cloud.html"&gt;do have the ability to auto-scale&lt;/a&gt;, but it’s not something that comes built in, sadly.&lt;/p&gt;
&lt;h2&gt;Increase Security for Your Applications&lt;/h2&gt;
&lt;p&gt;People sometimes talk negatively about containers’ security. After all, if you have access to the host, you can inspect and log in to any container easily. But as the industry learns more about containers, that perception is rightly starting to change. This doesn’t mean that you won’t need to worry anymore about security in your applications (for example, in SQL injections). It means that if for some reason, the attacker is able to gain access to the container, you can limit the damage that can be done. This is thanks to the fact that containers can work with only what’s needed. You don’t need to have all OS capabilities inside a container unless you specifically need it.&lt;/p&gt;
&lt;p&gt;For this reason, Docker recently launched a program that certifies images. If an image is certified, it means it’s been tested, it’s implementing best practices, and it doesn’t include common vulnerabilities. It’s also supported by Docker and the provider. So unless you can run a security &lt;a href="https://docs.docker.com/docker-cloud/builds/image-scan/"&gt;scan&lt;/a&gt;, don’t use other people’s images, and you should be good on that front.&lt;/p&gt;
&lt;p&gt;If for some reason an attacker gains access to the container, the attack surface is limited. That’s because, in Docker, containers run in an unprivileged way by default. Why is this important? Well, if that weren’t true, the attacker could gain root privileges and infect the host or other containers. But now, you don’t have to worry about that.&lt;/p&gt;
&lt;p&gt;Containers are also isolated thanks to namespaces in Linux. You can reserve a certain capacity (memory and CPU) to containers thanks to cgroups. This means you have a truly isolated environment for containers. It doesn’t matter if one container uses all its resources. It won’t affect the rest of containers and, more significantly, it won’t affect the host. (By default, Docker terminates the container if it uses 100 percent of memory.) Next time you see that something bad is happening to a container, you can just kill it and create another one. And again, you can do this in seconds. Want to know more? Take a look at this great security cheat sheet &lt;a href="http://container-solutions.com/docker-security-cheat-sheet/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Container Adoption is Increasing Rapidly&lt;/h2&gt;
&lt;p&gt;The adoption of containers is finally starting to grow. More enterprises are signing on for the adventure. You can check out a great study from &lt;a href="https://www.datadoghq.com/docker-adoption/"&gt;Datadog&lt;/a&gt; to get a better idea of how Docker adoption works. What’s interesting from that report is that large companies are the ones adopting containers. More and more tools are being released, and they’re being released frequently. Container vendors are also providing enterprise editions to companies that care about core features: portability, efficiency, and security. For example, Docker is offering an &lt;a href="https://www.docker.com/docker-news-and-press/docker-launches-new-enterprise-edition-accelerate-business-critical"&gt;enterprise edition&lt;/a&gt;. CoreOS has an enterprise-ready Kubernetes called &lt;a href="https://coreos.com/tectonic/"&gt;Tectonic&lt;/a&gt;. Red Hat offers &lt;a href="https://www.openshift.com/container-platform/"&gt;OpenShift&lt;/a&gt;. There’s also &lt;a href="http://rancher.com/"&gt;Rancher&lt;/a&gt;, and Hashicorp has &lt;a href="https://www.hashicorp.com/products/nomad/"&gt;Nomad&lt;/a&gt;. That offering list is growing, and I just named a few.&lt;/p&gt;
&lt;p&gt;So if you thought that containers were the new kids on the block, think twice. Maybe it’s time to modernize your application by using containers because containers are not the future: they are the present.&lt;/p&gt;</content><category term="misc"/><category term="containers"/><category term="docker"/><category term="devops"/></entry><entry><title>Infrastructure as Code (IaC): The Benefits</title><link href="https://cmelendeztech.com/posts/2017/12/infrastructure-as-code-the-benefits.html" rel="alternate"/><published>2017-12-01T00:00:00+01:00</published><updated>2017-12-01T00:00:00+01:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2017-12-01:/posts/2017/12/infrastructure-as-code-the-benefits.html</id><summary type="html">&lt;p&gt;When pushing application code changes to any environment, one of the most common problems you’ll encounter is that servers aren’t configured properly. How many of us have faced not having the same exact version of a dependency across all environments? I’d say everyone. When our application is …&lt;/p&gt;</summary><content type="html">&lt;p&gt;When pushing application code changes to any environment, one of the most common problems you’ll encounter is that servers aren’t configured properly. How many of us have faced not having the same exact version of a dependency across all environments? I’d say everyone. When our application is failing and we’re in a rush, we tend to log into the server, find the error, and apply the fix. This might not be seen as a big problem. But when the same problem arises in another environment and we don’t remember what we did to fix it, it is a big problem. Sound familiar?&lt;/p&gt;
&lt;p&gt;We humans often forget things, especially when it only caused us a small amount of pain. But we’ll never forget what we did wrong when we brought down a production application. The struggle at that moment is horrible; it’s sometimes traumatic. Maybe that’s one of the reasons we usually have a set of scripts and commands that take the risk of human error down a notch. There’s a ton of information out there on how to install and configure helpful services, like an Nginx server. The blog posts and articles that provide this information give a recipe of steps we need to follow, and those become our scripts.&lt;/p&gt;
&lt;p&gt;Nowadays, not only could you install and configure services but you could also do so for infrastructure. This mostly applies to cloud applications, but that doesn't mean it can't be done for your on-premise infrastructure. You can spin up a set of servers in minutes by just running a command or making an API call. Here’s where the term “infrastructure as code” (IaC) enters the game. IaC means you have cookbooks to help you manage and provision infrastructure in a consistent manner. You no longer have to remember which buttons to click or which commands to run in order to get an environment up and running. When you take this approach, several benefits come included.&lt;/p&gt;
&lt;h2&gt;Treat Infrastructure Like Application Code&lt;/h2&gt;
&lt;p&gt;When you treat your infrastructure like your application code, you can be  confident that the infrastructure’s file definition won’t get lost easily. Why? Because, as with your application code, you’ll store this file in a version control system. And you’ll enjoy additional perks like change history, ease in rolling back changes, redundant storage, and one source of truth, among others.&lt;/p&gt;
&lt;p&gt;When you implement IaC, gone are the days when you made manual changes to the server so the application worked. You and your team will get used to having an automated way of making changes to servers. Every change will be made in the infrastructure definition file. As for what language you’ll be working with, it can be any descriptive language. The most common language is YAML.&lt;/p&gt;
&lt;p&gt;Every time you need to make a patch to the server, you’ll define that change in code. A good example of this is Dockerfiles. All the dependencies that the container will need to run the application are defined in the Dockerfile. There, you’ll place the exact same commands you’ll run: say, for example, updating the packages repository and then installing a specific version of the package.&lt;/p&gt;
&lt;p&gt;As you do with code, you can deliver small changes frequently. This helps to increase the speed of deployments. According to several &lt;a href="http://toc.oreilly.com/2008/06/release-early-release-often-ag.html"&gt;reports&lt;/a&gt;, you reduce risk by releasing small changes frequently. Fail fast, fail often. If it’s hard to do, do it more frequently so you can become better at it. When you start implementing IaC, you might feel like it’s not for you. But just keep doing it until you get it right because you’ll eliminate the lack of knowledge about what’s installed and how it’s configured.&lt;/p&gt;
&lt;h2&gt;Same Code for All Environments&lt;/h2&gt;
&lt;p&gt;I know. The first thing you’re going to tell me is, “Production environments are way different than development environments—and more expensive, also.” But when you define your IaC in a way that lets you control the resources you assign or how many replicas you want, it’s possible to have a small version of the infrastructure for development and a bigger one for production. Environments then become similar.&lt;/p&gt;
&lt;p&gt;IaC is not just about provisioning; it’s also about configuration management. You’re reducing the chance of misconfigurations in the application. All the values that are different in each environment will be under version control. Of course, this presents an interesting challenge because you wouldn't put sensitive information like passwords there. The most common approach here is to use encryption or make use of environment variables where only certain people have access, like your Ops team.&lt;/p&gt;
&lt;p&gt;If you embrace end-to-end automation in your delivery pipeline, you’ll be promoting changes from one environment to another. In order to take full advantage of this, you shouldn’t allow yourself or your team to make any manual changes that weren’t tested in a different environment first. By testing first, you’re minimizing the chances of introducing instability and differences into each environment. &lt;/p&gt;
&lt;h2&gt;Anyone Can Build an Environment Anytime&lt;/h2&gt;
&lt;p&gt;If you have the code and the proper access, you’ll be able to spin up a similar environment from production. You don’t need to bother operations anymore. Imagine that! Maybe you just need to experiment with the newest version of a dependency of the server. You wouldn’t want to interrupt your team if you break something in the environment.&lt;/p&gt;
&lt;p&gt;By implementing IaC, you’re able to have disposable and immutable infrastructure. Instead of making a change to the current servers, you’re replacing them with a new version built from your file definition. No more hidden or surprise changes to the environment. If something is broken by a recent change, you can always go back to a previous version and rebuild the environment. That’s the beauty of IaC.&lt;/p&gt;
&lt;h2&gt;Validate Infrastructure Before Deployment&lt;/h2&gt;
&lt;p&gt;When I said, “treat infrastructure like application code,” I meant it. The cloud came to revolutionize the way we thought about infrastructure. In the past, you didn’t have to worry about paying more money because you left-turned on a server for several hours. But when you’re in the cloud, you pay for every hour, minute, and even second the server is on. So instead of considering this a drawback, the industry found new ways to protect the budget. I myself had to deal with this problem. When I was developing the scripts to spin up instances and something went wrong, I had to pay for the fragment that instance ran. I needed to be very sure that my script was doing what I wanted. &lt;/p&gt;
&lt;p&gt;That’s the reason you can even create &lt;a href="https://github.com/spulec/moto"&gt;unit tests&lt;/a&gt; for your infrastructure code. It’s also possible to do static code analysis (linting)—that will help you prevent some obvious problems. And as if that weren’t enough, you can also plan the changes your script will perform so you can preview how the infrastructure will look. It’s a pretty common feature in &lt;a href="https://www.terraform.io/docs/commands/plan.html"&gt;Terraform&lt;/a&gt;, and it was recently introduced in &lt;a href="https://aws.amazon.com/blogs/aws/new-change-sets-for-aws-cloudformation/"&gt;AWS CloudFormation&lt;/a&gt;. When the infrastructure is ready, you can also check that it’s properly configured by running some &lt;a href="http://serverspec.org/"&gt;Serverspec&lt;/a&gt; tests. Could you ever have imagined these kinds of features with your infrastructure? I didn’t.&lt;/p&gt;
&lt;h2&gt;Always Know What Changed&lt;/h2&gt;
&lt;p&gt;You can keep track of all changes made to the infrastructure because you defined each one in a file. If you respect this rule, when something goes wrong in the deployment and you don’t know why, you can always check the history, revert, and rebuild.&lt;/p&gt;
&lt;p&gt;Tracking your changes is also useful for compliance reasons. Auditors love to see that an organization keeps track of how a change went from one environment to another. When was the change done? Who made the change? Who approved the changed? Is there a separation of duties in place? What’s awesome about IaC and DevOps is that you can tell them that you closed all doors and the only way to promote changes is through code. Plus, it’s automated. No human intervention needed.&lt;/p&gt;
&lt;h2&gt;IaC Will Put a Smile on Your Face&lt;/h2&gt;
&lt;p&gt;If you decide to go with IaC, you’ll be setting the foundation for a consistent and automated delivery pipeline for your applications. Your entire team will always know how the application is architected at the infrastructure level because now they’ll have a standard language. Anyone can make suggestions or apply fixes. If you’d like to restrict who’s pushing the changes, you can protect the master branch and limit the merge only to the Ops team, for example.&lt;/p&gt;
&lt;p&gt;Developers can play around with similar infrastructure-as-test or prod before pushing application code changes. You can apply some proven practices from the development world to Ops. And there’s one last important aspect: you’ll provision and configure your infrastructure in the most elegant way possible through code. So it’s time to give some formality to those valuable scripts you always use and start implementing IaC.&lt;/p&gt;</content><category term="misc"/><category term="iac"/><category term="devops"/></entry><entry><title>Why Is Jenkins Good for Dev Teams?</title><link href="https://cmelendeztech.com/posts/2017/11/why-is-jenkins-good-for-dev-teams.html" rel="alternate"/><published>2017-11-22T00:00:00+01:00</published><updated>2017-11-22T00:00:00+01:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2017-11-22:/posts/2017/11/why-is-jenkins-good-for-dev-teams.html</id><summary type="html">&lt;p&gt;Some time ago, a new product demanded a lot of attention and manpower. Many of my fellow team members were taken off our project and diverted to this new one. That left us pretty shorthanded. In my primary role as developer, things were looking to get quite interesting. I didn …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Some time ago, a new product demanded a lot of attention and manpower. Many of my fellow team members were taken off our project and diverted to this new one. That left us pretty shorthanded. In my primary role as developer, things were looking to get quite interesting. I didn’t just have to worry about getting my changes ready; I also had to make sure those changes were in a production environment. I didn’t have any DevOps knowledge at the time (it didn’t even exist then, in 2008 or so), and I also thought that the project would end quickly. Silly me. My way of promoting our team’s changes was using a basic flow: build, copy and paste. And as I’m sure you know, many things can go wrong when we add any human intervention to the process.&lt;/p&gt;
&lt;h2&gt;We Learned the Wrong Way&lt;/h2&gt;
&lt;p&gt;There’s a funny anecdote from the days of this project, and those of us who were involved always joke about it. Here’s the story. We only had one operations guy when the company started. The number of applications kept increasing, and he couldn’t give our team’s application the attention it deserved. We decided to help him out by documenting the manual process we had for deployments (yes, again, manually), and it worked very well for the dev team. But we discovered that it was because we knew better than anyone how the application worked.&lt;/p&gt;
&lt;p&gt;A new operations guy joined, and we told him we already had some documentation for our deployments and he just needed to follow the recipe. One day, there was a need to do an emergency deployment, and only the Ops team was still in the office (so convenient). Deployment started. Everything was going well...until they started receiving emails, SMSs, and calls reporting that the system was down. The OPs team, in accordance with the protocol for problems like this, called the lead developer for help.&lt;/p&gt;
&lt;p&gt;When the lead developer arrived, he started reading all the error messages and discovered the problem. He fixed it right away, and errors stopped coming. What went wrong? Ops guy skipped a very important step in the recipe. Even though we had the most elaborate document explaining how to do deployments, we failed because we introduced human intervention to the process. But we knew there was something better: we had heard about Jenkins.&lt;/p&gt;
&lt;p&gt;Jenkins is an open-source platform that started in 2004, and it’s maintained mainly by &lt;a href="https://www.cloudbees.com/"&gt;CloudBees&lt;/a&gt;. (The GitHub repo is located at &lt;a href="https://github.com/jenkinsci/jenkins"&gt;https://github.com/jenkinsci/jenkins&lt;/a&gt;) It’s an automation server that’s most commonly used with builds, but it can also  automate a wide variety of tasks. It supports all common version control tools like Git, and the functionality can be extended with plugins. You can configure it to be automatically triggered by a push in Git or schedule it via a cron-like mechanism. &lt;/p&gt;
&lt;h2&gt;It’s the Easiest Way to Start&lt;/h2&gt;
&lt;p&gt;We already had some automation scripts for deployments. The part we were missing was something to keep running them in the proper order. With Jenkins, it doesn’t matter what OS or language you’re using. It runs in Linux and Windows, and you can plug in any tool you need. Jenkins is written in Java, so the only prerequisite is to have Java installed. (You can download the Jenkins installer here: &lt;a href="https://jenkins.io/download/"&gt;https://jenkins.io/download/&lt;/a&gt;) &lt;/p&gt;
&lt;p&gt;You can start with a very simple job, which is a task or step in your process. You can start off with only one job, but the recommendation is to have multiple jobs (e.g., one for each script) so you can identify problems very easily and avoid having to start over again every time something fails in the process.&lt;/p&gt;
&lt;p&gt;The very first thing you need to do to start taking full advantage to Jenkins is to document the set of steps you perform every time you need to deploy something. List the servers that you have for each environment, your source code repositories, and all the dependencies for your application to work. By doing this, you’ll identify what tools are going to be needed on the Jenkins server, what accesses or permissions are needed for your jobs, etc.&lt;/p&gt;
&lt;h2&gt;You Can Do Almost Everything&lt;/h2&gt;
&lt;p&gt;After installing Jenkins on your dedicated server, you can start installing everything you need. The Jenkins installation can be architected to have a master that can be used to authenticate users, manage security and permissions, and create the folder structure that you’ll need for your different application jobs. Because you might have different types of technologies, you’re better off having one Jenkins agent connected to the master for every line of business or every different stack (e.g., Windows for .NET or Linux for Java). &lt;/p&gt;
&lt;p&gt;In order to have a Jenkins agent, you simply need to have Jenkins installed on the server and then register it to the master. The agent must have all the dependencies needed to execute the jobs you’ll choose for it (e.g., Git, Java, etc.). By doing this type of configuration, you enable your team to automate applications that have different versions of a stack (e.g., Java 7 and 8). When this configuration is ready, you’re able to choose where the Jenkins job will run.&lt;/p&gt;
&lt;p&gt;Be aware that, as of the time of writing this article, there are 1,403 plugins that you can install on your Jenkins server. The Jenkins installation comes only with the essentials: a minimum set of plugins. But you’ll need to install extra plugins if you want to do things like notify the team via email or Slack about the status of any job, build .NET applications, use your cloud provider, and much more. (You can find all plugins you’ll need here: &lt;a href="https://plugins.jenkins.io/"&gt;https://plugins.jenkins.io/&lt;/a&gt;) There are so many at your disposal that, when I need to automate anything, I’ll joke that “there must be already a Jenkins plugin for this.” &lt;/p&gt;
&lt;h2&gt;Improve Time to Deploy to Any Environment&lt;/h2&gt;
&lt;p&gt;It’s every developer’s dream to push code and get it to production without any suffering. Deploying to any environment, mostly to production, should be a boring activity. It takes time to get there, but it’s possible. When you understand that our main goal as developers is to provide value to the company, you’ll start focusing on what’s adding that value: the code. We all have witnessed and lived the pain of integrating everyone’s changes into code and pushing them to production. It can be avoided.&lt;/p&gt;
&lt;p&gt;We live in a world of constant change where, if you don’t adapt, you die. Improving the speed and the frequency of pushing new changes to your users is a major determinant for success. Say you just pushed something that’s affecting your users. How fast can you react to that? Do you have an easy, fast, and reliable way of reverting or pushing a new change? Jenkins can help you respond favorably to these questions. &lt;/p&gt;
&lt;p&gt;Of course, Jenkins by itself won’t solve all your problems. For example, you’ll always need a set of automated tests—like unit tests, integration tests, and smoke tests—to assure that you don’t expose your users to bugs..&lt;/p&gt;
&lt;h2&gt;Consistency and Repetition&lt;/h2&gt;
&lt;p&gt;One of the best ways to avoid downtime in production is to avoid pushing new changes. Many things can go wrong with servers. There can be CPU spikes, memory leaks, storage capacity—all sorts of things. But nothing compares to getting live new features or fixes. When you have a consistent and repeatable way of doing things, you minimize the risk.&lt;/p&gt;
&lt;p&gt;With Jenkins, you can script all your deployment pipelines by using theirs instead. The Jenkins pipeline is a set of plugins that help you to have your delivery pipeline as code. It enables you to keep everything scripted and easy to review when something new is needed. It also gives you the confidence that comes with knowing that it doesn’t matter if someone made a change to a Jenkins job; you’ll always get the latest version from your source control. Almost the same way you treat code, right? This will be the first step to start practicing continuous delivery.&lt;/p&gt;
&lt;h2&gt;There’s No Excuse Not to Automate Deployments&lt;/h2&gt;
&lt;p&gt;Once you have an automated, consistent, repeatable, and reliable way of changing things in code, you and your team can focus on what’s really important: providing value. Jenkins is only the tool you’ll need to have a graphic representation of your deployment workflow, so you can visualize how your team pushes updates to end users. Check out &lt;a href="https://jenkins.io/"&gt;Jenkins&lt;/a&gt; and start coding your delivery pipeline, too. You don’t want to keep banging your head against the wall when something goes wrong in production. When we humans know that we’re causing damage, we tend to freak out and lose common sense. On the other hand, machines will keep doing what you told them to do. That’s where Jenkins is helpful.&lt;/p&gt;</content><category term="misc"/><category term="developers"/><category term="jenkins"/><category term="devops"/></entry><entry><title>My First Bot with Microsoft Bot Framework in .NET and Xamarin</title><link href="https://cmelendeztech.com/posts/2017/08/my-first-bot-with-microsoft-bot-framework-in-dotnet-and-xamarin.html" rel="alternate"/><published>2017-08-01T00:00:00+02:00</published><updated>2017-08-01T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2017-08-01:/posts/2017/08/my-first-bot-with-microsoft-bot-framework-in-dotnet-and-xamarin.html</id><summary type="html">&lt;p&gt;As developers we always try to find the easiest way to solve problems. This time, I'm glad to introduce you an easy way to create your own Bot in just minutes, from your local computer to the cloud. But that's not enough, we will take one step further and connect …&lt;/p&gt;</summary><content type="html">&lt;p&gt;As developers we always try to find the easiest way to solve problems. This time, I'm glad to introduce you an easy way to create your own Bot in just minutes, from your local computer to the cloud. But that's not enough, we will take one step further and connect our Bot with Xamarin, we'll see how easy is to get started.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Microsoft Bot Framework" src="/images/bot-framework.jpg"&gt;&lt;/p&gt;
&lt;p&gt;So, before we start we need to download a few things:&lt;/p&gt;
&lt;h3&gt;0. Requirements&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Download the template for Visual Studio &lt;a href="http://aka.ms/bf-bc-vstemplate"&gt;here&lt;/a&gt;. By having this template you'll avoid having to install the Nuget Packages and some initial code.&lt;/li&gt;
&lt;li&gt;To install the template, you need to copy the zip file (do not extract it) to your Visual Studio Templates folder, in my case is: &lt;code&gt;C:\Users\Christian\Documents\Visual Studio 2017\Templates\ProjectTemplates\Visual C#&lt;/code&gt; ... Just replace "Christian" with your user.&lt;/li&gt;
&lt;li&gt;Download and Install the Bot Framework Emulator &lt;a href="https://emulator.botframework.com/"&gt;here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Azure account to publish the bot (it could be anywhere, but it's easier here)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;1. Create the Bot&lt;/h3&gt;
&lt;p&gt;&lt;img alt="Visual Studio Template" src="/images/vs-create-bot-app.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Let's create the bot by following this steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Open VS and inside &lt;code&gt;Visual C#&lt;/code&gt; you'll see &lt;code&gt;Bot Application&lt;/code&gt; project (if you moved the zip file with VS opened, you need to close and open again), click there and then OK&lt;/li&gt;
&lt;li&gt;Create a new folder in the project called &lt;code&gt;Orders&lt;/code&gt; or choose a different name, it doesn't matter&lt;/li&gt;
&lt;li&gt;Inside this new folder, create a new class called &lt;code&gt;ComputerOrder&lt;/code&gt;, this is where we will define the questions of the Bot and the options. In this case we're choosing one easy way to create a guided conversation by using a &lt;code&gt;FormFlow&lt;/code&gt; dialog, it is like we were creating a form by using properties in the class, it supports some basic types and in our case today we'll use only the &lt;code&gt;Enumeration&lt;/code&gt; type, you can find more information in the docs &lt;a href="https://docs.microsoft.com/en-us/bot-framework/dotnet/bot-builder-dotnet-formflow"&gt;here&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;Add the &lt;code&gt;[Serializable]&lt;/code&gt; attribute to the ComputerOrder class (if not the message won't be serialized when sending it to the API)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;[Serializable]&lt;/span&gt;
&lt;span class="na"&gt;public class ComputerOrder&lt;/span&gt;
&lt;span class="na"&gt;{&lt;/span&gt;

&lt;span class="na"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Let's create our first question by creating an enum like this (create it in the same namespace or in a separate file, just make sure you reference it):&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;enum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Memory&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;_4GB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;_8GB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;_16GB&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;In the ComputerOrder class add a new property called &lt;code&gt;MemoryOption&lt;/code&gt; of the type &lt;code&gt;Memory&lt;/code&gt; (the enum you just created). The name of the class should be in CamelCase in order to have a more readable question, in this case the question will be &lt;code&gt;Please choose a Memory Option&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;public Memory? MemoryOption { get; set; }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Now, one important aspect of a bot is that it needs to be presented with a message, to do this add it inside the BuildForm method of the ComputerOrder class. It should look like this now:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;[Serializable]&lt;/span&gt;
&lt;span class="na"&gt;public class ComputerOrder&lt;/span&gt;
&lt;span class="na"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;public Memory? MemoryOption { get; set; }&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;public static IForm&amp;lt;ComputerOrder&amp;gt; BuildForm()&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="na"&gt;return new FormBuilder&amp;lt;ComputerOrder&amp;gt;()&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="na"&gt;.Message(&amp;quot;Welcome to the Computer Sale Bot!&amp;quot;)&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="na"&gt;.Message(&amp;quot;With my help you can build your custom computer, just choose an option or type the number that you wish.&amp;quot;)&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="na"&gt;.Build();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;}&lt;/span&gt;
&lt;span class="na"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Go back to the controllers in the project and in the MessagesController you need to add the references for the FormFlow dialog, Bot Connector and the class that includes all questions:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;using Microsoft.Bot.Builder.FormFlow;
using Microsoft.Bot.Connector;
using ComputerSaleBot.Orders;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Inside of the controller, create the method that will generate the dialogs for the bot:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;internal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;IDialog&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;ComputerOrder&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;MakeRootDialog&lt;/span&gt;&lt;span class="ss"&gt;()&lt;/span&gt;
{
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Chain&lt;/span&gt;.&lt;span class="nv"&gt;From&lt;/span&gt;&lt;span class="ss"&gt;(()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;FormDialog&lt;/span&gt;.&lt;span class="nv"&gt;FromForm&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ComputerOrder&lt;/span&gt;.&lt;span class="nv"&gt;BuildForm&lt;/span&gt;&lt;span class="ss"&gt;))&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Inside the Post action of the controller, you'll find something like this:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;await Conversation.SendAsync(activity, () =&amp;gt; new Dialogs.RootDialog());
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;You need to replace it with the following:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;await Conversation.SendAsync(activity, MakeRootDialog);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Test your bot by launching the website locally (as you usually launch local website apps)&lt;/li&gt;
&lt;li&gt;Open the Bot Framework Emulator and paste the URL that VS just launched and add the controller route &lt;code&gt;/api/messages&lt;/code&gt;, something like &lt;code&gt;http://localhost:3979/api/messages&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="Bot Framework Emulator" src="/images/bot-emulator-launch.jpg"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In a real world, just one question is not enough, so you can keep adding more enums and properties to the class and the Bot will have more questions to ask to the user.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. Publish the Bot&lt;/h3&gt;
&lt;p&gt;It doesn't matter if you didn't add more "questions", you're ready to publish the bot now. I'm going to use Azure to ease this task and this time I'll publish directly from Visual Studio but this is just to get started quickly, I don't recommend keeping it this way, instead we should configure an automated pipeline using tools like Jenkins or Team Services. So, for now you can follow these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Right click in the Web project and click "Publish"&lt;/li&gt;
&lt;li&gt;Choose "Microsoft Azure App Service" and "Create New"&lt;/li&gt;
&lt;li&gt;Fill in the blanks (API App Name, Subscription, Resource Group and App Service Plan)&lt;/li&gt;
&lt;li&gt;When choosing an &lt;code&gt;App Service Plan&lt;/code&gt; you can create a new one and choose the Free option (I did it)&lt;/li&gt;
&lt;li&gt;Click &lt;code&gt;Create&lt;/code&gt; and wait some time, when finished VS will launch the API in the browser&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img alt="VS Publish Bot with Azure" src="/images/vs-publish-bot-azure.jpg"&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img alt="VS Publish Bot with Azure - Free" src="/images/app-service-free.jpg"&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;3. Register the Bot&lt;/h3&gt;
&lt;p&gt;You need to register your Bot so you can easily add more integrations and focus the Bot only. So for this you just need to go to: &lt;a href="https://dev.botframework.com/login?requestUrl=%2Fbots"&gt;https://bots.botframework.com&lt;/a&gt;, sign in with your account and then:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Click the "Create a bot" button&lt;/li&gt;
&lt;li&gt;It will launch a new page, click the "Register" button&lt;/li&gt;
&lt;li&gt;Fill in the blanks all the details of your Bot profile&lt;/li&gt;
&lt;li&gt;In the configuration section, you need to put the URL of the bot endpoint (the one we published in Azure) using HTTPS, for example: &lt;code&gt;https://computersalebot20170731064536.azurewebsites.net/api/messages&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Click in the "Create Microsoft App ID and password" button to generate the keys, copy this generated values temporary because we'll use them to connect our Xamarin app with the Bot.&lt;/li&gt;
&lt;li&gt;Agree to the terms of use (obviously)&lt;/li&gt;
&lt;li&gt;Click "Register"&lt;/li&gt;
&lt;li&gt;Now, this is very important, in order for this to work you need to deploy the Webapi again but with the generated keys you just copied when registering the Bot. To do this go to the Web.config file in the project and fill all the blanks in the &lt;code&gt;appSettings&lt;/code&gt; section: BotId, MicrosoftAppId and MicrosoftAppPassword.&lt;/li&gt;
&lt;li&gt;Publish again and you're done&lt;/li&gt;
&lt;li&gt;You can go to the page where you registered the bot and test it, it will launch the same simulator you launched locally but in the browser, do this just to make sure the Bot it's well configured&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. Integrate with Xamarin&lt;/h3&gt;
&lt;p&gt;The way we're going to integrate the Bot with our Xamarin App is by using the Direct Line channel, this is a REST API that uses standard secret/token authentication, if you're interesting in knowing more go the docs &lt;a href="https://docs.microsoft.com/en-us/bot-framework/rest-api/bot-framework-rest-overview"&gt;here&lt;/a&gt;. This time, I'll give you an app where you just need to change the secret/token, you can go deeper by reading the code and extending it (I might write an article later). The idea here is to get your hands dirty as soon as possible and demonstrate how easy is to get started. So, follow these steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go to your Bot page in &lt;a href="https://dev.botframework.com/bots"&gt;https://dev.botframework.com/bots&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Click in the name of the bot you just created&lt;/li&gt;
&lt;li&gt;Under the "Add a channel" section, click in the Direct Line icon&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="Direct Line icon" src="/images/direct-line-icon.jpg"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Click in the "+ Add new site" button and put a name and click "Done"&lt;/li&gt;
&lt;li&gt;The generated keys are the ones we're going to use to connect the Xamarin app with the Bot&lt;/li&gt;
&lt;li&gt;Click in the "Show" link and copy the value&lt;/li&gt;
&lt;li&gt;Click in the "Done" button at the left-bottom of the page&lt;/li&gt;
&lt;li&gt;It's time to download the sample code, for this go &lt;a href="https://github.com/christianhxc/XamarinFormsBot"&gt;here&lt;/a&gt; and clone/download it&lt;/li&gt;
&lt;li&gt;Go to the MainPageViewModel.cs file and where it says "botSecret" &lt;a href="https://github.com/christianhxc/XamarinFormsBot/blob/master/BotFirst/BotFirst/ViewModel/MainPageViewModel.cs#L88"&gt;(line #88)&lt;/a&gt; replace the text "SecretKey" with the one you just copied when creating the Direct Line channel&lt;/li&gt;
&lt;li&gt;And that's it, launch the simulator in your computer (or deploy directly to your device) and start talking with your Bot&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is what you should see when the app is running ...&lt;/p&gt;
&lt;p&gt;&lt;img alt="Xamarin App Bot running" src="/images/xamarin-app-bot-running.jpg"&gt;&lt;/p&gt;
&lt;h3&gt;Reference Links&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Bot source code: &lt;a href="https://github.com/christianhxc/BotVentaDeComputadoras"&gt;https://github.com/christianhxc/BotVentaDeComputadoras&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Xamarin app source code: &lt;a href="https://github.com/christianhxc/XamarinFormsBot"&gt;https://github.com/christianhxc/XamarinFormsBot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Slides (Spanish): &lt;a href="https://www.slideshare.net/christianhxc/mi-primer-bot-bot-framework-xamarin"&gt;https://www.slideshare.net/christianhxc/mi-primer-bot-bot-framework-xamarin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Samples: https://github.com/Microsoft/BotBuilder-Samples&lt;/li&gt;
&lt;li&gt;Recorded workshop (Spanish): &lt;a href="https://www.youtube.com/watch?v=v6fgn8GB5KY"&gt;https://www.youtube.com/watch?v=v6fgn8GB5KY&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is my own version, the original content is from: &lt;a href="https://twitter.com/HJaimesDev"&gt;@HJaimesDev&lt;/a&gt; and &lt;a href="https://twitter.com/JorgeCupi"&gt;@JorgeCupi&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I gave this talk as a workshop for the Xamarin Fest in Guatemala City, you can take a look to another great talk on how to integrate &lt;code&gt;Custom Vision&lt;/code&gt; with Xamarin by  Guillermo Zepeda &lt;a href="https://twitter.com/cloudzepeda"&gt;@cloudzepeda&lt;/a&gt; in this &lt;a href="https://webdevazurehowto.blogspot.com/2017/06/xamarin-fest-guatemala-2017-y-orchid.html"&gt;[link]&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;I hope you have enjoyed this article and experienced by yourself how easy is to get started with the Bot Framework and not just that, connect it with your Xamarin App. This is just a jumpstart, I didn't do a deep dive on each section because the intention was to get you started fast (yes, I've said that so many times lol). If you'd like to do everything that I did here (with you hopefully) you can follow me in the Youtube video I put in the reference links, that's the video of my talk I mentioned, so even if you don't speak Spanish you can see how all steps connect in case you missed something or I didn't explain myself well enough ;)&lt;/p&gt;</content><category term="misc"/><category term="bot"/></entry><entry><title>What changes with Docker for Developers?</title><link href="https://cmelendeztech.com/posts/2017/07/what-changes-with-docker-for-developers.html" rel="alternate"/><published>2017-07-24T00:00:00+02:00</published><updated>2017-07-24T00:00:00+02:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2017-07-24:/posts/2017/07/what-changes-with-docker-for-developers.html</id><summary type="html">&lt;p&gt;Last week I was having a talk with a new friend (&lt;a href="https://twitter.com/rdiazconcha"&gt;@rdiazconcha&lt;/a&gt;) about Docker and one of the virtual table topics was: “What are the implications of adopting Docker for developers? Do we need to keep doing the same things as we’ve been doing it in the last years …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Last week I was having a talk with a new friend (&lt;a href="https://twitter.com/rdiazconcha"&gt;@rdiazconcha&lt;/a&gt;) about Docker and one of the virtual table topics was: “What are the implications of adopting Docker for developers? Do we need to keep doing the same things as we’ve been doing it in the last years (or months) or should we start considering other things too?” Well, in this article I’ll give my perspective and what changed for me and the good group of developers around me.&lt;/p&gt;
&lt;p&gt;But first, I don’t think this is a complete list of topics that you need to consider (I’m assuming that you already have some basic knowledge about Docker) in fact I think some one of them could need more than one article to discuss, so you can add more in the comments.&lt;/p&gt;
&lt;h2&gt;Is not just about having the same environments&lt;/h2&gt;
&lt;p&gt;We always read that the common phrase “it works in my machine” it’s dead with Docker, but let me tell you that this isn’t always true, but why? Because we need to be aware that there are many other components that are needed for our app to work, say for example: redis, elasticsearch, mysql, memcached, etc. &lt;/p&gt;
&lt;p&gt;We often have different environments too, where all tests need to be green (everybody test their code, right?), the most common ones are: local, dev, qa, staging and production (to name a few). And the idea of having Docker is that we can “build once run anywhere” so we need to have in mind that the app won’t run only on my machine but also in any other team member (yes, treat servers like a team member, lol). The usual flow is like this: I create my feature branch, make the changes, test the changes, push the code, make a merge request, my team lead approves it, it gets merged to master, then the CI tool is triggered to build the image and it’s deployed for the first time with the CD tool to the dev environment, after this we can just deploy the same image to the rest of environments … yes, when all tests passed.&lt;/p&gt;
&lt;p&gt;Sounds good and easy right? Not always, sometimes there are inconsistencies that causes so much pain. For example, one of the most common problems we had is that the endpoints for the resources weren’t always in the same way, for redis some used the server IP (that sometimes was changed because whatever) other used the domain name but then we realized that we needed to have a standard there so we changed the domains again and we always forgot to change something because eveng though the tests were green, when we shut down an old server we started noticing that some things were still pointing there. So, even us having a flow similar to the one described above, we always had some problems between environments.&lt;/p&gt;
&lt;p&gt;We never knew exactly what was happening (everything worked in our machines, remember?), but weren’t taking full advantage of something very useful (we’re in that): the debugger. Sometimes we have to go the limit of saying: “We don’t have the same environment as in production so we will need to debug there” and we end up having ugly debug messages that sometimes are exposed to our customers. 
No, no, no, we can’t keep working in that way, we do have a better way now because t’s possible to even debug our code inside a container, for example, if you’re a .NET developer, &lt;a href="https://docs.microsoft.com/en-us/azure/vs-azure-tools-docker-edit-and-refresh"&gt;Visual Studio 2017&lt;/a&gt; has this already integrated and for existing projects you just need to “Add Docker Support” to your projects and it will build all what’s necessary to run and debug locally your app, it will use some base structure and according to the version of your code it will create a proper Dockerfile, but hey, as Scott Hanselman said in the VS launch: “You can use this even to learn Docker” (you can do this with Java too: &lt;a href="https://blog.docker.com/2016/09/java-development-using-docker/"&gt;[here]&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Testing my app can be easily automated&lt;/h2&gt;
&lt;p&gt;We can’t just test (and/or debug) locally, if we have full controll of the environment we’ll always find the hack for our app to work and as our app grows, more and more tests will be needed so this means that more and more time is going to be needed and this might start slow you down. &lt;/p&gt;
&lt;p&gt;Yesterday, I found out that SQL server team use Docker to automate testing (&lt;a href="https://thenewstack.io/microsoft-uses-linux-containers-test-sql-server-2017/"&gt;link&lt;/a&gt;) and also Yelp says that they run millions of tests every day (&lt;a href="https://engineeringblog.yelp.com/amp/2017/04/how-yelp-runs-millions-of-tests-every-day.html"&gt;link&lt;/a&gt;), that’s amazing! We have two examples of big companies on how we can take advantage of containers to test our app to the limit to even run those type of tests locally. The approach you’ve been using to test your app needs to change because like the SQL Server team, now you have the ability to run the database in a desired state as the first step, run the tests with several containers at the same time and wait some time for the results (you’ll need more resources but we leverage that to the cloud, right?).&lt;/p&gt;
&lt;p&gt;Imagine that you can run all you test suite after you’ve deployed the app in the dev (or other one) environment with this approach, you’ll gain confidence the more you practice and also you’ll reduce not just lead time but risks when deploying something new to production.&lt;/p&gt;
&lt;h2&gt;Storage is ephemeral&lt;/h2&gt;
&lt;p&gt;You need to know that all changes that happen in a container when it’s running, might get lost forever because when you start again it will create a new container (unless you relaunch the same container). At the moment it gets stopped there’s no guarantee that your files will stay there, these can be logs, missing files when deploying and uploaded manually, new uploaded files when using the app, missing components that were installed, etc. I definetly recommend you reading this article &lt;a href="https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/"&gt;[here]&lt;/a&gt; to know more about how this works.&lt;/p&gt;
&lt;p&gt;Why this is important? Like I said before, when you have the control of the environment you will always find the way to make your app work and as humans (specially with deadlines) we tend to forgot what we did to fix it and that’s why our app stops working in other environments. Also, this means that you can’t depend on having the state inside a container, the container should always be stateless.&lt;/p&gt;
&lt;p&gt;Let me give you an example, let’s say a user uploads their profile pic with your app and you store that pic in the container, the user is happy because the profile pic is being displayed but then something happens with the container and it’s terminated. Boom, the profile pic is not there anymore, at scale it’s annoying to go and re start a stopped container. In this specific case you should instead move the image to a permanent storage like S3, Azure Blob or whatever you prefer.&lt;/p&gt;
&lt;h2&gt;Environment variables&lt;/h2&gt;
&lt;p&gt;Now, this is one of the most important things where you’ll see significant gains if you applied this correctly. This was for me the “aha” moment for “run anywhere” because by implementing environment variables you just need to “inject” the values you need for the environment the container will run. Let’s use the database endpoint as an example, by using an environment variable like DB_HOST I can start making the changes needed to my app to take the endpoint from the environment, then I need to add that variable to my computer … right? … ahmm you can do that but you won’t be changing things that much, just making everything more complex because what you did in your computer you’ll need to do it in the rest of the environments.&lt;/p&gt;
&lt;p&gt;So how can this be achieved? You need to make use of the environment variables when running the container, this way you’ll be injecting the desired values. This recommendation is based on the 12 Factor App guide and specifically for the config part, you can find more info &lt;a href="https://12factor.net/config"&gt;[here]&lt;/a&gt; and I also wrote a post about using docker env vars with .NET Core &lt;a href="http://cmelendeztech.com/posts/2017/02/using-docker-env-vars-in-dotnet-core.html"&gt;[here]&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Logs, logs, logs&lt;/h2&gt;
&lt;p&gt;Data might get lost, remember? So how do we know what happened after a container crashed? Logs. This is crucial in production so you need to be prepared by making sure you have this across all environments (even in your machine, yes, to verify it’s working). You need to know that by default all logs goes to the standard output (/dev/stdout) and standard error (/dev/stderr), take a look for example to an nginx container, the /var/log/nginx/access.log is a symbolic link to /dev/stdout. This way you can use the “docker logs” command to get the information without login in to the container or you can make use of other &lt;a href="https://docs.docker.com/engine/admin/logging/overview/"&gt;logging drivers&lt;/a&gt; and have a centralized logging server where all containers will push logs, as the 12 Factor App says “treat logs as event streams” &lt;a href="https://12factor.net/log"&gt;[here]&lt;/a&gt;. But you have to choose just one, if you decide to go with the logging driver approach, you are no longer able to get logs with the “docker logs” command and I should mention that you can only have just one logging driver, at least at the moment (that sucks).&lt;/p&gt;
&lt;p&gt;How this affects you as developer? You need to know that if you send logs to another path different that stdout or stderr (this is translated to all console writes your app can make) your logs might get lost (unless you send them to a shared volume, in this case the logs will be kept in the host, but there’s still a chance to lose them). So keep this in mind.&lt;/p&gt;
&lt;h2&gt;Port binding&lt;/h2&gt;
&lt;p&gt;You should find a way that this is not an impediment for your app, especially if you would like to scale out containers in the same host. The application inside your container will expose a port but the host is not going to necessary expose the same port (there is a default range but as developer you don’t need to know this, but if you’re curious go &lt;a href="https://docs.docker.com/engine/userguide/networking/default_network/binding/"&gt;[here]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And this is also a characteristic of a 12 Factor App, you can find more info &lt;a href="https://12factor.net/port-binding"&gt;[here]&lt;/a&gt;. But, why is this important? By having this option, you don’t need to worry where the container will be living, in your local computer could be port 8080 but in development could be port 32888. You might start thinking that his will make things more complex to you because you need to know in which port the container is running, this gets complicated when you run more than one container to have a cluster be fault tolerant.&lt;/p&gt;
&lt;p&gt;You also have some options to work with this and here they are:
1.  You can use docker compose and link the containers, more info &lt;a href="https://docs.docker.com/compose/networking/"&gt;[here]&lt;/a&gt;
2.  Use a load balancer, this will expose obviously a port that will always be the same and that you will use to call a container, the difference is that this will proxy the calls to the container’s port in the host that are registered to it, there are several ways to do this and &lt;a href="https://docs.docker.com/datacenter/dtr/2.2/guides/admin/configure/use-a-load-balancer/"&gt;here are some&lt;/a&gt;. And all the orchestrators have this feature in some way, but as a developer you don’t necessary need to know how to do implement it.
3.  Ignore this section and continue working with a fixed port number, the downside here is that you will only be able to have one container per host&lt;/p&gt;
&lt;h2&gt;Tooling to have my local environment&lt;/h2&gt;
&lt;p&gt;Now, you don’t need to learn a bunch of tools to start but there are some things that you should consider when beginning this journey:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Docker installed, kind of obvious but anyway, more info &lt;a href="https://docs.docker.com/engine/installation/"&gt;[here]&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;In the case of Windows, you might need to share the drive where you have the code so you can debug or use volumes in that drive&lt;/li&gt;
&lt;li&gt;In some cases, make sure you’re giving enough resources to the docker daemon, i.e. to run SQL Server containers you need to have at least 3.5 Gb of memory reserved&lt;/li&gt;
&lt;li&gt;A script to start the container app and all its dependencies (i.e. local redis), this can be another topic table, just take note that you’ll need to use compose to ease the work. This way when a new developer comes in he/she will just need to pull the code, read the README.md, follow some instructions maybe, run docker compose and start hacking. This sounds easy, but it can get complicated to get to this point, but it will worth it.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Create the Dockerfile with the operations team&lt;/h2&gt;
&lt;p&gt;You need to have this scripted, it will make everyone’s life easier, trust me. You can launch a container with a base image (even FROM scratch), install what you need, copy your app and then test, after you are happy with everything you just commit the container, create a new image tag, push the image to the repo and that’s all. In other words, you could treat the container like a virtual machine, don’t do that, please.&lt;/p&gt;
&lt;p&gt;Instead, make use of the Dockerfile, you can start with what you know you’re going to need for your app and then ask to the operations team for a review, they might have something to add or remove and they will know what the container will have installed. Same thing happens if other person is building the image, you would like to know what’s inside, right? Maybe something that it’s in there is what is making your app to crash or running slowly.&lt;/p&gt;
&lt;p&gt;A few things to consider here: avoid using a Dockerfile for build locally, other for development and another one for production, it will get a mess, instead use the multi-stage builds, more info &lt;a href="https://blog.docker.com/2017/07/multi-stage-builds/"&gt;[here]&lt;/a&gt;. Another thing is the image size, remember that the idea is to have only what you need to run your app, nothing else, so ideally you’ll try to have your image size as low as possible, for example you can achieve this by using base images like Alpine or CoreOS (create your own with Linux Kit?) instead of using the Ubuntu one. Why is this important? Well, when you scale out and a new server is launched, the image needs to be pulled and if the image is serveral GBs of size, it will take some time before you can launch your first container, you users might not even notice it but it can affect someone.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;I hope you have a good idea now what changes you might need to implement to your existing applications. But do not try to make all changes at once, start little by little, you will always have some benefits. Right from the very beginning you’ll be able to have a decent level of consistency between deployments, you might not be able to get the full advantages of Docker but at least give the first step: containerized your app :) &lt;/p&gt;</content><category term="misc"/><category term="developers"/><category term="docker"/></entry><entry><title>MSSQL Linux with Docker</title><link href="https://cmelendeztech.com/posts/2017/02/mssql-linux-with-docker.html" rel="alternate"/><published>2017-02-27T00:00:00+01:00</published><updated>2017-02-27T00:00:00+01:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2017-02-27:/posts/2017/02/mssql-linux-with-docker.html</id><summary type="html">&lt;p&gt;On February 18th I had the opportunity to give a talk about SQL Server running inside a Docker container in the SQL Saturday Guatemala event, more details &lt;a href="http://www.sqlsaturday.com/586/Sessions/Details.aspx?sid=62442"&gt;here&lt;/a&gt;. I thought no one was going to attend due to at the same time &lt;a href="https://twitter.com/jasonhorner"&gt;Jason Horner&lt;/a&gt; (Microsoft Certified Master of SQL Server …&lt;/p&gt;</summary><content type="html">&lt;p&gt;On February 18th I had the opportunity to give a talk about SQL Server running inside a Docker container in the SQL Saturday Guatemala event, more details &lt;a href="http://www.sqlsaturday.com/586/Sessions/Details.aspx?sid=62442"&gt;here&lt;/a&gt;. I thought no one was going to attend due to at the same time &lt;a href="https://twitter.com/jasonhorner"&gt;Jason Horner&lt;/a&gt; (Microsoft Certified Master of SQL Server) was giving a talk about database performance tricks, but to my surprise some people were interested in the talk (yes, mostly developers, one DBA and one auditor), nice!.&lt;/p&gt;
&lt;p&gt;So, I want to share the agenda with some useful reference links and I'm going to extend in the most important slide of the PPT, here it is:&lt;/p&gt;
&lt;h2&gt;Agenda&lt;/h2&gt;
&lt;p&gt;The agenda was pretty straight forward and short:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Docker &lt;/li&gt;
&lt;li&gt;MSSQL + Linux&lt;/li&gt;
&lt;li&gt;Use Cases&lt;/li&gt;
&lt;li&gt;Demo&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;1. Docker&lt;/h3&gt;
&lt;p&gt;I started by giving a quick tour about what Docker is and why it's, the architecture behind and some adoption details in the recent years. Here's the list of reference links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What is Docker? &lt;a href="https://www.docker.com/what-docker"&gt;https://www.docker.com/what-docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Docker Overview &lt;a href="https://docs.docker.com/engine/understanding-docker/"&gt;https://docs.docker.com/engine/understanding-docker/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Docker Adoption &lt;a href="https://www.datadoghq.com/docker-adoption/"&gt;https://www.datadoghq.com/docker-adoption/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. MSSQL Linux + Docker&lt;/h3&gt;
&lt;p&gt;Because there was another talk about MSSQL running on Linux I didn't focus on that and went straight to the instructions and considerations when running the container:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Run the SQL Server Docker image on Linux, Mac, or Windows &lt;a href="https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-setup-docker"&gt;https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-setup-docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;MSSQL for Linux Containers &lt;a href="https://hub.docker.com/r/microsoft/mssql-server-linux/"&gt;https://hub.docker.com/r/microsoft/mssql-server-linux/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;MSSQL for Windows Containers &lt;a href="https://hub.docker.com/r/microsoft/mssql-server-windows/"&gt;https://hub.docker.com/r/microsoft/mssql-server-windows/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;MSSQL Express for Windows Containers &lt;a href="https://hub.docker.com/r/microsoft/mssql-server-windows-express/"&gt;https://hub.docker.com/r/microsoft/mssql-server-windows-express/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, you need to consider the following when running the container (otherwise the container won't run):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pull the image from the docker registry (docker pull)&lt;/li&gt;
&lt;li&gt;Your computer needs to have at least 3.25 Gb of RAM (to be honest, I didn't like this but I still need to test if it runs with less memory assigned)&lt;/li&gt;
&lt;li&gt;You need to accept the license agreement with the env var ACCEPT_EULA&lt;/li&gt;
&lt;li&gt;You need to provide a strong password with the env var SA_PASSWORD&lt;/li&gt;
&lt;li&gt;Beware that you're running the full version of MSSQL so you have a trial of 150 days&lt;/li&gt;
&lt;li&gt;You can have persist data by attaching a volume, this is because by default the data is ephemeral and you will lose it once the container is stopped. You need to attach a volume to the "/var/opt/mssql" path&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here's the docker run command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker run -e &amp;#39;ACCEPT_EULA=Y&amp;#39; e &amp;#39;SA_PASSWORD=YourStrong!Passw0rd&amp;#39; -p 1433:1433 -d microsoft/mssql-server-linux:ctp1 linux:ctp1-2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here's the docker run command with a volume attached:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ACCEPT_EULA=Y&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;SA_PASSWORD=YourStrong!Passw0rd&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1433&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1433&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mssql&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;microsoft&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mssql&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;linux&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ctp1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;linux&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ctp1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you're running on Windows, you can replace &lt;host directory&gt; with for example C:/mssql&lt;/p&gt;
&lt;h3&gt;3. Use Cases&lt;/h3&gt;
&lt;p&gt;I gave some use cases that came to my mind, things that I will use to run MSSQL in a container, so if you have any other use case please share it in the comments, I'll glad to hear from the community:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Prototyping, things that you need to validate fast and don't want to have a full server for the DB&lt;/li&gt;
&lt;li&gt;Local environment for developers, a developer can start working in the code from day 1 without having to worry about the DB version for example&lt;/li&gt;
&lt;li&gt;Test/Practice environment for DBAs, there are times that we would like to test some scripts that might bring down the server or cause inconsistency&lt;/li&gt;
&lt;li&gt;Migration script testing, we might want to practice the migration from one version to a newer version&lt;/li&gt;
&lt;li&gt;Practice backups restore, we can configure a periodic practice to restore backups, we need to make sure that when we need them, they work&lt;/li&gt;
&lt;li&gt;Separate processing layer from storage layer, you might want to have all data in the cloud or a SAN and not in your computer, this also gives us the ability to copy data from another environment or partner (although we have the risk of corrupted data)&lt;/li&gt;
&lt;li&gt;Microservice Arquitecture, this is a good fit when you want to have a DB per service (it can also help you to migrate to a more lightweight storage like a no-sql db)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;4. Demo&lt;/h3&gt;
&lt;p&gt;I followed the "Getting Started" page for developers, but I didn't have enough time to do everything, so here are the activities we can do to practice:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Configure environment&lt;/li&gt;
&lt;li&gt;Create an application in C# connecting to a MSSQL&lt;/li&gt;
&lt;li&gt;Change the app using Columnstore for a 100x faster app&lt;/li&gt;
&lt;li&gt;mssql extension in Visual Studio Code&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Reference link: &lt;a href="https://www.microsoft.com/en-us/sql-server/developer-get-started/csharp-ubuntu"&gt;https://www.microsoft.com/en-us/sql-server/developer-get-started/csharp-ubuntu&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;SQL Saturday Guatemala&lt;/h3&gt;
&lt;p&gt;Here are some photos of that day :)&lt;/p&gt;
&lt;p&gt;&lt;img alt="MSSQL Linux and Docker" src="/images/mssql-docker-sql-sat-guatemala.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="SQL Saturday Guatemala Speakers" src="/images/sql-sat-guatemala-speakers.jpg"&gt;&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;As you saw, it's really easy to get started with MSSQL for Linux using a Docker container. I present to you some use cases that came to my mind, it might exist more and others would like to discuss some of them and that's why I want to make clear that my idea is not to define a rule, I just wanted to give some examples of how I would use this combination. I'm not sure yet if I would recommend use MSSQL in a Docker container for production environments, I see it more as a fast way to experiment.&lt;/p&gt;
&lt;p&gt;Oh yes, here's the PPT of the talk for that day (it's in Spanish): Download &lt;a href="https://cmelendeztech.com/ppt/sql-server-cross-platform-portable-con-docker.pdf"&gt;here&lt;/a&gt;&lt;/p&gt;</content><category term="misc"/><category term="mssql"/><category term="linux"/><category term="docker"/></entry><entry><title>Using Docker env vars in .NET Core</title><link href="https://cmelendeztech.com/posts/2017/02/using-docker-env-vars-in-dotnet-core.html" rel="alternate"/><published>2017-02-06T00:00:00+01:00</published><updated>2017-02-06T00:00:00+01:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2017-02-06:/posts/2017/02/using-docker-env-vars-in-dotnet-core.html</id><summary type="html">&lt;p&gt;One really good thing about packing your apps with Docker is that you're building once and deploying many times in many different places (environments), because of this it's a good idea to make your app configurable at the environment level (not just files). This means that you should avoid having …&lt;/p&gt;</summary><content type="html">&lt;p&gt;One really good thing about packing your apps with Docker is that you're building once and deploying many times in many different places (environments), because of this it's a good idea to make your app configurable at the environment level (not just files). This means that you should avoid having config files in the container that can be different in each environment you run the container, "An app’s config is everything that is likely to vary between deploys" (The 12 Factor App).&lt;/p&gt;
&lt;h2&gt;But why environment variables?&lt;/h2&gt;
&lt;p&gt;The idea comes from the 12 factor app methodology &lt;a href="https://12factor.net/config"&gt;(https://12factor.net/config)&lt;/a&gt;, where it says that we should prefer using this type of configuration because having files can compromise sensitive information (security in Docker is not that mature yet because you can easily inspect the container and see all the environment variables, but that's an interesting talk for another time).&lt;/p&gt;
&lt;p&gt;I'm not going to repeat what you already read in the previous link but I want to focus in the following: "In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as 'environments', but instead are independently managed for each deploy. This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime." (The 12 Factor App)&lt;/p&gt;
&lt;p&gt;So, the idea is that we should always have our app prepared to behave accordingly in each environment, we should not have to re-compile our code just because we need to change some configuration, imagine doing that in all of the software you use in your computer.&lt;/p&gt;
&lt;h2&gt;That's good, but how can this be done in .NET Core?&lt;/h2&gt;
&lt;p&gt;I'm glad you ask. By this moment I hope you are convinced that env vars are a good option and lucky for us this is how Docker works, we just need to know how to achieve this behavior in .NET Core. For this, there's also good documentation &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration"&gt;here&lt;/a&gt; but in this post I will focus only on how to read env vars that comes from Docker.&lt;/p&gt;
&lt;p&gt;.NET Core has a really good integration with env vars, actually the default template for a Web API use it as default, so we just need to make a few changes to our code in the Startup.cs class, create a new POCO class and use it in our Controllers by injecting the configuration we need.&lt;/p&gt;
&lt;h2&gt;Changes in the app&lt;/h2&gt;
&lt;p&gt;While I list the changes we need to make in the app, I'm going to give some explanation in each step. I have uploaded the code sample in Github, so in I couldn't explain myself enough you can see the source code &lt;a href="https://github.com/christianhxc/hellodocker"&gt;here&lt;/a&gt;. Here's the list of steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Make sure that in the Startup.cs class of your Web API project you have the line to add the env vars. This should be in the constructor of the class where the builder of the configuration is being defined. The builder definition should include the call "AddEnvironmentVariables()". Something like this:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ConfigurationBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetBasePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContentRootPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;calls&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddEnvironmentVariables&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;You need to create a POCO class where you define all the properties that you're interested to read 
from the environment. In my case I want to treat the profile name as an env var, so I created a class called EnvironmentConfig.cs and I included a public string property called "ProfileName" (his name should match with the env var, the framework makes reflection to fill the properties with env vars and because this is being done at startup, it won't affect performance when serving requests, this is also because in the container you will have only the environment variables you define when running the container).&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;public class EnvironmentConfig
{
     public string ProfileName { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Add the new configuration class in the Startup.cs services definition. This means that in the method called "ConfigureServices" you should include this line:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;services.Configure&amp;lt;EnvironmentConfig&amp;gt;(Configuration);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Finally, we just use it in the Controller (or wherever you want) by injecting the configuration in the constructor of the class. I recommend having a local var in the class, then you need to specify in the constructor the injection of the configuration class we just defined, but it should be done in the .NET Core way by using the 'IOptions' interface. In my case I want to include it in the ValuesController.cs so my constructor looks like this:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;private readonly EnvironmentConfig _configuration;

public ValuesController(IOptions&amp;lt;EnvironmentConfig&amp;gt; configuration)
{
    _configuration = configuration.Value;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In case you don't see it, one of the cool things by doing it in this way is that if you don't specify an env var called "ProfileName" your app won't crash (unless you want/need to) because when you read the property of the configuration class it will be empty.&lt;/p&gt;
&lt;p&gt;And that's all, if you want to deep dive in how configuration can be modified/used please read the following article &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;How to test and debug this with VS?&lt;/h2&gt;
&lt;p&gt;I assume you already have added Docker support to your solution, if not take a look to this &lt;a href="https://cmelendeztech.com/posts/2017/01/hello-world-dotnet-core-and-docker-with-vs.html"&gt;article&lt;/a&gt;. In your solution, open the docker-compose.override.yml file inside docker-compose section and in the environment list the ProfileName var, take a look:&lt;/p&gt;
&lt;p&gt;&lt;img alt="env var docker compose" src="/images/env-var-docker-compose.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Go and debug in Docker mode and the app should read that value from the container environment.&lt;/p&gt;
&lt;h2&gt;But what about Docker?&lt;/h2&gt;
&lt;p&gt;Yes, I know I almost forgot about this. But you know what? This is really simple, I'm going to put here the way I run my container so you can see how to define the env var that my .NET Core app will read.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker run -e ProfileName=&amp;#39;Christian&amp;#39; -d -p 9000:80 christianhxc/hellodocker:env
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now I need to go to: &lt;a href="http://localhost:9000/api/values"&gt;http://localhost:9000/api/values&lt;/a&gt; and boom! I see my name there. Of course, you don't need to specify all env vars in the run command, you can make use of docker compose to group them, but remember: don't include the any config file with the source code in version control.&lt;/p&gt;
&lt;p&gt;You don't need to follow this guide to test it, just run the above command with different values :)&lt;/p&gt;</content><category term="misc"/><category term="dotnet"/><category term="dotnetcore"/><category term="docker"/></entry><entry><title>Hello World .NET Core and Docker with VS</title><link href="https://cmelendeztech.com/posts/2017/01/hello-world-dotnet-core-and-docker-with-vs.html" rel="alternate"/><published>2017-01-28T00:00:00+01:00</published><updated>2017-01-28T00:00:00+01:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2017-01-28:/posts/2017/01/hello-world-dotnet-core-and-docker-with-vs.html</id><summary type="html">&lt;p&gt;Today I want to share with you how you can create a Hello World API with .NET Core but running inside of a Docker container and not just that, we will be able to even debug the API with Visual Studio (VS) and then I'll explain how easy is to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Today I want to share with you how you can create a Hello World API with .NET Core but running inside of a Docker container and not just that, we will be able to even debug the API with Visual Studio (VS) and then I'll explain how easy is to push an image that is ready for a production environment, so let's get started.&lt;/p&gt;
&lt;h3&gt;What I need to have first?&lt;/h3&gt;
&lt;p&gt;In order for this demo to work you need to have the following installed in your computer (I'm using Windows 10):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Visuatl Studio 2017 RC, you can download it &lt;a href="https://www.visualstudio.com/vs/visual-studio-2017-rc/"&gt;here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Docker for Windows, you can download it &lt;a href="https://docs.docker.com/docker-for-windows/"&gt;here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you're using more than one drive in your computer and you installed docker in a different drive than your project files, you need to share that drive in Docker, you can do it following this guide &lt;a href="https://blogs.msdn.microsoft.com/stevelasker/2016/06/14/configuring-docker-for-windows-volumes/"&gt;here&lt;/a&gt;. Read this part again, you might not be able to debug the API in VS if you don't do this.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Once you have everything installed/configured, you can continue.&lt;/p&gt;
&lt;h3&gt;Create a Hello World API&lt;/h3&gt;
&lt;p&gt;We're not just going to create a simple API (you might know how to do this already) but I'm going to focus on how you can integrate Docker to your project.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open your VS as an Administrator (right click and "Run as Administrator")&lt;/li&gt;
&lt;li&gt;Go to File -&amp;gt; New -&amp;gt; Project&lt;/li&gt;
&lt;li&gt;Choose Templates -&amp;gt; Visual C# -&amp;gt; .NET Core and then "ASP.NET Core Web Application (.NET Core)"&lt;/li&gt;
&lt;li&gt;Put a name to the project (in my case "HelloDocker"), choose the location of files and then click "OK"&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt="Create Web API in .NET Core" src="/images/hello-docker-api.jpg"&gt;&lt;/p&gt;
&lt;p&gt;After this, you should be seeing another screen where you need to enable docker support (you can do it later too).&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Choose "Web API" under "ASP.NET Core Templates 1.1"&lt;/li&gt;
&lt;li&gt;Check the "Enable Docker Support" box and click "OK"&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt="Enable Docker Support in VS" src="/images/enable-docker-support-vs.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Let's wait a little bit and you should be seeing something like this:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Project Structure with Docker enabled" src="/images/project-structure-with-docker-enabled.jpg"&gt;&lt;/p&gt;
&lt;p&gt;What's new here? If you notice you now have a new section in the solution called "docker-compose" and inside your project you have a "Dockerfile". I'm not going to explain why you have those files and what they do (for more details go &lt;a href="https://docs.microsoft.com/en-us/dotnet/articles/core/docker/visual-studio-tools-for-docker"&gt;here&lt;/a&gt;). Now, let's see the magic when debugging the API.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the ValuesController.cs file (In the web project, Controllers/ValuesController.cs)&lt;/li&gt;
&lt;li&gt;Put a break point in the line where return a list of values (line #16)&lt;/li&gt;
&lt;li&gt;In the solution explorer, go to "docker-compose", right click and then Debug -&amp;gt; Start new instance. If you do it in the project, it will launch the IIS Express and you don't want to do that right now. You should start seeing in the output how the image is being built by copying all the binaries inside the container.&lt;/li&gt;
&lt;li&gt;When it finishes, it will launch a new window in your browser&lt;/li&gt;
&lt;li&gt;In the same window, go to the /api/values URL and VS will catch that call in the break point we put&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt="Debug your Web API inside Docker" src="/images/debug-web-api-docker-vs.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Now, this where you can start screaming excited about what just happened (I did). If you don't get it, let me explain what just happened: VS built a container with the code you have in the project, then it launched the container and attached it to your VS so you can debug it. This means that you're not just testing locally but you're testing in the same way that the API will run in the production server. That's really awesome, I loved it.&lt;/p&gt;
&lt;p&gt;Close your mouth now please, we need to do some things to finish the demo :) ... In the same line that you put the breakpoint, let's add a new value, we're gonna push this to the Docker Hub.&lt;/p&gt;
&lt;h3&gt;What about deployment to Production server?&lt;/h3&gt;
&lt;p&gt;I know, that was my first question, so let's open the terminal window (I use Powershell) and let's do it, but first, we need to build the API in release mode.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In VS, change the configuration from Debug to Release mode and build the solution again. Why? It will start creating the image for a production environment (you never release your APIs in Debug mode, right?) and it chooses the best container base image that Microsoft team have configured for those environments, so it's not from the same image base we used to debug our code. More info &lt;a href="https://docs.microsoft.com/en-us/dotnet/articles/core/docker/building-net-docker-images"&gt;here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Open your terminal window and run "docker images"&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt="Docker Images" src="/images/docker-images.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Now, you see that I remarked the one with the "latest" tag, that's the one we need to use for production, the other one (with the tag "dev") it's the one just for development. Ok, let's push it to your docker registry.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Login to your Docker Hub account &lt;a href="https://id.docker.com/login/"&gt;here&lt;/a&gt; (If you don't have one, create it please)&lt;/li&gt;
&lt;li&gt;Now, let's create a public repository, mine is called "hellodocker"&lt;/li&gt;
&lt;li&gt;Go back to your terminal and run the "docker images" command&lt;/li&gt;
&lt;li&gt;Copy the IMAGE ID of the hellodocker with the latest tag and tag it with the name of your repository that you just created. In my case I need to run this "docker tag 95904eeb5775 christianhxc/hellodocker"&lt;/li&gt;
&lt;li&gt;List the images and you should see the one you just created&lt;/li&gt;
&lt;li&gt;Login to your docker repository by running "docker login"&lt;/li&gt;
&lt;li&gt;Push the image, in my case I ran "docker push christianhxc/hellodocker", wait a little bit and you should see the image in Docker Hub (it might take some time to see it)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt="Docker Images" src="/images/docker-push-image.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="Docker Images" src="/images/docker-image-in-repo.jpg"&gt;&lt;/p&gt;
&lt;h3&gt;How to run the container without VS?&lt;/h3&gt;
&lt;p&gt;Just open your terminal and run the following command: &lt;/p&gt;
&lt;p&gt;docker run -d -p 8000:80 christianhxc/hellodocker&lt;/p&gt;
&lt;p&gt;Open your browser in http://localhost:8000/api/values and see the latest version of the API&lt;/p&gt;
&lt;p&gt;So that's all, now you can easily create .NET Core apps with Docker support :)&lt;/p&gt;</content><category term="misc"/><category term="dotnet"/><category term="dotnetcore"/><category term="docker"/><category term="vs"/></entry><entry><title>JMeter 101: Load Test a Web API</title><link href="https://cmelendeztech.com/posts/2017/01/jmeter-101-load-test-a-web-api.html" rel="alternate"/><published>2017-01-24T00:00:00+01:00</published><updated>2017-01-24T00:00:00+01:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2017-01-24:/posts/2017/01/jmeter-101-load-test-a-web-api.html</id><summary type="html">&lt;p&gt;One of the most crutial things for a Web API is to know how many resources
you'll need to run it, this based on how much traffic you will (or expect to)
receive, the response time of your API and the payload (the content that it will
retrieve). And when …&lt;/p&gt;</summary><content type="html">&lt;p&gt;One of the most crutial things for a Web API is to know how many resources
you'll need to run it, this based on how much traffic you will (or expect to)
receive, the response time of your API and the payload (the content that it will
retrieve). And when I mention resources, I'm talking about how big/small your
server should be, the good part right now is that we have the cloud, where we
can experiment in minutes and just with a few clicks. But today, I'm not going
to talk about the cloud, I'm going to focus on how to prepare our local
environment to run this set of tests in our machines.&lt;/p&gt;
&lt;h3&gt;What will you need?&lt;/h3&gt;
&lt;p&gt;First thing first, we will need an API to test, for this we're going to create a
simple one, actually let's use the one from the VS templates. We can do that by
following these steps: 1. Open your Visual Studio (2015 or higher, try get up to
date) 2. In the left pannel, choose: "Visual C#" and then ".NET Core" 3. In the
middle pannel, choose: "Create a new ASP.NET Core Web Application (.NET Core)"
4. Put a name to your project (I put "HelloWorld") 5. Choose a location to save
the all project files 6. Click "OK"&lt;/p&gt;
&lt;p&gt;Easy, right? Here's an image of what I see:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Create Web API in .NET Core" src="/images/create-web-api-dotnet-core.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Now, you need to download JMeter (you'll need Java to run it) here:
&lt;a href="http://jmeter.apache.org/download_jmeter.cgi"&gt;http://jmeter.apache.org/download_jmeter.cgi&lt;/a&gt;. Extract it and go to the bin
folder, you'll find a file called: "ApacheJMeter.jar", run it and the UI will
appear.&lt;/p&gt;
&lt;p&gt;&lt;img alt="JMeter" src="/images/jmeter-screen.jpg"&gt;&lt;/p&gt;
&lt;p&gt;OK, now you're good to go, let's start having fun.&lt;/p&gt;
&lt;h3&gt;How to create my first load test?&lt;/h3&gt;
&lt;p&gt;It's really easy and we're going to do it in just a few steps, at the end I'll
share with you the link fo the xml configuration of the test, let's start:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Open JMeter (I guess you already did it after donwload it in previous step)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Right click in "Test Plan" and go to Add -&amp;gt; Threads (Users) -&amp;gt; Thread
    Group. This is where you will configure the users that JMeter launch, lets
    put 10 in "Number of Threads (users)" to simulate 10 concurrent users. You
    can also configure how much time the test will run, check the “Scheduler”
    box and in this case we will put 30 in “Duration (seconds)” so the load test
    runs for 30 seconds.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;JMeter will try to send as much load as it can, so we need to put something
    to assure a constant throughput to the API, do to this you need to right
    click in "Test Plan" and go to Add -&amp;gt; Timer -&amp;gt; Constan Throughput Timer.
    This is the maximum number of requests that it will send in one minute,
    because we already configure the test for 10 users let’s assume that it will
    send 10 requests per second (rps), in one minute it will send 600 requests,
    so put 600 in “Target throughput (in samples per minute)” box.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We need something to test, an endpoint. So let’s run the API in Visual
    Studio (VS) in debug mode for now and let VS launch the IIS express, it will
    assign a port so make sure you have it handy.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Let’s get back to JMeter and in “Thread Group” right click and go to Add -&amp;gt;
    Sampler -&amp;gt; HTTP Request. You can configure now the endpoint, in “Server
    Name or IP” just put “localhost” (this where you will put the IP of the
    service or the subdomain name). Specify the port number that you were
    assigned in the previous step, in my case it was 62029, so I put that number
    in “Port Number” box. You need to also specify the route of the API to test,
    so in “Path” it’s the place to put it, in my case I put “/api/filelog”
    because that was the endpoint in my IP. You can also configure parameters in
    the request but we will leave this example as simple as possible.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The good thing about JMeter is that you can see some output while the test
    is running, so let’s add a few. In “Thread Group” right click and go to Add
    -&amp;gt; Listener -&amp;gt; Aggregate Report. With this you’ll be able to see the
    number of request sent in total, the average latency in milliseconds (ms),
    the median of the latency, 90th percentile latency, the 95th and the 99th
    (don’t trust in averages please), minimum latency, maximum latency,
    percentage of requests with errors from total sent, the throughput (rps),
    data received and sent in total.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You can also add a response time graph to the test, to do this go to “Thread
    Group” right click and go to Add -&amp;gt; Listener -&amp;gt; Response Time Graph. So,
    when the load test is running you can see a graph of how the latency is
    behaving.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You’re done, so let’s run the test by going to the “Run” (Alt + R) menu and
    click in “Start”&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As you can see, in eight steps you were able to create a simple load test with
JMeter, so now practice adding more listeners and keep playing with the
configuration, add more users to the test and see how your API behaves, you
might find pretty interesting things.&lt;/p&gt;
&lt;p&gt;Here’s the final screen of how your test plan should look:&lt;/p&gt;
&lt;p&gt;&lt;img alt="JMeter" src="/images/jmeter-101-example.jpg"&gt;&lt;/p&gt;
&lt;p&gt;You can download the configuration file &lt;a href="https://cmelendeztech.com/examples/Demo.jmx"&gt;here&lt;/a&gt;, have fun!&lt;/p&gt;</content><category term="misc"/><category term="jmeter"/><category term="loadtest"/><category term="dotnet"/><category term="webapi"/></entry><entry><title>AWS Lambda - Automated Snapshots</title><link href="https://cmelendeztech.com/posts/2017/01/aws-lambda-automated-snapshots.html" rel="alternate"/><published>2017-01-10T00:00:00+01:00</published><updated>2017-01-10T00:00:00+01:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2017-01-10:/posts/2017/01/aws-lambda-automated-snapshots.html</id><summary type="html">&lt;p&gt;This is my version based on the code from the blog post from Ryan S. Brown, I recommend reading his blog before mine, you can find it &lt;a href="https://serverlesscode.com/post/lambda-schedule-ebs-snapshot-backups/"&gt;here&lt;/a&gt;. I'm also including a recipe of how to deploy, my opinion fo why you should use the funtion the way it is …&lt;/p&gt;</summary><content type="html">&lt;p&gt;This is my version based on the code from the blog post from Ryan S. Brown, I recommend reading his blog before mine, you can find it &lt;a href="https://serverlesscode.com/post/lambda-schedule-ebs-snapshot-backups/"&gt;here&lt;/a&gt;. I'm also including a recipe of how to deploy, my opinion fo why you should use the funtion the way it is and how to use the function to backup and restore your EC2 Volumes. Enjoy!&lt;/p&gt;
&lt;h3&gt;What's the difference?&lt;/h3&gt;
&lt;p&gt;I added the functionality to include the ec2 tags to the snapshot, downside is that now it makes a call to the API for each snapshot, it doesn't update them all at the same time (with just one call).&lt;/p&gt;
&lt;h3&gt;What it does?&lt;/h3&gt;
&lt;p&gt;The purpose of this tool is to automate the process of backing up important servers in AWS, the idea is to have a way that we can control what servers will need daily backups and what retention period will need. For this we're going to be using some AWS services: Lambda and EC2 Tags.&lt;/p&gt;
&lt;p&gt;By having daily snapshots we will have the opportunity to restore an instance easily, reasons can vary but common ones are: corrupted volumes, AZ failure, etc. So, how this process works? Here's how:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;There are two lambda functions, one for taking snapshots and other one to act as janitor&lt;/li&gt;
&lt;li&gt;Both functions are configured to run on daily basis&lt;/li&gt;
&lt;li&gt;The backup lambda look for instances that have the 'Backup' tag (it doesn't matter the value),
then it takes snapshots of all volumes attached to the instance and looks for the value in the
tag 'Retention' to set an expiration date for the snapshot, if there's no tag it will
use a default value (30 days). When creating the snapshot it adds the expiration date, so for
example the function runs on November 1st and it has a renetion period of 7 days, it will
add an expiration date of November 8th.&lt;/li&gt;
&lt;li&gt;The janitor lambda will look for snapshots that has to delete, meaning that it will
take the date when it's running and will search for snapshots that have the tag 'DeleteOn' with
the date.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Why snapshots and not AMIs?&lt;/h3&gt;
&lt;p&gt;There are a couple of reasons for this decision:&lt;/p&gt;
&lt;p&gt;AMIs
- AMIs are cool because in order to restore we just launch a new instance with few clicks
- Downside of this is that there are times that we will need to keep the IP, IAM Role assigned, Tags and SG ... and when an emergency comes taking care of all of those aspects is too risky and complex
- There's no guarantee at 100% that when we take an AMI from a running instance that when restoring the AMI will keep working, because it was still running there might be some files corrupted (that's why the recommendation is to stop the instance first)&lt;/p&gt;
&lt;p&gt;Snapshots
- Are incremental, only the first time will take time to create it
- It's easy to restore (read below for details)&lt;/p&gt;
&lt;p&gt;For more details about them, please check the official docs: &lt;a href="http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html"&gt;AMIs&lt;/a&gt; and &lt;a href="http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSSnapshots.html"&gt;Snapshots&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;How to upload/configure the code to AWS Lambda?&lt;/h3&gt;
&lt;p&gt;For both functions, we'll need to do the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create Lambda IAM Role with the permissions described in the policy from this repo (iam/policy.json)&lt;/li&gt;
&lt;li&gt;Go to AWS Lambda and click on "Create a lambda function" button&lt;/li&gt;
&lt;li&gt;Select "Blank Function" blueprint&lt;/li&gt;
&lt;li&gt;Configure the trigger, click on the left button and choose: "CloudWatch Events - Schedule"&lt;/li&gt;
&lt;li&gt;Put a rule name if it's new or choose from an existing one&lt;/li&gt;
&lt;li&gt;Choose a schedule expression, in this case should be one day&lt;/li&gt;
&lt;li&gt;Check the "Enable trigger" checkbox&lt;/li&gt;
&lt;li&gt;Click "Next"&lt;/li&gt;
&lt;li&gt;Configure the lambda function:&lt;/li&gt;
&lt;li&gt;Put the name of the function&lt;/li&gt;
&lt;li&gt;Choose "Python 2.7" as the Runtime&lt;/li&gt;
&lt;li&gt;In the box below, paste the code of the lambda function in the src folder of this repo&lt;/li&gt;
&lt;li&gt;For Role, select the option "Choose an existing role"&lt;/li&gt;
&lt;li&gt;Choose an existing role (the one created in step 0)&lt;/li&gt;
&lt;li&gt;Leave evyrthing else as default&lt;/li&gt;
&lt;li&gt;Click Next&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ref: &lt;a href="http://docs.aws.amazon.com/lambda/latest/dg/get-started-create-function.html"&gt;http://docs.aws.amazon.com/lambda/latest/dg/get-started-create-function.html&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;How to restore an instance from a snapshot?&lt;/h3&gt;
&lt;p&gt;Follow this instructions to restore an instance with previous snapshot:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go to EC2&lt;/li&gt;
&lt;li&gt;Identify the instance and the volume(s) with problems, take note of the volume id and the AZ of the instance&lt;/li&gt;
&lt;li&gt;Go to Snapshots and search for snapshots from volume id with problems&lt;/li&gt;
&lt;li&gt;Choose the most recent snapshot and create a volume in the same AZ from the instance&lt;/li&gt;
&lt;li&gt;While the volume(s) is/are being created, stop the instance with problems&lt;/li&gt;
&lt;li&gt;Detach the volume(s) from the instance, take note of the "Block Device" name (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-detaching-volume.html)&lt;/li&gt;
&lt;li&gt;When the volume(s) is/are ready, attach the volume to the instance with the same "Block Device" name (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-attaching-volume.html)&lt;/li&gt;
&lt;li&gt;Start the instance&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Questions or suggestions?&lt;/h3&gt;
&lt;p&gt;Easy, just send me an email or open an issue &lt;a href="https://github.com/christianhxc/aws-lambda-automated-snapshots"&gt;here&lt;/a&gt;&lt;/p&gt;</content><category term="misc"/><category term="aws"/><category term="python"/><category term="aws-lambda"/><category term="ebs"/><category term="backup"/><category term="ec2"/></entry><entry><title>AWS Lambda - Redshift Copy</title><link href="https://cmelendeztech.com/posts/2016/12/aws-lambda-redshift-copy.html" rel="alternate"/><published>2016-12-21T00:00:00+01:00</published><updated>2016-12-21T00:00:00+01:00</updated><author><name>Christian Melendez</name></author><id>tag:cmelendeztech.com,2016-12-21:/posts/2016/12/aws-lambda-redshift-copy.html</id><summary type="html">&lt;p&gt;This is a short post about how to interact with Redshift inside a lambda function using python, it will also introduce the way we include external libraries in AWS Lambda. The main reason for writting this is that I had the need of automate the copy command to Redshift but …&lt;/p&gt;</summary><content type="html">&lt;p&gt;This is a short post about how to interact with Redshift inside a lambda function using python, it will also introduce the way we include external libraries in AWS Lambda. The main reason for writting this is that I had the need of automate the copy command to Redshift but couldn't find much information about how to do it, so this is why I decided to share this piece of simple code.&lt;/p&gt;
&lt;h3&gt;How it works and how can I configure it?&lt;/h3&gt;
&lt;p&gt;The script is coded in a way that you can easily set the desired configurations, the initial section has a list of global variables where I have added a description of what you should add there but I think it's worth explaining how it works:&lt;/p&gt;
&lt;p&gt;First, this lambda receives a notification from S3, then it gets the bucket and the key, based on the prefix of the file it gets the copy query from another bucket and then do some replacements to finally build the copy query that will run in the destination. Before executing the copy, it checks if the file has not been copied yet, this is to make the lambda function idempotent.&lt;/p&gt;
&lt;h3&gt;What will I need to make it work?&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;S3 Bucket where you will store your copy queries (it can be one)
1.1 (Optional) A prefix where you will store your copy queries, i.e. queries/&lt;/li&gt;
&lt;li&gt;IAM Role ARN that the destination Redshift has assigned&lt;/li&gt;
&lt;li&gt;Host, user, (port?) and password of the destination Redshift &lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;How to upload this to AWS Lambda?&lt;/h3&gt;
&lt;p&gt;You just need to follow this simple steps:
1. Zip all the content of the src folder (including the psycopg2 folder)
2. Upload the zip file to AWS Lambda (you will be able to see the code there but not the psycopg2 library)&lt;/p&gt;
&lt;h3&gt;Why do we need to have psycopg2 included?&lt;/h3&gt;
&lt;p&gt;AWS Lambda doesn't have native support (at least yet) to execute queries into Redshift and when a library is not included in the stack, you need to include all libraries needed in the package (zip) that you upload to lambda.&lt;/p&gt;
&lt;h3&gt;How is this useful?&lt;/h3&gt;
&lt;p&gt;Well, I've used this to replicate in real time the data from one Redshift to another Redshift cluster. For example, imagine that you need to store data from Firehose, you configure your stream in a way that it will convert the data in files and it will store the files in S3, so that it can be executed the copy query that will upload the data to Redshift, but what happens if you would like to upload this data to another cluster (maybe for development purposes). Easy, you just need to configure an event trigger in the S3 bucket, and done! How? this is how: &lt;a href="http://docs.aws.amazon.com/lambda/latest/dg/with-s3.html"&gt;Lambda with S3&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Questions or suggestions?&lt;/h3&gt;
&lt;p&gt;Easy, just send me an email or open an issue &lt;a href="https://github.com/christianhxc/aws-lambda-redshift-copy"&gt;here&lt;/a&gt;&lt;/p&gt;</content><category term="misc"/><category term="aws"/><category term="python"/><category term="aws-lambda"/><category term="redshift"/></entry></feed>