What is the correct, programmatic way to identify if an Azure region supports a resource type fully in Powershell? - azure

Currently, I'm looking at using Front Door in an Azure resource group. When I look at https://azure.microsoft.com/en-gb/global-infrastructure/services/?products=frontdoor&regions=all , it shows that this resource is in GA.
However, if I attempt to deploy a working, tested ARM template to certain regions I get an error which explictly indicates that the region is unsupported (this error message is from an Azure Devops pipeline, but I have seen the same error using powershell deployment ofthe same template with a params file locally):
As such, it doesn't seem like I can trust the availability by region site (and to be fair, it does have a disclaimer on it).
How do I tell, before a deployment is fired, whether I can safely use (i.e. deploy a specified resource type to) the region?
Ideally I'm looking for a dynamic solution to this, as just because a region isn't supported now doesn't mean it won't be in the future.

For your use-((Register-AzResourceProvider -ProviderNamespace Microsoft.Network).ResourceTypes | where-object ResourceTypeName -eq frontdoors).Locations
which will provide list of locations
You can refer following link for more examples-
https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-supported-services#azure-powershell

Related

AzureTag Policy automation using AzureDevops pipelines

We have a requirement to force certain tags to our azure resources. Some tags which we need to enforce from subscription level say(eg: st1=st1, st2=st2..), But some are needed to be resourcegroup level(rt1-rt1, rt2=rt2..) and others are to specific resource type (like, aks, appservice, storage account).
By going through the MS doc I found that this can be achieved using azure policy. So the plan is to create azure policy with allowed tags and tag values which need to be enforced on
i) in subscription level
2) resource group level
3) Resource type wise
4) and for other remaining app specific tags to the resources use "az tag update" command.
We need to use automated solution to achieve all these with Azurepipleine and shell commands or scripts as we have only linux machines.
so for the 4th point i got some working pipeline solution to add the app specific tags to the resource level.
But for the requirements 1 to 3, will there any arm or script already available , so that we can integrate them with our azurepipelines.
Any automated solution or suggestion you already tried on this?
update on 12/12
As this docs for Use Tags to organize your azure resources sharing to us, you could use rest api or sdk to add the tags for your resource.
And for the loop for giving the resources with the tags from the resource groups. You could look into this potential workaround for reference. Bash Script

Apply NSG/ASG by default on new subnets (Azure)

We manage an Azure subscription operated by several countries. Each of them is quite independant about they can do (create/edit/remove resources). A guide of good practices has been sent to them, but we (security team) would like to ensure a set of NSG is systematically applied for every new subnet/vnet created.
Giving a look to Azure Triggers, I am not sure that subnet creation belongs to the auditable events. I also was told to give a look to Azure policy, but once again I am not sure this will match our expectations which are : For every new vnet/subnet, automatically apply a set of predefined NSG.
Do you have any idea about a solution for our need ?
I have done work like this in the past (not this exact issue) and the way I solved it was with an Azure Function that walked the subscription and looked for these kinds of issues. You could have the code run as a Managed Identity with Reader rights on the subscription to report issues, or as a Contributor to update the setting. Here's some code that shows how you could do this with PowerShell https://github.com/Azure/azure-policy/tree/master/samples/Network/enforce-nsg-on-subnet
You could consider using a Policy that has a DeployIfNotExists Action, to deploy an ARM template that contains all the data for the NSG. https://learn.microsoft.com/en-us/azure/governance/policy/samples/pattern-deploy-resources
You can get the ARM template by creating the NSG and getting the template:
GettingNSGTemplate
Note also that creating a subnet is audited, you can see it in the Activity Log for the VNet. See the screen shot.
AddingASubnet

How to retrieve App Service Plan instance name (RDXXXXX)?

I am having an issue trying to retrieve all the instance names in an Azure App Service Plan.
In Azure Monitor, if you specify a "Scope" to "App Service Plan" and look at the Metric "CPU Percentage" and then add a filter to specify the "Instance" property, you can see which instance uses the most CPU. I am trying to do a PowerShell script to get these values. Unfortunatly I have not found any Azure REST Api that would give me this information so that my script would be 100% dynamic. I looked at the AzureRm or Az PowerShell modules but did not find anything there.
Any ideas how I can retrieve this list? The instances names looks like this :RD123456.
Thanks for you help !
Suppose you want to get the web instance name, if that's right you could get it from instance process with Web Apps - Get Instance Process.
And under the environment_variables there is a COMPUTERNAME suppose this is what you want.

How can I programatically (C#) read the autoscale settings for a WebApp?

I'm trying to build a small program to change the autoscale settings for our Azure WebApps, using the Microsoft.WindowsAzure.Management.Monitoring and Microsoft.WindowsAzure.Management.WebSites NuGet packages.
I have been roughly following the guide here.
However, we are interested in scaling WebApps / App Services rather than Cloud Services, so I am trying to use the same code to read the autoscale settings but providing a resource ID for our WebApp. I have already got the credentials required for making a connection (using a browser window popup for Active Directory authentication, but I understand we can use X.509 management certificates for non-interactive programs).
This is the request I'm trying to make. Credentials already established, and an exception is thrown earlier if they're not valid.
AutoscaleClient autoscaleClient = new AutoscaleClient(credentials);
var resourceId = AutoscaleResourceIdBuilder.BuildWebSiteResourceId(webspaceName: WebSpaceNames.NorthEuropeWebSpace, serverFarmName: "Default2");
AutoscaleSettingGetResponse get = autoscaleClient.Settings.Get(resourceId); // exception here
The WebApp (let's call it "MyWebApp") is part of an App Service Plan called "Default2" (Standard: 1 small), in a Resource Group called "WebDevResources", in the North Europe region. I expect that my problem is that I am using the wrong names to build the resourceId in the code - the naming conventions in the library don't map well onto what I can see in the Azure Portal.
I'm assuming that BuildWebSiteResourceId is the correct method to call, see MSDN documentation here.
However the two parameters it takes are webspaceName and serverFarmName, neither of which match anything in the Azure portal (or Google). I found another example which seemed to be using the WebApp's geo region for webSpaceName, so I've used the predefined value for North Europe where our app is hosted.
While trying to find the correct value for serverFarmName in the Azure Portal, I found the Resource ID for the App Service Plan, which looks like this:
/subscriptions/{subscription-guid}/resourceGroups/WebDevResources/providers/Microsoft.Web/serverfarms/Default2
That resource ID isn't valid for the call I'm trying to make, but it does support the idea that a 'serverfarm' is the same as an App Service Plan.
When I run the code, regardless of whether the resourceId parameters seem to be correct or garbage, I get this error response:
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">
{"Code":"SettingNotFound","Message":"Could not find the autoscale settings."}
</string>
So, how can I construct the correct resource ID for my WebApp or App Service Plan? Or alternatively, is there a different tree I should be barking up to programatially manage WebApp scaling?
Update:
The solution below got the info I wanted. I also found the Azure resource explorer at resources.azure.com extremely useful to browse existing resources and find the correct names. For example, the name for my autoscale settings is actually "Default2-WebDevResources", i.e. "{AppServicePlan}-{ResourceGroup}" which I wouldn't have expected.
There is a preview service https://resources.azure.com/ where you can inspect all your resources easily. If you search for autoscale in the UI you will easily find the settings for your resource. It will also show you how to call the relevant REST Api endpoint to read or update that resorce.
It's a great tool for revealing a lot of details for your deployed resources and it will actually give you an ARM template stub for the resource you are looking at.
And to answer your question, you could programmatically call the REST API from a client with updated settings for autoscale. The REST API is one way of doing this, the SDK another and PowerShell a third.
The guide which you're following is based on the Azure Service Management model, aka Classic mode, which is deprecated and only exists mainly for backward compatibility support.
You should use the latest
Microsoft.Azure.Insights nuget package for getting the autoscale settings.
Sample code using the nuget above is as below:
using Microsoft.Azure.Management.Insights;
using Microsoft.Rest;
//... Get necessary values for the required parameters
var client = new InsightsManagementClient(new TokenCredentials(token));
client.AutoscaleSettings.Get(resourceGroupName, autoScaleSettingName);
Besides, the autoscalesettings is a resource under the "Microsoft.Insights" provider and not under the "Microsoft.Web" provider, which explains why you are not able to find it with your serverfarm resourceId.
See the REST API Reference below for getting the autoscale settings.
GET
https://management.azure.com/subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/microsoft.insights/autoscaleSettings/{autoscale-setting-name}?api-version={api-version}

Azure ARM template nested template deployment won't update resources\fails to start

I have the following ARM Template structure:
Parent Template
|--Nested Template 1
|--...
|--Nested Template 6
So I only have 2 levels of templates, Parent and nested.
Lets say I deploy parent to an empty resource group and everything works well. After that I delete one of the resources and want to deploy the same Parent Template with the same parameters to bring deleted resources back. But the deployment would fail saying that the resource already exists (the other, not the one i'm tried to recreate). I tried both incremental mode and full mode for deployments.
If i directly invoke nested template with the missing resources it works as expected (so specifically creating a deployment with nested template only, not with parent that invokes nested template).
UPD:
After some additional testing I can conclude thats even weirder then before. So I'm starting this deployment with powershell:
New-AzureRmResourceGroupDeployment #parameters
And it deploys just fine, however if I invoke the same command after the first deployment completed I would get an error:
The resource 'gggg-1s-the-wordd' already exists in location
'westeurope' in resource group 'gggg'. A resource with the same name
cannot be created in location 'northeurope'. Please select a new
resource name.
Is this behavior excepted? I can't seem to find anything relevant, thanks!
UPD2: It doesn't really matter if I use portal or powershell, I get the same error.
So with the help from Brian we were able to identify the culprit. The issue was that the WebApp had its location set to resourcegroup().location while the App Service Plan was correctly getting location from parameters. So that lead to a problem where at deployment time WebApp would deploy to the region where its App Service Plan was, but at evaluation time it would consider that this WebApp belongs to the region where the resource group was.
TLDR - copy paste error, which coupled with a bug in evaluation of location in ARM lead to a quite weird behavior.
If you deploy the same resource (intentionally did not use the word "template" there) to the same resource group, Azure should "make it so". IOW, if it's not there, it will create it, if it is there, it should no-op. It's not that black and white there are some nuances (like you can't change certain properties if the resource exsists) but if you deploy the same resource with the same property values to the same resource group you should not get an error.
In general, nesting (or not) shouldn't affect any of this.
If you're deploying to different resource groups, then you could see an error about "already exists" depending on the resource.
All that said, it's really hard to tell in your specific case what's going on without more detail... So if this doesn't help, can you add some detail (what's the exact error message) or a repro (template that we could see the problem with)?
I experienced the same issue. The reason was that, location of App Service was defined as [resourceGroup().location] instead of App service plan (ASP) location, which was creating the problem. I changed it by passing the location of ASP as a parameter to the template.
Getting location of of ASP is as:
internal static string GetASPLocation(TokenCloudCredentials credentials, string resourceGroup, string ASP)
{
Console.WriteLine($"Getting location of App Service Plan {ASP} in Resource Group {resourceGroup}");
var resourceClient = new ResourceManagementClient(credentials);
ResourceExistsResult result = resourceClient.Resources.CheckExistence(resourceGroup, new ResourceIdentity(ASP, "Microsoft.Web/serverfarms", "2015-08-01"));
var appServicePlan = resourceClient.Resources.Get(resourceGroup, new ResourceIdentity(ASP, "Microsoft.Web/serverfarms", "2015-08-01"));
return appServicePlan.Resource.Location;
}
And in ARM template, location can be changed as :
"location": "[parameters('ASPLocation')]"

Resources