All Products
Search
Document Center

Elastic Compute Service:Buat dan gunakan instans ECS menggunakan SDK

Last Updated:Apr 01, 2026

Gunakan ECS SDK 2.0 untuk Java guna membuat instans Elastic Compute Service (ECS), menjalankan perintah secara jarak jauh melalui Cloud Assistant, dan melepaskan semua sumber daya setelah selesai.

Tutorial ini mencakup:

  • Menyiapkan kredensial dan menginstal SDK melalui Maven

  • Membuat sumber daya jaringan yang diperlukan (Virtual Private Cloud (VPC), vSwitch, security group, pasangan kunci SSH)

  • Membuat instans ECS dan menunggu hingga berada dalam status Running

  • Menjalankan perintah shell pada instans tanpa login, menggunakan Cloud Assistant

  • Melepaskan semua sumber daya dalam urutan yang benar

Prasyarat

Sebelum memulai, pastikan Anda telah memiliki:

  • Pengguna Resource Access Management (RAM) dengan kebijakan berikut yang dilampirkan:

    LayananKebijakan
    VPCAliyunVPCFullAccess
    ECSAliyunECSFullAccess
  • ID AccessKey dan AccessKey Secret pengguna RAM yang dikonfigurasi sebagai variabel lingkungan. Lihat Konfigurasikan variabel lingkungan di Linux, macOS, dan Windows. Kode contoh membaca kredensial dari variabel lingkungan ini:

    Gunakan AccessKey pengguna RAM, bukan AccessKey akun Alibaba Cloud Anda. AccessKey tingkat akun memiliki izin penuh atas semua sumber daya — jika bocor, seluruh akun Anda berisiko. Lihat Buat pasangan AccessKey.
    VariabelNilai
    ALIBABA_CLOUD_ACCESS_KEY_IDID AccessKey Anda
    ALIBABA_CLOUD_ACCESS_KEY_SECRETAccessKey Secret Anda
  • Java dan Maven terinstal.

Instal SDK

Tambahkan dependensi SDK ECS dan VPC ke file pom.xml Anda:

<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>

Untuk metode instalasi lainnya, lihat Instal ECS SDK untuk Java dan Instal VPC SDK untuk Java.

Buat instans ECS

Membuat instans ECS memerlukan beberapa sumber daya prasyarat: VPC, vSwitch, security group, dan pasangan kunci SSH. Langkah-langkah di bawah ini membuat masing-masing sumber daya secara berurutan, lalu membuat instans tersebut.

Jika Anda sudah memiliki sumber daya ini, masukkan ID-nya langsung ke panggilan RunInstances.

Langkah 1: Buat VPC

VPC adalah jaringan pribadi yang terisolasi secara logis di cloud.

Panggil CreateVpc dengan parameter berikut:

ParameterDeskripsiContoh
RegionIdWilayah tempat VPC dibuatcn-hangzhou
CidrBlockBlok CIDR VPC192.168.0.0/16

Setelah memanggil CreateVpc, lakukan polling terhadap DescribeVpcs hingga status VPC berubah menjadi Available sebelum melanjutkan.

Langkah 2: Buat vSwitch

vSwitch menghubungkan instans ECS dalam VPC dan memungkinkan komunikasi antar instans tersebut.

Panggil CreateVSwitch dengan parameter berikut:

ParameterDeskripsiContoh
RegionIdWilayah vSwitchcn-hangzhou
ZoneIdZona dalam wilayah tersebutcn-hangzhou-i
VpcIdID VPC yang dibuat pada Langkah 1vpc-bp1aag0sb9s4i92i3****
CidrBlockBlok CIDR vSwitch (harus berada dalam blok CIDR VPC)192.168.0.0/24

Langkah 3: Buat security group

Security group berfungsi sebagai firewall virtual yang mengontrol lalu lintas inbound dan outbound untuk instans ECS.

Panggil CreateSecurityGroup dengan:

ParameterDeskripsiContoh
RegionIdWilayah security groupcn-hangzhou
VpcIdID VPCvpc-bp1aag0sb9s4i92i3****

Kemudian tambahkan aturan inbound melalui AuthorizeSecurityGroup:

ParameterDeskripsiContoh
SecurityGroupIdID security groupsg-bp1esyhwfbqeyudt****
IpProtocolProtokoltcp
SourceCidrIpRentang IP sumber yang diizinkan0.0.0.0/0
PortRangeRentang port (Linux: SSH; Windows: RDP)22/22

Langkah 4: Buat pasangan kunci SSH

Pasangan kunci SSH memungkinkan Anda login ke instans Linux tanpa password.

Panggil CreateKeyPair dengan:

ParameterDeskripsiContoh
RegionIdWilayahcn-hangzhou
KeyPairNameNama pasangan kuncisdk-key-pair
Penting

Simpan kunci privat yang dikembalikan dalam respons. Kunci tersebut tidak dapat diambil kembali setelah pembuatan.

Langkah 5: Buat instans ECS

Panggil RunInstances dengan:

ParameterDeskripsiContoh
RegionIdWilayahcn-hangzhou
ImageIdID imagealiyun_3_x64_20G_scc_alibase_20220225.vhd
InstanceTypeTipe instansecs.e-c1m2.xlarge
SecurityGroupIdID security group dari Langkah 3sg-bp1esyhwfbqeyudt****
VSwitchIdID vSwitch dari Langkah 2vsw-bp1nzprm8h7mmnl8t****
InstanceChargeTypeMetode penagihanPostPaid (pay-as-you-go)
KeyPairNamePasangan kunci SSH dari Langkah 4sdk-key-pair
SystemDisk.CategoryTipe disk sistemcloud_essd

Setelah memanggil RunInstances, polling DescribeInstanceStatus hingga status instans menjadi Running — biasanya sekitar 10 detik.

Pastikan saldo akun Anda mencukupi sebelum membuat instans pay-as-you-go.

Kode contoh lengkap

Kode berikut membuat semua sumber daya prasyarat secara berurutan, lalu membuat instans ECS dan menunggu hingga instans tersebut menyala.

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();
            // Buat VPC.
            vpcId = createVpc(vpcClient);
            System.out.println("VPC berhasil dibuat, vpcId :" + vpcId);
            // Tunggu hingga VPC berada dalam status Available sebelum melanjutkan.
            while (true) {
                String status = describeVpc(vpcId, vpcClient);
                if ("Available".equals(status)) {
                    break;
                }
            }
            // Buat vSwitch.
            vSwitchId = CreateVSwitch(vpcId, vpcClient);
            System.out.println("vSwitch berhasil dibuat, vSwitchId :" + vSwitchId);
            // Buat security group.
            securityGroupId = createSecurityGroup(vpcId, ecsClient);
            System.out.println("SecurityGroup berhasil dibuat, securityGroupId :" + securityGroupId);
            // Tambahkan aturan inbound ke security group.
            authorizeSecurityGroup(securityGroupId, ecsClient);
            // Buat pasangan kunci SSH. Simpan kunci privat untuk digunakan nanti saat login ke instans.
            CreateKeyPairResponse keyPair = createKeyPair(ecsClient);
            System.out.println("Pasangan kunci berhasil dibuat, keyPairName :" + keyPair.body.keyPairName);
            // Buat instans ECS.
            instanceId = createInstance(ecsClient, vSwitchId, securityGroupId);
            System.out.println("ECS berhasil dibuat, instanceId :" + instanceId);
            // Tunggu hingga instans berada dalam status 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) {
            // Jika beberapa sumber daya telah dibuat sebelum terjadi kegagalan, tambahkan logging, rollback,
            // atau logika kompensasi untuk membersihkan status parsial.
            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";   // Subscription
            public static final String POST_PAID = "PostPaid"; // Pay-as-you-go
        }
    }

    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);
    }

    /**
     * Membuat VPC dan mengembalikan ID-nya.
     *
     * @param vpcClient Klien VPC.
     * @return ID VPC baru.
     */
    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 gagal: " + e.getMessage());
        }
    }

    /**
     * Membuat vSwitch dalam VPC yang ditentukan dan mengembalikan ID-nya.
     *
     * @param vpcId     ID VPC.
     * @param vpcClient Klien VPC.
     * @return ID vSwitch baru.
     */
    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 gagal: " + e.getMessage());
        }
    }

    /**
     * Membuat security group dalam VPC yang ditentukan dan mengembalikan ID-nya.
     *
     * @param vpcId     ID VPC.
     * @param ecsClient Klien ECS.
     * @return ID security group baru.
     */
    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 gagal: " + e.getMessage());
        }
    }

    /**
     * Menambahkan aturan TCP inbound pada port 22 (SSH) dari semua sumber ke security group yang ditentukan.
     *
     * @param securityGroupId ID security group.
     * @param ecsClient       Klien 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 gagal: " + e.getMessage());
        }
    }

    /**
     * Membuat instans ECS dan mengembalikan ID-nya.
     *
     * @param ecsClient       Klien ECS.
     * @param vSwitchId       ID vSwitch.
     * @param securityGroupId ID security group.
     * @return ID instans ECS baru.
     */
    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 gagal: " + e.getMessage());
        }
    }

    /**
     * Membuat pasangan kunci SSH dan mengembalikan respons lengkap (termasuk kunci privat).
     *
     * @param ecsClient Klien ECS.
     * @return Respons dari CreateKeyPair, berisi nama pasangan kunci dan bahan kunci privat.
     */
    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 gagal: " + e.getMessage());
        }
    }

    /**
     * Mengembalikan status saat ini dari VPC yang ditentukan.
     *
     * @param vpcId     ID VPC.
     * @param vpcClient Klien VPC.
     * @return String status VPC, misalnya "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 gagal: " + e.getMessage());
        }
    }

    /**
     * Mengembalikan status instans ECS yang ditentukan.
     *
     * @param instanceIds Daftar ID instans ECS yang akan diquery.
     * @param ecsClient   Klien ECS.
     * @return Respons 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 gagal: " + e.getMessage());
        }
    }
}

Jalankan perintah tanpa login

Cloud Assistant memungkinkan Anda menjalankan perintah shell, PowerShell, dan batch pada instans ECS langsung dari API — tanpa sesi SSH atau jump server. Gunakan fitur ini untuk menginstal perangkat lunak, menjalankan skrip, mengelola layanan, atau menerapkan pembaruan secara massal.

Contoh berikut menginstal Java dan Tomcat pada instans Linux menggunakan RunCommand:

ParameterDeskripsiContoh
RegionIdWilayah instanscn-hangzhou
TypeJenis perintahRunShellScript
CommandContentSkrip shell yang akan dijalankanLihat kode contoh di bawah
InstanceIdID instans target["i-bp17f3kzgtzzj91r****"]
Timeout(Opsional) Batas waktu eksekusi, dalam detik60
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****");

        // Instal Java dan Tomcat pada instans.
        // Skrip mendeteksi OS dan menggunakan manajer paket yang sesuai.
        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";   // Instans Linux
            public static final String RUN_BAT_SCRIPT = "RunBatScript";       // Instans Windows
            public static final String RUN_POWERSHELL_SCRIPT = "RunPowerShellScript"; // Instans 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);
    }

    /**
     * Menjalankan perintah shell pada instans ECS yang ditentukan melalui Cloud Assistant.
     *
     * @param commandContent Konten skrip shell.
     * @param instanceIds    Daftar ID instans target.
     * @param ecsClient      Klien 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 gagal:" + e);
        }
    }
}

Untuk informasi lebih lanjut tentang Cloud Assistant, lihat Ikhtisar Cloud Assistant.

Lepaskan sumber daya

Saat Anda tidak lagi memerlukan sumber daya tersebut, hapus dalam urutan berikut. Menghapus sumber daya di luar urutan dapat menyebabkan error dependensi — misalnya, VPC tidak dapat dihapus selama vSwitch masih ada di dalamnya.

Kode contoh di bawah ini menghapus semua sumber daya yang dibuat dalam tutorial ini. Sesuaikan agar hanya mencakup sumber daya yang ingin Anda lepaskan.

Hapus pesanan:

  1. DeleteInstancesRegionId, InstanceId

  2. DeleteKeyPairsRegionId, KeyPairNames (array JSON, misalnya ["sdk-key-pair"])

  3. DeleteSecurityGroupRegionId, SecurityGroupId

  4. DeleteVSwitchRegionId, VSwitchId

  5. DeleteVpcRegionId, VpcId

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();
            // Hapus instans dan pasangan kunci segera.
            executorService.schedule(() -> deleteInstance(instanceId, ecsClient), 1, TimeUnit.SECONDS);
            executorService.schedule(() -> deleteKeyPairs(keyPairName, ecsClient), 1, TimeUnit.SECONDS);
            // Tunggu hingga instans selesai dihapus sebelum menghapus security group dan vSwitch.
            executorService.schedule(() -> deleteSecurityGroup(securityGroupId, ecsClient), 60, TimeUnit.SECONDS);
            executorService.schedule(() -> deleteVSwitch(vSwitchId, vpcClient), 60, TimeUnit.SECONDS);
            // Hapus VPC terakhir, setelah semua sumber daya di dalamnya dihapus.
            executorService.schedule(() -> deleteVpc(vpcId, vpcClient), 65, TimeUnit.SECONDS);
        } catch (Exception e) {
            System.err.println("Terjadi kesalahan: " + e.getMessage());
            // Beberapa sumber daya mungkin gagal dihapus. Tambahkan logging atau logika retry sesuai kebutuhan.
        } 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);
    }

    /**
     * Menghapus VPC yang ditentukan.
     *
     * @param vpcId     ID VPC yang akan dihapus.
     * @param vpcClient Klien VPC.
     */
    public static void deleteVpc(String vpcId, com.aliyun.vpc20160428.Client vpcClient) {
        try {
            System.out.println("Menghapus VPC...");
            DeleteVpcRequest deleteVpcRequest = new DeleteVpcRequest()
                    .setRegionId(Constants.REGION_ID)
                    .setVpcId(vpcId);
            vpcClient.deleteVpc(deleteVpcRequest);
        } catch (Exception e) {
            throw new RuntimeException("DeleteVpc gagal: " + e.getMessage());
        }
    }

    /**
     * Menghapus vSwitch yang ditentukan.
     *
     * @param vSwitchId ID vSwitch yang akan dihapus.
     * @param vpcClient Klien VPC.
     */
    public static void deleteVSwitch(String vSwitchId, com.aliyun.vpc20160428.Client vpcClient) {
        System.out.println("Menghapus vSwitch...");
        try {
            DeleteVSwitchRequest deleteVSwitchRequest = new DeleteVSwitchRequest()
                    .setRegionId(Constants.REGION_ID)
                    .setVSwitchId(vSwitchId);
            vpcClient.deleteVSwitch(deleteVSwitchRequest);
        } catch (Exception e) {
            throw new RuntimeException("DeleteVSwitch gagal: " + e.getMessage());
        }
    }

    /**
     * Menghapus security group yang ditentukan.
     *
     * @param securityGroupId ID security group yang akan dihapus.
     * @param ecsClient       Klien ECS.
     */
    public static void deleteSecurityGroup(String securityGroupId, Client ecsClient) {
        System.out.println("Menghapus security group...");
        try {
            DeleteSecurityGroupRequest deleteSecurityGroupRequest = new DeleteSecurityGroupRequest()
                    .setRegionId(Constants.REGION_ID)
                    .setSecurityGroupId(securityGroupId);
            ecsClient.deleteSecurityGroup(deleteSecurityGroupRequest);
        } catch (Exception e) {
            throw new RuntimeException("DeleteSecurityGroup gagal: " + e.getMessage());
        }
    }

    /**
     * Menghapus instans ECS yang ditentukan secara paksa.
     *
     * @param instanceId ID instans yang akan dihapus.
     * @param ecsClient  Klien ECS.
     */
    public static void deleteInstance(String instanceId, Client ecsClient) {
        System.out.println("Menghapus instans ECS...");
        try {
            DeleteInstanceRequest request = new DeleteInstanceRequest()
                    .setForce(true)
                    .setInstanceId(instanceId);
            ecsClient.deleteInstance(request);
        } catch (Exception e) {
            throw new RuntimeException("DeleteInstance gagal: " + e.getMessage());
        }
    }

    /**
     * Menghapus pasangan kunci SSH yang ditentukan.
     *
     * @param keyPairName Nama pasangan kunci SSH yang akan dihapus.
     * @param ecsClient   Klien ECS.
     */
    public static void deleteKeyPairs(String keyPairName, Client ecsClient) {
        System.out.println("Menghapus pasangan kunci SSH...");
        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 gagal: " + e.getMessage());
        }
    }
}

Langkah selanjutnya