如何使用Terraform正常关闭AWS ASG?

时间:2019-10-23 14:10:39

标签: amazon-web-services terraform terraform-provider-aws

问题

terraform destroy上,所有ASG资源均被终止,某些服务(在我的情况下为spark streaming)可能仍需要处理数据。

为确保我的应用正常关闭,我连接到我的ASG的每个实例以执行systemctl stop service,并且我想使用Terraform自动化该过程

我知道when="destroy关键字和remote-exec设置者,但是我不确定在ASG中正常关闭实例的推荐方法。

resource "aws_instance" "app" {
  # ...

  provisioner "remote-exec" {
    when    = "destroy"
    inline = [ "systemctl stop service" ]
  }
}

来源:

1 个答案:

答案 0 :(得分:1)

您可以使用autoscaling group lifecycle hooks来防止ASG在挂钩被标记为完成之前终止实例。

您可以使用aws_autoscaling_lifecycle_hook resource将终止生命周期挂钩连接到ASG:

resource "aws_autoscaling_group" "example" {
  availability_zones   = ["us-west-2a"]
  name                 = "example"
  min_size             = 1
  max_size             = 2
}

resource "aws_autoscaling_lifecycle_hook" "example" {
  name                   = "example"
  autoscaling_group_name = "${aws_autoscaling_group.example.name}"
  default_result         = "CONTINUE"
  heartbeat_timeout      = 300
  lifecycle_transition   = "autoscaling:EC2_INSTANCE_TERMINATING"

  notification_target_arn = "arn:aws:sqs:us-west-2:444455556666:queue1*"
  role_arn                = "arn:aws:iam::123456789012:role/S3Access"
}

上面的示例将使ASG在标记实例准备终止后等待5分钟(300秒)。一旦ASG尝试终止实例触发了生命周期挂钩,它将向notification_target_arn发送通知,该通知可以是SQS队列或SNS主题。

然后,您需要使用可以执行您想要执行的任何操作的通知来处理通知。在您的情况下,您可能在每个实例上运行一个小型应用程序,该应用程序轮询SQS队列以查找其实例ID的终止通知,如果收到该通知,则它将停止服务。另外,您可以让SNS主题触发Lambda函数来执行某些操作。

操作完成后,您将需要通过调用带有相关信息的AWS API将生命周期挂钩标记为已完成。或者,您可以等待超时,并根据default_result资源上的aws_authscaling_lifecycle_hook参数允许ASG继续终止。