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
Go to Pipelines, and then select Environments.
Select Create environment.
Type the name of the environment, enter the description and
select Virtual machines and click next.
- 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.
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.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.You will then be prompted to ask if you want to unzip for each
task, which is not required — so you can say no.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.
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
Go to Pipelines, and then select Pipelines.
Select Create Pipeline and connect to your application's source
code.
- Choose to show more on the configure pipeline step then select ASP.NET Core.
- 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:
YAML
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
- 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.
- You can then click Save and run to have a pipeline to build that creates your application.
Create release pipeline
- Go to Pipelines and select Pipelines.
- You will see the pipeline that you have created, on the left- hand side of your pipeline select more options and then select edit.
- Your pipeline will load then you can append the following YAML code to your pipeline:
YAML
- 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'
- 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:
YAML
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'
You should also have an environment to deploy your pipeline to called Dev.
When you navigate to pipelines it should look something like this:
You can have a look at this example repository as well:
https://github.com/Bassonrichard/azure-devops-iis-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.
Top comments (0)