<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mauricio Contreras</title>
    <description>The latest articles on DEV Community by Mauricio Contreras (@maurocon3ras).</description>
    <link>https://dev.to/maurocon3ras</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F70406%2Fa08aa507-f875-47f1-b306-6c0495b87914.jpeg</url>
      <title>DEV Community: Mauricio Contreras</title>
      <link>https://dev.to/maurocon3ras</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/maurocon3ras"/>
    <language>en</language>
    <item>
      <title>What the 🤬 is DevOps: Continuos Integration with Azure DevOps 👨‍💻✔</title>
      <dc:creator>Mauricio Contreras</dc:creator>
      <pubDate>Wed, 27 Nov 2019 02:39:50 +0000</pubDate>
      <link>https://dev.to/maurocon3ras/what-the-is-devops-continuos-integration-with-azure-devops-44gc</link>
      <guid>https://dev.to/maurocon3ras/what-the-is-devops-continuos-integration-with-azure-devops-44gc</guid>
      <description>&lt;p&gt;Hey there! If you haven't checked out the previous post from this series, I highly recommend it to get a bigger picture.&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Let's say that you and your team are developing the most awesome app from all times... it's Friday 5 PM, and one of your coworkers is going to miss a very important heavy metal show if he stays one more minute at the office, so he commits his work and pushes to master.&lt;/p&gt;

&lt;p&gt;Then... next Monday at 9 AM your boss enters the office jelling, WHO BROKE IT! everyone starts looking at the commit history, one by one, reverting, resetting, compiling different versions from the branches, after 4 exhausting hours they found out... it was the heavy metal guy, who pushed to master without even compiling his code that Friday.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/WH85q8e201wlO/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/WH85q8e201wlO/giphy.gif" alt="Boss"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is wrong in so many ways, just to point a few, first, why the heck your boss is an angry panda? now... seriously, you should never commit something anywhere without even testing locally on your machine. If it doesn't work on your machine don't expect to magically work somewhere else.&lt;/p&gt;

&lt;p&gt;Nobody should be able to push directly to master without passing some kind of test and, reviews and final approvement, you should have a branching strategy that is clear and known by all team members.&lt;/p&gt;

&lt;p&gt;But we can do this better and in fact, be able to deliver our code faster and safer.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Continuous Integration?
&lt;/h1&gt;

&lt;p&gt;In &lt;a href="https://docs.microsoft.com/en-us/azure/devops/learn/what-is-continuous-integration" rel="noopener noreferrer"&gt;Sam Guckenheimer&lt;/a&gt; words&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Continuous Integration (CI) is the process of automating the build and testing of code every time a team member commits changes to version control. CI encourages developers to share their code and unit tests by merging their changes into a shared version control repository after every small task completion. Committing code triggers an automated build system to grab the latest code from the shared repository and to build, test, and validate the full master branch (also known as the trunk or main).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So the whole idea of having Continuous Integration is that you're always compiling your app as your Code Repository changes, so everyone knows if something fails, you can figure out which change broke the code, who pushed the changes, find the error and solve it faster. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/MmozymbZc0RdC/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/MmozymbZc0RdC/giphy.gif" alt="Kid falling"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adopting DevOps practices won't avoid failure, you got it wrong if you thought that by adopting DevOps practices nothing is going to go wrong, instead... you're more common to be failing more than before, but you'll fail FASTER and you learn faster too.&lt;/p&gt;

&lt;h1&gt;
  
  
  Getting Started
&lt;/h1&gt;

&lt;p&gt;As we have discussed before, there are several colors and flavors of tools and products made to help you adopting DevOps practices such as Continuous Integration, but we will be using Azure DevOps, which is what I like the most.&lt;/p&gt;

&lt;h1&gt;
  
  
  But, what is Azure DevOps?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://azure.microsoft.com/en-us/services/devops" rel="noopener noreferrer"&gt;Azure DevOps&lt;/a&gt; is Microsoft's collection of Services to take your ideas into production. It has everything you need to plan and organize your work with Azure Boards, a single source for all your repositories in Azure Repos, a great CI/CD service Azure Pipelines, &lt;/p&gt;

&lt;p&gt;You don't have to use all of this, you can pick whatever service you may need, if you already have your source code somewhere else like Gitlab, you don't have to use Azure Repos, or maybe you or your company already invested in a CI/CD automation technology, again you don't have to use Azure Pipelines. Just pick what you need, they work great by themselves, but when you use altogether, you can have the best traceability of your code, you can find a bug and solve it in record time.&lt;/p&gt;

&lt;h1&gt;
  
  
  Demo Scenario
&lt;/h1&gt;

&lt;p&gt;We are going to create a CI pipeline for an application built upon ASP.NET and React, every time we make a change to our code repo, we're going to build a Docker image.&lt;/p&gt;

&lt;h1&gt;
  
  
  Pre-requisites
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Azure Subscription&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;   Don't have one yet? &lt;a href="https://azure.microsoft.com/free" rel="noopener noreferrer"&gt;create an Azure subscription for free&lt;/a&gt;. Get credits that can be used to try paid Azure services. Once you consume all your credits you can keep the account and use all free Azure services and features.&lt;/li&gt;
&lt;li&gt;   If you are Visual Studio subscriber, &lt;a href="https://azure.microsoft.com/pricing/member-offers/credit-for-visual-studio-subscribers" rel="noopener noreferrer"&gt;claim your benefits&lt;/a&gt;. Visual Studio subscription gives access to monthly credits that you can use on Azure services.&lt;/li&gt;
&lt;li&gt;   Are you student? Create an &lt;a href="https://azure.microsoft.com/free/students" rel="noopener noreferrer"&gt;Azure Student Account&lt;/a&gt; and get free credits.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;GitHub account&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h1&gt;
  
  
  Let's create our first Build Pipeline
&lt;/h1&gt;

&lt;p&gt;First, we need some code and a repository to work with, I'll be using GitHub as my code repository to show you that you don't have to use Azure Repos if you already have an existing repository.&lt;/p&gt;

&lt;p&gt;For this demo I'll be using Microsoft's TailwindTraders Open Source project, it's a fictitious e-shop that &lt;a href="https://github.com/Microsoft/TailwindTraders" rel="noopener noreferrer"&gt;you can contribute to&lt;/a&gt; on GitHub. &lt;a href="https://tailwindtraders.com" rel="noopener noreferrer"&gt;check the live running website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Make sure to fork the repo to follow along&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/microsoft" rel="noopener noreferrer"&gt;
        microsoft
      &lt;/a&gt; / &lt;a href="https://github.com/microsoft/TailwindTraders-Website" rel="noopener noreferrer"&gt;
        TailwindTraders-Website
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Tailwind Traders Website
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Tailwind Traders Website&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/microsoft/TailwindTraders-WebsiteDocuments/Images/Website.png"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fmicrosoft%2FTailwindTraders-WebsiteDocuments%2FImages%2FWebsite.png" alt="Tailwind Traders Website"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://dev.azure.com/TailwindTraders/Website/_build?definitionId=22" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/e08ba490b258be225116f0cd458174998f71dd69466d0eea77d4a7fea7a65f80/68747470733a2f2f6465762e617a7572652e636f6d2f5461696c77696e64547261646572732f576562736974652f5f617069732f6275696c642f7374617475732f576562736974652d4349" alt="Build status"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Repositories&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;For this demo reference, we built several consumer and line-of-business applications and a set of backend services. You can find all repositories in the following locations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Microsoft/TailwindTraders" rel="noopener noreferrer"&gt;Tailwind Traders&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Microsoft/TailwindTraders-Backend" rel="noopener noreferrer"&gt;Backend (AKS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Microsoft/TailwindTraders-Website" rel="noopener noreferrer"&gt;Website (ASP.NET &amp;amp; React)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Microsoft/TailwindTraders-Desktop" rel="noopener noreferrer"&gt;Desktop (WinForms &amp;amp; WPF -.NET Core)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Microsoft/TailwindTraders-Rewards" rel="noopener noreferrer"&gt;Rewards (ASP.NET Framework)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Microsoft/TailwindTraders-Mobile" rel="noopener noreferrer"&gt;Mobile (Xamarin Forms 4.0)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Deploy to Azure&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;With the following ARM template you can automate the creation of the resources for this website.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FMicrosoft%2FTailwindTraders-Website%2Fmaster%2FDeploy%2Fdeployment.json" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fmicrosoft%2FTailwindTraders-WebsiteDocuments%2FImages%2Fdeploy-to-azure.png" alt="Deploy to Azure"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When you deploy this website to Azure you can define the &lt;a href="https://github.com/Microsoft/TailwindTraders-Backend" rel="noopener noreferrer"&gt;Backend&lt;/a&gt; you want to use in case you have deploy your own backend. By defaults it is configured the public Backend environment provided by Microsoft.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: you can change the InstrumentationKey of the &lt;strong&gt;Application Insight&lt;/strong&gt; that is configured by default.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you want to update the application to use your own &lt;a href="https://github.com/Microsoft/TailwindTraders-Backend" rel="noopener noreferrer"&gt;backend&lt;/a&gt;, set &lt;code&gt;apiBaseUrl&lt;/code&gt; parameter on the ARM template provided to the url where your aks is configured.&lt;/p&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/microsoft/TailwindTraders-Website" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;You could just go to Azure Pipelines and create a Build Pipeline in dev.azure.com but today we will start from GitHub to show this great experience.&lt;/p&gt;

&lt;p&gt;Navigate to &lt;a href="https://github.com/marketplace" rel="noopener noreferrer"&gt;GitHub's Marketplace&lt;/a&gt; and search for Azure Pipelines (not Actions, we will talk about it in next posts)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fz6ydfzjd0mtubmd5lg7i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fz6ydfzjd0mtubmd5lg7i.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then install the extension and grant it access to your existing repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fxutjluvc2c566w4zho5e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fxutjluvc2c566w4zho5e.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we need to assign an Organization and project if you don't have any you can totally create them at this step. Keep in mind that Organizations are just groupings of Projects, you can have many projects inside an organization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fh8b92szakos52qg84h0m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fh8b92szakos52qg84h0m.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that Azure Pipelines already knows that we want to integrate our repository from GitHub, this is because we used the extension from GitHub's Marketplace, so select your repo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Flfulhhlq9lye9jluag4g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Flfulhhlq9lye9jluag4g.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is time to create our build definition! Azure DevOps by default offers a lot of different Templates ready to use so we can have the option to not start from scratch, and be more productive.&lt;/p&gt;

&lt;p&gt;Select or search the Docker Template&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2h4wzed5ww4gyox2osdf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2h4wzed5ww4gyox2osdf.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It will ask you to specify your app's Dockerfile path, but what is a Dockerfile, to put it simply, a Dockerfile is a like a cookbook recipe instruction, where it specifies each step in order to compile your application. Our project already has a Dockerfile, that specifies tasks like copying directories, and running commands such as npm and dotnet, it also specifies which Docker image to use, in this case, Docker Alpine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:10-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build-node&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /ClientApp&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ClientApp/package.json .&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ClientApp/package-lock.json .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ClientApp/ . &lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm run build

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;microsoft/dotnet:2.2.100-preview3-sdk-stretch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build-net&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; BuildingDocker true&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; ASPNETCORE_ENVIRONMENT=Development&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; *.csproj .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;dotnet restore
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;dotnet build
&lt;span class="k"&gt;RUN &lt;/span&gt;dotnet publish &lt;span class="nt"&gt;-o&lt;/span&gt; /ttweb

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;microsoft/dotnet:2.1-aspnetcore-runtime&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;runtime&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /web&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build-net /ttweb .&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build-node /ClientApp/build ./ClientApp/build&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; [ "dotnet","Tailwind.Traders.Web.dll" ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;for our project the path is Source/Tailwind.Traders.Web/Dockerfile&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fa2f97qie1wprfup2yd9m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fa2f97qie1wprfup2yd9m.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click Validate and configure and it will generate the following YAML definition for your Build Pipeline, it contains every step that your CI is going to execute in order to compile your application, in our case we just need one task, Docker build, specifying our Dockerfile path.&lt;/p&gt;

&lt;p&gt;Your YAML code should look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Docker&lt;/span&gt;
&lt;span class="c1"&gt;# Build a Docker image &lt;/span&gt;
&lt;span class="c1"&gt;# https://docs.microsoft.com/azure/devops/pipelines/languages/docker&lt;/span&gt;

&lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;

&lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;self&lt;/span&gt;

&lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;$(Build.BuildId)'&lt;/span&gt;

&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build&lt;/span&gt;
  &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build image&lt;/span&gt;
  &lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;job&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build&lt;/span&gt;
    &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build&lt;/span&gt;
    &lt;span class="na"&gt;pool&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;vmImage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ubuntu-latest'&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Docker@2&lt;/span&gt;
      &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build an image&lt;/span&gt;
      &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
        &lt;span class="na"&gt;dockerfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Source/Tailwind.Traders.Web/Dockerfile'&lt;/span&gt;
        &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;$(tag)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we click save, it will ask if you want to directly commit to master branch or create a Pull Request, I don't mind pushing code to master in my own demo, but if you're working on a real project, go should for the Pull Request 😁&lt;/p&gt;

&lt;p&gt;It will keep your Build Pipeline together with your application code, meaning, this has some cool advantages, for example, you can make Code Review over the Build Pipeline if someone modifies it, and ask questions about it. Another reason is that the code and how to compile the code will live together. If someone new is onboarding your project he won't have any problems trying to get it working.&lt;/p&gt;

&lt;p&gt;Once you hit Save it will start working on your pipeline tasks, such as preparing the job, downloading the source code and compiling with our Yaml definition. You can now go and prepare some coffee, or enjoy the view looking at the output window.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F667balq9xs9jl40wg6a6.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F667balq9xs9jl40wg6a6.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If everything goes as expected, when you come back you'll get a nice overview of every task marked with a green ticket ✔, and a pretty email in your inbox saying that the &lt;em&gt;[Build succeeded]&lt;/em&gt; yay! 🙌&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpc4ths8cllc4i665owdj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpc4ths8cllc4i665owdj.gif" alt="Thumbs Up"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! 🎉 you just Setup Continuous Integration for your project! So what would happen now? For every committed change coming to our master branch, there will be a new Build triggered, ensuring that what we're sending to our repo is not breaking our app.&lt;/p&gt;

&lt;h1&gt;
  
  
  Let's make a change!
&lt;/h1&gt;

&lt;p&gt;Go to your Build Pipeline and click on the three dots button, you'll see an option called Status badge, it's an indicator that you can show off on your project readme file to let everyone know about the Build status.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnnu517uif822myokvql1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnnu517uif822myokvql1.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the Sample Markdown and paste it on your README.md file, commit that change to your repository and see what happens on your Build Pipeline.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/cp3j533hjkw"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Voilà! Now you have Continuous Integration for your GitHub project! &lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;We started talking about the problems that come with not having Continuous Integration for our projects, we covered some concepts behind CI, and why it's important on DevOps. &lt;/p&gt;

&lt;p&gt;I introduced to you Azure DevOps, we just moved around in one specific service, Azure Pipelines, and to be more specific, Build Pipelines which is our CI. &lt;br&gt;
We took an existing application written in ASP.NET and React, and built a simple Pipeline using the Docker Template in just minutes.&lt;/p&gt;

&lt;p&gt;Finally, after setting up our CI, we tested that seconds after committing new code on GitHub it automatically triggered a new Build on Azure DevOps, completing our CI cycle.&lt;/p&gt;

&lt;p&gt;This is just a simple demo, this is not a production-ready CI by no means, but I hope it helps you to get started.&lt;/p&gt;

&lt;h1&gt;
  
  
  Next steps
&lt;/h1&gt;

&lt;p&gt;In the next episode, we will cover how to take what we just compiled, and deliver it to Azure through a Release Pipeline 🚀☁ as we deep dive into Continuous Delivery, stay tuned!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/14rk56liuv7mQo/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/14rk56liuv7mQo/giphy.gif" alt="See you"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>azure</category>
      <category>development</category>
      <category>agile</category>
    </item>
    <item>
      <title>Increasing your .NET Core App's Resilience: Building a Faulting API</title>
      <dc:creator>Mauricio Contreras</dc:creator>
      <pubDate>Tue, 19 Nov 2019 18:53:34 +0000</pubDate>
      <link>https://dev.to/maurocon3ras/increasing-your-net-core-app-s-resiliency-building-a-faulting-api-2dll</link>
      <guid>https://dev.to/maurocon3ras/increasing-your-net-core-app-s-resiliency-building-a-faulting-api-2dll</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Imagine you're building an app that depends heavily on consuming some API that you don't own. How do you handle errors while making requests? Maybe the API couldn't respond for a couple of seconds, and now it's working again (transient errors), or maybe the service is down and no answer will be given back for a while.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fodsbvb1yhbpm090aww8c.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fodsbvb1yhbpm090aww8c.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will be covering both scenarios on this post series, we will be simulating a faulting API that responds correctly a couple of times and then stops working for a predefined time and we will look at how to implement a retry mechanism to try sending a request again and what to do if the service does not respond after some failed intents.&lt;/p&gt;

&lt;h1&gt;
  
  
  So let's start coding!
&lt;/h1&gt;

&lt;p&gt;I created this sample using the .NET Core API Template from Visual Studio 2019, the "Weather Forecast".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fi9e2doviuwppoknw9fnz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fi9e2doviuwppoknw9fnz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our sample uses &lt;a href="https://github.com/stefanprodan/AspNetCoreRateLimit" rel="noopener noreferrer"&gt;AspNetCoreRateLimit nuget&lt;/a&gt; to restrict API calls by IP to simulate the "Out of service" state. You should definitely check it out, it has different ways to restrict API calls, and it's easy to get it to work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Once you installed the NuGet library you can add it to your &lt;strong&gt;Startup.cs&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This method gets called by the runtime. Use this method to add services to the container.&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ConfigureServices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceCollection&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// needed to load configuration from appsettings.json&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddOptions&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// needed to store rate limit counters and ip rules&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddMemoryCache&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;//load general configuration from appsettings.json&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configure&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IpRateLimitOptions&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"IpRateLimiting"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;//load ip rules from appsettings.json&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configure&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IpRateLimitPolicies&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"IpRateLimitPolicies"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;// inject counter and rules stores&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IIpPolicyStore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MemoryCacheIpPolicyStore&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IRateLimitCounterStore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MemoryCacheRateLimitCounterStore&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// https://github.com/aspnet/Hosting/issues/793&lt;/span&gt;
    &lt;span class="c1"&gt;// the IHttpContextAccessor service is not registered by default.&lt;/span&gt;
    &lt;span class="c1"&gt;// the clientId/clientIp resolvers use it.&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IHttpContextAccessor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HttpContextAccessor&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// configuration (resolvers, counter key builders)&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IRateLimitConfiguration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RateLimitConfiguration&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddControllers&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;h3&gt;
  
  
  Don't forget to also add &lt;strong&gt;app.UseIpRateLimiting();&lt;/strong&gt; to your Configure Method, mine looks like this:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IApplicationBuilder&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IWebHostEnvironment&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsDevelopment&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseDeveloperExceptionPage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseIpRateLimiting&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseHttpsRedirection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseRouting&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseAuthorization&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseEndpoints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endpoints&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;endpoints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapControllers&lt;/span&gt;&lt;span class="p"&gt;();&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;h3&gt;
  
  
  After setting up everything you can go and modify your API's appsettings.json and add the following:
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;btw: don't forget to modify the &lt;strong&gt;appsettings.Development.json&lt;/strong&gt; as I always do&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"IpRateLimiting"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"EnableEndpointRateLimiting"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"StackBlockedRequests"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"RealIpHeader"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"X-Real-IP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ClientIdHeader"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"X-ClientId"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"HttpStatusCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"QuotaExceededMessage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Oops, Something very bad went wrong and the server couldn't respond."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"GeneralRules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Period"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Limit"&lt;/span&gt;&lt;span class="p"&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="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This will be the IpRateLimit that will be used on the services you just defined on startup.cs, it will Limit the APIs calls to 3 requests per 5 seconds only. If you receive a 4th request in between those 5 seconds, you'll get a 500 error (you can set whatever HtppStatusCode you want) and a message with a response of "Oops, Something very bad went wrong and the server couldn't respond."&lt;/p&gt;

&lt;p&gt;Note that in &lt;em&gt;GeneralRules&lt;/em&gt; you can add as many rules you want, in my case for this demo purposes I just declared that I would apply one rule to all my endpoints "Endpoint": "*", but you can create rules for one specific endpoint like "Endpoint": "get:/api/values".&lt;/p&gt;

&lt;p&gt;That would be for our faulting API. You can now manually test the endpoint to check how it behaves.&lt;/p&gt;
&lt;h3&gt;
  
  
  Now let's work on our client app that will consume the faulting API.
&lt;/h3&gt;

&lt;p&gt;We will be creating a .NET Core 3.0 Worker Service that will be making requests repeatedly to our faulting API and printing on the console all the results.&lt;/p&gt;

&lt;p&gt;For that, I started by creating a new project from the template 'Worker Service'.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fr248vfxjfxoswm2cvq0y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fr248vfxjfxoswm2cvq0y.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then at &lt;strong&gt;Program.cs&lt;/strong&gt; at the CreateHostBuilder method, we add the HttpClientFactory service for our API Requests.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddHttpClient&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Our Program class should look like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.DependencyInjection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.Hosting&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;NETCore_ClientConsole&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;CreateHostBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;IHostBuilder&lt;/span&gt; &lt;span class="nf"&gt;CreateHostBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateDefaultBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConfigureServices&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;hostContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddHttpClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddHostedService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
                &lt;span class="p"&gt;});&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 we need to edit our Worker.cs class&lt;/p&gt;

&lt;p&gt;First, we need to create a new variable for our Client Factory&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IHttpClientFactory&lt;/span&gt; &lt;span class="n"&gt;_clientFactory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then we can inject it to our Worker constructor like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IHttpClientFactory&lt;/span&gt; &lt;span class="n"&gt;clientFactory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_logger&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;_clientFactory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clientFactory&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;Note that our Worker class inherits from BackgroundService, it will let us override some methods that we need for execution such as StartAsync, StopAsync, and ExecuteAsync.&lt;/p&gt;

&lt;p&gt;We need to override the StartAsync method to create our Http Client, like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;StartAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_clientFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cancellationToken&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;We already defined that every time the service starts it should create our Http Client, but what if our service stops, for that, we need to override the StopAsync method, we need to tell the service that when it stops, it also Disposes our Http Client.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;StopAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Dispose&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StopAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cancellationToken&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;And finally, we implement our logic in the ExecuteAsync task, it will make repeatedly request calls delayed by 1 second to our Faulting API that we created previously &lt;strong&gt;&lt;a href="http://localhost:59316/weatherforecast" rel="noopener noreferrer"&gt;http://localhost:59316/weatherforecast&lt;/a&gt;&lt;/strong&gt; while we don't stop the process.&lt;/p&gt;

&lt;p&gt;If the request success, we will log a message letting us know that our API responded ok. If not, it will log a Request Failed message with the respective code status. (Remember we defined that it should be a 500 code status?)&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;ExecuteAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;stoppingToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;stoppingToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsCancellationRequested&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://localhost:59316/weatherforecast"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsSuccessStatusCode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Request Succeed with code status: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;else&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Request Failed with code status: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stoppingToken&lt;/span&gt;&lt;span class="p"&gt;);&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;Our final Worker class should look like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Net.Http&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.Hosting&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.Logging&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;NETCore_ClientConsole&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Worker&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BackgroundService&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IHttpClientFactory&lt;/span&gt; &lt;span class="n"&gt;_clientFactory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;HttpClient&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IHttpClientFactory&lt;/span&gt; &lt;span class="n"&gt;clientFactory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_logger&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;_clientFactory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clientFactory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;StartAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_clientFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;StopAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Dispose&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StopAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;ExecuteAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;stoppingToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;stoppingToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsCancellationRequested&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://localhost:59316/weatherforecast"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsSuccessStatusCode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Request Succeed with code status: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;else&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Request Failed with code status: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stoppingToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&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;We did it! now you can run our Worker Service by hitting F5! &lt;br&gt;
&lt;em&gt;psst! don't forget to &lt;a href="https://docs.microsoft.com/en-us/visualstudio/ide/how-to-set-multiple-startup-projects?view=vs-2019" rel="noopener noreferrer"&gt;set up both projects&lt;/a&gt;, the API and the Service.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpsw3goi6ecn53x8f8392.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpsw3goi6ecn53x8f8392.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;That's all for now! you already learned to create a Faulting API by restricting incoming API calls and responding with different HTTP responses.&lt;br&gt;
Also, we created a Worker Service client to consume our API and see how it behaves after several API calls.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed this as much as me while writing this. &lt;br&gt;
In the next chapter I'll be adding different Resilience patterns to our client like Retry and Circuit Breaker, so Subscribe!&lt;/p&gt;

&lt;p&gt;You can find the full working sample at GitHub ❤&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/maurobytes" rel="noopener noreferrer"&gt;
        maurobytes
      &lt;/a&gt; / &lt;a href="https://github.com/maurobytes/NETCore-FaultingAPI" rel="noopener noreferrer"&gt;
        NETCore-FaultingAPI
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      .NET Core 3.0 API throttled on purpose with Worker Service as a client application
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;ASP.NETCore Resilience Sample&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;This sample demonstrates how to create a Faulting Web API utilizing .NET Core 3.0 and a throttling library.&lt;/p&gt;

&lt;p&gt;The solution has two projects, the Faulting API itself and a Worker Service that calls the API to make repeated requests and logs the responses obtained.&lt;/p&gt;

&lt;p&gt;You can follow along &lt;a href="https://dev.to/maurocon3ras/increasing-your-net-core-app-s-resiliency-building-a-faulting-api-2dll" rel="nofollow"&gt;this post I made at the Dev Community&lt;/a&gt; to learn how I built this sample&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;This sample was made with:&lt;/h2&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/aspnet/core/?view=aspnetcore-3.0" rel="nofollow noopener noreferrer"&gt;ASP.NET Core 3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/stefanprodan/AspNetCoreRateLimit" rel="noopener noreferrer"&gt;ASP.NET Core rate limiting middleware&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/maurobytes/NETCore-FaultingAPI" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>netcore</category>
      <category>csharp</category>
      <category>dotnet</category>
      <category>showdev</category>
    </item>
    <item>
      <title>What’s the most painful part of DevOps for you as a developer?</title>
      <dc:creator>Mauricio Contreras</dc:creator>
      <pubDate>Fri, 15 Nov 2019 15:58:42 +0000</pubDate>
      <link>https://dev.to/maurocon3ras/what-is-the-most-painful-part-of-devops-for-you-as-a-developer-385p</link>
      <guid>https://dev.to/maurocon3ras/what-is-the-most-painful-part-of-devops-for-you-as-a-developer-385p</guid>
      <description>&lt;p&gt;Are you working on a team that is adopting DevOps? what hurts the most? Maybe for you it is that there are too many tools, or maybe you find too difficult to build a CI/CD workflow. Let's discuss your personal experience ✌&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>devops</category>
    </item>
    <item>
      <title>What the 🤬 is DevOps: People, Process and Products </title>
      <dc:creator>Mauricio Contreras</dc:creator>
      <pubDate>Fri, 15 Nov 2019 01:37:27 +0000</pubDate>
      <link>https://dev.to/maurocon3ras/what-the-is-devops-people-process-and-products-4m4j</link>
      <guid>https://dev.to/maurocon3ras/what-the-is-devops-people-process-and-products-4m4j</guid>
      <description>&lt;p&gt;DevOps is a state of mind, that's all... you can go in peace now. Just kidding, it isn't, and if it were we could all do some yoga and meditation and everything would be solved. So, let's begin.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fx8etrzayti5id9q01kdb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fx8etrzayti5id9q01kdb.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the things that I wondered the most even before joining Microsoft was what the #&lt;em&gt;$@&lt;/em&gt;! was DevOps. The first time I heard someone talk about it I thought it was a job title, a mix between a Developer and an IT Ops guy, so the companies could need fewer people. Then after attending some events, my head was it's all about automating things, no people involved at all, damn we gonna lose our jobs!. I've seen organizations giving people the title DevOps engineer, others told me it's a certification you earn once you pass an exam.&lt;/p&gt;

&lt;p&gt;The good thing (and bad also) is that DevOps is like this giant building you stand next to, depending on where you are standing it's what you really see. If you're a developer, you probably gonna look at DevOps as automated builds, having a nice and healthy Continuous Integration(CI) and automated tests. &lt;br&gt;
If you more an Operations person, you gonna probably see DevOps as implementing infrastructure as code (IaC), Continuous Deployment (CD), and if you come from the dark side (aka as Project Manager) it's all about agile and scrum.&lt;/p&gt;

&lt;p&gt;Well... then I'm more confused than when I entered this clickbait post!&lt;br&gt;
Luckily, Microsoft decided to gather all essential aspects of DevOps in one single definition. Donovan Brown, Cloud Advocate Manager of Methods and Practices, came out with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;DevOps is the union of people, processes, and products to enable continuous delivery of value to our end users.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The most important part of this definition is, do you guess it? maybe it's people, yeah... we're super important, and the hardest part of it. Maybe it's the products we use, yeah you have to choose some technologies to be productive, but no, those are not the most important. &lt;/p&gt;

&lt;p&gt;The most important word from the definitions is &lt;strong&gt;Value&lt;/strong&gt;, why? because that's our &lt;strong&gt;end goal&lt;/strong&gt;, it's not to finish our backlog items in a Sprint, it's not to deliver a new feature. It is to deliver &lt;strong&gt;value&lt;/strong&gt; to our end users, and we can do that without changing a line of code. &lt;/p&gt;

&lt;p&gt;Think of this, me as a developer... I spend 4 months developing a new feature, I work as hard as I can to meet the deadline, work after hours, even really, having poor sleeping, solving those bugs!, I really commit to finishing these User Stories. I finally do, commit push last changes, happiness, leave instructions for Operations team to install the feature on QA and then Production.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fegku46gz34zy0nny4iea.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fegku46gz34zy0nny4iea.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Months later, I hear from my manager, "Hey! we need to talk... looks like no one is using our awesome new feature that you really worked hard on these past months". &lt;strong&gt;Has this happened to you before?, leave a comment in discussion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So shipping new features doesn't really mean shipping value. How do we overcome this type of situation?&lt;/p&gt;

&lt;p&gt;Remember the definition of DevOps? it consists of 3 main components: People, Process and Products. Let's overview each one of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  People
&lt;/h2&gt;

&lt;p&gt;Remember that I told you that People are the hardest part of the definition of DevOps? That's why we are unique, we are super complex, and we don't want to learn more things! for the sake of dog, I'll explode if I have to learn a new Mobile Framework.&lt;/p&gt;

&lt;p&gt;But how do we work? Developers really try hard creating new features, trying to get into production, they're encouraged to change things. While in the other hand we have Ops teams, they are the OPPOSITE side of things, they're encouraged to maintain servers up &amp;amp; running, healthy machines, so... they're not going to let you go into production, because the last time you changed something, you broke it and we were unable to serve customers for hours!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fw6u7k25m0c2grshx6sfj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fw6u7k25m0c2grshx6sfj.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have to change the way we encourage people end goals, deliver value to our customers and end-users! When both, developers and operations start focusing on the same goals, they start working together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Process
&lt;/h2&gt;

&lt;p&gt;In order to work together, you're going to need to adopt some processes for continuous collaboration:&lt;/p&gt;

&lt;h3&gt;
  
  
  Plan
&lt;/h3&gt;

&lt;p&gt;You need to plan your work, gather your team of highly creative and committed members, business people, devs, everyone is invited. Transform business ideas into Epics, Features and User Stories, create your product backlog and keep tracking of those tasks, while you keep discovering new features to keep delivering value to your customers.&lt;/p&gt;

&lt;p&gt;Nowadays products and services are never-ending stories, they evolve iteration by iteration. I highly recommend you invest some time to dive into the Agile work process and the Scrum Framework, in the end what we do is a team sport!&lt;/p&gt;

&lt;h3&gt;
  
  
  Develop &amp;amp; Test
&lt;/h3&gt;

&lt;p&gt;Once you have your idea you’ll need to develop it in some technology stack, preferably Microservices with .NET Core on Azure with AKS, just kidding. Choose whatever you like and need, but keep in mind some considerations.&lt;/p&gt;

&lt;p&gt;Code versioning, choose a code repo host like GitHub to keep tracking of your code changes. Establish practices like Peer Code Review, Choose a branching strategy like maintain in a master branch just what is ready to production, and have a pseudo master branch per sprint, or having a branch per feature.&lt;/p&gt;

&lt;p&gt;Continuous Integration meaning that you automatically compile your code every time you make a change, so you know that what you’re building is not breaking and when it breaks you already know and it gets easier to find who made the change and where it fails.&lt;/p&gt;

&lt;p&gt;Also try to adopt testing practices like Unit Testing, Integration Test and UI testing. I always recommend taking the time to dive into Test Driven Development (TDD) to ensure software quality. You can automate all your testing as part of your CI pipeline so that every time you compile the app you also test it to maintain the quality of your software.&lt;/p&gt;

&lt;h3&gt;
  
  
  Release
&lt;/h3&gt;

&lt;p&gt;Once you start building those small packages of value, you will want to start delivering those changes to different environments, like dev, staging, QA and Prod, among others. You can have as many environments as you and the business needs.&lt;/p&gt;

&lt;p&gt;An important part of this process is having as much as automated tasks, so you don't mess up everything. You really tried hard on building new features and creating bug free code, so why messing it up by not compiling things right, or by copying files manually, when you can have automated tasks that build and deploy the app for you and you just realize it's deployed when you receive an email with Subject: "Deployment Succeed!".&lt;/p&gt;

&lt;p&gt;You can achieve this by having a Continuous Deployment Pipeline (CD), with automated tasks that describe how to install your app on different stages. Inside this you can have integration testing, automated functional tests, even have some automated deployment on just some stages, and in others manual approval, so your boss can press that green button to go to Production. You have a LOT of things to have fun and try on this phase.&lt;/p&gt;

&lt;p&gt;In my experience a very basic or common scenario is having an automated deployment on Dev environment, so you'll always know how things are working as you make changes. On QA environment you'll have automated deployment with some release gates, meaning you should have automated test looking for open bugs or measure your Server/Cloud service performance. And for stagings and Production stages you would have a mix of automated tasks and manual approval by the business people.&lt;/p&gt;

&lt;p&gt;Well, you already planned your app, developed it and deployed into production... we're done, right? we delivered value, right? We're not done yet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Monitor &amp;amp; Learn
&lt;/h3&gt;

&lt;p&gt;This process is super crucial, as much as important as every other process we already reviewed. You must monitor what you already delivered, track your users and understand them. Most of Apps ideas fail mostly because they never understood their users, look at what features users use the most and focus your efforts in those, if your users are not using something, maybe it's time to rethink it or maybe stop wasting time on that feature and move to the other.&lt;/p&gt;

&lt;p&gt;It's crucial to learn from these data insights, you can collect a lot interesting of data from your apps, like in which time are features used, on which countries, what devices are using your apps, which buttons and functionalities are pressed, what is failing, and what is not used.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Repeat&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Probably you get the idea from the title, all these processes become a cycle, after you get insights and feedback from users you can plan new ideas and changes, develop them, test them and so on. People and technologies change, so your apps should and evolve with them.&lt;/p&gt;

&lt;h1&gt;
  
  
  Products
&lt;/h1&gt;

&lt;p&gt;In order to materialize what we talked about before, you're going to need some products or technologies. There are A TON of colors and flavors to choose from. Just to name a few, for planning: Jira or Azure Boards, Develop: Visual Studio Code, Azure, GitHub, GitLab. For Release Jenkins, Chef, Puppet or Azure Pipelines, and monitoring Azure Monitor, again, there are a ton of tools to choose from, these are just a few examples.&lt;/p&gt;

&lt;p&gt;My personal favorite is Azure for app muscle and computing power, Visual Studio &amp;amp; VS Code as IDE, GitHub for my repos and Azure DevOps to everything related to Plan, Develop, Test, Release and Monitor, in future posts I hope to go deeper on some of these tools.&lt;/p&gt;

&lt;h1&gt;
  
  
  Closing up
&lt;/h1&gt;

&lt;p&gt;DevOps is here to stay, your competition is already doing it, we need to work as teams and start collaborating, we must stop being separate organizational Silos who fight each other, or we're going to lose in the hands of the ones that are changing.&lt;/p&gt;

&lt;p&gt;Thank you so much for getting all over here, I hope you find this interesting, catch me on the next episode of &lt;strong&gt;What the 🤬 is DevOps&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>development</category>
      <category>agile</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
