仮想マシンの自動シャットダウン(Java SDK編)

こんにちは、サイオステクノロジー技術部 武井です。今回は、仮想マシンをAzureのJava SDKで自動シャットダウンする処理を作ってみたいと思います。

Azureの利用料金の大半を占めるのは、仮想マシンを動作させているときの料金です。これをこまめにシャットダウンすれば、かなり全体的な料金を抑えられるのですが、なかなかみんなやってくれないものです。

そこで夜中に全ての仮想マシンを強制的にシャットダウンと割り当て解除するプログラムをAzureのJava SDKで作ってみました。

Azureポータルにログインして、Azure Active Directory→アプリの登録とクリックします。

Screen Shot 2017-10-10 at 19.02.01

「新しいアプリケーションの登録」をクリックします。

Screen Shot 2017-10-10 at 19.03.37

「名前」にアプリケーションを識別するための任意の名称、「アプリケーションの種類」に「Web アプリ/API」、「サインオンURL」に「http://localhost/」と入力します。

Screen Shot 2017-10-10 at 19.05.11

アプリケーションの作成が完了すると、下記のようなリストに表示されますので、クリックします。

Screen Shot 2017-10-10 at 19.07.14

「プロパティ」をクリックします。表示される「アプリケーションID」をメモしておきます。

Screen Shot 2017-10-10 at 19.08.31

「キー」をクリックします。

Screen Shot 2017-10-10 at 19.09.36

「説明」の部分にキーを識別する任意の名称、「有効期限」に適切な有効期限を選択(期限なしはおすすめできません)して、「保存」をクリックします。

Screen Shot 2017-10-10 at 19.10.33

下図の赤枠のところに生成されたキーが表示されます。これをメモしておいて下さい。この画面から離れると二度と表示されなくなりますので、忘れずにメモを!!

Screen Shot 2017-10-10 at 19.12.26

Azure Active Directory→プロパティとクリックします。表示される「ディレクトリID」をメモしておきます。

Screen Shot 2017-10-10 at 19.13.49

次にサブスクリプションにAPIがアクセスする権限を与えます。サブスクリプションをクリックします。権限を与えたいサブスクリプションをリストの中からクリックします。

Screen Shot 2017-10-10 at 19.16.22

「アクセス制御(IAM)」→「+追加」の順にクリックします。

Screen Shot 2017-10-10 at 19.17.45

「役割」に「仮想マシン共同作成者」、「アクセスの割り当て先」に「Azure ADのユーザー、グループ、またはアプリケーション」を選択します。そして、先程作成したアプリを選択して、「保存」をクリックします。これで、サブスクリプションへのアクセス権限の付与は完了です。

Screen Shot 2017-10-13 at 22.29.04

 

ビルドツールはMavenを使うことを前提とします。

pom.xmlに以下を追記下さい。

<dependency>
	<groupId>com.microsoft.azure</groupId>
	<artifactId>azure</artifactId>
	<version>1.3.0</version>
</dependency>
<dependency>
	<groupId>com.microsoft.azure</groupId>
	<artifactId>azure-mgmt-compute</artifactId>
	<version>1.3.0</version>
</dependency>

以下のコードをかきます。

public class VMPowerOff {

    private static final String client = "[先程メモしたクライアントID]"; // クライアントID
    private static final String tenant = "[先程メモしたディレクトリID]"; // ディレクトリID
    private static final String key = "[先程メモしたキー]"; // キー
	// このStringの配列に停止したい仮想マシンがあるサブスクリプションIDを複数指定します。
	private static final String[] subsctiptions = { "XXXXXX", // サブスクリプション1
			"XXXXXX" // サブスクリプション2
	};
	// このStringの配列に停止対象から除外したい仮想マシンのリソースIDを複数指定します。
	private static final String[] whiteLists = {
			"/subscriptions/XXXXXX/resourceGroups/PROXY/providers/Microsoft.Compute/virtualMachines/proxy", // 停止除外仮想マシン1
			"/subscriptions/XXXXXX/resourceGroups/KEMONO-RSG/providers/Microsoft.Compute/virtualMachines/compute-machine", // 停止除外仮想マシン1
	};

	public static void main(String[] args) throws CloudException, IOException {

		ApplicationTokenCredentials credentials = new ApplicationTokenCredentials(client, tenant, key,
				AzureEnvironment.AZURE);

		System.out.println("Azure Virtual Machine Power Off Script Start...");
		for (String subscriptionId : subsctiptions) {
			Azure azure = Azure.configure().withLogLevel(LogLevel.NONE).authenticate(credentials)
					.withSubscription(subscriptionId);

			Iterator vmIterator = azure.virtualMachines().list().iterator();

			while (vmIterator.hasNext()) {
				try {
					VirtualMachine vm = (VirtualMachine) vmIterator.next();

					if (!Arrays.asList(whiteLists).contains(vm.id())) {
						if (vm.powerState() != null) {
							if (vm.powerState().toString().equals("PowerState/running")) {
								// 稼働中のものはPower Off
								System.out
										.println(vm.resourceGroupName() + "/" + vm.computerName() + " power off start...");
								vm.powerOff();
								vm.deallocate();
							}
						} else {
							// StatusがNULLのものはPower Offに失敗してる可能性があるので、もう一度Power Off
							System.out.println(vm.resourceGroupName() + "/" + vm.computerName() + " power off start...");
							vm.powerOff();
							vm.deallocate();

						}
					} else {
						System.out.println(vm.resourceGroupName() + "/" + vm.computerName() + " is excluded");
					}

				} catch (Exception e) {
					e.printStackTrace();
				}

			}
		}
		System.out.println("Azure Virtual Machine Power Off Script End");
	}
}

 

上記のコードを動かすと、仮想マシンが自動でシャットダウンされます。これでムダな課金が防げるはず

Be the first to comment

コメント投稿

Your email address will not be published.


*