I have the current situation. Some big processes are made on Azure Web Jobs, and we have a lot of customers, each one of those customers can execute an instance of those functions triggered by Azure Queue. I have a button on our website (Azure App Service) that says "cancel execution", how can I cancel the execution of that Azure Web Job for that customer after clicking the button?
I was thinking of creating a cancellation queue that triggers that WebJob and has some logic to cancel the other execution, is there some way of doing it? Should I use cancellation tokens?
public static void EngineForProcessQueue([QueueTrigger(WebJobHelper.JOB_FOR_PROCESS_QUEUE)] string message, TextWriter log)
{
ProcessQueueMessage(message, log);
}
Thanks srgrn, In your website clicking the button to stop web job. you need to specify the process id/job name.
You can use the Kudu API and powershell script to kill the web job process
$username = $website.PublishingUsername
$password = $website.PublishingPassword
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username,$password)))
$ps = Invoke-RestMethod -Uri "$apiBaseUrl/processes" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method GET
$id = $($ps | where {$_.name -eq $jobname} ).id
Invoke-RestMethod -Uri "$apiBaseUrl/processes/$id" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method DELETE
write-host "killed process $id"
Refer here for more info
Related
I am developing a azure function which needs to connect to Microsoft Dataverse via managed Identity. During local development I have added my azure account in visual studio and selected for azure function authentication. I'm using the below code to access token :
var vsCred = new VisualStudioCredential();
var tok = await vsCred.GetTokenAsync(
new TokenRequestContext(new[] { "CLIENT ID of managed identity" }),default
);
But getting this error :
System.Private.CoreLib: Exception while executing function: ManagedIdentityTestFxn. System.Private.CoreLib: Process "C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\IDE\CommonExtensions\Microsoft\Asal\TokenService\Microsoft.Asal.TokenService.exe" has failed with unexpected error: TS003: Error, TS004: Unable to get access token. 'AADSTS65001: The user or administrator has not consented to use the application with ID '' named 'VS with native MSA'. Send an interactive authorization request for this user and resource.
Azure AD Permissions :
enter image description here
enter image description here
I tried giving admin consent but still facing the same issue.
enter image description here
enter image description here
Instead of using VisualStudioCredential you can use this DefaultAzureCredential to get access an token like below:
using Azure.Core;
using Azure.Identity;
string userAssignedClientId = "<your managed identity client Id>";
var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = userAssignedClientId });
var accessToken = credential.GetToken(new TokenRequestContext(new[] { "https://vault.azure.net" }));
// To print the token, you can convert it to string
String accessTokenString = accessToken.Token.ToString();
//You can use the credential object directly with Key Vault client.
var client = new SecretClient(new Uri("https://myvault.vault.azure.net)",credential);
Alternatively, you can run the below PowerShell script In the kudo console of your function app like below
$resourceURI ="https://admin.services.crm.dynamics.com"
$client_id = "dd8770dc-cbae-43f0-a36d-e27XXXXX"
$tokenAuthURI = $env:IDENTITY_ENDPOINT + "?resource=$resourceURI&client_id=$client_id&api-version=2019-08-01"
$tokenResponse = Invoke-RestMethod -Method Get -Headers #{"X-IDENTITY-HEADER"="$env:IDENTITY_HEADER"} -Uri $tokenAuthURI
$accessToken = $tokenResponse.access_token
I tried to reproduce the same in my environment with powershell script and got the results like below:
I have a function app where I added managed identity like this:
Go to kudo console in function app, Now open kudo console by selecting the advancedtool in your function App :
Now I selected powershell and ran the script like below:
$resourceURI ="https://admin.services.crm.dynamics.com"
$client_id = "dd8770dc-cbae-43f0-a36d-e27XXXXX"
$tokenAuthURI = $env:IDENTITY_ENDPOINT + "?resource=$resourceURI&client_id=$client_id&api-version=2019-08-01"
$tokenResponse = Invoke-RestMethod -Method Get -Headers #{"X-IDENTITY-HEADER"="$env:IDENTITY_HEADER"} -Uri $tokenAuthURI
$accessToken = $tokenResponse.access_token
When I ran the $accessToken I got the token successfully like below:
Reference:
Use managed identities on a virtual machine to acquire access token - Azure AD - Microsoft Entra | Microsoft Learn
I have installed IBM MQ 9.2 version and trying to connect with c# application but facing the security issue[MQRC_NOT_AUTHORIZED-2035].
I have used these properties to connect through c# application.
string QueueManagerName = "***";
string QueueName = "***";
string ChannelInfo= "***/TCP/localhost(PORT)";
char[] separator = { '/' };
string[] ChannelParams; ChannelParams = ChannelInfo.Split(separator);
channelName = ChannelParams[0];
transportType = ChannelParams[1];
connectionName = ChannelParams[2];
MQQueueManager queueManager = new MQQueueManager(QueueManagerName,channelName, connectionName);
I found the following error message in MQ_DATA_PATH\qmgrs\qm-name\errors\AMQERR01.LOG
AMQ8079W: Access was denied when attempting to retrieve group membership information
for user ''
ACTION: Ensure Active Directory access permissions allow user '' to read
group memberships for user ''. To retrieve group membership
information for a domain user, MQ must run with the authority of a domain user
and a domain controller must be available.
Any help to resolve this issue will be much appreciated.
Make sure you are not using a SYSTEM channel.
Create your own SVRCONN channel. i.e. RK.TEST.CHL Then create a CHLAUTH rule to allow you to connect. See examples here: https://www.ibm.com/support/pages/example-using-back-stop-rule-together-mq-channel-authentication-rule-maps-client-user-fred-queue-manager-user-fulano
Next, issue setmqaut commands to allow your UserId to connect and access a queue:
setmqaut -m {QM_NAME} -t qmgr -g {GROUP} +connect +inq +dsp
setmqaut -m {QM_NAME} -n MY.QUEUE.** -t queue -g {GROUP} +allmqi +dsp
Full example (presumes installation is complete)
Create Queue Manager named 'QMDEV1' as 'mqm' user
. /opt/mqm/bin/setmqenv -n Installation1
/opt/mqm/bin/crtmqm -lc -lf 65535 -lp 3 -ls 2 -u SYSTEM.DEAD.LETTER.QUEUE QMDEV1
/opt/mqm/bin/strmqm QMDEV1
Add MQ Objects -- including queue 'ORDER.INPUT'
. /opt/mqm/bin/setmqenv -n Installation1
/opt/mqm/bin/runmqsc QMDEV1 << EOF
ALTER QMGR MAXMSGL(4194304)
ALTER QL(SYSTEM.CLUSTER.TRANSMIT.QUEUE) MAXMSGL(4194304)
DEFINE LISTENER(QMDEV1.LISTENER) TRPTYPE(TCP) CONTROL(QMGR) PORT(1414)
START LISTENER(QMDEV1.LISTENER)
DEFINE CHANNEL(QMDEV1.SVRCONN) CHLTYPE(SVRCONN) MCAUSER('mqm') MAXMSGL(4194304) DESCR('Channel for incoming clients')
DEFINE QL(ORDER.INPUT)
end
EOF
Add a UNIX user account (as root)
groupadd ordergroup
useradd -G ordergroup order
Add MQ permissions for the 'ordergroup' to work with all queues prefix by 'ORDER.'
/opt/mqm/bin/setmqaut -m QMDEV1 -t qmgr -g ordergroup +connect +inq +dsp
/opt/mqm/bin/setmqaut -m QMDEV1 -n ORDER.** -t queue -g ordergroup +allmqi +dsp
Add CHLAUTH for 'order' user
. /opt/mqm/bin/setmqenv -n Installation1
/opt/mqm/bin/runmqsc QMDEV1 << EOF
SET CHLAUTH(QMDEV1.SVRCONN) TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(NOACCESS)
SET CHLAUTH(QMDEV1.SVRCONN) TYPE(USERMAP) CLNTUSER('order') USERSRC(MAP) MCAUSER('order') ADDRESS('*') ACTION(ADD)
EOF
Validate CHLAUTH
. /opt/mqm/bin/setmqenv -n Installation1
/opt/mqm/bin/runmqsc QMDEV1 << EOF
DISPLAY CHLAUTH(QMDEV1.SVRCONN) MATCH(RUNCHECK) CLNTUSER('order') ADDRESS('1.2.3.4')
EOF
Send test message (Java JMS code sample)
MQConnectionFactory mqConnectionFactory = new MQConnectionFactory();
mqConnectionFactory.setHostName("qmdev1.mycompany.com");
mqConnectionFactory.setPort(1414);
mqConnectionFactory.setQueueManager("QMDEV1");
mqConnectionFactory.setChannel("QMDEV1.SVRCONN");
mqConnectionFactory.setTransportType(1);
Connection connection = mqConnectionFactory.createConnection("order", "order00");
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer messageProducer = session.createProducer(session.createQueue("ORDER.INPUT"));
messageProducer.send(session.createTextMessage("Hello world!"));
connection.start();
MessageConsumer messageConsumer = session.createConsumer(session.createQueue("ORDER.INPUT"));
Message message = messageConsumer.receive(2000l);
System.out.println("Received message body: " + TextMessage.class.cast(message).getText());
messageConsumer.close();
messageProducer.close();
session.close();
connection.close();
Verify by changing the username in the code in step #7 and you'll get an exception with reason code 2035.
I need to downscale a database in Azure to its Basic plan.
I have created a task in my Release flow on VSO, a PowerShell Azure Task with my subscription specified in it, and I've put this script in it :
Start-Sleep -s 60
$Credential = Get-Credential
$serverContext = New-AzureSqlDatabaseServerContext -ServerName "XXX-com-staging" -Credential $Credential
$db = Get-AzureSqlDatabase -ServerName "XXX-com-staging" -DatabaseName "YYY-com-staging"
$P1 = Get-AzureSqlDatabaseServiceObjective $serverContext -ServiceObjectiveName "P1"
Set-AzureSqlDatabase $serverContext -Database $db -ServiceObjective $P1 -Force -Edition Basic
It doesn't work because $Credential is either Null, or it throws an Error saying that:
Credential Parameter is mandatory.
Is there any simple way to achieve this, or a fix for my script ?
It was easy, no need for Credentials
$P0 = Get-AzureSqlDatabaseServiceObjective -ServerName "XXX-com-staging" -ServiceObjectiveName "Basic"
Set-AzureSqlDatabase -DatabaseName "YYY-com-staging" -ServerName "XXX-com-staging" -ServiceObjective $P0 -Force -Edition Basic
I'm hoping to manage some Azure resources using a scheduled C# Azure Function.
Currently in a command line application I've made, I've been using libraries 'Microsoft.IdentityModel.Clients.ActiveDirectory' for token authorization and 'Microsoft.Azure.Management.Compute' for client calls for resource management like so.
//... var credential generated my AD authentication and extending Microsoft.Rest.ServiceClientCredentials
using (var client = new ComputeManagementClient(credential)) {
client.SubscriptionId = "[SOME_SUBSCRIPTION_ID]";
client.VirtualMachines.BeginPowerOff("[RESOURCE_GROUP]", "[VM_NAME]");
}
Can my management client interact with Azure resources without providing a User Credential or Key-Secret like credential establishment?
My previous experience is related to AWS and admittedly it has confused my view of Azure Resource Management.
Older posts I've looked at are: Start and Stop Azure Virtual Machine
and
Is it possible to stop/start an Azure ARM Virtual from an Azure Function?
-EDIT 1-
I was hoping for something similar to run-time credentials in AWS resource clients for Lambda based on an assigned role with a variety of permissions. I will have a look at certificates though.
There are a few resources online on using C# to make REST API calls to start and stop a VM. Here's a link to such a document:
https://msftstack.wordpress.com/2016/01/03/how-to-call-the-azure-resource-manager-rest-api-from-c/
You could use the above as a reference to create C# Functions to start/stop your VM.
However, using C# to make these REST calls requires pre-packaging the HTTP request and post processing the HTTP response. If your use-case just calls for a start/stop VM, an easier approach would be use PowerShell in Azure Functions to call the Start-AzureRmVM and Stop-AzureRmVM cmdlets.
The following are steps on how to create HTTP-triggered PowerShell Functions to start and stop a VM:
Setup a service principal to obtain the username, password and tenant id. This initial setup may be considered tedious by some users, but since it's a one-time task, I feel that it is worth it to leverage running Azure PowerShell in Functions. There are many docs online, but here are some links to documents on how to setup your service principal:
i. http://blog.davidebbo.com/2014/12/azure-service-principal.html (I used this one)
ii. https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal
Log into the Functions portal to access your Function app.
Click on Function app settings->Configure app settings and add the key-value pairs for the settings SP_USERNAME, SP_PASSWORD, and TENANTID (You may use other desired key names).
Create an HTTP-triggered PowerShell Function named, e.g. StartVm with the following content in its run.ps1 file.
$requestBody = Get-Content $req -Raw | ConvertFrom-Json
# Set Service Principal credentials
# SP_PASSWORD, SP_USERNAME, TENANTID are app settings
$secpasswd = ConvertTo-SecureString $env:SP_PASSWORD -AsPlainText -Force;
$mycreds = New-Object System.Management.Automation.PSCredential ($env:SP_USERNAME, $secpasswd)
Add-AzureRmAccount -ServicePrincipal -Tenant $env:TENANTID -Credential $mycreds;
$context = Get-AzureRmContext;
Set-AzureRmContext -Context $context;
# Start VM
Start-AzureRmVM -ResourceGroupName $requestBody.resourcegroup -Name $requestBody.vmname | Out-String
Click on the Save button.
Next, click on the Logs button to open the log viewer.
Click on the Test button to open the simple HTTP client. In the request body, provide the vmname and resourcegroup values for the VM, e.g.
{
"vmname": "testvm",
"resourcegroup": "testresourcegroup"
}
Click on the Run button and wait for a few seconds. It takes some time for the Start-AzureRmVM cmdlet to run to completion. When it does, you should see similar entries in the log viewer.
2016-11-30T07:11:26.479 Function started (Id=1e38ae2c-3cca-4e2f-a85d-f62c0d565c34)
2016-11-30T07:11:28.276 Microsoft.Azure.Commands.Profile.Models.PSAzureContext
2016-11-30T07:11:28.276 Microsoft.Azure.Commands.Profile.Models.PSAzureContext
2016-11-30T07:11:59.312 RequestId IsSuccessStatusCode StatusCode ReasonPhrase
--------- ------------------- ---------- ------------
True OK OK
2016-11-30T07:11:59.327 Function completed (Success, Id=1e38ae2c-3cca-4e2f-a85d-f62c0d565c34)
Repeat steps 4-8 to create the StopVm Function with the following content in its run.ps1 file. If the execution succeeds, the log output should be similar to the log entries for the StartVm Function.
$requestBody = Get-Content $req -Raw | ConvertFrom-Json
# Set Service Principal credentials
# SP_PASSWORD, SP_USERNAME, TENANTID are app settings
$secpasswd = ConvertTo-SecureString $env:SP_PASSWORD -AsPlainText -Force;
$mycreds = New-Object System.Management.Automation.PSCredential ($env:SP_USERNAME, $secpasswd)
Add-AzureRmAccount -ServicePrincipal -Tenant $env:TENANTID -Credential $mycreds;
$context = Get-AzureRmContext;
Set-AzureRmContext -Context $context;
# Stop VM
Stop-AzureRmVM -ResourceGroupName $requestBody.resourcegroup -Name $requestBody.vmname -Force | Out-String
When the StopVm Function execution succeeds, you may also add another GetVm Function with the following content in its run.ps1 file to verify that the VM has indeed been stopped.
$requestBody = Get-Content $req -Raw | ConvertFrom-Json
# Set Service Principal credentials
# SP_PASSWORD, SP_USERNAME, TENANTID are app settings
$secpasswd = ConvertTo-SecureString $env:SP_PASSWORD -AsPlainText -Force;
$mycreds = New-Object System.Management.Automation.PSCredential ($env:SP_USERNAME, $secpasswd)
Add-AzureRmAccount -ServicePrincipal -Tenant $env:TENANTID -Credential $mycreds;
$context = Get-AzureRmContext;
Set-AzureRmContext -Context $context;
# Get VM
Get-AzureRmVM -ResourceGroupName $requestBody.resourcegroup -Name $requestBody.vmname -Status | Out-String
The log entries for the GetVM Function on a stopped VM will would be similar to the following:
2016-11-30T07:53:59.956 Function started (Id=1841757f-bbb8-45cb-8777-80edb4e75ced)
2016-11-30T07:54:02.040 Microsoft.Azure.Commands.Profile.Models.PSAzureContext
2016-11-30T07:54:02.040 Microsoft.Azure.Commands.Profile.Models.PSAzureContext
2016-11-30T07:54:02.977 ResourceGroupName : testresourcegroup
Name : testvm
BootDiagnostics :
ConsoleScreenshotBlobUri : https://teststorage.blob.core.windows.net/boot
diagnostics-vmtest-[someguid]/testvm.[someguid].screenshot.bmp
Disks[0] :
Name : windowsvmosdisk
Statuses[0] :
Code : ProvisioningState/succeeded
Level : Info
DisplayStatus : Provisioning succeeded
Time : 11/30/2016 7:15:15 AM
Extensions[0] :
Name : BGInfo
VMAgent :
VmAgentVersion : Unknown
Statuses[0] :
Code : ProvisioningState/Unavailable
Level : Warning
DisplayStatus : Not Ready
Message : VM Agent is unresponsive.
Time : 11/30/2016 7:54:02 AM
Statuses[0] :
Code : ProvisioningState/succeeded
Level : Info
DisplayStatus : Provisioning succeeded
Time : 11/30/2016 7:15:15 AM
Statuses[1] :
Code : PowerState/deallocated
Level : Info
DisplayStatus : VM deallocated
2016-11-30T07:54:02.977 Function completed (Success, Id=1841757f-bbb8-45cb-8777-80edb4e75ced)
Note: FYI, while you may write a Function to create a VM by calling the New-AzureRmVM cmdlet, it will not run to completion in Azure Functions. VM creation in Azure Function's infrastructure seem to take ~9 mins to complete but a Function's execution is terminated at 5 minutes. You may write another script to poll the results separately. This limitation will be lifted when we start supporting custom configuration for maximum execution time in one of our upcoming releases.
--Update--
I just realized you were trying to create scheduled Functions. In that case, you can use Timer-triggered PowerShell Functions and hard-code the vmname and resourcegroup.
Well, I don't really understand how do you expect to authenticate without authenticating, I guess your only option would be certificates?
https://azure.microsoft.com/en-us/resources/samples/active-directory-dotnet-daemon-certificate-credential/
I'd like to automate the setup of Azure Application Insights accounts for a ASP.Net web application.
I've installed the nuget package: Install-Package Microsoft.Azure.Insights -Pre
Now I'm looking at the Microsoft.Azure.Management.Insights.InsightsManagementClient
There are lot's of operations to manage an existing account, except I can't find the one to create a new one.
To be clear: On https://portal.azure.com I can click on New > Create > Developer Services > Application Insights. How do I do that in c#?
Here is the script created by Eric Mattingly (You need Azure PowerShell installed for this to work):
Output:
App Insights Name = erimattestapp
IKey = 00000000-0000-0000-0000-000000000000
Script:
cls
##################################################################
# Set Values
##################################################################
#If running manually, comment this out to before the first execution to login to the Azure Portal
#Add-AzureAccount
#Set the name of the Application Insights Resource
$appInsightsName = "erimatTestApp"
#Set the application name used for the value of the Tag "AppInsightsApp" - http://azure.microsoft.com/en-us/documentation/articles/azure-preview-portal-using-tags/
$applicationTagName = "erimatTestApp"
#Set the name of the Resource Group to use. By default will use the application Name as a starter
$resourceGroupName = "erimatTestAppRG"
##################################################################
# Create the Resource and Output the name and iKey
##################################################################
#Set the script to Resource Manager - http://azure.microsoft.com/en-us/documentation/articles/powershell-azure-resource-manager/
Switch-AzureMode AzureResourceManager
#Select the azure subscription
Select-AzureSubscription -SubscriptionName "ECIT Preproduction Monitoring"
#Create the App Insights Resource
$resource = New-AzureResource -Name $appInsightsName -ResourceGroupName $resourceGroupName -Tag #{ Name = "AppInsightsApp"; Value = $applicationTagName} -ResourceType "Microsoft.Insights/Components" -Location "Central US" -ApiVersion "2014-08-01"
#Give team owner access - http://azure.microsoft.com/en-us/documentation/articles/role-based-access-control-powershell/
New-AzureRoleAssignment -Mail "ECITTelemetryTeam#microsoft.com" -RoleDefinitionName Owner -Scope $resource.ResourceId | Out-Null
#Display iKey
Write-Host "App Insights Name = " $resource.Properties["Name"]
Write-Host "IKey = " $resource.Properties["InstrumentationKey"]
Thanks to Anastasia's powershell example I was able to look at the powershell cmdlet implementation and figure out, how to do this in code:
// initialize resource management client
var resourceManagement = new ResourceManagementClient(this.Credentials);
resourceManagement.Providers.RegisterAsync("microsoft.insights").Result;
// create identity & parameters for create call
var resourceIdentity = new ResourceIdentity(
"SomeResourceName", // ResourceName
"microsoft.insights/components", // ResourceType
"2014-04-01" // Api Version
);
var parameters = new GenericResource {
Location = 'centralus'
};
// send call off and hope for the best
var result = this.ManagementContext.ResourceManagement.Resources.CreateOrUpdateAsync(
"SomeResourceGroupName",
resourceIdentity,
parameters,
CancellationToken.None).Result;