I have a .net Azure function project which includes multiple functions such as EventGridTrigger function, BlobTrigger function etc. Few trigger functions in the project needs to be enabled only for specific regions. Is it possible to enable/disable trigger functions based on regions through app settings ?
[FunctionName("CosmosDBFunction")] //enable only in US-west
public static void Run([CosmosDBTrigger()])
{}
[FunctionName("EventGridFunction")] //enable only in US-east
public static void Run([EventGridTrigger]EventGridEvent eventGridEvent)
{}
Edit:
I'm trying to disable in "isolated" Azure functions via appsettings.json within the project. The "[Disable]" and AzureWebJobs.$FunctionName.Disabled properties are not working from appsettings.json, though it is working if mentioned in azure portal.
You can use the Disable attribute, which dynamically disables specific Functions based on app settings.
For example:
[Disable("FUNCTION_DISABLED")]
[FunctionName(nameof(EventGridFunction))]
public static void Run(...
Each regional deployment will then set the FUNCTION_DISABLED setting to true if the Function should be disabled.
One way to disable/Enable Azure functions based on regions by using PowerShell command. I could able to achieve this by using Update-AzFunctionAppSetting command wherein all the functions of the mentioned location will be Disabled - MSFT Docs.
Subscription Level
$GetFunction=Get-AzFunctionApp -SubscriptionId <SUBSCRIPTION_ID>
$ResourceGroup=($GetFunction).ResourceGroupName
$Name = ($GetFunction).Name
For($I=0;$I -lt $ResourceGroup.count;$I++) {
$FunctionDetails=Get-AzResource -ApiVersion "2022-03-01" -Name $Name[$I] -ResourceGroupName $ResourceGroup[$I] -ResourceType "Microsoft.Web/sites/functions"
if($GetFunction[$I].Location -eq "<YOUR_REQUIRED_LOCATION>"){
For($J=0;$J -lt $FunctionDetails.count;$J++){
$Function=$FunctionDetails[$J].ResourceName
$FunctionName=$Function.Substring(($Function.IndexOf("/")+1),($Function.length-($Function.IndexOf("/")+1)))
Update-AzFunctionAppSetting -Name $Name[$I] -ResourceGroupName $ResourceGroup[$I] -AppSetting #{"AzureWebJobs.$FunctionName.Disabled" = "true"}
}
}
}
FunctionApp Level
$FunctionDetails=Get-AzResource -ApiVersion "2022-03-01" -Name <FUNCTIONAPP_NAME> -ResourceGroupName <RESOURCE_GROUP> -ResourceType "Microsoft.Web/sites/functions"
$Function=$FunctionDetails.ResourceName | Where-Object {$FunctionDetails.Location -eq "<YOUR_REQUIRED_LOCATION>"}
For($I=0;$I -lt $Function.count;$I++) {
$FunctionExtract=$Function[$I]
$FunctionName=$FunctionExtract.Substring(($FunctionExtract.IndexOf("/")+1),($FunctionExtract.length-($FunctionExtract.IndexOf("/")+1)))
Update-AzFunctionAppSetting -Name <FUNCTIONAPP_NAME> -ResourceGroupName <RESOURCE_GROUP> -AppSetting #{"AzureWebJobs.$FunctionName[$I].Disabled" = "true"}
}
SAMPLE RESULTS:
Note: Replace -AppSetting #{"AzureWebJobs.$FunctionName.Disabled" = "false"} to true to enable it again.
Related
I am working on writing some Powershell that I am going to use in Azure DevOPS pipelines. This is to create an AppServiceplan. I have included the code below. I have used this same basic template to deploy a few other things and I have not run into this problem before.
This piece of the code $appSP = Get-AzAppServicePlan -Name $appServicePlanName -ResourceGroupName $rgname does not return a value, which is expected because this is the first time running it, yet its triggering this piece of code Write-verbose "AppService Plan '$appServicePlanName' already exists."
So it seems that even though the Get-AzAppServicePlan appears to be blank, maybe its returning some sort of object that I cant see?
Any ideas?
function Assert-AppServicePlan {
<#
.SYNOPSIS
This function will ensure that specified AppServicePlan exists.
.DESCRIPTION
Function will check if specified Azure AppServicePlan exists, and if not - it will be created.
Will return AppServicePLan object or, in case of error, $null.
.PARAMETER appServicePlanName
App Service Plan to be checked or created.
.PARAMETER rgName
Resource Group.
.PARAMETER SKU
SKU for App Service Plan. Default is P2V2.
.EXAMPLE
Assert-AppServicePlan -appServicePlansName "BARF" -rgName "MyResourceGroup" -SKU "F1" -verbose
#>
param(
[Parameter(Mandatory = $true)][ValidateNotNullorEmpty()][string]$appServicePlanName,
[Parameter(Mandatory = $true)][ValidateNotNullorEmpty()][string]$rgName,
[Parameter(Mandatory = $true)][ValidateNotNullorEmpty()][string]$SKU
);
$appSP = Get-AzAppServicePlan -Name $appServicePlanName -ResourceGroupName $rgname
if ($notPresent)
{
Write-Verbose "App Service Plan '$appServicePlanName' doesn't exist. Creating it."
try
{
$appSP = New-AzResourceGroupDeployment -ResourceGroupName `
$rgname -TemplateFile .\templates\appserviceplan.json `
-TemplateParameterFile .\templates\appserviceplan.parameters.json `
-ErrorAction Stop
}
catch
{
Write-verbose "Error while creating App Service Plan."
Write-Error $_
}
}
else
{
Write-verbose "AppService Plan '$appServicePlanName' already exists."
}
return $appSP
}
The Get-AzAppServicePlan cmdlet returns the App Service Plan object if found in the specified resource group, else nothing. So, it would be sufficient to check on this result in your if condition.
Another case where the result might mislead returning null is when you query under an incorrect PS context or a different Subscription (locally). However, since you intend to run this as part of Azure DevOps pipelines, the Service connection used by the task would ensure it.
Just another suggestion, you can use ErrorVariable
Get-AzAppServicePlan -Name $appServicePlanName -ResourceGroupName $rgname -ErrorAction Silentlycontinue -ErrorVariable notPresent
if ($notPresent)
{
#create something
}
else {
#exits
}
I have a powershell script that creates the storage and blob account for a given subscription that works fine . Subscription Name, resource group keeps changing for different environments like DEV,UAT,PROD
STRUCTURE OF MY TEMPLATE / CODE :
param(
[string] $subscriptionName ="ABC",
[string] $resourceGroupName = "XYZ",
[string] $resourceGroupLocation ="westus",
[string] $templateFilePath = "template.json",
[string] $parametersFilePath = "parameters.json"
)
Function RegisterRP {
Param(
[string]$ResourceProviderNamespace
)
Write-Host "Registering resource provider '$ResourceProviderNamespace'";
Register-AzureRmResourceProvider -ProviderNamespace $ResourceProviderNamespace;
}
$ErrorActionPreference = "Stop"
$confirmExecution = Read-Host -Prompt "Hit Enter to continue."
if($confirmExecution -ne '') {
Write-Host "Script was stopped by user." -ForegroundColor Yellow
exit
}
# sign in
Write-Host "Logging in...";
Login-AzureRmAccount;
# select subscription
Write-Host "Selecting subscription '$subscriptionName'";
Select-AzureRmSubscription -SubscriptionName $subscriptionName;
# Register RPs
$resourceProviders = #("microsoft.storage");
if($resourceProviders.length) {
Write-Host "Registering resource providers"
foreach($resourceProvider in $resourceProviders) {
RegisterRP($resourceProvider);
}
}
#Create or check for existing resource group
$resourceGroup = Get-AzureRmResourceGroup -Name $resourceGroupName -ErrorAction SilentlyContinue
if(!$resourceGroup)
{
Write-Host "Resource group '$resourceGroupName' does not exist. To create a new resource group, please enter a location.";
if(!$resourceGroupLocation) {
$resourceGroupLocation = Read-Host "resourceGroupLocation";
}
Write-Host "Creating resource group '$resourceGroupName' in location '$resourceGroupLocation'";
New-AzureRmResourceGroup -Name $resourceGroupName -Location $resourceGroupLocation
}
else{
Write-Host "Using existing resource group '$resourceGroupName'";
}
# Start the deployment
Write-Host "Starting deployment...";
if(Test-Path $parametersFilePath) {
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name $deploymentName -TemplateFile $templateFilePath -TemplateParameterFile $parametersFilePath -storageAccounts_name $storageAccountName
} else {
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name $deploymentName -TemplateFile $templateFilePath; -storageAccounts_name $storageAccountName
}
Approach 1 :
Created multiple powershell scripts for each denvironment
Created 1 Menu Based powershell script that calls the other script and executes like : Select 1 for Dev , 2 for UAt , 3 for PROD , this approach works but is not effective .
Approach 2 :
I would like to combine all scripts and just have one script for all environments and based on select should allow me to create the storage accounts. Only Subscription and resource group change rest all structure of the powershell remains same .
I tried using GET function commandlets and it selects but still throws the error
[string] $subscriptionName = Get-AzureSubscription,
[string] $resourceGroupName = Get-AzureRmLocation,
If i try to use it using an array based approach like passing the values as below im unable to understand how do i pass these array based values to the code and get it to work .
$environment=#('DEV','TEST','QA','PROD')
$resourcegroupname = #('test','test1','test2','test3')
$subscriptionName = #('devsub1','devsub2','test3','prod4')
I'm trying to call the functions using :
$environment[0]
$subscriptionName[0]
It returns the value as below if i execute it seperately but how do i pass these values to my script to create storage account ?
DEV
devsub1
Requesting expert help if anyone has come across such scenarios earlier and if you can help in changing the above code and provide a tested code that would be of great help.
APPROACH 3:
$subscription = #(Get-AzureRmSubscription)
$resourcegroup = #(Get-AzureRmResourceGroup)
$Environment = #('DEV','TEST','QA','PROD')
$resourceGroupName = $resourcegroup | Out-GridView -PassThru -Title 'Pick the environment'
$subscriptionName = $subscription | Out-GridView -PassThru -Title 'Pick the subscription'
Write-Host "Subscription:" $subscriptionName
Write-Host "ResourceGroup:" $resourcegroup
OUTPUT :
If you look at resource group it fails to give the selection option for resource group .
Subscription: < it returns the subscription name >
ResourceGroup: Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels.PSResourceGroup Microsoft.Azure.Commands.ResourceManager.Cmd
lets.SdkModels.PSResourceGroup Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels.PSResourceGroup Microsoft.Azure.Commands.Res
ourceManager.Cmdlets.SdkModels.PSResourceGroup
What you are proposing is an interesting approach. I would likely an input parameter that defines which environment the work will be done in, and then have a conditional block that sets the dynamic variables for that environment. There would be some duplication of initialization code for each environment, but the main code block would still be unified.
I have many operations failed in my Azure Logic App.
I see that if you click on a single operation on the Azure portal you can re-started the operation:
Is it possible to select ALL of these failed operations, and re-run all together?
Thanks a lot guys
If you want to resubmit one or more logic app runs that failed, succeeded, or are still running, you could bulk resubmit Logic Apps from the Runs Dashboard.
About how to use this function, you could refer to this article:Monitor logic apps with Azure Monitor logs. Under the tile View logic app run information, you could find the Resubmit description.
Alternative to bulk resubmit Logic Apps from the Runs Dashboard, you can utilize the PowerShell commands. Take a look at the script below, which can automate listing Failed logic app runs, identify triggers, actions responsible and restart the apps by input ResourceGroupName. You can change some of those bits as per your needs. (skip the interactions and just restart apps again) I have just show it for understanding.
Using: Get-AzLogicApp, Get-AzLogicAppRunHistory ,
Get-AzLogicAppRunAction, Get-AzLogicAppTrigger and Start-AzLogicApp
cmdlets.
Script using Az PowerShell 6.2 Module: Az.LogicApp [Copy below to file, say restart.ps1 and run] Make sure you assign $rg with your actual AzResourceGroup name
$rg = "MyResourceGrp"
#get logic apps
$logicapps = Get-AzLogicApp -ResourceGroupName $rg
Write-Host "logicapps:" -ForegroundColor "Yellow"
write-output $logicapps.Name
#list all logicapp runs failed
$failedruns = #(foreach($name in $logicapps.Name){
Get-AzLogicAppRunHistory -ResourceGroupName $rg -Name $name | Where {$_.Status -eq 'Failed'}
})
Write-Host "failedruns:" -ForegroundColor "Yellow"
Write-Output $failedruns.Name | select -Unique
Write-Host "failedruns: LogicAppNames" -ForegroundColor "Yellow"
Write-Output $failedruns.Workflow.Name | select -Unique
#list all logicappRunsActions failed
foreach($i in $logicapps){
foreach($y in $failedruns){
if ($i.Version -eq $y.Workflow.Name) {
$resultsB = Get-AzLogicAppRunAction -ResourceGroupName $rg -Name $i.Name -RunName $y.Name -FollowNextPageLink | Where {$_.Status -eq 'Failed'}
}
}
}
foreach($item in $resultsB){
Write-Host "Action:" $item.Name " " -NoNewline "Time:" $item.EndTime
Write-Output " "
}
#get logicapp triggers
foreach($ii in $logicapps){
foreach($yy in $failedruns){
if ($ii.Version -eq $yy.Workflow.Name) {
$triggers = Get-AzLogicAppTrigger -ResourceGroupName $rg -Name $ii.Name
}
}
}
Write-Host "triggers:" -ForegroundColor "Yellow"
Write-Output $triggers.Name
#start logic apps with triggers
Write-Host "Starting logic apps....." -ForegroundColor "green"
foreach($p in $logicapps){
foreach($tri in $triggers){
if ($p.Version -eq $triggers.Workflow.Name) {
Start-AzLogicApp -ResourceGroupName $rg -Name $p.Name -TriggerName $tri.Name
}
}
}
$verify = Read-Host "Verify ruuning app? y or n"
if ($verify -eq 'y') {
$running = #(foreach($name2 in $logicapps.Name){
Get-AzLogicAppRunHistory -ResourceGroupName $rg -Name $name2 | Where {$_.Status -eq 'Running' -or $_.Status -eq 'Waiting'}
})
Write-Host $running
}
else {
Write-Host "Bye!"
}
Although my LogicApp has failed again, but you can see it was triggered in time by script
Note: If your logic app trigger expects inputs or actions (unlike recurrence or scheduled) please edit or make changes accordingly for Start-AzLogicApp command to execute successfully.
Here I am considering all logic apps are enabled (use -State Enabled) parameter for Get-AzLogicApp command if you want to run this on only currently enabled apps.
Example: Get-AzLogicApp -ResourceGroupName "rg" | where {$_.State -eq 'Enabled'}
2. You can also try advanced settings for triggers in workflow. Such as retry policy.
You can specify it to retry at custom intervals in case of failures due to an intermittent issues.
You can submit a feedback or Upvote a similar Feedback : ability-to-continue-from-a-particular-point-as-in
Refer: help topics for the Logic Apps cmdlets
I am new person to Azure development. Is it possible to add custom domain names to web apps using .Net REST API?
yes, you can do that.
1) Install the NuGet Web Sites Management Package into your project.
2) Get Azure Publish Settings file (for example, by using Powershell Get-AzurePublishSettingsFile). You will need that later (the value of the management certificate field inside of that file).
2) Instantiate WebSiteManagementClient. That should help with the understanding of the code.
3) Next, the code is below. I just tested and it works. First, it lists the webspaces, then the websites inside of each of webspace, and you should copy and paste the website webspace into the
public const string base64EncodedCertificate = "ManagementCertificateValueFromPublishSettingsFile";
public const string subscriptionId = "AzureSubscriptionId";
static SubscriptionCloudCredentials getCredentials()
{
return new CertificateCloudCredentials(subscriptionId, new X509Certificate2(Convert.FromBase64String(base64EncodedCertificate)));
}
static void Main(string[] args)
{
WebSiteManagementClient client = new WebSiteManagementClient(getCredentials());
WebSpacesListResponse n = client.WebSpaces.List();
n.Select(p =>
{
Console.WriteLine("webspace {0}", p.Name);
WebSpacesListWebSitesResponse websitesInWebspace = client.WebSpaces.ListWebSites(p.Name,
new WebSiteListParameters()
{
});
websitesInWebspace.Select(o =>
{
Console.Write(o.Name);
return o;
}).ToArray();
return p;
}).ToArray();
Console.ReadLine();
var configuration = client.WebSites.Get("WebSpaceName", "WebSiteName", new WebSiteGetParameters());
configuration.WebSite.HostNames.Add("new domain");
var resp = client.WebSites.Update("WebSpaceName", "WebSiteName", new WebSiteUpdateParameters() { HostNames = configuration.WebSite.HostNames });
Console.WriteLine(resp.StatusCode);
Console.ReadLine();
}
https://learn.microsoft.com/en-us/azure/app-service/scripts/app-service-powershell-configure-custom-domain
Most easily done with PowerShell.
$fqdn="<Replace with your custom domain name>"
$webappname="mywebapp$(Get-Random)"
$location="West Europe"
# Create a resource group.
New-AzureRmResourceGroup -Name $webappname -Location $location
# Create an App Service plan in Free tier.
New-AzureRmAppServicePlan -Name $webappname -Location $location `
-ResourceGroupName $webappname -Tier Free
# Create a web app.
New-AzureRmWebApp -Name $webappname -Location $location -AppServicePlan $webappname `
-ResourceGroupName $webappname
Write-Host "Configure a CNAME record that maps $fqdn to $webappname.azurewebsites.net"
Read-Host "Press [Enter] key when ready ..."
# Before continuing, go to your DNS configuration UI for your custom domain and follow the
# instructions at https://aka.ms/appservicecustomdns to configure a CNAME record for the
# hostname "www" and point it your web app's default domain name.
# Upgrade App Service plan to Shared tier (minimum required by custom domains)
Set-AzureRmAppServicePlan -Name $webappname -ResourceGroupName $webappname `
-Tier Shared
# Add a custom domain name to the web app.
Set-AzureRmWebApp -Name $webappname -ResourceGroupName $webappname `
-HostNames #($fqdn,"$webappname.azurewebsites.net")
Is it possible to update the value of a setting in an Azure Cloud Service with Azure Powershell?
So far there is no way to update just a single setting (the Service Management API does not allow it - it only accepts the whole service configuration). So, in order to update a single setting, you will have to update the entire configuration. And you can do this with PowerShell:
# Add the Azure Account first - this will create a login promppt
Add-AzureAccount
# when you have more then one subscription - you have explicitly select the one
# which holds your cloud service you want to update
Select-AzureSubscription "<Subscription name with spaces goes here>"
# then Update the configuration for the cloud service
Set-AzureDeployment -Config -ServiceName "<cloud_service_name_goes_here>" `
-Configuration "D:/tmp/cloud/ServiceConfiguration.Cloud.cscfg" `
-Slot "Production"
For the the `-Configuration' parameter I have provided full local path to the new config file I want to use with my cloud service.
This is verified and working solution.
As astaykov says, you can't update a single cloud config value using Powershell.
But you can read all of the settings, update the one you wish to change, save it to a temp file, and then set all the settings again, like so:
UpdateCloudConfig.ps1:
param
(
[string] $cloudService,
[string] $publishSettings,
[string] $subscription,
[string] $role,
[string] $setting,
[string] $value
)
# param checking code removed for brevity
Import-AzurePublishSettingsFile $publishSettings -ErrorAction Stop | Out-Null
function SaveNewSettingInXmlFile($cloudService, [xml]$configuration, $setting, [string]$value)
{
# get the <Role name="Customer.Api"> or <Role name="Customer.NewsletterSubscription.Api"> or <Role name="Identity.Web"> element
$roleElement = $configuration.ServiceConfiguration.Role | ? { $_.name -eq $role }
if (-not($roleElement))
{
Throw "Could not find role $role in existing cloud config"
}
# get the existing AzureServiceBusQueueConfig.ConnectionString element
$settingElement = $roleElement.ConfigurationSettings.Setting | ? { $_.name -eq $setting }
if (-not($settingElement))
{
Throw "Could not find existing element in cloud config with name $setting"
}
if ($settingElement.value -eq $value)
{
Write-Host "No change detected, so will not update cloud config"
return $null
}
# update the value
$settingElement.value = $value
# write configuration out to a file
$filename = $cloudService + ".cscfg"
$configuration.Save("$pwd\$filename")
return $filename
}
Write-Host "Updating setting for $cloudService" -ForegroundColor Green
Select-AzureSubscription -SubscriptionName $subscription -ErrorAction Stop
# get the current settings from Azure
$deployment = Get-AzureDeployment $cloudService -ErrorAction Stop
# save settings with new value to a .cscfg file
$filename = SaveNewSettingInXmlFile $cloudService $deployment.Configuration $setting $value
if (-not($filename)) # there was no change to the cloud config so we can exit nicely
{
return
}
# change the settings in Azure
Set-AzureDeployment -Config -ServiceName $cloudService -Configuration "$pwd\$filename" -Slot Production
# clean up - delete .cscfg file
Remove-Item ("$pwd\$filename")
Write-Host "done"