天天看點

【Azure Developer】使用Java代碼啟動Azure VM(虛拟機)

問題描述

在使用Java的啟動Azure VM的過程中,遇見了com.azure.core.management.exception.ManagementException: Status code 404錯誤,糾起原因就是訂閱無法發現。詳細的錯誤為:

Selected subscription: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

com.azure.core.management.exception.ManagementException: Status code 404, "{"error":{"code":"SubscriptionNotFound","message":"The subscription 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' could not be found."}}": The subscription 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' could not be found.

sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)

以上問題主要時在使用Java代碼通路Azure資源的時候出現的權限問題有關。是以解決的辦法是需要先讓應用程式有權限通路到Azure VM資源,這裡使用的是AAD認證。在代碼中使用ApplicationTokenCredentials方式認證。

AzureTokenCredentials credentials = new ApplicationTokenCredentials("clientid", "tenantid", "clientsecret", AzureEnvironment.AZURE_CHINA);
Azure azure = Azure.authenticate(credentials).withSubscription("subid");
VirtualMachine testvm = azure.virtualMachines().getById("/subscriptions/<your subscription id>/resourceGroups/<group name>/providers/Microsoft.Compute/virtualMachines/<vm name>");      
  • 通過AAD中注冊應用的client id, tenantid,secret擷取token認證
  • 輸入訂閱号登入到Azure
  • 在Azure VM門戶中擷取到該VM的屬性ID

(擷取以上值的方式見附錄一)

完整的代碼内容

package org.example;

import com.microsoft.azure.AzureEnvironment;
import com.microsoft.azure.credentials.ApplicationTokenCredentials;
import com.microsoft.azure.credentials.AzureTokenCredentials;
import com.microsoft.azure.management.Azure;
import com.microsoft.azure.management.compute.*;



/**s
* Hello world!
*
*/
public class App 
{
    public static void main( String[] args )

    {
        AzureTokenCredentials credentials = new ApplicationTokenCredentials("clientid", "tenantid", "clientsecret", AzureEnvironment.AZURE_CHINA);
        Azure azure=null;

        azure=Azure.authenticate(credentials).withSubscription("subid");

        VirtualMachine testvm = azure.virtualMachines().getById("vmresourceid");
        testvm.start();

        System.out.println( "Hello World!" );
    }
}      

POM.XML檔案内容(使用的依賴包:com.microsoft.azure):

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>getvm</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>getvm</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.microsoft.azure</groupId>
      <artifactId>azure</artifactId>
      <version>1.37.1</version>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
        <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
        <plugin>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.7.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>      

附錄一:如何擷取代碼中需要的配置值:

一:擷取 AAD中應用的Client ID, Tenant ID

  • 登入Azure 門戶,進入AAD頁面(https://portal.azure.cn/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/Overview)
  • 選擇“App registrations”,如已經有App,則直接選中即可進入下一步。否則點選“Add Application”按鈕,注冊一個新應用,名稱唯一即可。如mykeyvaultapp01,,
  • 建立完成後,進入應用Overview頁面,複制儲存(Client ID, Tenant ID, Object ID)值,以備後續使用。
【Azure Developer】使用Java代碼啟動Azure VM(虛拟機)

二:擷取AAD中應用的Secret

  • 在AAD應用頁面,進入“證書和密碼”頁面,點選“新用戶端密碼”按鈕,添加新的Secret(因密碼值隻能在最開始建立時可見,是以必須在離開頁面前複制它)
【Azure Developer】使用Java代碼啟動Azure VM(虛拟機)

三:擷取Azure VM的Resource ID

【Azure Developer】使用Java代碼啟動Azure VM(虛拟機)

參考文檔

使用 Java 建立和管理 Azure 中的 Windows VM: https://docs.azure.cn/zh-cn/virtual-machines/windows/java

當在複雜的環境中面臨問題,格物之道需:濁而靜之徐清,安以動之徐生。 雲中,恰是如此!

繼續閱讀