0

好的,所以我尝试将使用 Terraform 创建的 EBS 卷附加到使用 userdata 的 ASG 实例,但现在问题是两者都在不同的 AZ 中,因此无法附加。以下是我正在尝试和失败的步骤:

resource "aws_ebs_volume" "this" {
  for_each = var.ebs_block_device
    size              = lookup(each.value,"volume_size", null)
    type              = lookup(each.value,"volume_type", null)
    iops              = lookup(each.value, "iops", null)
    encrypted         = lookup(each.value, "volume_encrypt", null)
    kms_key_id        = lookup(each.value, "kms_key_id", null)
    availability_zone = join(",",random_shuffle.az.result)
} 

在上述资源中,我使用随机提供者从 AZ 列表中获取一个 AZ,并为下面的 ASG 资源提供了相同的列表:

resource "aws_autoscaling_group" "this" {
  desired_capacity          = var.desired_capacity
  launch_configuration      = aws_launch_configuration.this.id
  max_size                  = var.max_size
  min_size                  = var.min_size
  name                      = var.name
  vpc_zone_identifier       = var.subnet_ids // <------ HERE
  health_check_grace_period = var.health_check_grace_period
  load_balancers            = var.load_balancer_names
  target_group_arns         = var.target_group_arns

  tag {
    key                 = "Name"
    value               = var.name
    propagate_at_launch = true
  }
}

这是我正在使用的用户数据:

TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`

instanceId = curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/instance-id

aws ec2 attach-volume --volume-id ${ebs_volume_id} --instance-id $instanceId --device /dev/nvme1n1

上面将附加新创建的卷,因为我正在传递${ebs_volume_id}上述资源的输出。

但是,它失败了,因为实例和卷位于不同的可用区。

任何人都可以帮助我解决这个问题,而不是在 ASG 和 Volume 上硬编码 AZ吗?

4

1 回答 1

0

我必须更多地了解您试图通过 aws 提供程序和 terraform 解决这个问题。老实说,大多数想法都会有点复杂。

每个 AZ 可以有一个 ASG。否则,ASG 将在每次启动时选择一些可用区。而且,您在一个 AZ 中拥有的实例将多于您在其他 AZ 中拥有的卷和卷,而其他 AZ 中没有可附加的实例。

因此,您可以为每个可用区创建多个卷,每个可用区创建一个 ASG。然后 userdata 应该列出 AZ 中未附加到实例的所有卷。然后选择未附加的第一个卷的 id。然后附上它。如果所有内容都已附加,您应该触发警报,因为您拥有的实例多于卷。

任何使用单个 ASG 执行此操作的尝试实际上都是在尝试编写您自己的 ASG,但这样做的方式与您的实际 ASG 冲突。


但是有一家公司提供将其作为服务进行管理。它们还可以帮助您将它们作为现场实例进行管理以节省成本:https ://spot.io/

elastigroup资源是由它们管理的 ASG 因此,您将不再拥有 aws asg。但它们有一些有趣的有状态配置。

我们通过以下配置支持实例持久化。所有值都是布尔值。有关实例持久性的更多信息,请参阅:有状态配置 persist_root_device -(可选)布尔值,实例是否应维护其根设备卷。persist_block_devices - (可选)布尔值,实例是否应维护其数据卷。persist_private_ip - (可选)布尔值,实例是否应维护其私有 IP。block_devices_mode - (可选)字符串,确定我们将数据卷附加到数据设备的方式,可能的值:“reattach”和“onLaunch”(默认为 onLaunch)。private_ips - (可选)与组实例关联的私有 IP 列表。(例如“172.1.1.0”)。请注意:此设置仅适用于 persistence.persist_private_ip 设置为 true

stateful_deallocation {
     should_delete_images              = false
     should_delete_network_interfaces  = false
     should_delete_volumes             = false
     should_delete_snapshots           = false
}

这使您可以拥有一个自动缩放器来保留卷并为您处理复杂性。

于 2020-10-09T22:26:46.603 回答