問題描述
在使用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)值,以備後續使用。

二:擷取AAD中應用的Secret
- 在AAD應用頁面,進入“證書和密碼”頁面,點選“新用戶端密碼”按鈕,添加新的Secret(因密碼值隻能在最開始建立時可見,是以必須在離開頁面前複制它)
三:擷取Azure VM的Resource ID
參考文檔
使用 Java 建立和管理 Azure 中的 Windows VM: https://docs.azure.cn/zh-cn/virtual-machines/windows/java
當在複雜的環境中面臨問題,格物之道需:濁而靜之徐清,安以動之徐生。 雲中,恰是如此!