YAML-based deployment not working from ADO, can do a manual deploy from VS Code - azure-devops

I am building a yaml-based release pipeline to deploy an app service from ADO to Azure App Services. I can perform a manual deploy and all of the code deploys as a zip and then it works with WEBSITE_RUN_FROM_PACKAGE="1".
for example from VS Code:
az webapp config appsettings set --resource-group RGP --name sitename --settings WEBSITE_RUN_FROM_PACKAGE="1"
az webapp deployment source config-zip --resource-group RGP --name sitename --src sitename.zip
It returns
"author": "N/A",
"author_email": "N/A",
"complete": true,
"deployer": "ZipDeploy",
"end_time": "2022-02-02T04:28:38.6143958Z",
"id": "xxx",
"is_readonly": true,
"is_temp": false,
"last_success_end_time": "2022-02-02T04:28:38.6143958Z",
"log_url": "https://sitename.scm.azurewebsites.net/api/deployments/latest/log",
"message": "Created via a push deployment",
"progress": "",
"provisioningState": "Succeeded",
"received_time": "2022-02-02T04:28:10.9806495Z",
"site_name": "sitename",
"start_time": "2022-02-02T04:28:11.3244119Z",
"status": 4,
"status_text": "",
"url": "https://sitename.scm.azurewebsites.net/api/deployments/latest"
However, in my YAML release, I am using the following, and it both over-writes WEBSITE_RUN_FROM_PACKAGE="1" and won't run with or without that value added after the fact. It return a site permission error.
Here is the relevant YAML section. I'm wondering if I need to use deployer: zipDeploy somehow, based on the above success and the below failing even though it puts the same zip file in the wwwroot dir of the app service. FYI - I am using terraform to provision the site and Configuration Items and then running the deploy afterwards.
- stage: deploy
dependsOn: [infrastructure]
displayName: DEPLOY APP
jobs:
# Track deployments on the environment.
- deployment: DeployWeb
displayName: deploy Web App
pool:
vmImage: 'windows-latest'
# Creates an environment if it doesn't exist.
environment: '$(workstream)-$(env_identifier)'
strategy:
# Default deployment strategy
runOnce:
deploy:
steps:
- checkout: self
- bash: ls $BUILD_ARTIFACTSTAGINGDIRECTORY
- bash: ls $PIPELINE_WORKSPACE
- task: AzureRmWebAppDeployment#4
displayName: 'deploy $(tier_prefix)-$(region_prefix)-$(workstream)-UI-01'
inputs:
ConnectionType: 'AzureRM'
azureSubscription: 'subname'
# SlotName: 'slot'
appType: 'webApp'
WebAppName: '$(tier_prefix)-$(region_prefix)-$(workstream)-UI-01'
ResourceGroupName: 'XZ$(region_prefix)-E-N-$(rgp_identifier)-$(tier_prefix)-RGP-10'
# DeployToSlotOrASEFlag: true
Package: '$(Pipeline.Workspace)/build/eu-web-$(workstream)/'
UseWebDeploy: true
enableCustomDeployment: true
deploymentMethod: runFromPackage
ExcludeFilesFromAppDataFlag: false
TakeAppOfflineFlag: false
removeAdditionalFilesFlag: true
additionalArguments: '-useCheckSum'

Here was my solution, so far it seems to work.
I completely dropped everything around UseWebDeploy
UseWebDeploy: true
enableCustomDeployment: true
deploymentMethod: runFromPackage
ExcludeFilesFromAppDataFlag: false
TakeAppOfflineFlag: false
removeAdditionalFilesFlag: true
additionalArguments: '-useCheckSum'
and change this
Package: '$(Pipeline.Workspace)/build/eu-web-$(workstream)/'
to this
Package: '$(Pipeline.Workspace)/build/eu-web-$(workstream)/eu-web-$(workstream)-$(env_identifier).zip'

Related

Update env file in Azure Pipeline

I have an Azure build pipeline and I want to update the .env file when deploying to the dev environment. Below is the deployment stage,
- stage: 'deploy_to_DEV'
jobs:
- job: deploy_to_dev
pool:
vmImage: ubuntu-latest
steps:
- task: DownloadPipelineArtifact#2
enabled: true
inputs:
source: 'current'
targetPath: '$(Pipeline.Workspace)'
- script: |
echo "REACT_APP_DEV_API_KEY=Test" > '$(Pipeline.Workspace)/$(Build.BuildId)/.env'
- script: |
cat '$(Pipeline.Workspace)/$(Build.BuildId)/.env'
- script: pwd && ls -alR '$(Pipeline.Workspace)'
- task: AzureStaticWebApp#0
enabled: true
displayName: "Deploy Dev01"
name: DeployDev01
inputs:
workingDirectory: '$(Pipeline.Workspace)/$(Build.BuildId)/'
app_location: './'
output_location: './'
skip_app_build: true
skip_api_build: true
verbose: true
is_static_export: true
azure_static_web_apps_api_token: $(dev-token)
By default the content of the .env file are,
REACT_APP_DEV_API_KEY=Original
After I run the following scripts,
echo "REACT_APP_DEV_API_KEY=Test" > '$(Pipeline.Workspace)/$(Build.BuildId)/.env'
cat '$(Pipeline.Workspace)/$(Build.BuildId)/.env'
The following content is printed on the console,
REACT_APP_DEV_API_KEY=Test
This means that the content of the file has been updated. But after the pipeline is finished successfully, my REACT app is still showing the value
Original
Why the file is not updated on the Azure Static Web when I update it before copying and the updated file should be copied to the target?

Matrix in Azure DevOps yaml pipeline: The pipeline is not valid

For our mobile app, I am trying to use matrix to set different pipeline values in Debug and Release:
jobs:
- job: Job_1
displayName: .Net MAUI Job
strategy:
maxParallel: 2
matrix:
Debug:
BuildConfiguration: Debug
ProvProfile: 'My_Testing_Profile.mobileprovision'
CertSecureFile: 'ios_development.p12'
CertPwd: $(IOSP12Password-testing)
Release:
BuildConfiguration: Release
ProvProfile: 'My_Distribution_Profile.mobileprovision'
CertSecureFile: 'ios_distribution.p12'
CertPwd: $(IOSP12Password-distribution)
...
- task: InstallAppleCertificate#2
displayName: Install Apple Certificate
inputs:
certSecureFile: $(CertSecureFile)
certPwd: $(CertPwd)
setUpPartitionIdACLForPrivateKey: false
deleteCert: false
deleteCustomKeychain: false
- task: InstallAppleProvisioningProfile#1
displayName: Install Testing Apple Provisioning Profile
inputs:
provisioningProfileLocation: 'secureFiles'
provProfileSecureFile: $(ProvProfile)
...
- task: DotNetCoreCLI#2
displayName: 'dotnet publish ($(BuildConfiguration))'
inputs:
command: 'publish'
publishWebProjects: false
projects: 'My_MobileApp.sln'
arguments: '-f:net6.0-ios -c:$(BuildConfiguration) -r ios-arm64 /p:ArchiveOnBuild=true /p:EnableAssemblyILStripping=false'
zipAfterPublish: false
modifyOutputPath: false
IOSP12Password-testing and IOSP12Password-distribution are variables set in the pipeline.
I am getting the following error:
There was a resource authorization issue: "The pipeline is not valid.
Job Job_1: Step InstallAppleCertificate input certSecureFile references secure file $(CertSecureFile) which could not be found. The secure file does not exist or has not been authorized for use.
Job Job_1: Step InstallAppleProvisioningProfile input provProfileSecureFile references secure file $(ProvProfile) which could not be found. The secure file does not exist or has not been authorized for use.
I suspect that CertPwd is also wrong.
I don't understand why it is not working, if there is no problem with BuildConfiguration at all.
Azure Devops Services now don't support using variable in secure file.
So if your profile and certificate files have already been added into the library-secure file, you need to directly write the name of the file into your yaml instead of variables.
If you do need the feature, you can directly report the feature requests. That will allow you to directly interact with the appropriate engineering team and make it more convenient for the engineering team to collect and categorize your suggestions.
updates:
You could try to use 'condition sytax' here to repeat the two tasks with different hard code value, if you need to choose the value in runtime, you could use parameters, it should be something like this:
parameters:
- name: CertSecureFile
values:
- ios_development.p12
- ios_distribution.p12
- name: ProvProfile
values:
- My_Testing_Profile.mobileprovision
- My_Distribution_Profile.mobileprovision
stages:
- stage: A
jobs:
- job: Job_1
displayName: .Net MAUI Job
strategy:
maxParallel: 2
matrix:
Debug:
BuildConfiguration: Debug
ProvProfile: 'My_Testing_Profile.mobileprovision'
CertSecureFile: 'ios_development.p12'
CertPwd: $(IOSP12Password-testing)
Release:
BuildConfiguration: Release
ProvProfile: 'My_Distribution_Profile.mobileprovision'
CertSecureFile: 'ios_distribution.p12'
CertPwd: $(IOSP12Password-distribution)
steps:
- task: InstallAppleCertificate#2
condition: eq('${{ parameters.CertSecureFile }}', 'ios_development.p12')
displayName: Install Apple Certificate
inputs:
certSecureFile: ios_development.p12
certPwd: $(CertPwd)
setUpPartitionIdACLForPrivateKey: false
deleteCert: false
deleteCustomKeychain: false
- task: InstallAppleProvisioningProfile#1
condition: eq('${{ parameters.ProvProfile }}', 'My_Testing_Profile.mobileprovision')
displayName: Install Testing Apple Provisioning Profile
inputs:
provisioningProfileLocation: 'secureFiles'
provProfileSecureFile: My_Testing_Profile.mobileprovision
- task: InstallAppleCertificate#2
condition: eq('${{ parameters.CertSecureFile }}', 'ios_distribution.p12')
displayName: Install Apple Certificate
inputs:
certSecureFile: ios_distribution.p12
certPwd: $(CertPwd)
setUpPartitionIdACLForPrivateKey: false
deleteCert: false
deleteCustomKeychain: false
- task: InstallAppleProvisioningProfile#1
condition: eq('${{ parameters.ProvProfile }}', 'My_Distribution_Profile.mobileprovision')
displayName: Install Testing Apple Provisioning Profile
inputs:
provisioningProfileLocation: 'secureFiles'
provProfileSecureFile: My_Distribution_Profile.mobileprovision
updates:
If you want to use template with parameters, you could put the repeated two jobs with two fixed value in two templates yaml in the same repo and branch.(here we name it for example, template1.yaml and template2.yaml)
Then you could try something like this:
steps:
- ${{ if and(eq(parameters.CertSecureFile, 'ios_development.p12'),eq(parameters.ProvProfile, 'My_Testing_Profile.mobileprovision')) }}:
- template: template1.yaml
- ${{ else }}:
- template: template2.yaml

Azure devops deploy to function app with access restrictions

I am trying to deploy a function app via an Azure DevOps pipeline, however I am receiving the following error:
##[error]Failed to deploy web package to App Service.
##[error]To debug further please check Kudu stack trace URL : $URL_REMOVED
##[error]Error: Error: Failed to deploy web package to App Service. Ip Forbidden (CODE: 403)
From some googling a suggested solution seems to be to whitelist agent IP before the deployment, and then remove it after. I have added this to my pipeline, and I can see the agent IP get added to access restrictions, however the deployment still fails.
Here is my pipeline file:
# Node.js Function App to Linux on Azure
# Build a Node.js function app and deploy it to Azure as a Linux function app.
# Add steps that analyze code, save build artifacts, deploy, and more:
# https://learn.microsoft.com/azure/devops/pipelines/languages/javascript
trigger:
- main
variables:
# Azure Resource Manager connection created during pipeline creation
azureSubscription: 'xxx'
# Function app name
functionAppName: 'xxx'
# Environment name
environmentName: 'xxx'
# Agent VM image name
vmImageName: 'ubuntu-latest'
stages:
- stage: Build
displayName: Build stage
jobs:
- job: Build
displayName: Build
pool:
vmImage: $(vmImageName)
steps:
- task: NodeTool#0
inputs:
versionSpec: '10.x'
displayName: 'Install Node.js'
- script: |
if [ -f extensions.csproj ]
then
dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin
fi
displayName: 'Build extensions'
- script: |
npm install
npm run build --if-present
npm run test --if-present
displayName: 'Prepare binaries'
- task: ArchiveFiles#2
displayName: 'Archive files'
inputs:
rootFolderOrFile: '$(System.DefaultWorkingDirectory)'
includeRootFolder: false
archiveType: zip
archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
replaceExistingArchive: true
- upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
artifact: drop
- stage: Deploy
displayName: Deploy stage
dependsOn: Build
condition: succeeded()
jobs:
- deployment: Deploy
displayName: Deploy
environment: $(environmentName)
pool:
vmImage: $(vmImageName)
strategy:
runOnce:
deploy:
steps:
- task: AzureCLI#2
inputs:
azureSubscription: '$(azureSubscription)'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
agentIP=$(curl -s https://api.ipify.org/)
az functionapp config access-restriction add -g xxx -n xxx --action Allow --ip-address $agentIP --priority 200
- task: AzureFunctionApp#1
displayName: 'Azure Functions App Deploy: xxx'
inputs:
azureSubscription: '$(azureSubscription)'
appType: functionAppLinux
appName: $(functionAppName)
package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip'
Is anyone able to advise where I am going wrong?
I've had a simmilar issue while adding the agent IP to the network restrictions of an storage account (using Powershell but you'll understand the idea), we added a 60s sleep to be sure that the setting are taken into account by Azure.
$sa_name = "sapricer$env_prefix"
if ($null -ne (Get-AzStorageAccount -ResourceGroupName $sa_rg -AccountName $sa_name -ErrorAction Ignore)) {
Write-Output "Storage account '$sa_name' exists"
if ($enable) {
Write-Output "Add ip rule for $current_ip on $sa_name..."
Add-AzStorageAccountNetworkRule -ResourceGroupName $sa_rg -AccountName $sa_name -IPAddressOrRange $current_ip
}
else {
Write-Output "Remove ip rule for $current_ip on $sa_name..."
Remove-AzStorageAccountNetworkRule -ResourceGroupName $sa_rg -AccountName $sa_name -IPAddressOrRange $current_ip
}
}
Start-Sleep -Seconds 60
I found the solution to this.
Function Apps have two IP Restriction sections, one for the App and one for the SCM site. The SCM site is the one that requires the IP to be whitelisted in order for the deployment to work:
az functionapp config access-restriction add --scm-site true -g xxx -n xxx --action Allow --ip-address $agentIP --priority 200
You can deploy Azure function app to azure devops pipeline using azure function app task from Azure devops pipeline tasks
Here is the sample snippet for deploying azure function app
variables:
azureSubscription: Contoso
# To ignore SSL error, uncomment the below variable
# VSTS_ARM_REST_IGNORE_SSL_ERRORS: true
steps:
- task: AzureFunctionApp#1
displayName: Azure Function App Deploy
inputs:
azureSubscription: $(azureSubscription)
appName: samplefunctionapp
package: $(System.DefaultWorkingDirectory)/**/*.zip
Here is the Microsoft Document for deploying azure function app.

Uploading Repo Changes to Remote Server via FTP using DevOp

I am new to Azure Devops and i am trying to update the changes from the Repo to the production website via Azure Devops through ftp since its on a remote server / different host.
i am using Upload Via FTP Task but iam getting the following error :
/azure-pipelines.yml (Line: 3, Col: 1): A sequence was not expected
this the YAML Task :
# FTP upload
# Upload files using FTP
- task: FtpUpload#2
inputs:
credentialsOption: 'inputs'
serverUrl: 'serverurl'
username: 'username'
password: 'mypass'
rootDirectory: '$(System.DefaultWorkingDirectory)/Directoryname'
filePatterns: '**'
remoteDirectory: 'ftp url link'
clean: false
cleanContents: false
preservePaths: false
trustSSL: false
The Repo is is done and Using Default Agent
I am not sure if i am missing something or there is an alternative way.
Help is Appreciated.
Thanks
Edit :
# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
- master
pool:
vmImage: ubuntu-latest
steps:
- script: echo Hello, world!
displayName: 'Run a one-line script'
- script: |
echo Add other tasks to build, test, and deploy your project.
inputs:
credentialsOption: 'inputs'
serverUrl: 'input'
username: 'input'
password: 'input'
rootDirectory: 'input'
filePatterns: '**'
remoteDirectory: 'input'
clean: false
cleanContents: false
preservePaths: false
trustSSL: false
echo See https://aka.ms/yaml
displayName: 'Run a multi-line script'
Updated YAML, no more errors but no result in the remote ftp or files being uploaded
Below steps can successfully upload the files on my side.
1, Make sure your FTP url, username and password is correct(Make sure you can do it on local firstly.)
1, Create an FTP service connection on DevOps Project-level settings:
2, Create a repo that contains the files that you want to use FTP to upload:
This is the structure on my side:
3, Set up a pipeline based on this repo:
4, Use the below pipeline YAML definition to replace the previous content and then run the pipeline.
pool:
name: Azure Pipelines
steps:
- task: FtpUpload#2
displayName: 'FTP Upload: FTPUploadFolder'
inputs:
serverEndpoint: 'FTPTo_testbowman1'
rootDirectory: FTPUploadFolder
remoteDirectory: this_is_remote_dir
5, you can see that the entire folder uploaded successfully:
Let me know if you have more concerns.

Java Azure Function Deployed from Azure DevOps pipeline says success, but no Functions are deployed

I would like to create pipeline which deploy Java Azure Function. The pipeline Job says successful (1 artifact produced.100% tests passed. 13 files uploaded) but I cannot see Functions deployed in Azure Portal.
Please advice me. I'm following tutorial as base, but I'm using Git Repo of Azure DevOps instead of GitHub. https://learn.microsoft.com/en-us/azure/devops/pipelines/ecosystems/java-function?view=azure-devops
My Visual Code project (unzipped) is located on git /MyProject/FunctionsJava/
Pom.xml is located (unzipped) /MyProject/FunctionsJava/pom.xml
My yml is followings:
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
# at the top of your YAML file
# set some variables that you'll need when you deploy
variables:
# the name of the service connection that you created above
serviceConnectionToAzure: connection-to-TestRG-rg
# the name of your web app here is the same one you used above
# when you created the web app using the Azure CLI
appName: JavaFuncApp
# ...
steps:
# ...
# add these as the last steps
# to deploy to your app service
- task: CopyFiles#2
displayName: Copy Files
inputs:
SourceFolder: $(system.defaultworkingdirectory)/MyProject/FunctionsJava/
Contents: '**'
TargetFolder: $(build.artifactstagingdirectory)
- task: Maven#3
inputs:
mavenPomFile: '$(System.DefaultWorkingDirectory)/MyProject/FunctionsJava/pom.xml'
mavenOptions: '-Xmx3072m'
javaHomeOption: 'JDKVersion'
jdkVersionOption: '1.8'
jdkArchitectureOption: 'x64'
publishJUnitResults: true
testResultsFiles: '**/surefire-reports/TEST-*.xml'
goals: 'package'
- task: PublishBuildArtifacts#1
displayName: Publish Artifact
inputs:
PathtoPublish: $(build.artifactstagingdirectory)
- task: AzureWebApp#1
inputs:
azureSubscription: 'TestRG-Conn'
appType: 'webApp'
appName: '$(appName)'
package: $(build.artifactstagingdirectory)
deploymentMethod: 'auto'
The problem should be caused by appType: 'webApp' in the AzureWebApp task, appType should be functionApp. Web app is deployed to app service.
You can try Azure Function App deploy task or Azure App Service deploy task.
- task: AzureFunctionApp#1
displayName: Azure Function App deploy
inputs:
azureSubscription: $(serviceConnectionToAzure)
appType: functionApp
appName: $(appName)
package: $(build.artifactstagingdirectory)