Cannot deploy to 'stage' slot - azure-deployment-slots

I am trying to deploy my ASP.NET Core application to an application slot in Azure using the following azure-pipelines.yaml:
jobs:
- deployment: DeployToProduction
displayName: Deploy to Production
environment: Production
strategy:
runOnce:
deploy:
steps:
- task: DownloadBuildArtifacts#0
inputs:
buildType: current
downloadType: single
downloadPath: '$(System.ArtifactsDirectory)'
artifactName: 'drop'
- task: AzureWebApp#1
inputs:
azureSubscription: '<Azure service connection>'
appType: webApp
appName: '<the name of the stage web app>'
deployToSlotOrASE: true
slotName: 'stage'
package: '$(System.ArtifactsDirectory)/**/drop/*.zip'
However the application is released directly to the production slot and not even reaching the 'stage' slot. What am I doing wrong here? If you look at the documentation it's supposed to be pretty straight forward and easy https://learn.microsoft.com/en-us/azure/devops/pipelines/targets/webapp?view=azure-devops&tabs=windows%2Cyaml#deploy-to-multiple-web-apps
The value "Auto swap enabled" on the "General settings" page is also set to "Off".

Related

Azure DevOps Pipeline with environments get stuck

I created an environment and registered a virtual machine (on prem) as a resource
Whenever I try to run the deployment in the resources, the pipeline gets stuck in the deployment stage. Inside of the job, the only log that I see is JOb is pending...
This is the relevant section of the pipeline:
- stage: deployInTest
displayName: Deploy in Test Envs
dependsOn: build
jobs:
- deployment: Deploy
displayName: "Deploy in Test"
environment:
name: 'Development'
resourceType: VirtualMachine
strategy:
runOnce:
deploy:
steps:
- task: DownloadBuildArtifacts#1
inputs:
buildType: 'current'
downloadType: 'single'
artifactName: 'frontEnd'
downloadPath: '$(System.ArtifactsDirectory)'
Note that if I change this to the following yaml, the stage runs, but it tries to execute the task IISWebAppManagementOnMachineGroup#0 on the deployment server (OnPrem too) where IIS is not installed.
- stage: deployInTest
displayName: Deploy in Test Envs
dependsOn: build
jobs:
- deployment: Deploy
displayName: "Deploy in dev3"
environment: "Development"
strategy:
runOnce:
deploy:
steps:
- task: DownloadBuildArtifacts#1
inputs:
buildType: 'current'
downloadType: 'single'
artifactName: 'frontEnd'
downloadPath: '$(System.ArtifactsDirectory)'
Ok, so after trying something that was in the back on my mind since yesterday it worked. I saw another post in SO (I can't find it right now) that had the same issue, but they had 2 deployment jobs.
Their solution was to give them unique names i.e. 'DeployInTest' instead of deploy.
For me changing
- stage: deployInTest
displayName: Deploy in Test Envs
dependsOn: build
jobs:
- deployment: Deploy
displayName: "Deploy in Test"
Into
- stage: deployInTest
displayName: Deploy in Test Envs
dependsOn: build
jobs:
- deployment: DeployInTest #<-- this is what changed
displayName: "Deploy in Test"
Did the trick. I just realized that I was even trying that before writing the question. I'll edit the question to show the actual status with which it was not working

How to use Azure DevOps Pipelines Machine File Copy Using Environments?

I need to move files from ADO to a VM. This VM is set up using "Environments" and tagged appropriately. I would like to copy those files to that VM using its environment name and tag. So far I've only found "Windows machine file copy" which requires storing a admin login. Is there a way to use the Environments instead of hardcoding a login?
You can set up the YAML pipeline like as below:
If you want to copy the build artifact files to the VM, reference below sample.
In the Build stage set up the jobs to build the source code, and publish the artifact files for use.
In the Deploy stage, when setting the deployment job with an environment on an VM, all steps in this job will be run on this VM. In the deployment job, at the very first step, it will automatically download the artifact files to the working directory on the VM.
Then you can use the CopyFiles task to the copy the artifact files to any accessible directory on the VM.
stages:
- stage: Build
displayName: 'Build'
. . .
- stage: Deploy
displayName: 'Deploy'
dependsOn: Build
condition: succeeded()
jobs:
- deployment: Deployment
displayName: 'Deployment'
environment: '{EnvironmentName.ResourceName}'
strategy:
runOnce:
deploy:
steps:
- task: CopyFiles#2
displayName: 'Copy Files to: {Destination Directory}'
inputs:
SourceFolder: '$(Pipeline.Workspace)/drop'
Contents: '**'
TargetFolder: '{Destination Directory}'
CleanTargetFolder: true
If the files you want to copy the VM are the source files in the repository, reference below sample.
stages:
- stage: Deploy
displayName: 'Deploy'
dependsOn: Build
condition: succeeded()
jobs:
- deployment: Deployment
displayName: 'Deployment'
environment: '{EnvironmentName.ResourceName}'
strategy:
runOnce:
deploy:
steps:
- checkout: self
- task: CopyFiles#2
displayName: 'Copy Files to: {Destination Directory}'
inputs:
SourceFolder: '$(Pipeline.Workspace)'
Contents: '**'
TargetFolder: '{Destination Directory}'
CleanTargetFolder: true
For more details, you can see: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/environments-kubernetes?view=azure-devops
I have been struggling for a while with setting up an Azure Pipeline to deploy .Net Core service to VM. I had the following requirements:
to use YAML files instead of classic UI
to deploy as a windows service not to IIS
to use stages in pipeline
I was using monorepo with the service residing in MyService folder
In addition I had an external NuGet feed
My solution consisted of several projects and I was building only one of them
appsettings.release.json was being replaced with the one persisted on the server to preserve settings
I was inspired by Bright Ran-MSFT answer and suggest my complete azure-pipelines.yml file
trigger:
branches:
include:
- staging
paths:
include:
- MyService
pool:
vmImage: "windows-latest"
variables:
solution: "MyService/MyService.sln"
buildPlatform: "Any CPU"
buildConfiguration: "Release"
stages:
- stage: Build
jobs:
- job: BuildJob
steps:
- task: NuGetCommand#2
inputs:
restoreSolution: "$(solution)"
feedsToUse: "config"
nugetConfigPath: "MyService/NuGet.Config"
- task: VSBuild#1
inputs:
solution: "$(solution)"
msbuildArgs: '/t:MyService:Rebuild /p:DeployOnBuild=true /p:WebPublishMethod=Package /p:SkipInvalidConfigurations=true /p:OutDir="$(build.artifactStagingDirectory)\service_package"'
platform: "$(buildPlatform)"
configuration: "$(buildConfiguration)"
- task: VSTest#2
inputs:
platform: "$(buildPlatform)"
configuration: "$(buildConfiguration)"
- task: PublishPipelineArtifact#1
inputs:
targetPath: '$(build.artifactStagingDirectory)\service_package'
artifactName: "service_package"
- stage: Deploy
displayName: 'Deploy'
dependsOn: Build
condition: succeeded()
jobs:
- deployment: Deployment
displayName: 'Deployment'
environment: 'MainDeployEnv.MY_VM_SERVER'
strategy:
runOnce:
deploy:
steps:
- task: CopyFiles#2
displayName: 'Copy Package to: C:\azservices\MyService\service'
inputs:
SourceFolder: '$(Pipeline.Workspace)/service_package'
Contents: '**'
TargetFolder: 'C:\azservices\MyService\service\'
CleanTargetFolder: true
- task: CopyFiles#2
displayName: 'Replace appsettings.release.json'
inputs:
SourceFolder: 'C:\azservices\MyService\settings'
Contents: 'appsettings.release.json'
TargetFolder: 'C:\azservices\MyService\service\'
OverWrite: true

Configure approval for Azure Pipelines deployment stage against Azure App Services

I'm defining an Azure Pipeline as code in which there will be several deployment stages (staging and production). I need the production stage to be executed on approval from some users.
Currently there's a way to define approvals for "Environments". However this only includes resources such as VMs and K8s, but the application will be deployed on Azure App Services:
Pipeline scerpt:
- stage: Deploy_Production
pool:
vmImage: ubuntu-latest
jobs:
- job: deploy
steps:
- script: find ./
- task: DownloadBuildArtifacts#0
inputs:
buildType: 'current'
downloadType: 'single'
artifactName: 'drop'
downloadPath: '$(System.ArtifactsDirectory)'
- script: 'find $(System.ArtifactsDirectory)'
- task: AzureRmWebAppDeployment#4
inputs:
ConnectionType: 'AzureRM'
azureSubscription: 'Free Trial(xxx)'
appType: 'webAppLinux'
WebAppName: 'app'
packageForLinux: '$(System.ArtifactsDirectory)/**/*.jar'
RuntimeStack: 'JAVA|11-java11'
StartupCommand: 'java - jar $(System.ArtifactsDirectory)/drop/build/libs/app.jar'
How can I configure approvals in this scenarios?
UPDATE:
Following MorrowSolutions' answer I updated my pipeline
If I leave it as shown in the answer, the steps entry is highlighted as invalid syntax:
If I indent it, it seems to be correct. The deployment stage executes and downloads the artifact, but nothing else seems to be executed (scripts, deploy task...):
So, the resources you tie to an environment do not restrict which pipelines can be associated with that environment. Also, they're not required and at the moment Microsoft only supports Kubernetes & VMS, so you won't be able to associate an Azure App Service.
In your case, don't associate any resources with your environment. You'll want to update your YAML to use a deployment job specifically and specify the environment within your parameters. This will tell your pipeline to associate releases with the environment you've configured. It should look something like this in your case:
stages:
- stage: Deploy_Production
pool:
vmImage: ubuntu-latest
jobs:
- deployment: DeployWeb
displayName: Deploy Web App
environment: YourApp-QA
pool:
vmImage: 'ubuntu-latest'
strategy:
runOnce:
deploy:
steps:
- script: find ./
- task: DownloadBuildArtifacts#0
inputs:
buildType: 'current'
downloadType: 'single'
artifactName: 'drop'
downloadPath: '$(System.ArtifactsDirectory)'
- script: 'find $(System.ArtifactsDirectory)'
- task: AzureRmWebAppDeployment#4
inputs:
ConnectionType: 'AzureRM'
azureSubscription: 'Free Trial(xxx)'
appType: 'webAppLinux'
WebAppName: 'app'
packageForLinux: '$(System.ArtifactsDirectory)/**/*.jar'
RuntimeStack: 'JAVA|11-java11'
StartupCommand: 'java - jar $(System.ArtifactsDirectory)/drop/build/libs/app.jar'
Here is Microsoft's documentation on the deployment job schema, with more information on how to use the environment parameter:
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/deployment-jobs?view=azure-devops#schema
I actually just had a conversation with someone about this. You're not alone in thinking that the resources you tie to an environment have to be associated with the resources you're deploying within your YAML pipeline :)

Solution not found using search pattern 'D:\a\1\s\**\*.sln' Azure Devops

I am getting this error of Solution not found using search pattern 'D:\a\1\s***.sln' while building and deploying dacpac via yaml file.
My yaml file is below.
trigger:
- master
pool:
name: Azure Pipelines
vmImage: 'vs2017-win2016'
jobs:
- deployment: BuildAndDeploy
displayName: Build And Deploy Dacpac
environment: 'DEV'
strategy:
runOnce:
deploy:
steps:
- task: VSBuild#1
displayName: 'Build solution **\*.sln'
- task: CopyFiles#2
displayName: 'Copy Files to: $(build.artifactstagingdirectory)'
inputs:
SourceFolder: '$(agent.builddirectory)'
TargetFolder: '$(build.artifactstagingdirectory)'
- task: AzureKeyVault#1
displayName: 'Azure Key Vault: kv-agaurav-poc'
inputs:
azureSubscription: 'Visual Studio Enterprise-abonnement (b5970491-02a8-4fd0-b9b4-73a6e63a273a)'
KeyVaultName: 'kv-agaurav-poc'
RunAsPreJob: true
- task: SqlAzureDacpacDeployment#1
displayName: 'Azure SQL DacpacTask'
inputs:
azureSubscription: 'Visual Studio Enterprise-abonnement (b5970491-02a8-4fd0-b9b4-73a6e63a273a)'
ServerName: 'fastbin-server.database.windows.net'
DatabaseName: 'fastbin-db'
SqlUsername: agaurav
SqlPassword: '$(sqlpassword)'
DacpacFile: 'D:\a\1\a\s\bin\Debug\fastbin-db.dacpac'
One thing to note is that if I have the steps and tasks outside the environment, it works.
So, my question is how can I make yaml file find the solution inside any environment tags (In this case environment: 'DEV').
deployment job doesn't checkout you code by default. You need to add - checkout: self to download code first before you try to build you solution.

Error deploying with devops multi staging pipelines

I am using azure devops multi staging pipelines and have the following YAML file. I can create a build and then publish the build artifact to drop. When I try to deploy, I get an error seen below.
I have tried many things but I want my deployment to be in the same pipeline as I know you can add it to the release pipeline. Am I missing something?
stages:
- stage: Build
jobs:
- job: Build
pool:
name: Hosted Windows 2019 with VS2019
demands: azureps
steps:
# Restore
- task: DotNetCoreCLI#2
displayName: Restore
inputs:
command: restore
projects: '**/*.csproj'
feedsToUse: select
vstsFeed : myfeed
includeNuGetOrg : true
# Build
- task: DotNetCoreCLI#2
displayName: Build
inputs:
command: build
projects: '**/*.csproj'
arguments: '--configuration Release'
# Publish
- task: DotNetCoreCLI#2
displayName: Publish
inputs:
command: publish
publishWebProjects: True
arguments: '--configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory)'
zipAfterPublish: True
# Publish Artifact
- task: PublishBuildArtifacts#1
- stage: Dev
jobs:
# track deployments on the environment
- deployment: DeployWeb
pool:
vmImage: 'ubuntu-latest'
# creates an environment if it doesn’t exist
environment: 'my-dev'
strategy:
# default deployment strategy
runOnce:
deploy:
steps:
- task: DownloadBuildArtifacts#0
inputs:
buildType: 'current'
downloadType: 'single'
artifactName: 'drop'
downloadPath: '$(build.ArtifactStagingDirectory)'
- task: AzureWebApp#1
displayName: Azure Web App Deploy
inputs:
appType: 'webapp'
azureSubscription: '213456123'
appName: mytestapp
package:$(System.DefaultWorkingDirectory)/**/*.zip
Error I am getting
The artifact has been downloaded to artifact folder $(build.ArtifactStagingDirectory), so the package path could be: package:$(build.ArtifactStagingDirectory)/**/*.zip
In my case, I simply copied artifact download path from DownloadBuildArtifacts#0 task after its implementation and pasted it in AzureWebApp#1 task's package property.
Yes, it required me to run a single fail so that I can find exact path where artifacts are downloaded. Can simply run DownloadBuildArtifacts#0 task only so that you can find exact download path of artifacts.