Azure Function role like permissions to Stop Azure Virtual Machines

前端 未结 2 2040
北海茫月
北海茫月 2020-12-07 04:58

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 \'Micr

相关标签:
2条回答
  • 2020-12-07 05:05

    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:

    1. 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://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal

    2. Log into the Functions portal to access your Function app.

    3. 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).

    4. 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
    
    
    1. Click on the Save button.

    2. Next, click on the Logs button to open the log viewer.

    3. 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"
        }
    
    1. 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)
    
    
    1. 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
    
    
    1. 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.

    0 讨论(0)
  • 2020-12-07 05:21

    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/

    0 讨论(0)
提交回复
热议问题