Экземпляры EC2 воссозданы Terraform после выпуска нового AMI - PullRequest
1 голос
/ 23 апреля 2019

Я написал код Terraform для создания нескольких серверов.Для AMI я использовал модуль данных Terraform, чтобы получить последний идентификатор образа Ubuntu 16.04 и назначить его экземплярам EC2.

Недавно я хотел добавить еще один экземпляр EC2 в эту среду, однако когда я запускаю terraform plan, я вижу, что Terraform пытается удалить существующий экземпляр EC2 и воссоздать их.Причина в том, что был выпущен новый образ Ubuntu, и он пытается удалить старый экземпляр и создать новые с новым идентификатором AMI.

Есть ли шанс, что я смогу решить эту проблему, так как не могухотите случайно удалить наши производственные серверы?

data "aws_ami" "ubuntu" {
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}

module "jenkins" {
  source = "terraform-aws-modules/ec2-instance/aws"

  name           = "Jenkins"
  instance_count = 1

  ami                         = "${data.aws_ami.ubuntu.id}"
  instance_type               = "t2.small"
  associate_public_ip_address = true
  disable_api_termination     = true
  key_name                    = "${aws_key_pair.ssh_key.key_name}"
  monitoring                  = false
  vpc_security_group_ids      = "${module.jenkins_http_sg.this_security_group_id}", "${module.jenkins_https_sg.this_security_group_id}", "${module.ssh_sg.this_security_group_id}"]
  subnet_id                   = "${module.vpc.public_subnets[0]}"
  iam_instance_profile        = "${aws_iam_instance_profile.update-dns-profile.name}"

  tags = {
    Terraform       = "true"
  }
}

Ответы [ 2 ]

2 голосов
/ 23 апреля 2019

Terraform делает именно то, что вы просили. Каждый раз, когда он запускается, он ищет самый последний AMI с именем, начинающимся с ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-*, а затем передает этот идентификатор AMI в ресурс aws_instance. Поскольку невозможно изменить идентификатор изображения экземпляра, Terraform правильно определяет, что он должен уничтожить старые экземпляры и восстановить их из нового AMI.

Если вы хотите указать конкретный AMI, вам следует либо заставить источник данных возвращать только один AMI (например, указав отметку даты в фильтре name), либо жестко закодировать идентификатор AMI, который вы хотите использовать.

data "aws_ami" "ubuntu" {
  most_recent = true
  owners      = ["099720109477"] # Canonical

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-20190403"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}

или

variable "ami" {
  default = "ami-0727f3c2d4b0226d5"
}

Если вы удалите параметр most_recent = true, то вместо этого ваш источник данных найдет несколько изображений, соответствующих этим критериям, а затем потерпит неудачу, поскольку источник данных aws_ami может вернуть только один AMI:

ПРИМЕЧАНИЕ. Если при поиске возвращается более или менее одного совпадения, Terraform завершится ошибкой. Убедитесь, что ваш поиск достаточно конкретен, чтобы возвращать только один идентификатор AMI, или используйте most_recent, чтобы выбрать самый последний. Если вы хотите сопоставить несколько AMI, используйте источник данных aws_ami_ids.

Также обратите внимание, что я добавил поле owners в ваш источник данных. Это сейчас требуется начиная с версия 2.0.0, потому что в противном случае это было бы очень небезопасно, поскольку ваш источник данных мог вернуть любое общедоступное изображение, использующее эту схему именования.

0 голосов
/ 24 апреля 2019

Хотя приведенный выше ответ помогает, я решил проблему, добавив следующее в ресурс aws_instance.

lifecycle {
    ignore_changes = ["ami"]
  }

Обратите внимание, что если вы используете модуль AWS, как я, вам нужно будет ввести этот код в файл main.tf в .terraform / modules /.

...