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
Related
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
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'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;
Is it possible to convert NetworkCredentials (or a variant) to a PSCredential?
I want to transparently use the credentials of the current user, but don't want to prompt them.
$cred = new-object PSCredential($nc.UserName, (ConvertTo-SecureString $nc.Password -AsPlainText -Force))
[System.Reflection.Assembly]::Load("System.Management.Automation")
$dc = [System.Net.CredentialCache]::DefaultCredentials
$psc = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $dc.UserName, $dc.SecurePassword
That would do it, except that the default credentials are not set for the current application domain in which PowerShell is running.
At least this illustrates how you can create a PSCredential from a persisted username and password. The SecureString is always a bummer but I believe NetworkCredential offers a plaintext constructor you can use and a SecureString property to read from.