Skip to content

vanroon/TGIF_AzurePipelines

 
 

Repository files navigation

Azure pipelines

Welcome to the workshop building and deploying applications with Azure Devops. This workshop focusses on the possibilities of building your software pipeline and the practice of creating a single (immutable) artifact and upgrading that artifact through all your software pipeline phases. Each succesfull phase will improve your confidence in the quality of your artifact and lowering the risk when it hits production. alt text

Azure Devops is completely free up to 5 users. You can set it up without a creditcard and it is the only tool we will be using for this workshop.

Before we start

We can't publish anything without the sources to create an artifact. All the code needed during this workshop is in this repository or will be provide in the text.

Let's do it!

  1. Get the sources
    We are going to get the code from the github repo into your own Azure Devops Git repo to build and run it. This way we can validate the code in an independent place and prevent any "It works on my machine" conversations. Once the code builds we have our artifact to start the deployment.
    alt text

    • In your project click on menu item Repos
    • Check which ways you can create your repository alt text
    • Click on import under heading or import a repository
    • Enter URL: https://github.com/ErickSegaar/TGIF_AzurePipelines.git and click import
    • After the import is done, you should be redirected to your Git repository with the sources of the workshop.
      Note: In this workshop we'll use the web interface for any code changes. If you prefer you can swith to Git. Use the Clone button on the top right to get your repository's URL.
  2. Create your first build

    • Go to Pipelines -> New pipeline
      alt text

    • We come back to yaml later for now choose the classic editor.
      alt text

    • Leave everything default and click Continue
      alt text

    • Select the .NET Desktop template and click Apply
      alt text

    • To get familiar with the build check each task. You can see the template added:

      • The restore of nuget packages used for compilation of your application in our case NUnit
      • Build and unittest our application
      • Publish the symbols for later debug possibilities
      • Publish the created artifacts back into Azure Devops
    • Click on menu Save & queue and select menu item Save & queue and in the new window click on Save & Run.

    • Click on the new job Agent Job 1:
      alt text

  3. Fixing your build

    By now you should notice that your build failed, this is because there is a bug in the calculator class.

    • Go back to the job overview and click Tests
    • In the test results you can see that some tests succeeded and some failed

      To fix this we need to change the calculator class, but first create a continues build. This will make it so that everytime we make a change to the code a build will trigger to validate the changes. This will notify you when you made a change that does not compute. This is not Continues Integration! CI is a practice that requires more than just a continuous build every time you change your bits, but it is certainly part of it.
    • Enable Continuous Build
      Go to your pipeline definition and choose Edit, Triggers, check the box of Enable continuous integration, open the and Save and queue menu, click Save and Save.
    • Fix the calculator class Go to your Repos find the Calculator.cs click Edit
      Replace just the line return a * b; with return a + b; because we abviously made a mistake using a Multiplication (*) instead of Add (+)
    • Click Commit add a nice message and click Commit again
      Now your build is triggered immediately, go and check it out now your tests should succeed.
  4. Create release for single environment

    alt text
    Now we have an artifact it is time to spin up some tasks to mimic the deployment. We are going to use powershell for that.

    • In the menu go to Pipeline > Releases and click on New pipeline
    • Select Empty job
    • Add the artifact of the build with Add an artifact
    • Click on Stage 1 and change the Stage name to Prod
    • Click on Tasks to define your deployment for Prod
    • Click the + button and add a Powershell task
    • Click on the Powershell task and configure it:
      • Rename the Display name to Fake deployment
      • Set Type to inline
      • Overwrite the Script field with:
        Write-Host "This task mimics the deployment as we won't go to azure today"
    • Right-click the Powershell task and select Clone task(s)
    • Configure the cloned task:
      • Rename the Display name to Call the application
      • Change Script to:
        &"$(System.DefaultWorkingDirectory)/$(Release.PrimaryArtifactSourceAlias)/drop/EchoConsole/bin/Release/EchoConsole.exe" "Hello World"
        alt text
    • Save the release pipeline
    • Create a new release to deploy your build and check the logs of the deployment
    • Talk about approvals
  5. Prepare pipeline and code for multiple environments

    alt text
    Now we have an artifact deployed to our production environment we start to wonder if that is such a wise descision. Let's create a few more phases, we first want to test our deployment and want to have the possibility to test our code before it will be released to production. Therefore we create 2 stages Develop and Test. We also want to deploy to an environment that is "production like", as a final check that we won't bump into some trouble in prod that we could have caught earlier. (There are more strategy types verry usefull to give you more confidence in prod like matrix, ringdeployment and feature switch strategy. But this pre-prod is a well known and often wrongly used one.) Of course we can start and clone/copy the current Prod. A problem with that is whenever we make a change afterwards we need to apply that change to all stages identically, a disaster waiting to happen. Let's make sure alle stages always use the same steps for deployment.

    • Create a taskgroup
      Go to the Tasks of you Prod stage and Ctrl+Click the Fake deployment and Call the application tasks. Now rightclick and choose Create task group. Next choose a nice name and leave everything default and click Create. We now made a taskgroup and you can re-use it in any phase. Next Save
    • We should also Enable CD because whenever we have a new artifact it should be deployed automatic.
      Go to your release pipeline and choose Edit, and click on the lightning bolt at the artifact, set the Continuous deployment trigger to Enabled and Save
    • First change the application to get some values from the applicationconfig. Go to Repos, EchoConsole/Program.cs and click on Edit to change the file to:
      using System;
      using System.Linq;
      
      namespace EchoConsole
      {
          class Program
          {
              static void Main(string[] args)
              {
                  bool runSmoke = args.Contains("-smoke");
      
                  if (runSmoke)
                  {
                      Smoke smoke = new Smoke();
                      smoke.Execute();
                      return;
                  }
      
                  if (args.Any())
                  {
                      Console.WriteLine($"Given argument {args.First()}");
                  }
      
                  Console.WriteLine(System.Configuration.ConfigurationManager.AppSettings.Get("ApplicationEnvironment"));            
              }
          }
      }
      
    • Now commit your changes, with the comment Changed my program with application settings
    • Check your build and once that's finished the new release. Talk about what you see
  6. Change pipeline to inject different values for each environment

    If we are going to use the same artifact for deployment to all environments; how do we defer database connections or different web adresses? We are accomplishing that by the use of tokens in the configuration files. Those tokens will be injected by the pipeline at deployment time.

    • First we're going to install an extenstion from the marketplace:
      • Click on the shopping bag icon in the top-right, then Browse Marketplace
      • Search & install "Replace Tokens"
    • Add 3 more environments with different environment variables:
      • Go to the Edit screen of your release pipeline and go to Tasks right click the recently created task group Manage task group.
      • Add the Replace Tokens task as the first step after the Fake Deployment step, save the Task group
      • Go back to Variables and add the ApplicationEnvironment variable with a Prod value and scope Prod. Click Save.
      • Go back to the pipeline overview and clone the Prod stage 3 times to:
        • Develop
        • Test
        • Pre prod
          alt text
      • Arrange the environments that Develop triggers after release creation and each other environment after a succesfull deploy of the previous one
      • Now go back to the variables and notice that also the ApplicationEnvironment variable has been cloned. Replace the value for each environment to one to represent the scope. alt text
      • Talk about the variables to understand its scoping and what each value means for each stage in your release pipeline
      • Save your release pipeline
    • start a new release and watch your deployment going automaticly first to dev, test, preprod, prod. After the release completes you can validate the injected values from the log for each environment.
  7. Explain different possibilities for releasing, libraries, and taskgroups
    Administering one pipeline can be easy, but what makes it hard is when you have hundreds. How can you make it easier to change multiple envrionments at once?

    • Talk about versions and drafts
    • Add a variable group
      • Go to Pipelines, Library and click on + Variable Group
      • Give it the name GeneralVariables
      • Use + Add to create variable GeneralInfo and give it a unique value
      • Save the variable group
    • Link the variable group to your release pipeline
      • Go to the Edit screen of your release pipeline and go to Variables, Variable groups and click the Link variable group button
      • Select GeneralVariables and click the Link button
      • Save your release pipeline
    • Edit the following code:
      • In EchoConsole/program.cs replace:
          Console.WriteLine(System.Configuration.ConfigurationManager.AppSettings.Get("ApplicationEnvironment"));            
      
      with:
          Console.WriteLine(System.Configuration.ConfigurationManager.AppSettings.Get("ApplicationEnvironment"));            
          Console.WriteLine(System.Configuration.ConfigurationManager.AppSettings.Get("GeneralInfo")); 
      
    • check the changes in your build and deployment logs
  8. Add smoke tests to your deployment

    We just can't introduce new changes to our code and not test them. We have our unit tests, and of course the team will run tests on the test environment, but we are changing configuration every step. We need to validate this before any of our customers uses our application. We do that by using smoke tests. And yes, you do those tests also in production. There is a simple implementation in the code for the workshop. But how you implement depends on application type, architecture and environment. But it is an absolute MUST, we can let an application crash just as hard using a configuration change as I can by changing the code

    • Go to the earlier created taskgroup
      • add a new inline powershell script right after the Deploy step. Make use of this script:
        &"$(System.DefaultWorkingDirectory)/$(Release.PrimaryArtifactSourceAlias)/drop/EchoConsole/bin/Release/EchoConsole.exe" "-smoke"
      • Next add Publish Test results step with:
        • Test result format VSTest
        • Test result files **/smoketestresult.trx
        • Under Control Options change Run this task to Even if a previous task has failed, unless the deployment was canceled
    • Save and start a new release, now you can see once an environment completes a percentage succeeded test, click on it and adujust the filter to find out what worked and what didn't.

      To fix any errors make sure there is somewhere in the value the word local in both the GeneralInfo library and the ApplicationEnvironment variables. And start a Create a release.
  9. Change release to use parrallelization

    alt text

    • Add a Pipeline variable array (comma separated value variable)Environments with the value First, Second
    • change Execution plan of the latest 2 stages to Multi-configuration with 2 agents and set Multiplier to $(Environments). Save the pipeline.
    • change the taskGroup to call the application to &"$(System.DefaultWorkingDirectory)/$(Release.PrimaryArtifactSourceAlias)/drop/EchoConsole/bin/Release/EchoConsole.exe" "Hello World $(Environments)" when you then go back to the root of the taskgroup your will notice that there has been an parameter added. Make sure you give a default value $(Environments). Start a new release and see the last 2 stages run in parallel.

About

A repository for the #TGIF sessions @Devoteam. This Topic Azure Pipelines

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C# 100.0%