#amazon-ec2 #terraform #devops #amazon-ami
#amazon-ec2 #terraform #devops #amazon-ami
Вопрос:
Я написал некоторый код 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"
}
}
Комментарии:
1. Какое отношение к этому имеет Ansible? Вы имеете в виду, что написали некоторый код Terraform для создания некоторых серверов?
2. извините, я имел в виду, что код terraform не доступен. Моя ошибка.
Ответ №1:
Хотя приведенный выше ответ помогает, я решил проблему, добавив следующее в ресурс aws_instance.
lifecycle {
ignore_changes = ["ami"]
}
Пожалуйста, обратите внимание, что если вы используете модуль AWS, как я, вам нужно будет ввести этот код в main.tf файл в .terraform/modules/.
Комментарии:
1. Ответ @ydaetskcor был полезным и актуальным, но это тот, который я искал. Просто отмечая, что использование кавычек, как указано выше,
[”ami”]
, теперь устарело, просто поместите[ami]
Ответ №2:
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
, поскольку в противном случае это было бы очень небезопасно, поскольку ваш источник данных мог возвращать любое общедоступное изображение, использующее эту схему именования.