Is it possible to route Slot traffic programmatically via an Az Cmdlet? - azure

I would like to be able to route traffic from the "production" Slot to a different slot in Azure via powershell. How could I go about this that does not use RampUpRules?
We have an application in Azure currently with 3 slots (the production slot and 2 additional slots) and via a release pipeline we would like to automatically route all traffic to one of those two slots.
I have found that a "RampUpRule" can achieve this (shown in the code snippet), but it does so via the x-ms-routing-name cookie based on the given rule. I also know that the slot traffic can be done via the Deployment Slots UI on the app service but would like to automate this (if possible).
I have been unable to find a way of doing it using the existing Az cmdlets myself so far - so I was wondering if anyone knew of a way to do this.
$appName = "myapp"
$appService = Get-AzWebApp -Name $appName
$appConfig = $appService.SiteConfig
$rulesList = New-Object -TypeName System.Collections.Generic.List[Microsoft.Azure.Management.WebSites.Models.RampUpRule]
$rule = New-Object -TypeName Microsoft.Azure.Management.WebSites.Models.RampUpRule
$rule.Name = "LiveTraffic"
$rule.ActionHostName = "myapp-staging.azurewebsites.net"
$rule.ReroutePercentage = 100
$rulesList.Add($rule)
$appConfig.Experiments.RampUpRules = $rulesList
Set-AzWebApp -WebApp $appService
The RampUpRules achieve what we would like, but I am not sure if it being done via the set cookie is going to be acceptable.

Your script seems works. If you set the ReroutePercentage of the staging slot with 100, your users will be routed to the staging slot automatically, because the routing percentage of production is set to 0. Unless you provide a link with x-ms-routing-name=self like Go back to production app.
For more details, you could refer to this link.

Related

IP Address Micro Application Insights

We have an Azure web app that we use for dev\testing. I noticed in Application Insights that it is getting pinged like 500-700 times per minute. I tried blocking the IP in Networking and of course being no network expert didn't realize it will just keep rolling to the next one.
Question 1 is - How do I block by group of IP's used?
Question 2 if that doesn't work - How do I block the "U.K." as I only need in the US currently for dev\testing. I prefer question one so that I can use for my prod. version also and as needed.
Blocking arbitrary IP ranges brings you nowhere. If you really want to restrict access to your test environments on the network level, I suggest defining allowed IP ranges and blocking the rest of the internet. That can be done in the portal, using PS like HariKrishnaRajoli-MT showed or preferably with IaC like Bicep or Terraform.
If you want to have some dynamic blocking (like country-based), you'll need a component in front of your App Service like an Azure App GW with WAF. However, that has some notable costs included.
Lastly, why is pinging an issue? It does not cause any significant stress to the service. If you want to protect your service from outside access, you should enable some authentication. Azure App Service provides an easy way of enabling authentication and authorization with different identity providers.
Question 1 is - How do I block by group of IP's used?
Create a new text file and store all the IP Addresses which you want to allow or block and each separated with a Comma (,) as shown below:
Paste this code in an PowerShell File to read the above text file:
Param``(
[``Parameter``(``Mandatory = $true``)]
[string] $ResourceGroupName``,
[``Parameter``(``Mandatory = $true``)]
[string] $WebAppName``,
[``Parameter``(``Mandatory = $true``)]
[string] $IPAddressSourceFileName
)
#Step1 - Get All IP Addresses from the File
$SourceIPAddresses = (``Get-Content $IPAddressSourceFileName``).Trim() | ConvertFrom-Csv
#Step2 - Get All existing IP Addresses from the Config of App Service
$APIVersion = ((``Get-AzResourceProvider -ProviderNamespace Microsoft.Web).ResourceTypes | Where-Object ResourceTypeName -eq sites).ApiVersions[0]
$config = (``Get-AzResource -ResourceType Microsoft.Web/sites/config -Name $WebAppName -ResourceGroupName $ResourceGroupName -ApiVersion $APIVersion``)
#Step3 - Prepare the new IP Addresses list from that IPAddressList file and collect all the new ones into the $IpSecurityRestrictions collection
foreach``(``$item in $SourceIPAddresses``){
$Rule``=``$config``.Properties.ipSecurityRestrictions | Where-Object { $_``.ipAddress -eq $item``.IPAddress}
if``(``$null -ne $Rule``)
{
Write-Host -ForegroundColor Green 'No Action on the IP:' $item``.ipAddress
}
else
{
$config``.Properties.ipSecurityRestrictions+=``$item
}
}
#Step4 - Finally update the new IP Addresses to Azure App Service
Set-AzResource -ResourceId $config``.ResourceId -Properties $config``.Properties -ApiVersion $APIVersion -Force
Run the above PowerShell Script from VS Code > Terminal > Run this following command:
.\ReadIPAddresses.ps1 azdevops-rg-eus-dev azuredevops-wapp1-eus-dev IPAddresses.txt
After running this command, you can see all the IP Addresses will be added to the Access Restrictions blade as shown here:

How to change/set priority of Azure Application Gateway rule

I'm trying to set up a rule in my Azure Application Gateway which applies a longer timeout limit on certain requests to allow a service to serve requests/data without a timeout.
The rule is configured with path-based routing so it should only kick in if requests contain a specific path prefix.
I believe that my rule is not being executed however, because it sits lower down in the list of rules from the more general rule.
Is there a way to set the priority within the Azure Portal, or can this only be done when managing this configuration via power shell scripts?
At this moment in time you can't set rule priority through the Azure Portal for an existing Application Gateway. You will need to set a priority on all of your existing rules through Powershell/Azure CLI, then you will be able to manage them through the portal. Note that this only applies to Application Gateway V2.
In order to do that, you can loop over all your existing rules and set them a unique priority between 1 and 20000 (1 = highest priority, 20000=lowest priority). Here's an example of such Powershell script:
Connect-AzAccount -Tenant 'TENANT-GUID-HERE'
$AppGW = Get-AzApplicationGateway -Name "APP-GATEWAY-NAME-HERE" -ResourceGroupName "RESSOURCE-GROUP-HERE"
$Rules = Get-AzApplicationGatewayRequestRoutingRule -ApplicationGateway $AppGW
$i = 1000
foreach ($Rule in $Rules) {
$Rule.Priority = $i
$i++
}
Set-AzApplicationGateway -ApplicationGateway $AppGw
Then, if the script succeeds, you will now be able to manage rules priorities on the Portal (look for the "Priority" textbox while adding or modifying a rule).

Azure Web App: Cannot add a VNET Restriction Rule using PowerShell when VNET is on a different subscription

I have a web application in azure and I want to make sure that only my build server (or any other VM on the same subnet) are the only ones which are able to access the SCM site. I thought the most obvious thing would be to create an access restriction rule and in fact that works, I am able to create it from the portal with no issue whatsoever.
The problem, however, happens when I try to automate this using powershell. My build server subnet is located on a subscription different from the one where my web application is.
I am executing the following powershell script:
$subnetId = "/subscriptions/$VNETSubscriptionId/resourceGroups/$VNETResourceGroup/providers/Microsoft.Network/virtualNetworks/$buildServerVNET/subnets/$buildServerSubNet"
Add-AzWebAppAccessRestrictionRule -ResourceGroup $webAppRg -WebAppName $webAppname -Name VNETAccess -Priority 1000 -Action Allow -SubnetId $subnetId
And I get the following error:
Add-AzWebAppAccessRestrictionRule : The client '{{my user credential}}' with object id '81fa4eb1-5553-4daa-af44-3c717b19eda2' does not have authorization to perform action 'Microsoft.Network/virtualNetworks/subnets/read' over scope '/subscriptions/{{websiteSubscriptionId}}/resour
ceGroups/{{VNETResourceGroup}}/providers/Microsoft.Network/virtualNetworks/{{buildServerVNET}}/subnets/{{buildServerSubNet}}' or
the scope is invalid. If access was recently granted, please refresh your credentials.
The error seems to indicate that the cmdlet is searching for the subnet on the same subscription id than the website instead of the subscription where the subnet is located, since the resourceId string that is being returned on the error messsage has the wrong subscription Id. It is using the one where the website is instead of using the one where the build server is.
What else needs to be done in order to create this rule through powershell?
The error message is confused.
In fact, after my validation, you need to add the -IgnoreMissingServiceEndpoint parameter when adding a subnet from a different subscription. Read this GitHub case WebApp:Add-AzWebAppAccessRestrictionRule.md - incorrect use of subscription context over SubnetId param
When using a subnet from a different subscription, we cannot validate
the subnet to see if the correct service endpoint (Microsoft.Web) has
been set. If you use -IgnoreMissingServiceEndpoint the rule can be
added.

Move Azure website between App Service Plans

Is it possible to move an Azure Website to a different (or new) App Service Plan?
I have already tried both the old and new portals but cannot find the options for this.
The original accepted answer is more than a year old. In Azure world, that's an eternity. The "Change App Plan" button in the Azure Portal is no longer present it appears (as of 2016-06-17), so I'm throwing in the Powershell command I needed to use in order to move a Webapp to another App Service Plan.
Set-AzureRmWebApp -Name <webapp name> -ResourceGroupName <resource group name> -AppServicePlan <new app service plan>
Set-AzureRmWebAppSlot -Name <webapp name> -Slot <slot name> -ResourceGroupName <resource group name> -AppServicePlan <new app service plan>
The option "Change App Service plan" has been moved to the APP SERVICE PLAN menu.
Yes, you can do this from the Web app blade in the Azure portal. You have to expand the toolbar though to see the option. See below.
I needed to move things between different subscriptions, which is quite possible according to documentation. Much is shamelessly copied from the azure website. This solution is taking advantage of the Azure Powershell 1.0.
First off, if you need to move a Web app and it's connected webfarm there are some limitations:
You can move Azure Web App resources using the ARM Move Resources Api.
Azure Web Apps currently supports the following move scenarios:
Moving the entire contents of a resource group (web apps, app service plans, and certificates) to another resource group.
Note: The destination resource group can not contain any Microsoft.Web resources in this scenario
Moving individual web apps to a different resource group, while still hosting them in their current app service plan (the app service
plan stays in the old resource group)
Basically you need to get the resource id from the resources you want to move and use the Move-AzureRmResource command. You'll naturally need an Azure login which is able to read and write to the subscriptions involved.
$webapp = Get-AzureRmResource -ResourceGroupName OldGroup -ResourceName WebApp -ResourceType Microsoft.Web/sites
$plan = Get-AzureRmResource -ResourceGroupName OldGroup -ResourceName Plan -ResourceType Microsoft.Web/serverFarms
Move-AzureRmResource -DestinationResourceGroupName NewGroup -ResourceId ($webapp.ResourceId, $plan.ResourceId) -DestinationSubscriptionId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
I'd point out that if you're moving the resources to another subscription, there are some caveats. First, that subscription must have rights to provision the website in that region, the API's for that are beyond this scope, but simply creating a website and removing it will give the subscription those rights. In my case i had a second error which is still unresolved, but i suspect that other resources that are connected to the resources being moved are the culprits. Will update with further information if i resolve the issue.
As a final note, there is also the possibility to use the REST API.

New deployment slot for azure websites

Is there a REST API call to create a new deployment slot in Azure website?
I am not able to find anything here.
You can do this using the Azure PowerShell cmdlets. For example, I tested this with a site named "cloudallocweb" in East US and then used the following command to create a new deployment slot in the cloudallocweb site.
New-AzureWebsite -Name "cloudallocweb" -Location "East US" -Slot "test"
Peeking into what the New-AzureWebsite cmdlet is doing in the command above, I found this POST operation which is basically the Create a web site REST API. Notice that it is passing the WebSpace setting (matching in the URL), which I don't see documented in the REST API.
At any rate, it appears the Create a Web Site REST API is what you need. This makes sense considering that a deployment slot is really just a web site. You may also take a look at the List Webspaces API to find the right web space value for your site.
Following the steps above, the new deployment slot will appear under the original site as shown here. You can then swap the deployment slots using the portal, REST API, or the Switch-AzureWebsiteSlot cmdlet.

Resources