Назад | Перейти на главную страницу

Как с Terraform перерабатывать тома корневых инстансов EC2?

Мне интересно, занимался ли кто-нибудь сохранением корневого тома EC2, чтобы можно было испортить ресурс экземпляра и повторно применить, и экземпляр будет использовать этот том вместо ami?

Насколько я понимаю из документации, aws_ebs_volume и aws_ebs_volume_attachment работают только с некорневыми томами.

Terraform's aws_instance ресурс требует AMI, а корневым устройством всегда является новый том, созданный из базового моментального снимка EBS этого AMI. Это (насколько мне известно) ограничение базового API EC2.

Как вы видели, можно прикрепить существующий том EBS к работающему экземпляру, используя aws_ebs_volume_attachment но нет возможности использовать существующий том EBS в качестве корневой файловой системы нового экземпляра.

Официальная документация по корневым томам заявляет, что мы можем приблизиться к тому, что вы хотите здесь:

  • Выключите старый экземпляр, сохранив его корневой том EBS.
  • Создайте снимок старого корневого тома EBS.
  • Создайте новый AMI, используя созданный снимок.
  • Запустите новый образ, используя этот новый AMI.

Такой многоэтапный процесс сложно организовать, используя только Terraform, поскольку Terraform не может отслеживать свое положение в таком процессе. Однако конфигурация, подобная следующей, позволит вам добиться этого с помощью небольшого ручного рабочего процесса, когда вам нужно заменить экземпляр:

variable "source_volume_id" {
}

resource "aws_ebs_snapshot" "new" {
  volume_id = "${var.source_volume_id}"
}

resource "aws_ami" "new" {
  name = "from-${aws_ebs_snapshot.new.id}"
  virtualization_type = "hvm"
  root_device_name = "/dev/xvda"

  ebs_block_device {
    device_name = "/dev/xvda"
    snapshot_id = "${aws_ebs_snapshot.new.id}"
    volume_size = "${aws_ebs_snapshot.new_volume_size}"
  }
}

resource "aws_instance" "new" {
  ami = "${aws_ami.new.id}"
  # ...etc...
}

Эта конфигурация предполагает, что вы уже вручную завершили работу старого экземпляра EC2 и отметили идентификатор тома EBS корневого тома. Затем вы передаете этот идентификатор тома через source_volume_id переменной, и он выполнит оставшиеся шаги.

Каждый раз source_volume_id Изменения Terraform должен повторить этот процесс, создав новый снимок, AMI и экземпляр. Если вы снова запустите Terraform с тем же source_volume_id поскольку он использовался в последний раз, все должно оставаться без изменений.

Странная проблема с этим полуавтоматическим процессом заключается в том, что у него есть проблема с курицей и яйцом, когда при первом запуске у вас, вероятно, уже не будет тома, на котором будет основан ваш AMI. В этом случае вам придется сначала закомментировать все, кроме aws_instance ресурс, жестко запрограммируйте идентификатор AMI для начальной загрузки и позвольте Terraform создать этот начальный экземпляр. При последующих запусках вы можете следить за процессом, как описано выше.

Как отмечалось выше, Terraform в настоящее время не подходит для такого рода задач. Учитывая, что в любом случае есть некоторые ручные шаги, может оказаться проще просто сценарий всего этого процесса, используя более императивный подход, например. использование одного из пакетов SDK AWS с вашим любимым языком программирования, хотя использование Terraform для части процесса, по крайней мере, освобождает вас от задачи отслеживания ранее использованных снимков состояния и идентификаторов AMI, чтобы гарантировать их очистку.

Вы правы, терраформ aws_instance требует AMI и не может запустить экземпляр из существующего тома EBS (можно проверить в исходный код ресурса).