Invoke Sync with Powershell - powershell

Normally, I integrate the deployment source to webapp, and then run the 'Sync' button found in the webapp dashboard as and when required to sync the Azure webapp with my onedrive folder.
But, if I want to give a non-Azure user, I mean , who need not be logged in to Azure portal itself, rather could invoke with a demo credential or sort, what should I do? Or, If I want to run it myself from shell, how to approach?
Would it be possible to run the sync from power-shell with service principal or similar ways ( runbooks, http trigger with azure functions for sync ) without actually giving the user a login credential itself?
Update:
1. I read this blog on Kudu but not sure whether it is what I am actually looking for. Please suggest. https://dzimchuk.net/post/azure-web-apps-continuous-deployment
Update 31/Aug:
My workflow got 3 slots dev/stage/mirror. I aim to integrate dev with source repo. So, Sync is enabled at lowest environment.
SiteName : YourWebApp(dev)
State : Running
DefaultHostName : YourWebApp-dev.azurewebsites.net
Id : /subscriptions/1234567890-{my}-{subscription}_{id}/resourceGroups/Default-Web/providers/Microsoft.Web/sites/YourWebApp/slots/dev
Name : YourWebApp/dev
Location : East US
Type : Microsoft.Web/sites/slots

If you install the latest Azure PowerShell, you can run this command to trigger a sync:
Invoke-AzureRmResourceAction -ResourceGroupName {YourResourceGroup} -ResourceType Microsoft.Web/sites -ResourceName YourWebApp -Action sync -ApiVersion 2015-08-01 -Force
Or if you're dealing with a slot, it will look like this:
Invoke-AzureRmResourceAction -ResourceGroupName {YourResourceGroup} -ResourceType Microsoft.Web/sites/slots -ResourceName YourWebApp/YourSlot -Action sync -ApiVersion 2015-08-01 -Force
As far as letting some other user authenticate, you have a couple options:
You can make them a Contributor on that Web App (using RBAC - Role Based Access Control)
You can set up a Service Principal

Related

How do I update the IP whitelist for a staging slot via Azure Powershell from an Azure DevOps Release Pipeline?

I have an application hosted in Azure, and I use Azure DevOps to manage my build and release pipelines. As part of the release, I warm up the application by making a request to the root url (e.g. https://myapp.azurewebsites.net). In order to make this request I must first make sure the hosted build agent running the deployment has access to that url (or I will get a 403). I have written a short powershell script to achieve this, and put it in an Azure Powershell task. It adds the IP of the build agent to the IpSecurityConfiguration of the app service. So far so good. It works perfectly for apps that are just apps. Where it falls down is when I try to use it against a staging environment. When we release to production we first push the code to a staging slot, then flip it over to live when we've run our tests and made sure everything is good. The powershell script that correctly handles the IpSecurityConfiguration for the app services does not work on the staging slot. To access a staging slot, we use myappname/slots/staging for the variable $(WebApiName), normally it would just be the name of the app service itself. Again, this works perfectly if I run the script from my local environment, it only fails in the pipeline. The code is below:
# Whitelist Azure Agent IPs
$agentIP = Invoke-RestMethod http://ipinfo.io/json | Select -exp ip
Write-Host "Connecting to Azure"
$APIVersion = ((Get-AzureRmResourceProvider -ProviderNamespace Microsoft.Web).ResourceTypes | Where-Object ResourceTypeName -eq sites).ApiVersions[0]
Write-Host "API Version is $APIVersion. Getting web app config for $(WebApiName) in $(ResourceGroupName)"
$WebApiConfig = (Get-AzureRmResource -ResourceType Microsoft.Web/sites/config -ResourceName $(WebApiName) -ResourceGroupName $(ResourceGroupName) -ApiVersion $APIVersion)
Write-Host "Got web app config: $WebApiConfig"
$webIP = [PSCustomObject]#{
ipAddress = "$agentIP/32";
action = "Allow";
tag = 'Default';
priority = 300;
name = $agentIP.ToString();
description = $agentIP.ToString()
}
Write-Host "Adding $agentIP to security restrictions"
$WebApiConfig.Properties.ipSecurityRestrictions += $webIP
Write-Host "Updating security restrictions"
# update app restrictions, do not prompt for confirmation
$result = Set-AzureRmResource -ResourceId $WebApiConfig.ResourceId -Properties $WebApiConfig.Properties -ApiVersion $APIVersion -Force
To muddy the water somewhat, I can get the exact same code to work perfectly with the staging slot locally by changing
$WebApiConfig = (Get-AzureRmResource -ResourceType Microsoft.Web/sites/config -ResourceName $(WebApiName) -ResourceGroupName $(ResourceGroupName) -ApiVersion $APIVersion)
to
$WebApiConfig = (Get-AzureRmResource -ResourceType Microsoft.Web/sites -ResourceName $(WebApiName)/config -ResourceGroupName $(ResourceGroupName) -ApiVersion $APIVersion)
but this doesn't work in the Azure Powershell task. Instead I can't deploy to any environment because the task fails while trying to access IpSecurityRestrictions on the $WebApiConfig object. The exception is "Exception setting "ipSecurityRestrictions": "The property 'ipSecurityRestrictions' cannot be found on this object. Verify that the property exists and can be set."
As I said earlier, if I run the script in exactly this form locally, it works perfectly. Obviously I have to manually replace the variables that come from the build pipeline, but otherwise there is no difference between code that works exactly as I want it to on my local machine and code that fails in the release. You can verify this by swapping out $(WebApiName) for a valid app service name and $(ResourceGroupName) for the resource group that app service is in. I put a line in about halfway down that outputs $WebApiConfig so that I can see what it is, and on my local machine I see a valid object, while in the output of the task I get nothing. The line just says "Got web app config:"
Anyone got any ideas?
I've tried changing the version of powershell used by the task to
match the version I've got.
I've tried using the preview version of the task (v4, otherwise I've been using v3).
I've tried every permutation of /sites/config everywhere I can think of in the call to Get-AzureRmResource (since that was what allowed it to work locally on the slot).
Just one final thing in case anyone wonders. I'm doing it this way instead of whitelisting all the IPs in Microsoft's list (https://www.microsoft.com/en-us/download/confirmation.aspx?id=41653) for two reasons, firstly it's a lot easier to maintain a short list of our own IPs, and secondly there seems to be a bug somewhere in the way Azure handles those CIDR definitions because IPs that are categorically in those ranges are frequently blocked during our deployments even when we have the entire file whitelisted. This way I just add whichever IP is currently being used dynamically to the whitelist, and remove it after we're done. Assuming I can get it to work...
Finally figured out the solution to this. In order to work with slots the resource type has to be subtly different. This line works in an Azure Powershell task:
$WebApiConfig = (Get-AzureRmResource -ResourceType Microsoft.Web/sites/slots/config -ResourceName $(WebApiName) -ResourceGroupName $(ResourceGroupName) -ApiVersion $APIVersion)
Posting in case it helps anyone else with the same issue. I can confirm that the approach I've taken works great in managing access to Azure sites by build agents, and saves a lot of messing around with Microsoft's build agent xml file.

Azure App Service ApiApp

I am trying to create an API App in Azure App Service with PowerShell.
The cmdlet I am calling always create a Web App by default. If it is possible, I would like to know how I can specify the type/kind to be Api App instead of Web App?
New-AzureRmWebApp -Name $name -Location $location -AppServicePlan $plan -ResourceGroupName $resourceGroup
From my reading there is not much different between both except the icon, is it worth it to set the type to "Api App" if it's what my app is all about?
I am using version 5.4.0 of AzureRM PowerShell module.
> Get-Module "AzureRM"
ModuleType Version Name
---------- ------- ----
Script 5.4.0 AzureRM
Just call New-AzureRmResource instead and pass in -Kind 'api':
# CREATE "just-an-api" API App
$ResourceLocation = "West US"
$ResourceName = "just-an-api"
$ResourceGroupName = "demo"
$PropertiesObject = #{
# serverFarmId points to the App Service Plan resource id
serverFarmId = "/subscriptions/SUBSCRIPTION-GUID/resourceGroups/demo/providers/Microsoft.Web/serverfarms/plan1"
}
New-AzureRmResource -Location $ResourceLocation `
-PropertyObject $PropertiesObject `
-ResourceGroupName $ResourceGroupName `
-ResourceType Microsoft.Web/sites `
-ResourceName "just-an-api/$ResourceName" `
-Kind 'api' `
-ApiVersion 2016-08-01 -Force
..which produces an API App, a Microsoft.Web/sites resource type of the api kind:
Hold on.. How did you come up with this stuff?
Visit https://resources.azure.com and navigate to an existing API App, build the PowerShell syntax by combining the PowerShell tab with the desired values from the JSON resource definition.
There is not a parameter in New-AzureRmWebApp supported to explicitly indicate whether API App or Web App. The resource provider is still Microsoft.Web. And there is no parameter which indicates the type in ARM template.
These two types technically still work in the same way. The difference would be the purpose, icon, OS running choice and debugging capability (refer here What is the difference between an API App and a Web App?).
You may want to classify between the two types by tagging it, which would help manage in case your resource groups have many web resources.
You can create API App via Azure Portal, or Visual Studio.
Also, look at Azure API Management for more flexibility of API wrapping instead of Azure App Service.

How to change deployment password of AzureWeb App with Powershell?

I want to change the deployment password of an existing Azure Web (or Azure Function to be exact, but I think it 's the same) using Powershell.
So in the Azure Portal,
MyWebApp > resource Explorer Tab > Go > Powershell
I have found that command :
Invoke-AzureRmResourceAction
-ResourceGroupName MyGroup
-ResourceType Microsoft.Web/sites
-ResourceName MyWebApp
-Action newpassword
-ApiVersion 2015-08-01
-Force
But where is the password ?
How do I provide it ?
First, make sure you understand the difference between User (aka deployment) credentials and Site (aka publishing) credentials. See here for details.
The PowerShell command you have in your question refers to Site credentials, and is the equivalent of clicking 'Reset Publishing Profile' from the portal. The Site credential is always a randomly generating string, and is not something that you set to your own value. That is why that command does not take any parameters.

Add virtual folder to Azure Web App

I want to automate my deployment to Azure Web App.
I am using Octopus Deploy to deploy my app to a Azure Web App into a sub-folder based on my git-branch.
This works.
The problem is, that I need to add that folder to the list of virtual directories in the Application Settings of the Web App and I also have to mark it as an application.
How can I do this?
I can use anything that is possible with PowerShell.
P.S. I found this old thread: https://social.msdn.microsoft.com/Forums/azure/en-US/990f41fd-f8b6-43a0-b942-cef0308120b2/add-virtual-application-and-directory-to-an-azure-website-using-powershell?forum=windowsazurewebsitespreview, but this no longer seems to be working.
I'd recommend looking into the Azure Resource Manager - https://resources.azure.com - if you drill down to an existing Web App you can view REST & PowerShell commands for managing resources. In the Web App JSON, you'll find a section for Virtual Applications:
"virtualApplications": [
{
"virtualPath": "/",
"physicalPath": "site\\wwwroot",
"preloadEnabled": true,
"virtualDirectories": null
}
],
Since you are using Azure PowerShell, after Get-AzureSubscription, you should be able to do something like:
# PowerShell equivalent script
Switch-AzureMode -Name AzureResourceManager
# GET web
Get-AzureResource -ResourceGroupName yourResourceGroup -ResourceType Microsoft.Web/sites/config -ResourceName yourWebApp/web -OutputObjectFormat New -ApiVersion 2015-08-01
# SET web
$PropertiesObject = #{
#Property = value;
}
Set-AzureResource -PropertyObject $PropertiesObject -ResourceGroupName yourResourceGroup -ResourceType Microsoft.Web/sites/config -ResourceName yourWebApp/web -OutputObjectFormat New -ApiVersion 2015-08-01 -Force

Download Azure Resource Template

How can I download Azure Resource Template using PowerShell commands? I want to edit it and then redeploy it. I have tried it but its not giving me proper values. Its giving me empty object array for virtual applications while I have one virtual application on my azure portal. Below is the command I have used.
Get-AzureResource -ResourceGroupName Default-Web-BrazilSouth -ResourceType Microsoft.Web/sites/config -ResourceName TestGhaffar/web -OutputObjectFormat New -ApiVersion 2015-08-01
This feature is not currently available, although it is under review. Another workaround is to view the current JSON representation of your service using https://resources.azure.com.