For running unit test, you can use Jasmine and the coverage report can be generated with nyc and report type as cobertura, which is supported in Azure DevOps.
Jasmine.json
For running unit test, you can use Jasmine and the coverage report can be generated with nyc and report type as cobertura, which is supported in Azure DevOps.
Jasmine.json
#Comment: Make sure you are not using Application ID parameter while adding access policy as it will add the identity as on behalf of.
# PowerShell code
########################################################
# Parameters
########################################################
[CmdletBinding()]
param(
[Parameter(Mandatory=$True,Position=0)]
[string]$NPResourceGroupName,
[Parameter(Mandatory=$True,Position=1)]
[string]$NPWebVmssID,
[Parameter(Mandatory=$True,Position=2)]
[string]$NPEngVmssID,
[Parameter(Mandatory=$False,Position=3)]
[string]$NPPayVmssID,
[Parameter(Mandatory=$False,Position=4)]
[string]$NPMasterKeyvaultName,
[Parameter(Mandatory=$False,Position=5)]
[string]$NPWebKeyvaultName
)
# Keep track of time
$StartDate=(GET-DATE)
########################################################
# Log in to Azure with AZ (standard code)
########################################################
Write-Verbose -Message 'Connecting to Azure'
# Name of the Azure Run As connection
$ConnectionName = 'AzureRunAsConnection'
try
{
# Get the connection properties
$ServicePrincipalConnection = Get-AutomationConnection -Name $ConnectionName
'Log in to Azure...'
$null = Connect-AzAccount `
-ServicePrincipal `
-TenantId $ServicePrincipalConnection.TenantId `
-ApplicationId $ServicePrincipalConnection.ApplicationId `
-CertificateThumbprint $ServicePrincipalConnection.CertificateThumbprint
}
catch
{
if (!$ServicePrincipalConnection)
{
# You forgot to turn on 'Create Azure Run As account'
$ErrorMessage = "Connection $ConnectionName not found."
throw $ErrorMessage
}
else
{
# Something else went wrong
Write-Error -Message $_.Exception.Message
throw $_.Exception
}
}
try
{
#Adding to master keyvault
Write-Verbose -Message 'Adding to master keyvault'
# Web vmss
$identityWeb = Get-AzUserAssignedIdentity -ResourceGroupName $NPResourceGroupName -Name $NPWebVmssID
Write-Verbose -Message 'Adding webvmssid'
'Adding webvmssid'
Set-AzKeyVaultAccessPolicy `
-ResourceGroupName $NPResourceGroupName -VaultName $NPMasterKeyvaultName -ObjectId $identityWeb.PrincipalId `
-PermissionsToKeys get,list,unwrapKey,wrapKey `
-PermissionsToSecrets get -PermissionsToCertificates get,list,delete,create -BypassObjectIdValidation
# Eng vmss
$identityEng = Get-AzUserAssignedIdentity -ResourceGroupName $NPResourceGroupName -Name $NPEngVmssID
Write-Verbose -Message 'Adding engvmssid'
'Adding engvmssid'
Set-AzKeyVaultAccessPolicy `
-ResourceGroupName $NPResourceGroupName -VaultName $NPMasterKeyvaultName -ObjectId $identityEng.PrincipalId `
-PermissionsToKeys get,list,unwrapKey,wrapKey `
-PermissionsToSecrets get -PermissionsToCertificates get,list,delete,create -BypassObjectIdValidation
# Pay vmss
$identityPay = Get-AzUserAssignedIdentity -ResourceGroupName $NPResourceGroupName -Name $NPPayVmssID
Write-Verbose -Message 'Adding payvmssid'
'Adding payvmssid'
Set-AzKeyVaultAccessPolicy `
-ResourceGroupName $NPResourceGroupName -VaultName $NPMasterKeyvaultName -ObjectId $identityPay.PrincipalId `
-PermissionsToKeys get,list,unwrapKey,wrapKey `
-PermissionsToSecrets get -PermissionsToCertificates get,list,delete,create -BypassObjectIdValidation
#Adding to web keyvault
Write-Verbose -Message 'Adding to master keyvault'
# Web vmss
#$identityWeb = Get-AzUserAssignedIdentity -ResourceGroupName $NPResourceGroupName -Name $NPWebVmssID
Write-Verbose -Message 'Adding webvmssid'
'Adding webvmssid'
Set-AzKeyVaultAccessPolicy `
-ResourceGroupName $NPResourceGroupName -VaultName $NPWebKeyvaultName -ObjectId $identityWeb.PrincipalId `
-PermissionsToKeys get,list,unwrapKey,wrapKey `
-PermissionsToSecrets get -PermissionsToCertificates get,list,delete,create -BypassObjectIdValidation
# Eng vmss
#$identityEng = Get-AzUserAssignedIdentity -ResourceGroupName $NPResourceGroupName -Name $NPEngVmssID
Write-Verbose -Message 'Adding engvmssid'
'Adding engvmssid'
Set-AzKeyVaultAccessPolicy `
-ResourceGroupName $NPResourceGroupName -VaultName $NPWebKeyvaultName -ObjectId $identityEng.PrincipalId `
-PermissionsToKeys get,list,unwrapKey,wrapKey `
-PermissionsToSecrets get -PermissionsToCertificates get,list,delete,create -BypassObjectIdValidation
# Pay vmss
#$identityPay = Get-AzUserAssignedIdentity -ResourceGroupName $NPResourceGroupName -Name $NPPayVmssID
Write-Verbose -Message 'Adding payvmssid'
'Adding payvmssid'
Set-AzKeyVaultAccessPolicy `
-ResourceGroupName $NPResourceGroupName -VaultName $NPWebKeyvaultName -ObjectId $identityPay.PrincipalId `
-PermissionsToKeys get,list,unwrapKey,wrapKey `
-PermissionsToSecrets get -PermissionsToCertificates get,list,delete,create -BypassObjectIdValidation
}
catch
{
Write-Error -Message $_.Exception.Message
throw $_.Exception
}
Sometimes we have a scenario to update the devops pipeline variables dynamically during the task execution without having to update manually and create new release. you can use the below approach by adding Powershell task to the pipeline.
# Write your PowerShell commands here.
$cosmosconnstr = "$(cosmosconnstring)"
if("$(cosmosconnstring)".Chars("$(cosmosconnstring)".Length - 1) -eq ';')
{
$cosmosconnstr = "$(cosmosconnstring)".TrimEnd(';')
}
Write-Output("##vso[task.setvariable variable=ApplicationSettings.CacheConnection;]$cosmosconnstr")
#End
#Run the below script in another stage to make sure you get the updated value
Write-host "CacheConnection Variable in previous task is: $(ApplicationSettings.CacheConnection)"
You can add multiple extensions to Azure VMSS through the extensionProfile of ARM template. The below script shows the extension configuration and mapping workspaceId to collect custom logs from VMSS instances.
n App Analytics you can slice and dice on your App Insights custom dimensions and measurements just as easily as any of the so-called “standard” properties.
The only thing that’s a little bit tricky is extracting them first.
It’s tricky because of 2 things:
When we run the build pipeline in Azure Devops, if we encounter below error then you can make the change recommended here.
Issue
D:\DevOps\Build\33\s\PT\<foldername>cannot be deleted because it is not empty.
D:\DevOps\Build\33\s\PT\<foldername> cannot be deleted because it is not empty.
---- Summary: 0 conflicts, 1 warnings, 0 errors ----
Sleeping for 200 ms
Retrying. Attempt $2/$3
##[error]_proc should be null. (Parameter '_proc')
Cause
You can perform different kinds of cleaning of the working directory of your private agent before the build is run. If the Clean is set to false, it does not get a fresh pull before the build is run.
Resolution
The script below checks whether a key exists in the DB and if yes it updates and if not it adds the key and value to the table. The context used here is the Service Principal Name (SPN) which is the client ID and secret key. Also the SQL authentication user ID and password is required. Make sure your machine ip is added in the firewall rules to run the query.
$dbuser = "username"
$password = "dbpswd"
$tenid = "tenantid"
$clientid = "client ID"
$secretkey = "Secret Key"
$Servername ="dbservername"
$database="dbname"
Write-Output "Starting"
#$clientid = Get-AzureRMAutomationVariable -Name $varclientid
#$secretkey = Get-AzureRMAutomationVariable -Name $varsecretkey
#$dbuser = Get-AzureRMAutomationVariable -Name $vardbuser
#$password = Get-AzureRMAutomationVariable -Name $vardbpass
#$sbpk = "test"
Add-SqlAzureAuthenticationContext -ClientID $clientid -Secret $secretkey -Tenant $tenid
$sqlConn = New-Object System.Data.SqlClient.SqlConnection
$sqlConn.ConnectionString = "Server=$Servername.database.windows.net; User ID = $dbuser ; Password = $password ; Database = $database; Column Encryption Setting=enabled;"
$sqlConn.Open()
Write-Output "sql conn opened"
function updateparamMaster($sqlconn,$paraID,$ParaGrp,$ParaValue)
{
#Check if the paramid and ParamGroup exists
$sqlcmd = New-Object System.Data.SqlClient.SqlCommand
$sqlcmd.Connection = $sqlConn
$query = "select * from parametermaster where paramid= $paraID and ParamGroup= '"+$ParaGrp+"'"
$sqlcmd.CommandText = $query
$adp = New-Object System.Data.SqlClient.SqlDataAdapter $sqlcmd
$data = New-Object System.Data.DataSet
$adp.Fill($data)
$paramcount = $data.Tables[0].Rows.count
Write-Host "Row count-" $paramcount
if($paramcount -eq 0)
{
Write-Output $ParaGrp "ParamGroup does not exist- creating new entry"
$sqlcmd = New-Object System.Data.SqlClient.SqlCommand
$sqlcmd.Connection = $sqlConn
$sqlcmd.CommandText = "INSERT into parametermaster(paramid,ParamGroup,Value) VALUES (@paramid, @ParamGroup, @Val)"
$sqlcmd.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@paramid",[Data.SQLDBType]::Int)))
$sqlcmd.Parameters["@paramid"].Value = $paraID
$sqlcmd.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@ParamGroup",[Data.SQLDBType]::VarChar, 50)))
$sqlcmd.Parameters["@ParamGroup"].Value = $ParaGrp
$sqlcmd.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@val",[Data.SQLDBType]::NVarChar, 500)))
$sqlcmd.Parameters["@val"].Value =$ParaValue
$sqlcmd.ExecuteNonQuery();
}
else
{
Write-Output $ParaGrp "ParamGroup exist- updating entry"
$sqlcmd = New-Object System.Data.SqlClient.SqlCommand
$sqlcmd.Connection = $sqlConn
$sqlcmd.CommandText = "UPDATE parametermaster SET [Value] = @Val WHERE paramid = @paramid AND ParamGroup = @ParamGroup"
$sqlcmd.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@paramid",[Data.SQLDBType]::Int)))
$sqlcmd.Parameters["@paramid"].Value = $paraID
$sqlcmd.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@ParamGroup",[Data.SQLDBType]::VarChar, 50)))
$sqlcmd.Parameters["@ParamGroup"].Value = $ParaGrp
$sqlcmd.Parameters.Add((New-Object Data.SqlClient.SqlParameter("@val",[Data.SQLDBType]::NVarChar, 500)))
$sqlcmd.Parameters["@val"].Value =$ParaValue
$sqlcmd.ExecuteNonQuery();
}
}
updateparamMaster -sqlconn $sqlConn -paraID 118 -ParaGrp "SharedDb" -ParaValue