使用 AWS Java 的 SDK,如何终止当前实例的 CloudFormation 堆栈?

Using AWS Java's SDKs, how can I terminate the CloudFormation stack of the current instance?

使用在线decomentation我想出以下代码来终止当前的EC2实例:

public class Ec2Utility {

    static private final String LOCAL_META_DATA_ENDPOINT = "http://169.254.169.254/latest/meta-data/";
    static private final String LOCAL_INSTANCE_ID_SERVICE = "instance-id";

    static public void terminateMe() throws Exception {
        TerminateInstancesRequest terminateRequest = new TerminateInstancesRequest().withInstanceIds(getInstanceId());
        AmazonEC2 ec2 = new AmazonEC2Client();
        ec2.terminateInstances(terminateRequest);
    }

    static public String getInstanceId() throws Exception {
        //SimpleRestClient, is an internal wrapper on http client.
        SimpleRestClient client = new SimpleRestClient(LOCAL_META_DATA_ENDPOINT);
        HttpResponse response = client.makeRequest(METHOD.GET, LOCAL_INSTANCE_ID_SERVICE);
        return IOUtils.toString(response.getEntity().getContent(), "UTF-8");
    }
}

我的问题是我的 EC2 实例在 CloudFormationStack 下的 AutoScalingGroup 下,这是因为我的组织部署标准,尽管这个单一的 EC2 就是这个功能的全部。

所以,我想从 JavaSDK 中终止整个 CloudFormationStack,请记住,我没有事先知道 CloudFormation 堆栈名称,因为我没有 EC2 实例 ID,所以我必须得到它来自使用 API 调用的代码。
如果我能做到,我该怎么做?

您应该可以使用云形成 sdk 中的 deleteStack 方法

DeleteStackRequest request = new DeleteStackRequest();
request.setStackName(<stack_name_to_be_deleted>);

AmazonCloudFormationClient client = new AmazonCloudFormationClient (<credentials>);
client.deleteStack(request);

如果您没有堆栈名称,您应该可以从实例的标签中检索

DescribeInstancesRequest request =new DescribeInstancesRequest();   
request.setInstanceIds(instancesList);
DescribeInstancesResult disresult = ec2.describeInstances(request);
List <Reservation> list  = disresult.getReservations();

for (Reservation res:list){
    List <Instance> instancelist = res.getInstances();

    for (Instance instance:instancelist){

        List <Tag> tags = instance.getTags();
        for (Tag tag:tags){
            if (tag.getKey().equals("aws:cloudformation:stack-name")) {
                tag.getValue(); // name of the stack
            }
        }

最后,我使用我编写的以下 util 函数集实现了所需的行为:

/**
 * Delete the CloudFormationStack with the given name.
 * 
 * @param stackName
 * @throws Exception
 */
static public void deleteCloudFormationStack(String stackName) throws Exception {
    AmazonCloudFormationClient client = new AmazonCloudFormationClient();
    DeleteStackRequest deleteStackRequest = new DeleteStackRequest().withStackName("");
    client.deleteStack(deleteStackRequest);
}

static public String getCloudFormationStackName() throws Exception {
    AmazonEC2 ec2 = new AmazonEC2Client();
    String instanceId = getInstanceId();
    List<Tag> tags = getEc2Tags(ec2, instanceId);
    for (Tag t : tags) {
        if (t.getKey().equalsIgnoreCase(TAG_KEY_STACK_NAME)) {
            return t.getValue();
        }
    }
    throw new Exception("Couldn't find stack name for instanceId:" + instanceId);
}

static private List<Tag> getEc2Tags(AmazonEC2 ec2, String instanceId) throws Exception {
    DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest().withInstanceIds(instanceId);
    DescribeInstancesResult describeInstances = ec2.describeInstances(describeInstancesRequest);
    List<Reservation> reservations = describeInstances.getReservations();
    if (reservations.isEmpty()) {
        throw new Exception("DescribeInstances didn't returned reservation for instanceId:" + instanceId);
    }
    List<Instance> instances = reservations.get(0).getInstances();
    if (instances.isEmpty()) {
        throw new Exception("DescribeInstances didn't returned instance for instanceId:" + instanceId);
    }
    return instances.get(0).getTags();
}

// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// Example of usage from the code:
deleteCloudFormationStack(getCloudFormationStackName());
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX