DEV Community

Cover image for How to deploy to IIS using Azure DevOps YAML pipelines
Richard Basson
Richard Basson

Posted on

How to deploy to IIS using Azure DevOps YAML pipelines

This blog is intended as a practical guide on how to deploy to IIS on a virtual machine using Azure DevOps YAML pipelines. If you want to read more about Azure DevOps and the benefits of DevOps check this out:
https://docs.microsoft.com/en-us/azure/devops/pipelines/?view=azure-devops

Some assumptions before we start:

  • You have access to the server you want to deploy on and admin access to PowerShell.
  • You have access to the internet on the remote server you want to deploy on.
  • You have admin access to install the .net core hosting bundle on the server.
  • You can create environments, push code to your repo and create pipelines.
  • You have a .net core API to deploy.

Creating Environment

  1. Go to Pipelines, and then select Environments.

  2. Select Create environment.

  3. Type the name of the environment, enter the description and
    select Virtual machines and click next.

New environment creation dialog example image

  1. Then select the Generic provider in the dropdown and select Windows as the operating system. You can then copy the registration script using the copy icon.

Example of new environment creation dialog

  1. Open an Administrative Powershell terminal on the windows
    machine you want to deploy to, paste the registration script in
    the terminal, and run the script. This step usually takes a
    while.

  2. When the agent is done downloading you will be prompted if you
    want to add a tag to the machine. This is not required if there
    is a single machine in the environment but you will need to add
    the associated tags if you have multiple machines in the
    environment.

  3. You will then be prompted to ask if you want to unzip for each
    task, which is not required β€” so you can say no.

  4. You will then be prompted to enter a user account for the agent
    running on the machine. You can leave it as default or create a
    new service account under which the agent will run.

Azure pipeline agent install console

When your agent creation succeeds you will be able to go back to Azure DevOps and see your virtual machine added as a resource in the environment!

Creating build stage

  1. Go to Pipelines, and then select Pipelines.

  2. Select Create Pipeline and connect to your application's source
    code.

repo selection dialogue

  1. Choose to show more on the configure pipeline step then select ASP.NET Core.

Image where configuration step is selectd

  1. You will then have a base pipeline for ASP.NET Core applications, you can then add the build stage by adding the following code snippet:
trigger:
- master

pool:
  vmImage: ubuntu-latest

variables:
  buildConfiguration: 'Release'

  #Replace these variables to suit your application
  projectName: 'WeatherService'
  websiteName: 'WeatherService'
  appPoolName: 'WeatherService'

stages:
- stage: 'Build'
  displayName: 'Build'
  jobs:
     - job: 
       steps:  
        - task: DotNetCoreCLI@2
          displayName: 'dotnet restore'
          inputs:
            command: 'restore'
            projects: '*.sln'

        - task: DotNetCoreCLI@2
          displayName: Build
          inputs:
            command: 'build'
            projects: '*.sln'
            arguments: --configuration Release

        - task: DotNetCoreCLI@2
          displayName: Test
          inputs:
            command: test
            projects: '*.sln'
            arguments: '--configuration $(BuildConfiguration)'

        - task: DotNetCoreCLI@2
          displayName: 'Publish the project - $(buildConfiguration)'
          inputs:
            command: 'publish'
            projects: '**/*.csproj'
            publishWebProjects: false
            arguments: '--no-build --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)'
            zipAfterPublish: true

        - publish: '$(Build.ArtifactStagingDirectory)'
          artifact: drop
Enter fullscreen mode Exit fullscreen mode
  1. Replace the variables at the top to suit your application by replacing the app pool name, website name, and project name with your project’s details.
  2. You can then click Save and run to have a pipeline to build that creates your application.

Create release pipeline

  1. Go to Pipelines and select Pipelines.
  2. You will see the pipeline that you have created, on the left- hand side of your pipeline select more options and then select edit.
  3. Your pipeline will load then you can append the following YAML code to your pipeline:
- stage: 'Dev'
  displayName: 'Dev'
  dependsOn: 'Build'
  condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))
  jobs:
   - deployment: Dev
     displayName: Dev
     environment: 
       name: 'Dev'    
       resourceType: VirtualMachine
     variables:
     - name: websitePhysicalPath
       value: '%SystemDrive%\inetpub\wwwroot\$(websiteName)'

     strategy:
      runOnce:
        deploy:
          steps: 
          - task: IISWebAppManagementOnMachineGroup@0
            inputs:            
              IISDeploymentType: 'IISWebsite'
              ActionIISWebsite: 'CreateOrUpdateWebsite'
              WebsiteName: '$(websiteName)'
              WebsitePhysicalPath: '$(websitePhysicalPath)'
              WebsitePhysicalPathAuth: 'WebsiteUserPassThrough'
              CreateOrUpdateAppPoolForWebsite: true
              AppPoolNameForWebsite: '$(appPoolName)'
              DotNetVersionForWebsite: 'No Managed Code'
              PipeLineModeForWebsite: 'Integrated'
              AppPoolIdentityForWebsite: 'ApplicationPoolIdentity'
              AddBinding: true
              Bindings: |
                  {
                      bindings:[
                          {
                              "protocol":"http",
                              "ipAddress":"",
                              "hostname":"",
                              "port":"80",
                              "sslThumbprint":"",
                              "sniFlag":false
                          }
                      ]
                  }
          - task: IISWebAppDeploymentOnMachineGroup@0
            inputs:
              WebSiteName: '$(websiteName)'
              Package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/$(projectName).zip'

Enter fullscreen mode Exit fullscreen mode
  1. After adding the script select Save and run you will be able to release it to the environment you created earlier.

Recap

When you are done your script it should look something like this:

trigger:
- master

pool:
  vmImage: ubuntu-latest

variables:
  buildConfiguration: 'Release'
  projectName: 'WeatherService'
  websiteName: 'WeatherService'
  appPoolName: 'WeatherService'

stages:
- stage: 'Build'
  displayName: 'Build'
  jobs:
     - job: 
       steps:  
        - task: DotNetCoreCLI@2
          displayName: 'dotnet restore'
          inputs:
            command: 'restore'
            projects: '*.sln'

        - task: DotNetCoreCLI@2
          displayName: Build
          inputs:
            command: 'build'
            projects: '*.sln'
            arguments: --configuration Release

        - task: DotNetCoreCLI@2
          displayName: Test
          inputs:
            command: test
            projects: '*.sln'
            arguments: '--configuration $(BuildConfiguration)'

        - task: DotNetCoreCLI@2
          displayName: 'Publish the project - $(buildConfiguration)'
          inputs:
            command: 'publish'
            projects: '**/*.csproj'
            publishWebProjects: false
            arguments: '--no-build --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)'
            zipAfterPublish: true

        - publish: '$(Build.ArtifactStagingDirectory)'
          artifact: drop

- stage: 'Dev'
  displayName: 'Dev'
  dependsOn: 'Build'
  condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))
  jobs:
   - deployment: Dev
     displayName: Dev
     environment: 
       name: 'Dev'    
       resourceType: VirtualMachine
     variables:
     - name: websitePhysicalPath
       value: '%SystemDrive%\inetpub\wwwroot\$(websiteName)'

     strategy:
      runOnce:
        deploy:
          steps: 
          - task: IISWebAppManagementOnMachineGroup@0
            inputs:            
              IISDeploymentType: 'IISWebsite'
              ActionIISWebsite: 'CreateOrUpdateWebsite'
              WebsiteName: '$(websiteName)'
              WebsitePhysicalPath: '$(websitePhysicalPath)'
              WebsitePhysicalPathAuth: 'WebsiteUserPassThrough'
              CreateOrUpdateAppPoolForWebsite: true
              AppPoolNameForWebsite: '$(appPoolName)'
              DotNetVersionForWebsite: 'No Managed Code'
              PipeLineModeForWebsite: 'Integrated'
              AppPoolIdentityForWebsite: 'ApplicationPoolIdentity'
              AddBinding: true
              Bindings: |
                  {
                      bindings:[
                          {
                              "protocol":"http",
                              "ipAddress":"",
                              "hostname":"",
                              "port":"80",
                              "sslThumbprint":"",
                              "sniFlag":false
                          }
                      ]
                  }
          - task: IISWebAppDeploymentOnMachineGroup@0
            inputs:
              WebSiteName: '$(websiteName)'
              Package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/$(projectName).zip'

Enter fullscreen mode Exit fullscreen mode

You should also have an environment to deploy your pipeline to called Dev.

Example of environment

When you navigate to pipelines it should look something like this:

Example of pipelines

You can have a look at this example repository as well:
https://github.com/Bassonrichard/AzureDevopsIISDEploy

Example of pipeline stages ready to deploy

When you release this you will have a DevOps pipeline setup using YAML pipelines, making your solution ready for the future with the ease of deployment of your solution.

Discussion (0)