Is it possible to enable Always On for Azure websites through management/resource management APIs? - api

I am writing some code for automatic deployment of Azure websites (including the creation of the website in Azure). I'm using the Azure Management Libraries and Azure Resource Management Libraries available in Nuget. Most of it is in place, however I have not been able to find a way to enable the "Always On" property through any of the APIs I've seen. This property can be set through the azure management portal under the Configure tab for a website.
I've checked:
The properties reference on MSDN: http://msdn.microsoft.com/en-us/library/azure/dn236426.aspx
The powershell APIs (get-azureresource, get-azurewebsite, ...) to see if there's a reference to Always On (there's not)
The REST calls the management portal is sending, through Fiddler. Here there is a reference to Always On in a POST going to https://manage.windowsazure.com/Websites/UpdateConfig (which is not part of the management or resource management APIs as far as I know). The exact path in the JSON body that is sent is /siteConfig/AlwaysOn.
So, the question is, is it possible to enable/disable Always On through an "official" API?
Thanks!

I believe I found the solution!
Using the resource management API, I can set the AlwaysOn property through the siteConfig object. In powershell:
Set-AzureResource -ApiVersion 2014-04-01 -PropertyObject #{"siteConfig" = #{"AlwaysOn" = $false}} -Name mywebsite -ResourceGroupName myrg -ResourceType Microsoft.Web/sites
In the resource management API in .NET it would be similar to this.
The resulting REST call, to
https://management.azure.com/subscriptions/xxx/resourcegroups/yyy/providers/Microsoft.Web/sites/zzz?api-version=2014-04-01:
{
"location": "West Europe",
"properties": {
"siteConfig": {
"AlwaysOn": true
}
},
"tags": {}
}

Using updated ARM (Azure Resource Manager) Powershell, v1.0+
Get-AzureRmResource: https://msdn.microsoft.com/en-us/library/mt652503.aspx
Set-AzureRmResource: https://msdn.microsoft.com/en-us/library/mt652514.aspx
# Variables - substitute your own values here
$ResourceGroupName = 'My Azure RM Resource Group Name'
$WebAppName = 'My Azure RM WebApp Name'
$ClientAffinityEnabled = $false
# Property object for nested, not exposed directly properties
$WebAppPropertiesObject = #{"siteConfig" = #{"AlwaysOn" = $true}}
# Variables
$WebAppResourceType = 'microsoft.web/sites'
# Get the resource from Azure (consider adding sanity checks, e.g. is $webAppResource -eq $null)
$webAppResource = Get-AzureRmResource -ResourceType $WebAppResourceType -ResourceGroupName $ResourceGroupName -ResourceName $WebAppName
# Set a directly exposed property, in this case whether client affinity is enabled
$webAppResource.Properties.ClientAffinityEnabled = $ClientAffinityEnabled
# Pass the resource object into the cmdlet that saves the changes to Azure
$webAppResource | Set-AzureRmResource -PropertyObject $WebAppPropertiesObject -Force

For those using the .Net API, it's
var cfg = await websiteClient.Sites.GetSiteConfigAsync(site.ResourceGroup, site.Name, cancellationToken).ConfigureAwait(false);
if (!cfg.AlwaysOn.GetValueOrDefault())
{
cfg.AlwaysOn = true;
await websiteClient.Sites.UpdateSiteConfigAsync(site.ResourceGroup, site.Name, cfg, cancellationToken).ConfigureAwait(false);
}

Related

Azure Synapse Analytics Powershell or CLI to provision Managed Private Endpoint

I have been struggling a lot to find Microsoft documentation on Azure Synapse Analytics to provision Managed Private Endpoints using powershell or CLI?
I can easily do it thru Azure Portal (basically thru Studio) but we want to do it as part of our Azure DevOps pipeline and provision the Managed Private endpoints (not the customer private endpoints) thru Powershell/CLI.
Any help?
Thank you
In the updated PowerShell module, there is now a powershell commandlet available: New-AzSynapseManagedPrivateEndpoint.
This should be the way to go. If you don't have PowerShell available, you can still use this CLI approach.
Additionally we have done the following to approve the Managed Endpoint connection. You need to have permissions on the resource that you are connecting to, if you want to be able to approve the Endpoint connection.
# list all private endpoints
endpointList = Get-AzPrivateEndpointConnection -PrivateLinkResourceId '/subscriptions/<xxx>/resourceGroups/<xxx>/providers/Microsoft.Storage/storageAccounts/<xxx>'
# filter the synapse endpoint
$synpapseEndpoint = $endpointList | Where-Object { $_.PrivateEndpoint.Id.EndsWith('<yourworkspacename>.<yourmanagedenpointname>') }
Approve-AzPrivateEndpointConnection -ResourceId $synpapseEndpoint.Id
Currently we don’t have native Synapse PowerShell and CLI commands for creating managed private endpoints. There is a workaround to create private endpoints through Azure CLI. The sample code is as below.
Setup
$workspaceName = "your-workspace-name"
$synapseAnalyticsResourceId = "https://dev.azuresynapse.net"
$managedVirtualNetworkName = "your-managed-virtual-network-name"
$newEndpointName = "your-new-endpoint-name"
To list private endpoints
az rest --resource $synapseAnalyticsResourceId --method GET --url "https://$($workspaceName).dev.azuresynapse.net/managedVirtualNetworks/$($managedVirtualNetworkName)/managedPrivateEndpoints?api-version=2019-06-01-preview"
To create private endpoints
Doc for this API
# GroupId in the body is specifically for a Data Lake endpoint (Storage with Hierarchical namespace enabled)
$body = "{""properties"":{""privateLinkResourceId"": ""<resourceid-to-your-resource-for-endpoint>"", ""groupId"": ""dfs""}}"
$body | Out-File body.json
az rest --resource $synapseAnalyticsResourceId --method PUT --headers "Content-Type=application/json" --url "https://$($workspaceName).dev.azuresynapse.net/managedVirtualNetworks/$($managedVirtualNetworkName)/$($newEndpointName)?api-version=2019-06-01-preview" --body `#body.json
Remove-Item body.json

Need PCS_AAD_APPID and more to run Azure IoT storage-adapter microserver locally

I'm trying the Azure IoT Accelerators Remote Monitoring solution and trying to follow the instructions here:
https://learn.microsoft.com/en-us/azure/iot-accelerators/iot-accelerators-remote-monitoring-create-simulated-device
In it, I need to run the storage adapter microservice locally and for that to work, it seems that I need three environmental variables WHICH I DON'T KNOW HOW TO FIND THE VALUES FOR:
PCS_AAD_APPID = { Azure service principal id }
PCS_AAD_APPSECRET = { Azure service principal secret }
PCS_KEYVAULT_NAME = { Name of Key Vault resource that stores settings and configuration }
I can create those environmental variables but I have no idea what values I should put in there. Anyone?
FYI, right now when I'm running the storage adapter microservice locally, I get this error:
"{"Name":"StorageAdapter","Status":{"IsHealthy":false,"Message":"Storage check failed"}..."
...which is preceeded by a caught exception with this messae:
"AuthKey = '((Microsoft.Azure.Documents.Client.DocumentClient)this.client).AuthKey' threw an exception of type 'System.ArgumentNullException'"

Azure API Management - Update Swagger Schema

I have Imported my swagger schema and the management service has built out all the documentation for my API. I have now made changes and re-deployed the changes. Do I have remove the API from the API Management and re-import or is there a way to 'update' the existing one?
Ok guys I'm going to do my duty to humanity and show you the REAL way to do this. By "real" I mean, let's face it, nobody in the real world is going to keep clicking the portal to refresh changes to their API. What everyone wants is to automate this annoying manual task.
So I wrote this Powershell script which we are currently using in production. This will get you there for sure.
PREREQUISITE: You need a service principal to be able to automate the login. I used this guide to do that.
param(
[String]$pass,
[String]$swaggerUrl,
[String]$apiId,
[String]$apiName,
[String]$apiServiceUrl
)
Try
{
$azureAccountName = "[YOUR AZURE AD APPLICATION ID FOR THE SERVICE PRINCIPAL]"
$azurePassword = ConvertTo-SecureString $pass -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAccountName, $azurePassword)
Add-AzureRmAccount -Credential $psCred -TenantId "[YOUR AZURE TENANT ID]" -ServicePrincipal
$azcontext = New-AzureRmApiManagementContext -ResourceGroupName "[YOUR RESOURCE GROUP NAME]" -ServiceName "[THE NAME OF YOUR API MANAGEMENT INSTANCE]"
Import-AzureRmApiManagementApi -Context $azcontext -SpecificationFormat "Swagger" -SpecificationUrl $swaggerUrl -ApiId $apiId
Set-AzureRmApiManagementApi -Context $azcontext -ApiId $apiId -ServiceUrl $apiServiceUrl -Protocols #("https") -Name $apiName
}
Catch
{
Write-Host "FAILURE! An error occurred!!! Aborting script..."
exit
}
Obviously you'll need to replace the bracketed strings above. An explanation of the parameters:
"pass" : Your service principal's password
"swaggerUrl" : The path to your application's swagger json document
"apiId" : Get this value from your API Management instance, it will be shown in the portal's dashboard if you check that existing API
"apiName" : Whatever you want to name it
"apiServiceUrl" : The Azure App Service Url of your API (or wherever your API is)
Nevermind, turns out you just tell the import that its an existing API and it will update. I was concerned I was going to end up with an error message that the 'operation already existed'.
I am currently using this script below, a modified version I can run locally or can be updated in CI/CD solution for automated updates
Login-AzureRmAccount
$subscriptionId =
( Get-AzureRmSubscription |
Out-GridView `
-Title "Select an Azure Subscription ..." `
-PassThru
).SubscriptionId
$subscriptionId
Select-AzureRmSubscription -SubscriptionId $subscriptionId
$apiMSName = "<input>"
$swaggerUrl = "<input>"
$apiId = "<input>"
$apiName = "<input>"
$apiServiceUrl = "<input>"
$resourceGroupName = "<input>"
$azcontext = New-AzureRmApiManagementContext -ResourceGroupName
$resourceGroupName -ServiceName $apiMSName
Import-AzureRmApiManagementApi -Context $azcontext -SpecificationFormat "Swagger" -SpecificationUrl $swaggerUrl -ApiId $apiId
Set-AzureRmApiManagementApi -Context $azcontext -ApiId $apiId -ServiceUrl $apiServiceUrl -Protocols #("https") -Name $apiName
Just as reference, since i had the same challenge, you have the option to use ARM templates, and create a CI (using VSTS, git, whatever) and deploy the ARM template. The advantage is, if for some reason you need to delete your API Management service and create it again, it will also be possible with the ARM template. If you need to do the changes to some specific configuration, or to the api specification, then you can do it, and deploy it, and it will update your changes.

Create Octopus machine via REST API (PowerShell)

I’m trying to create a machine via the REST API, calling it through PowerShell.
According to the documentation, only the name and thumbprint of the machine are needed to create a machine. But everything I try leads to either 405 or 500 errors:
$newMachine = #{Name='machineName';Thumbprint='asdvblsafghkvadc';} | ConvertTo-Json
$webClient.UploadString('http://server/octopus/api/machines','POST',$newMachine)
### OR
$newMachine = #{Name='machineName';Thumbprint='asdvblsafghkvadc';Roles='[web-server]';EnvironmentIds='[Environment-12]'; | ConvertTo-Json
$webClient.UploadString('http://server/octopus/api/machines','POST',$newMachine)
Creating environments and editing machines work perfectly, I just can’t get this machine creation down.
The post mentioned by ShaneC its a bit old by now. I recommend anyone trying to do this in Powershell to check the Module I started writing for Octopus Deploy.
Module site: http://octoposh.net/
Example of adding a machine using the module: https://github.com/Dalmirog/OctoPosh/wiki/Creating-Resources#machines
The module is still a work in progress, but I've been getting quite a good feedback of it lately.
With some help and feedback from the community, I'm sure It'll be end up being really good :)
Usually when you're adding the tentacle agent to your server, immediately afterwards you'd want to register said tentacle to the desired Octopus server. I would supply you with the PowerShell code that I used to do such a task, however it's probably worth reading the Octopus blog post on how they create their tentacle army. They supply the PowerShell and that was great start on how to do it.
Note: I had a terrible time of getting the tentacles to connect AFTER registering with the Octopus Server. The secret to getting it working? Stop the tentacle service and start it again.
After rereading your post, it looks like you're trying to add a tentacle to an Octopus server outside or after the tentacle installation itself. Can you clarify? I would think that at a minimum an environmentids and squid would be a requirement as well. Try adding the squid.
To create a machine from the Octopus REST API, certain libraries need to imported. Dalmiro Grañas outlines this in the first of a series of blog posts on interfacing with Octopus through PowerShell
He does not cover creating machines though, this is something I had to figure out myself from the library documentation on the MachineResource class
Below is the code I wound up using to create machines:
#Adding libraries
Add-Type -Path 'C:\OctopusLibraries\Newtonsoft.Json.dll'
Add-Type -Path 'C:\OctopusLibraries\Octopus.Client.dll'
Add-Type -Path 'C:\OctopusLibraries\Octopus.Platform.dll'
#Setting variables
$apikey = 'API-QBGAAZEUMSUKJVSADFSDFA5Y2FLC'
$OctopusURI = 'http://OctopusServer/octopus/api/'
#Creating a connection
$endpoint = new-object Octopus.Client.OctopusServerEndpoint $OctopusURI,$apikey
$repository = new-object Octopus.Client.OctopusRepository $endpoint
#Set the machine properties
$Properties = #{Name="MachineName";Thumbprint="1AE1B6F81A30C2C5771AC5B234S4FE975";EnvironmentIds="Environments-65";Roles="web-server";URI="https://MyServer:10933/";CommunicationStyle="TentaclePassive"}
$envObj = New-Object Octopus.Client.Model.MachineResource -Property $Properties
$repository.Machines.Create($envObj)
I needed to do this at work this week, here is an example of the code you are looking for (you will need PowerShell v3.0 to use Invoke-RestMethod, download for Windows 7 here: https://www.microsoft.com/en-us/download/details.aspx?id=34595 [before MS went spyware]):
$headers = #{"X-Octopus-ApiKey"="<YOUR OCTOPUS API KEY>"}
$url = "http://<YOUR OCTOPUS SERVER>/api/"
$envname = "<YOUR ENVIRONMENT NAME FROM OCTOPUS>"
$machine = "<YOUR MACHINE NAME>"
$dropPath = "\\<DROP MACHINE>\drop"
$appPath = "C:\Application"
$octopusPath = "C:\Octopus"
$roles = {"role1", "role2"}
# Get list of Environments
$environments = Invoke-RestMethod ($url + "environments/all") -Headers $headers -Method Get
# Choose the specific Environment by Name
$environmentId = $environments | ? { $_.Name -eq $envname }
# Fix up slashes
$dropPath = $dropPath.Replace("\","\\")
$appPath = $appPath.Replace("\","\\")
$octopusPath = $octopusPath.Replace("\","\\")
# build request
$body = "{""Endpoint"":{""CommunicationStyle"":""OfflineDrop"",""DropFolderPath"":""" + $dropPath + """,""ApplicationsDirectory"":""" + $appPath + """,""OctopusWorkingDirectory"":""" + $octopusPath + """},""Status"":""Unknown"",""Name"":""" + $machine + """,""EnvironmentIds"":[""" + $environmentId + """],""Roles"":[" + $roles + "]}"
# send request
$added = Invoke-RestMethod ($url + "machines") -Headers $headers -Body $body -Method Post
# show result
echo $added
I used similar code at work which I've tested, though I haven't got Octopus running at home (it's not that great of a product, I am forced to work with it and given the choice, I'd use alternate release control, means [Team Foundation and vNext build system specifically], the UI isn't great, the API isn't great and the value it adds in the form of release management is questionable for someone already working with TeamFoundation which provides everything required in a more accessible form for developers).
Still people have taken to it and it's not going away.

Exchange Web Services authentication problem against Office 365

I'm in the process of developing my first Orchard CMS module, which will interface with Exchange Server for the purpose of adding Exchange Task functionality to Orchard (basically providing web management of personal Tasks). Unfortunately, I don't think Office 365 supports the type of authentication required. This Microsoft document outlines some instructions on setting up a service account with impersonation rights, in order to use Exchange Web Services.
Unfortunately, I need to be able to run the "New-ManagementRoleAssignment" cmdlet, in order to assign the impersonation rights. The error I'm receiving when attempting this cmdlet is:
The term 'New-ManagementRoleAssignment' is not recognized as the name of a cmdlet, function, script file, or operable program.
I'm definetely connected properly, as instructed in that previous URL. Everything I'm reading suggests that this command should be available. Am I missing something? I'm using the Enterprise version of Office 365, in case that matters. The account that I'm using to log in with PowerShell is my global admin account.
Any help and/or insight would be very much appreciated! I have a support in with Microsoft as well, so I'll post anything I get back from them.
Vito
[EDIT]
I've decided to add some code, for those who have an Exchange Server and are interested in trying this out. You'll have to download the Exchange Web Services dll, in order to make use of the namespace Microsoft.Exchange.WebServices.
using Microsoft.Exchange.WebServices.Data;
using Microsoft.Exchange.WebServices.Autodiscover;
private static ExchangeService _service;
private static void ConnectToExchangeService()
{
_service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
_service.TraceEnabled = true;
_service.Credentials = new System.Net.NetworkCredential("me#domain.com", "password");
AutodiscoverService ads = new AutodiscoverService();
ads.EnableScpLookup = false;
ads.RedirectionUrlValidationCallback = delegate { return true; };
GetUserSettingsResponse grResp = ads.GetUserSettings("me#domain.com", UserSettingName.ExternalEwsUrl);
Uri casURI = new Uri(grResp.Settings[UserSettingName.ExternalEwsUrl].ToString());
_service.Url = casURI;
ControllerContext ctx = new ControllerContext();
ctx.HttpContext.Response.Write("Server Info: " + _service.ServerInfo.VersionString);
ctx.HttpContext.Response.Flush();
}
AFAIK, the cmdlet New-ManagementRoleAssignment is not available for the Small Business Plan (P1) on Office 365. However, the administrator is assigned impersonation rights by default so you have to connect with the administrator credentials.