すべてのプロダクト
Search
ドキュメントセンター

Elastic Compute Service:SDK を使用した ECS インスタンスの作成と使用

最終更新日:Apr 01, 2026

Java 向け ECS SDK 2.0 を使用して Elastic Compute Service (ECS) インスタンスを作成し、クラウドアシスタント経由でリモートでコマンドを実行し、完了後にすべてのリソースをリリースします。

このチュートリアルでは、以下の内容について説明します。

  • 認証情報の設定と Maven を介した SDK のインストール

  • 必要なネットワークリソース (Virtual Private Cloud (VPC)、vSwitch、セキュリティグループ、SSH キーペア) の作成

  • ECS インスタンスを作成し、そのステータスが 実行中 になるまで待機

  • クラウドアシスタントを使用して、ログインせずにインスタンス上でシェルコマンドを実行

  • すべてのリソースを正しい順序でリリース

前提条件

開始する前に、以下のものがあることを確認してください。

  • 以下のポリシーがアタッチされた Resource Access Management (RAM) ユーザー:

    サービスポリシー
    VPCAliyunVPCFullAccess
    ECSAliyunECSFullAccess
  • RAM ユーザーの AccessKey ID と AccessKey Secret が環境変数として設定されていること。詳細については、「Linux、macOS、Windows で環境変数を設定する」をご参照ください。サンプルコードは、これらの環境変数から認証情報を読み取ります。

    Alibaba Cloud アカウントの AccessKey ではなく、RAM ユーザーの AccessKey を使用してください。アカウントレベルの AccessKey はすべてのリソースに対する完全な権限を持っており、漏洩した場合、アカウント全体がリスクにさらされます。詳細については、「AccessKey ペアの作成」をご参照ください。
    変数
    ALIBABA_CLOUD_ACCESS_KEY_IDご利用の AccessKey ID
    ALIBABA_CLOUD_ACCESS_KEY_SECRETご利用の AccessKey Secret
  • Java と Maven がインストールされていること。

SDK のインストール

pom.xml に ECS と VPC の SDK 依存関係を追加します。

<dependencies>
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>ecs20140526</artifactId>
        <version>5.3.0</version>
    </dependency>
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>vpc20160428</artifactId>
        <version>7.12.0</version>
    </dependency>
</dependencies>

その他のインストール方法については、「Java 向け ECS SDK のインストール」および「Java 向け VPC SDK のインストール」をご参照ください。

ECS インスタンスの作成

ECS インスタンスを作成するには、VPC、vSwitch、セキュリティグループ、SSH キーペアといったいくつかの前提リソースが必要です。以下の手順では、各リソースを順に作成し、その後インスタンスを作成します。

これらのリソースが既にある場合は、それらの ID を直接 RunInstances の呼び出しに渡してください。

ステップ 1:VPC の作成

VPC は、クラウド内で論理的に分離されたプライベートネットワークです。

以下のパラメーターで CreateVpc を呼び出します。

パラメーター説明
RegionIdVPC が作成されるリージョンcn-hangzhou
CidrBlockVPC の CIDR ブロック192.168.0.0/16

CreateVpc を呼び出した後、次に進む前に VPC のステータスが Available になるまで DescribeVpcs をポーリングします。

ステップ 2:vSwitch の作成

vSwitch は VPC 内の ECS インスタンスを接続し、それらの間の通信を可能にします。

以下のパラメーターで CreateVSwitch を呼び出します。

パラメーター説明
RegionIdvSwitch のリージョンcn-hangzhou
ZoneIdリージョン内のゾーンcn-hangzhou-i
VpcIdステップ 1 で作成した VPC の IDvpc-bp1aag0sb9s4i92i3****
CidrBlockvSwitch の CIDR ブロック (VPC の CIDR 内にある必要があります)192.168.0.0/24

ステップ 3:セキュリティグループの作成

セキュリティグループは仮想ファイアウォールとして機能し、ECS インスタンスのインバウンドおよびアウトバウンドトラフィックをコントロールします。

以下のパラメーターで CreateSecurityGroup を呼び出します。

パラメーター説明
RegionIdセキュリティグループのリージョンcn-hangzhou
VpcIdVPC の IDvpc-bp1aag0sb9s4i92i3****

次に、AuthorizeSecurityGroup を介してインバウンドルールを追加します。

パラメーター説明
SecurityGroupIdセキュリティグループの IDsg-bp1esyhwfbqeyudt****
IpProtocolプロトコルtcp
SourceCidrIp許可されるソース IP 範囲0.0.0.0/0
PortRangeポート範囲 (Linux:SSH、Windows:RDP)22/22

ステップ 4:SSH キーペアの作成

SSH キーペアを使用すると、パスワードなしで Linux インスタンスにログインできます。

以下のパラメーターで CreateKeyPair を呼び出します。

パラメーター説明
RegionIdリージョンcn-hangzhou
KeyPairNameキーペアの名前sdk-key-pair
重要

レスポンスで返される秘密鍵を保存してください。作成後に再度取得することはできません。

ステップ 5:ECS インスタンスの作成

以下のパラメーターで RunInstances を呼び出します。

パラメーター説明
RegionIdリージョンcn-hangzhou
ImageIdイメージ IDaliyun_3_x64_20G_scc_alibase_20220225.vhd
InstanceTypeインスタンスタイプecs.e-c1m2.xlarge
SecurityGroupIdステップ 3 のセキュリティグループ IDsg-bp1esyhwfbqeyudt****
VSwitchIdステップ 2 の vSwitch IDvsw-bp1nzprm8h7mmnl8t****
InstanceChargeType課金方法PostPaid (従量課金)
KeyPairNameステップ 4 の SSH キーペアsdk-key-pair
SystemDisk.Categoryシステムディスクタイプcloud_essd

RunInstances を呼び出した後、インスタンスのステータスが 実行中 になるまで DescribeInstanceStatus をポーリングします。通常、約 10 秒かかります。

従量課金インスタンスを作成する前に、アカウントに十分な残高があることを確認してください。

完全なサンプルコード

以下のコードは、すべての前提リソースを順に作成し、その後 ECS インスタンスを作成して起動を待ちます。

import com.aliyun.ecs20140526.models.*;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.vpc20160428.models.CreateVSwitchRequest;
import com.aliyun.vpc20160428.models.CreateVSwitchResponse;
import com.aliyun.vpc20160428.models.CreateVpcRequest;
import com.aliyun.vpc20160428.models.CreateVpcResponse;
import com.aliyun.vpc20160428.models.DescribeVpcsRequest;

import java.util.ArrayList;
import java.util.List;

public class EcsDemo {
    public static void main(String[] args) {
        String vpcId = null;
        String vSwitchId = null;
        String securityGroupId = null;
        String instanceId = null;
        com.aliyun.vpc20160428.Client vpcClient = null;
        com.aliyun.ecs20140526.Client ecsClient = null;
        try {
            vpcClient = createVpcClient();
            ecsClient = createEcsClient();
            // VPC を作成します。
            vpcId = createVpc(vpcClient);
            System.out.println("VPC create success, vpcId :" + vpcId);
            // 次に進む前に、VPC が Available 状態になるまで待機します。
            while (true) {
                String status = describeVpc(vpcId, vpcClient);
                if ("Available".equals(status)) {
                    break;
                }
            }
            // vSwitch を作成します。
            vSwitchId = CreateVSwitch(vpcId, vpcClient);
            System.out.println("VSwitch create success, vSwitchId :" + vSwitchId);
            // セキュリティグループを作成します。
            securityGroupId = createSecurityGroup(vpcId, ecsClient);
            System.out.println("SecurityGroup create success, securityGroupId :" + securityGroupId);
            // セキュリティグループにインバウンドルールを追加します。
            authorizeSecurityGroup(securityGroupId, ecsClient);
            // SSH キーペアを作成します。インスタンスへのログイン時に後で使用するために秘密鍵を保存します。
            CreateKeyPairResponse keyPair = createKeyPair(ecsClient);
            System.out.println("KeyPair create success, keyPairName :" + keyPair.body.keyPairName);
            // ECS インスタンスを作成します。
            instanceId = createInstance(ecsClient, vSwitchId, securityGroupId);
            System.out.println("ECS create success, instanceId :" + instanceId);
            // インスタンスが Running 状態になるまで待機します。
            while (true) {
                List<String> instanceIds = new ArrayList<>();
                instanceIds.add(instanceId);
                DescribeInstanceStatusResponse describeInstanceStatus = describeInstanceStatus(instanceIds, ecsClient);
                List<DescribeInstanceStatusResponseBody.DescribeInstanceStatusResponseBodyInstanceStatusesInstanceStatus> instanceStatusList = describeInstanceStatus.body.instanceStatuses.instanceStatus;
                if (instanceStatusList != null && !instanceStatusList.isEmpty()) {
                    String status = instanceStatusList.get(0).status;
                    if ("Running".equals(status)) {
                        break;
                    }
                }
            }
        } catch (Exception e) {
            // 失敗前に一部のリソースが作成された場合は、ログ記録、ロールバック、
            // または補償ロジックを追加して、部分的な状態をクリーンアップします。
            System.out.println(e.getMessage());
        }
    }

    public static class Constants {
        public static final String NAME = "sdk-test";
        public static final String REGION_ID = "cn-hangzhou";
        public static final String ZONE_ID = "cn-hangzhou-i";
        public static final String CIDR_BLOCK_VPC = "192.168.0.0/16";
        public static final String CIDR_BLOCK_VSWITCH = "192.168.0.0/24";
        public static final String IMAGE_ID = "aliyun_3_x64_20G_scc_alibase_20220225.vhd";
        public static final String INSTANCE_TYPE = "ecs.e-c1m2.xlarge";
        public static final String SYSTEM_DISK_CATEGORY = "cloud_essd";
        public static final String KEY_PAIR_NAME = "sdk-key-pair";

        public static final class ENDPOINT {
            public static final String VPC = "vpc.cn-hangzhou.aliyuncs.com";
            public static final String ECS = "ecs.cn-hangzhou.aliyuncs.com";
        }

        public static final class INSTANCE_CHARGE_TYPE {
            public static final String PRE_PAID = "PrePaid";   // サブスクリプション
            public static final String POST_PAID = "PostPaid"; // 従量課金
        }
    }

    public static com.aliyun.vpc20160428.Client createVpcClient() throws Exception {
        Config config = new Config();
        config.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
        config.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        config.endpoint = Constants.ENDPOINT.VPC;
        return new com.aliyun.vpc20160428.Client(config);
    }

    public static com.aliyun.ecs20140526.Client createEcsClient() throws Exception {
        Config config = new Config();
        config.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
        config.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        config.endpoint = Constants.ENDPOINT.ECS;
        return new com.aliyun.ecs20140526.Client(config);
    }

    /**
     * VPC を作成し、その ID を返します。
     *
     * @param vpcClient VPC クライアント。
     * @return 新しい VPC の ID。
     */
    public static String createVpc(com.aliyun.vpc20160428.Client vpcClient) {
        try {
            CreateVpcRequest createVpcRequest = new CreateVpcRequest()
                    .setRegionId(Constants.REGION_ID)
                    .setCidrBlock(Constants.CIDR_BLOCK_VPC)
                    .setVpcName(Constants.NAME);
            CreateVpcResponse vpc = vpcClient.createVpc(createVpcRequest);
            return vpc.body.vpcId;
        } catch (Exception e) {
            throw new RuntimeException("createVpc failed: " + e.getMessage());
        }
    }

    /**
     * 指定された VPC に vSwitch を作成し、その ID を返します。
     *
     * @param vpcId     VPC の ID。
     * @param vpcClient VPC クライアント。
     * @return 新しい vSwitch の ID。
     */
    public static String CreateVSwitch(String vpcId, com.aliyun.vpc20160428.Client vpcClient) {
        try {
            CreateVSwitchRequest createVSwitchRequest = new CreateVSwitchRequest()
                    .setRegionId(Constants.REGION_ID)
                    .setZoneId(Constants.ZONE_ID)
                    .setCidrBlock(Constants.CIDR_BLOCK_VSWITCH)
                    .setVpcId(vpcId)
                    .setVSwitchName(Constants.NAME);
            CreateVSwitchResponse vSwitch = vpcClient.createVSwitch(createVSwitchRequest);
            return vSwitch.body.vSwitchId;
        } catch (Exception e) {
            throw new RuntimeException("CreateVSwitch failed: " + e.getMessage());
        }
    }

    /**
     * 指定された VPC にセキュリティグループを作成し、その ID を返します。
     *
     * @param vpcId     VPC の ID。
     * @param ecsClient ECS クライアント。
     * @return 新しいセキュリティグループの ID。
     */
    public static String createSecurityGroup(String vpcId, com.aliyun.ecs20140526.Client ecsClient) {
        try {
            CreateSecurityGroupRequest createSecurityGroupRequest = new CreateSecurityGroupRequest()
                    .setRegionId(Constants.REGION_ID)
                    .setVpcId(vpcId)
                    .setSecurityGroupName(Constants.NAME);
            CreateSecurityGroupResponse securityGroup = ecsClient.createSecurityGroup(createSecurityGroupRequest);
            return securityGroup.body.securityGroupId;
        } catch (Exception e) {
            throw new RuntimeException("createSecurityGroup failed: " + e.getMessage());
        }
    }

    /**
     * 指定されたセキュリティグループに、すべてのソースからのポート 22 (SSH) でのインバウンド TCP ルールを追加します。
     *
     * @param securityGroupId セキュリティグループの ID。
     * @param ecsClient       ECS クライアント。
     */
    public static void authorizeSecurityGroup(String securityGroupId, com.aliyun.ecs20140526.Client ecsClient) {
        try {
            AuthorizeSecurityGroupRequest.AuthorizeSecurityGroupRequestPermissions permission =
                    new AuthorizeSecurityGroupRequest.AuthorizeSecurityGroupRequestPermissions()
                            .setIpProtocol("tcp")
                            .setPortRange("22/22")
                            .setSourceCidrIp("0.0.0.0/0");
            List<AuthorizeSecurityGroupRequest.AuthorizeSecurityGroupRequestPermissions> permissions = new ArrayList<>();
            permissions.add(permission);
            AuthorizeSecurityGroupRequest authorizeSecurityGroupRequest = new AuthorizeSecurityGroupRequest()
                    .setRegionId(Constants.REGION_ID)
                    .setSecurityGroupId(securityGroupId)
                    .setPermissions(permissions);
            ecsClient.authorizeSecurityGroup(authorizeSecurityGroupRequest);
        } catch (Exception e) {
            throw new RuntimeException("authorizeSecurityGroup failed: " + e.getMessage());
        }
    }

    /**
     * ECS インスタンスを作成し、その ID を返します。
     *
     * @param ecsClient       ECS クライアント。
     * @param vSwitchId       vSwitch の ID。
     * @param securityGroupId セキュリティグループの ID。
     * @return 新しい ECS インスタンスの ID。
     */
    public static String createInstance(com.aliyun.ecs20140526.Client ecsClient, String vSwitchId, String securityGroupId) {
        try {
            RunInstancesRequest.RunInstancesRequestSystemDisk systemDisk =
                    new RunInstancesRequest.RunInstancesRequestSystemDisk()
                            .setCategory(Constants.SYSTEM_DISK_CATEGORY);
            RunInstancesRequest runInstancesRequest = new RunInstancesRequest()
                    .setRegionId(Constants.REGION_ID)
                    .setImageId(Constants.IMAGE_ID)
                    .setInstanceType(Constants.INSTANCE_TYPE)
                    .setSecurityGroupId(securityGroupId)
                    .setVSwitchId(vSwitchId)
                    .setInstanceChargeType(Constants.INSTANCE_CHARGE_TYPE.POST_PAID)
                    .setInstanceName(Constants.NAME)
                    .setInternetMaxBandwidthOut(1)
                    .setSystemDisk(systemDisk)
                    .setKeyPairName(Constants.KEY_PAIR_NAME);
            RunInstancesResponse resp = ecsClient.runInstances(runInstancesRequest);
            return resp.body.getInstanceIdSets().getInstanceIdSet().get(0);
        } catch (Exception e) {
            throw new RuntimeException("createInstance failed: " + e.getMessage());
        }
    }

    /**
     * SSH キーペアを作成し、完全なレスポンス (秘密鍵を含む) を返します。
     *
     * @param ecsClient ECS クライアント。
     * @return CreateKeyPair からのレスポンス。キーペア名と秘密鍵のマテリアルを含みます。
     */
    public static CreateKeyPairResponse createKeyPair(com.aliyun.ecs20140526.Client ecsClient) {
        try {
            CreateKeyPairRequest createKeyPairRequest = new CreateKeyPairRequest()
                    .setRegionId(Constants.REGION_ID)
                    .setKeyPairName(Constants.KEY_PAIR_NAME);
            return ecsClient.createKeyPair(createKeyPairRequest);
        } catch (Exception e) {
            throw new RuntimeException("createKeyPair failed: " + e.getMessage());
        }
    }

    /**
     * 指定された VPC の現在のステータスを返します。
     *
     * @param vpcId     VPC ID。
     * @param vpcClient VPC クライアント。
     * @return VPC のステータス文字列 (例: "Available")。
     */
    public static String describeVpc(String vpcId, com.aliyun.vpc20160428.Client vpcClient) {
        try {
            DescribeVpcsRequest request = new DescribeVpcsRequest()
                    .setRegionId(Constants.REGION_ID)
                    .setVpcId(vpcId);
            return vpcClient.describeVpcs(request).body.vpcs.getVpc().get(0).status;
        } catch (Exception e) {
            throw new RuntimeException("describeVpc failed: " + e.getMessage());
        }
    }

    /**
     * 指定された ECS インスタンスのステータスを返します。
     *
     * @param instanceIds クエリ対象の ECS インスタンス ID のリスト。
     * @param ecsClient   ECS クライアント。
     * @return DescribeInstanceStatus レスポンス。
     */
    public static DescribeInstanceStatusResponse describeInstanceStatus(List<String> instanceIds, com.aliyun.ecs20140526.Client ecsClient) {
        try {
            DescribeInstanceStatusRequest request = new DescribeInstanceStatusRequest()
                    .setRegionId(Constants.REGION_ID)
                    .setInstanceId(instanceIds);
            return ecsClient.describeInstanceStatus(request);
        } catch (Exception e) {
            throw new RuntimeException("describeInstanceStatus failed: " + e.getMessage());
        }
    }
}

ログインなしでのコマンド実行

クラウドアシスタントを使用すると、API から直接 ECS インスタンス上でシェル、PowerShell、バッチコマンドを実行できます。SSH セッションやジャンプサーバーは不要です。これを使用して、ソフトウェアのインストール、スクリプトの実行、サービスの管理、または大規模な更新の適用が可能です。

以下の例では、RunCommand を使用して Linux インスタンスに Java と Tomcat をインストールします。

パラメーター説明
RegionIdインスタンスのリージョンcn-hangzhou
TypeコマンドタイプRunShellScript
CommandContent実行するシェルスクリプト以下のサンプルコードを参照
InstanceIdターゲットインスタンス ID["i-bp17f3kzgtzzj91r****"]
Timeout(オプション) 実行タイムアウト (秒)60
import com.aliyun.ecs20140526.Client;
import com.aliyun.ecs20140526.models.RunCommandRequest;
import com.aliyun.ecs20140526.models.RunCommandResponse;
import com.aliyun.teaopenapi.models.Config;
import com.google.gson.Gson;

import java.util.ArrayList;
import java.util.List;

public class CloudAssistant {
    public static void main(String[] args) throws Exception {
        Client ecsClient = createEcsClient();
        List<String> instanceIds = new ArrayList<>();
        instanceIds.add("i-bp17f3kzgtzzj91r****");

        // インスタンスに Java と Tomcat をインストールします。
        // スクリプトは OS を検出し、適切なパッケージマネージャを使用します。
        String commandContent = "#!/bin/bash\n" +
                "if cat /etc/issue | grep -i Ubuntu; then\n" +
                "\tsudo apt-get update\n" +
                "\tsudo apt-get install -y default-jdk\n" +
                "\tsudo apt-get install -y tomcat9\n" +
                "else\n" +
                "  yum install -y java\n" +
                "\tyum install -y tomcat\n" +
                "fi";
        runCommand(commandContent, instanceIds, ecsClient);
    }

    public static class Constants {
        public static final String REGION_ID = "cn-hangzhou";

        public static final class ENDPOINT {
            public static final String ECS = "ecs.cn-hangzhou.aliyuncs.com";
        }

        public static final class COMMAND_TYPE {
            public static final String RUN_SHELL_SCRIPT = "RunShellScript";   // Linux インスタンス
            public static final String RUN_BAT_SCRIPT = "RunBatScript";       // Windows インスタンス
            public static final String RUN_POWERSHELL_SCRIPT = "RunPowerShellScript"; // Windows インスタンス
        }
    }

    public static com.aliyun.ecs20140526.Client createEcsClient() throws Exception {
        Config config = new Config();
        config.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
        config.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        config.endpoint = Constants.ENDPOINT.ECS;
        return new com.aliyun.ecs20140526.Client(config);
    }

    /**
     * クラウドアシスタントを介して、指定された ECS インスタンスでシェルコマンドを実行します。
     *
     * @param commandContent シェルスクリプトのコンテンツ。
     * @param instanceIds    ターゲットインスタンス ID のリスト。
     * @param ecsClient      ECS クライアント。
     */
    public static void runCommand(String commandContent, List<String> instanceIds, com.aliyun.ecs20140526.Client ecsClient) {
        try {
            RunCommandRequest request = new RunCommandRequest();
            request.setRegionId(Constants.REGION_ID);
            request.setType(Constants.COMMAND_TYPE.RUN_SHELL_SCRIPT);
            request.setCommandContent(commandContent);
            request.setInstanceId(instanceIds);
            request.setTimeout(60L);
            RunCommandResponse runCommandResponse = ecsClient.runCommand(request);
            System.out.println(new Gson().toJson(runCommandResponse));
        } catch (Exception e) {
            throw new RuntimeException("runCommand failed:" + e);
        }
    }
}

クラウドアシスタントの詳細については、「クラウドアシスタントの概要」をご参照ください。

リソースのリリース

リソースが不要になった場合は、以下の順序で削除してください。リソースを正しい順序で削除しないと、依存関係のエラーが発生する可能性があります。たとえば、VPC 内に vSwitch がまだ存在する場合、VPC は削除できません。

以下のサンプルコードは、このチュートリアルで作成されたすべてのリソースを削除します。リリースしたいリソースのみに一致するように調整してください。

削除順序:

  1. DeleteInstancesRegionIdInstanceId

  2. DeleteKeyPairsRegionIdKeyPairNames (JSON 配列、例:["sdk-key-pair"])

  3. DeleteSecurityGroupRegionIdSecurityGroupId

  4. DeleteVSwitchRegionIdVSwitchId

  5. DeleteVpcRegionIdVpcId

import com.aliyun.ecs20140526.Client;
import com.aliyun.ecs20140526.models.*;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.vpc20160428.models.DeleteVSwitchRequest;
import com.aliyun.vpc20160428.models.DeleteVpcRequest;
import com.google.gson.Gson;

import java.util.Collections;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class DeleteResources {
    public static void main(String[] args) {
        String vpcId = "vpc-bp1aag0sb9s4i92i3****";
        String vSwitchId = "vsw-bp1nzprm8h7mmnl8t****";
        String securityGroupId = "sg-bp1esyhwfbqeyudt****";
        String instanceId = "i-bp17f3kzgtzzj91r****";
        String keyPairName = "sdk-key-pair";
        ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
        try {
            com.aliyun.ecs20140526.Client ecsClient = createEcsClient();
            com.aliyun.vpc20160428.Client vpcClient = createVpcClient();
            // インスタンスとキーペアをすぐに削除します。
            executorService.schedule(() -> deleteInstance(instanceId, ecsClient), 1, TimeUnit.SECONDS);
            executorService.schedule(() -> deleteKeyPairs(keyPairName, ecsClient), 1, TimeUnit.SECONDS);
            // セキュリティグループと vSwitch を削除する前に、インスタンスの削除が完了するのを待ちます。
            executorService.schedule(() -> deleteSecurityGroup(securityGroupId, ecsClient), 60, TimeUnit.SECONDS);
            executorService.schedule(() -> deleteVSwitch(vSwitchId, vpcClient), 60, TimeUnit.SECONDS);
            // 内部のすべてのリソースが削除された後、最後に VPC を削除します。
            executorService.schedule(() -> deleteVpc(vpcId, vpcClient), 65, TimeUnit.SECONDS);
        } catch (Exception e) {
            System.err.println("An error occurred: " + e.getMessage());
            // 一部のリソースの削除に失敗した可能性があります。必要に応じて、ログ記録またはリトライロジックを追加してください。
        } finally {
            executorService.shutdown();
        }
    }

    public static class Constants {
        public static final String REGION_ID = "cn-hangzhou";

        public static final class ENDPOINT {
            public static final String VPC = "vpc.cn-hangzhou.aliyuncs.com";
            public static final String ECS = "ecs.cn-hangzhou.aliyuncs.com";
        }
    }

    public static com.aliyun.vpc20160428.Client createVpcClient() throws Exception {
        Config config = new Config();
        config.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
        config.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        config.endpoint = Constants.ENDPOINT.VPC;
        return new com.aliyun.vpc20160428.Client(config);
    }

    public static com.aliyun.ecs20140526.Client createEcsClient() throws Exception {
        Config config = new Config();
        config.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
        config.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        config.endpoint = Constants.ENDPOINT.ECS;
        return new com.aliyun.ecs20140526.Client(config);
    }

    /**
     * 指定された VPC を削除します。
     *
     * @param vpcId     削除する VPC の ID。
     * @param vpcClient VPC クライアント。
     */
    public static void deleteVpc(String vpcId, com.aliyun.vpc20160428.Client vpcClient) {
        try {
            System.out.println("Deleting VPC...");
            DeleteVpcRequest deleteVpcRequest = new DeleteVpcRequest()
                    .setRegionId(Constants.REGION_ID)
                    .setVpcId(vpcId);
            vpcClient.deleteVpc(deleteVpcRequest);
        } catch (Exception e) {
            throw new RuntimeException("DeleteVpc failed: " + e.getMessage());
        }
    }

    /**
     * 指定された vSwitch を削除します。
     *
     * @param vSwitchId 削除する vSwitch の ID。
     * @param vpcClient VPC クライアント。
     */
    public static void deleteVSwitch(String vSwitchId, com.aliyun.vpc20160428.Client vpcClient) {
        System.out.println("Deleting vSwitch...");
        try {
            DeleteVSwitchRequest deleteVSwitchRequest = new DeleteVSwitchRequest()
                    .setRegionId(Constants.REGION_ID)
                    .setVSwitchId(vSwitchId);
            vpcClient.deleteVSwitch(deleteVSwitchRequest);
        } catch (Exception e) {
            throw new RuntimeException("DeleteVSwitch failed: " + e.getMessage());
        }
    }

    /**
     * 指定されたセキュリティグループを削除します。
     *
     * @param securityGroupId 削除するセキュリティグループの ID。
     * @param ecsClient       ECS クライアント。
     */
    public static void deleteSecurityGroup(String securityGroupId, Client ecsClient) {
        System.out.println("Deleting security group...");
        try {
            DeleteSecurityGroupRequest deleteSecurityGroupRequest = new DeleteSecurityGroupRequest()
                    .setRegionId(Constants.REGION_ID)
                    .setSecurityGroupId(securityGroupId);
            ecsClient.deleteSecurityGroup(deleteSecurityGroupRequest);
        } catch (Exception e) {
            throw new RuntimeException("DeleteSecurityGroup failed: " + e.getMessage());
        }
    }

    /**
     * 指定された ECS インスタンスを強制的に削除します。
     *
     * @param instanceId 削除するインスタンスの ID。
     * @param ecsClient  ECS クライアント。
     */
    public static void deleteInstance(String instanceId, Client ecsClient) {
        System.out.println("Deleting ECS instance...");
        try {
            DeleteInstanceRequest request = new DeleteInstanceRequest()
                    .setForce(true)
                    .setInstanceId(instanceId);
            ecsClient.deleteInstance(request);
        } catch (Exception e) {
            throw new RuntimeException("DeleteInstance failed: " + e.getMessage());
        }
    }

    /**
     * 指定された SSH キーペアを削除します。
     *
     * @param keyPairName 削除する SSH キーペアの名前。
     * @param ecsClient   ECS クライアント。
     */
    public static void deleteKeyPairs(String keyPairName, Client ecsClient) {
        System.out.println("Deleting SSH key pair...");
        try {
            DeleteKeyPairsRequest deleteKeyPairsRequest = new DeleteKeyPairsRequest()
                    .setRegionId(Constants.REGION_ID)
                    .setKeyPairNames(new Gson().toJson(Collections.singletonList(keyPairName)));
            ecsClient.deleteKeyPairs(deleteKeyPairsRequest);
        } catch (Exception e) {
            throw new RuntimeException("DeleteKeyPairs failed: " + e.getMessage());
        }
    }
}

次のステップ