Azure slots :Can i swap only app settings/connection strings? - azure

Is there a way we can swap only app settings/connectionstrings but not code from Azure App Service slot using azure DevOps pipeline or Azure CLI?

We are trying to get connectionstring directly from the slot and swap it to prod but not code.
As far as I know, you can use Azure CLI to achieve it.
Appsettings: az webapp config appsettings
ConnectString: az webapp config connection-string
You could use Azure CLI to list appsettings/connectionstring. Then you could use the set command to pass the values to the slot.
Here is my sample(In Azure Devops Azure CLI Task):
$appsettings=az webapp config appsettings list --name webappname -g ResourcesGroupName --slot slotname
$appsettings| Out-File "$(System.DefaultWorkingDirectory)\appsettings.json"
az webapp config appsettings set -g ResourcesGroupName -n webappname --settings -slot slotname "#$(System.DefaultWorkingDirectory)\appsettings.json"
$connectstring=az webapp config connection-string list --name webappname -g ResourcesGroupName --slot slotname
$test = $connectstring | ConvertFrom-Json
$test | Select-Object -Property Name,slotSetting ,type,Value | ForEach-Object {
Write-Host $_.Name $_.Value
$msg = $_.Name , $_.Value -join '='
echo $msg
az webapp config connection-string set --name webappname -g ResourcesGroupName -slot slotname -t mysql --settings $msg
}
Note: Here is an known issue about the az webapp config connection-string set. It couldn't support to set files in settings parameter for the time being.

You can try this,
Step 1 : Create two separated environments in a release as per your needs!
Step 2 : Create a variable with the same name as your connection string name in your web.config, one scoped for staging environment and the other for production.
Step 3 : Add a Deploy Azure App Service task to each environment.
Then you could use the File transformation and substitution options and mark to make the transformation. Take a look at XML Transformation and JSON transformation

Related

Zip-deploy Azure functions while public access is disabled (access regstrictions are in place)

I disabled Allow public access on an Azure Function App for security reasons:
However after that, zip deploys from Visual Studio (publish functionality) and via Github Actions fail, as also the API for deployment isn't publicly reachable anymore. In that case, how would one zip deploy updated Azure functions?
If you need ZIP deployment, you need to deploy the code from inside the VNET to the private endpoint of the AppService. For GitHub Actions, this means deploying a self-hosted runner on a VM inside the VNET to push the new code to AppService. There is an example for Azure DevOps self-hosted agents.
As an alternative, you can publish your ZIP to a storage account and let the function pull the new application code to run. There is also a full example including GitHub Actions.
The most relevant quotes from the second example are:
This article shows how to deploy to a Private Endpoint-enabled site from a Continuous Integration pipeline (such as GitHub Actions, Circle CI, Jenkins, or Travis CI) without having to self-host the CI service on a VM. Since Private Endpoints disables all inbound traffic from the internet, our CI pipeline will publish the files to a storage account and give the web app a SAS URL to files. Once the web app is given this SAS URL, it will pull the files from the storage account.
- name: Set SAS token expiration
run: echo "expiry=`date -u -d "$EXPIRY_TIME" '+%Y-%m-%dT%H:%MZ'`" >> $GITHUB_ENV
- name: Azure CLI script
uses: azure/CLI#v1
with:
azcliversion: 2.19.1
inlineScript: |
az extension add --name webapp
az storage account create -n $ACCOUNT -g $GROUP -l westus
az storage container create -n $CONTAINER --account-name $ACCOUNT
az storage blob upload -f app.zip --account-name $ACCOUNT -c $CONTAINER -n $ACCOUNT
ZIP_URL=$(az storage blob generate-sas --full-uri --permissions r --expiry ${{ env.expiry }} --account-name $ACCOUNT -c $CONTAINER -n $ACCOUNT | xargs)
az webapp deploy --name $WEBAPP --resource-group $GROUP --type zip --src-url $ZIP_URL --async false
az storage container delete -n $CONTAINER --account-name $ACCOUNT

Azure Function App - Swap deployment Slots stuck then crashing completely

Recently my function apps have stopped swapping slots, they worked fine for months but suddenly they have all stopped swapping by taking a long time then crashing. I have recreated the function apps using the same scripts and have replicated the issue but still can't fix.
Is there anything I am setting to stop the slots from switching?
Here is the fundamental build script I am using. I am able to run this but when trying to swap slots in Azure it freezes then crashes with a vague error message:
# Azure Login
az login
# Set deployment Environment
$environment = "stage"
# Resource Group Variables
$subscriptionId = ""
$domain = "test4"
$resourceGroup = "xx-platform-$domain-$environment"
$region = "northEurope"
# Functions app variables
$storageName = "xxfn$domain$environment" # must be less than 24 chars and all lower case
$functionAppDeploymentSlotName = "test"
$functionAppName = "xx-platform-$domain-fn-$environment"
$functionAppEnvironment = "AZURE_FUNCTIONS_ENVIRONMENT=Development"
$websiteRunFromPackage = "WEBSITE_RUN_FROM_PACKAGE=1"
#########################################################################################################################################################################
## Resource Group
Write-output "Creating resource group";
# Set subscription
az account set --subscription $subscriptionId
# Create resource group
az group create -l $region -n $resourceGroup
#########################################################################################################################################################################
## Functions App
Write-output "Creating Functions App";
# Create storage account
az storage account create --name $storageName --location $region --resource-group $resourceGroup --sku Standard_LRS
# Create functions app - using consumption plan
az functionapp create --name $functionAppName --storage-account $storageName --consumption-plan-location northEurope --resource-group $resourceGroup --functions-version 4
# Set functions app configuration settings
# Environment
az functionapp config appsettings set --name $functionAppName --resource-group $resourceGroup --settings $functionAppEnvironment
# WEBSITE_RUN_FROM_PACKAGE
az functionapp config appsettings set --name $functionAppName --resource-group $resourceGroup --settings $websiteRunFromPackage
# SET DOT NET FRAMEWORK ERSION
az functionapp config set --net-framework-version v6.0 -g $resourceGroup -n $functionAppName
# Create functions app deployment slot
az functionapp deployment slot create --name $functionAppName --resource-group $resourceGroup --slot $functionAppDeploymentSlotName
I have modified your script in initializing the variable values directly to the cmdlets:
# Azure Login
az login
az account set --subscription "<Ur_Azure_Subscription_Id>"
# Function App Create
az functionapp create --name dt-platform-fn-stage --storage-account dtfnstageenvironment --consumption-plan-location northEurope --resource-group HariTestRG --runtime dotnet --functions-version 4
# Environment
az functionapp config appsettings set --name dt-platform-fn-stage --resource-group HariTestRG --settings AZURE_FUNCTIONS_ENVIRONMENT=Development
# WEBSITE_RUN_FROM_PACKAGE
az functionapp config appsettings set --name dt-platform-fn-stage --resource-group HariTestRG --settings WEBSITE_RUN_FROM_PACKAGE=1
# SET DOT NET FRAMEWORK ERSION
az functionapp config set --net-framework-version v6.0 -g HariTestRG -n dt-platform-fn-stage
# Create functions app deployment slot
az functionapp deployment slot create --name dt-platform-fn-stage --resource-group HariTestRG --slot test
Created the Http Trigger Function using the cmdlets given in the below given MS Document.
For Continuous deployments, this app setting needs to be configured:
az functionapp config appsettings set --name dt-platform-fn-stage --resource-group HariTestRG --settings "SCM_DO_BUILD_DURING_DEPLOYMENT=true"
Deployed the Function to the Azure Functions using az cli cmdlet given in one of my workarounds.
By default, Auto Swap on Slots will be disabled:
It is working fine during the slot swapping and make sure you have followed the considerations mentioned in this MS Doc that also provides the list of az cli cmdlets for managing the slots like creating, listing, deleting, swapping and auto swapping configuration.
Above Azure CLI Commands have been taken from this MS Doc references.

Best way to deploy code and restore database in a managed Application on Azure MarketPlace

Our goal is publishing our offer to Azure MarketPlace. We created an ARM template for our infrastructure and had no issues with that.
Our main issue is how to deploy our code and DB schema through the purchase process.
Microsoft recommends Deployment Scripts so we made ours which contains, CLI commands to restore a .BACPAC sql file, app settings configurations and a CURL command for zip deployment via KUDU for the web application.
.BACPAC and zip package for code are in blob storage.
If we run our scripts in a custom ARM template deployment in Azure, they work fine !!
But when we run them through the marketplace purchase, they fail with no error logs.
Down below you can find our script commands.
"scriptContent": "
az sql db import -s $sqlserver -n $sqldatabase -g $rg -p $sqlpassword -u $sqlusername --storage-key $sqlstoragekey --storage-key-type $storagekeytype --storage-uri $storageuri \r\n
az webapp deployment user set --user-name $deploymentUser --password $deploymentPass \r\n
az webapp config connection-string set --name $applicationName --resource-group $rg --settings DefaultConnection=\"Server=tcp:$sqlserver.database.windows.net,1433;Initial Catalog=$sqldatabase;Persist Security Info=False;User ID=$sqlusername;Password=$sqlpassword;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;\" --connection-string-type SQLAzure \r\n
az webapp config appsettings set --name $applicationName --resource-group $rg --settings PortalUrl=\https://$applicationName.azurewebsites.net/\ \r\n
az webapp config appsettings set --name $applicationName --resource-group $rg --settings AzureAd:Domain=\"$AADDomain\" \r\n
az webapp config appsettings set --name $applicationName --resource-group $rg --settings AzureAd:ClientId=\"$AADClientId\" \r\n
az webapp config appsettings set --name $applicationName --resource-group $rg --settings AzureAd:TenantId=\"$AADTenantId\" \r\n
az webapp config appsettings set --name $applicationName --resource-group $rg --settings AzureAd:ClientSecret=\"$AADClientSecret\" \r\n
az webapp restart --name $applicationName --resource-group $rg \r\n
curl -X PUT -u $deploymentUser:$deploymentPass https://$applicationName.scm.azurewebsites.net/api/zipdeploy -H \"Content-Type: application/json\" -d \"{'packageUri':'$applicationUri$applicationStorageKey'}\" \r\n
",
In case our approach is wrong, any example, documentation and suggestions will be super helpful.
Feel free to ask for more information if any.
Thank you

Azure Cli How to enable Application Insights for webapp

Consider the following code. It creates an application insight, then it retrieves the instrumentationkey and assigns it to my webapp.
az monitor app-insights component create -g $resourceGroup --app $webapp --application-type web --kind web --tags $defaultTags
$instrumentationKey = az monitor app-insights component show -g $resourceGroup -a $webapp --query 'instrumentationKey' -o tsv
az webapp config appsettings set -g $resourceGroup -n $webapp --settings APPINSIGHTS_INSTRUMENTATIONKEY=$instrumentationKey APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=$instrumentationKey
However, this does not turn on application insight for the webapp as shown in this screen capture. I cannot figure out how to turn it on from azure cli.
Using the link #Alex AIT provided the cli could be as follows.
Please note that you could also rely on the fact that if you don't create an App Insights instance an auto instance will be created and used.
# (...) Set up $plan, $resourcegroup and $region
az appservice plan create --name $plan --resource-group $resourcegroup --location $region --sku FREE
[String]$webapp="myapp"
az webapp create --name $webapp --plan $plan --resource-group $resourcegroup
[String]$appinsights=$webapp
az monitor app-insights component create --app $appinsights --location $region --resource-group $resourcegroup
# Get the instrumentation key
# '--output tsv', which is 'Tab-separated values, with no keys'
# is used to obtain the unquoted value
# as shown in https://learn.microsoft.com/en-us/cli/azure/query-azure-cli?view=azure-cli-latest#get-a-single-value
[String]$instrumentationKey = (az monitor app-insights component show --app $appinsights --resource-group $resourcegroup --query "instrumentationKey" --output tsv)
# Configure the app to use new app insights instance
# Based on https://learn.microsoft.com/en-us/azure/azure-monitor/app/azure-web-apps?tabs=net#enabling-through-powershell
az webapp config appsettings set --name $webapp --resource-group $resourcegroup --settings APPINSIGHTS_INSTRUMENTATIONKEY=$instrumentationKey APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=$instrumentationKey ApplicationInsightsAgent_EXTENSION_VERSION=~2
You need to set a couple more app settings to make it exactly like if you enabled it from the Azure Portal. I believe the second important key after the instrumentation key is ApplicationInsightsAgent_EXTENSION_VERSION.
https://learn.microsoft.com/en-us/azure/azure-monitor/app/azure-web-apps?tabs=net#automate-monitoring
Powershell example which you can adapt to AzureCLI:
$app = Get-AzWebApp -ResourceGroupName "AppMonitoredRG" -Name "AppMonitoredSite" -ErrorAction Stop
$newAppSettings = #{} # case-insensitive hash map
$app.SiteConfig.AppSettings | %{$newAppSettings[$_.Name] = $_.Value} # preserve non Application Insights application settings.
$newAppSettings["APPINSIGHTS_INSTRUMENTATIONKEY"] = "012345678-abcd-ef01-2345-6789abcd"; # set the Application Insights instrumentation key
$newAppSettings["APPLICATIONINSIGHTS_CONNECTION_STRING"] = "InstrumentationKey=012345678-abcd-ef01-2345-6789abcd"; # set the Application Insights connection string
$newAppSettings["ApplicationInsightsAgent_EXTENSION_VERSION"] = "~2"; # enable the ApplicationInsightsAgent
$app = Set-AzWebApp -AppSettings $newAppSettings -ResourceGroupName $app.ResourceGroup -Name $app.Name -ErrorAction Stop
There is a better approach than trying to manually set the app settings. Simply use this command (Link to docs provided):
az monitor app-insights component connect-webapp --app
--resource-group
--web-app
[--enable-debugger {false, true}]
[--enable-profiler {false, true}]
Connecting an application insights to a web app.

How to edit configuration settings in Azure Function for Azure Gov

I'd like to use code like this in my Azure Function:
var key = ConfigurationManager.AppSettings["SubscriptionKey"];
Given that there's no UI for Azure Functions in the Azure Government portal yet, is there a way to add this via the Azure CLI or is there another way to make this happen?
Update
I figured it out:
az functionapp config appsettings set --name appname --settings SubscriptionKey=1234 --resource-group resourcegroupname
As you've already found out, you can do this via Azure CLI with the following command:
az functionapp config appsettings set --name appname --settings SubscriptionKey=1234 --resource-group resourcegroupname

Resources