Можно ли попросить Terraform уничтожить узлы AWS с известными IP-адресами?
Мы используем Terraform для создания и уничтожения кластера Mesos DC/OS на AWS EC2. Количество узлов агента определяется в variable.tf
файл:
variable "instance_counts" {
type = "map"
default = {
master = 1
public_agent = 2
agent = 5
}
}
После запуска кластера вы можете добавить или удалить узлы агентов, изменив номер агента в этом файле и применив его снова. Terraform достаточно умен, чтобы распознать разницу и действовать соответственно. Когда он уничтожает узлы, он стремится к узлам с наибольшим номером. Например, если у меня кластер dcos с 8 узлами и я хочу завершить работу двух агентов, Terraform отключит dcos_agent_node-6
а также dcos_agent_node-7
,
Что если я захочу уничтожить агента с определенным IP? Terraform должен знать IP-адреса, потому что он знает порядок экземпляров. Как мне взломать Terraform, чтобы удалить агентов, предоставив IP-адреса?
1 ответ
Я думаю, вы неправильно понимаете, как работает Terraform.
Terraform берет вашу конфигурацию и строит график зависимости того, как создать ресурсы, описанные в конфигурации. Если у него есть файл состояния, он накладывает информацию от поставщика (например, AWS), чтобы увидеть, что уже создано и управляется Terraform, и удаляет ее из плана и потенциально создает планы уничтожения для ресурсов, которые существуют в файле поставщика и состояния.
Таким образом, если у вас есть конфигурация с кластером из 6 узлов и новым полем (без файла состояния, ничего, созданного Terraform в AWS), то Terraform создаст 6 узлов. Если затем вы установите 8 узлов, Terraform попытается построить план, содержащий 8 узлов, поймет, что у него уже есть 6 узлов, а затем создаст план для добавления двух отсутствующих узлов. Когда вы затем измените свою конфигурацию обратно на 6 узлов, Terraform создаст план с 6 узлами, поймет, что у вас есть 8 узлов, и создайте план уничтожения для узлов 7 и 8.
Попытка заставить его сделать что-то отличное от этого потребовало бы некоторого ужасного взлома файла состояний, так что он думает, что узлы 7 и 8 отличаются от тех, которые были недавно добавлены Terraform.
Например, ваш файл состояния может выглядеть примерно так:
{
"version": 3,
"terraform_version": "0.8.1",
"serial": 1,
"lineage": "7b565ca6-689a-4aab-a3ec-a1ed77e83678",
"modules": [
{
"path": [
"root"
],
"outputs": {},
"resources": {
"aws_instance.test.0": {
"type": "aws_instance",
"depends_on": [],
"primary": {
"id": "i-01ee444f57aa32b8e",
"attributes": {
...
},
"meta": {
"schema_version": "1"
},
"tainted": false
},
"deposed": [],
"provider": ""
},
"aws_instance.test.1": {
"type": "aws_instance",
"depends_on": [],
"primary": {
"id": "i-07c1999f1109a9ce2",
"attributes": {
...
},
"meta": {
"schema_version": "1"
},
"tainted": false
},
"deposed": [],
"provider": ""
}
},
"depends_on": []
}
]
}
Если бы я хотел вернуться к одному экземпляру вместо 2, то Terraform попытался бы удалить i-07c1999f1109a9ce2
экземпляр как конфигурация говорит о том, что aws_instance.test.0
должен существовать, но не aws_instance.test.1
, Чтобы заставить его удалить i-01ee444f57aa32b8e
вместо этого я мог бы отредактировать свой файл состояния, чтобы перевернуть их, и тогда Terraform подумал бы, что этот экземпляр должен быть удален.
Однако, вы попадаете на очень сложную территорию, как только начинаете делать такие вещи и взламывать файл состояния. Хотя это то, что вы можете сделать (и иногда это может понадобиться), вы должны серьезно подумать о том, как вы работаете, если это что-то, кроме единичного случая по особой причине (например, перемещение необработанных ресурсов в модули - теперь это стало проще с помощью Terraform). state mv
команда).
В вашем случае я бы спросил, почему вам нужно удалить два конкретных узла в кластере Mesos, а не просто указать размер кластера Mesos. Если дело в том, что конкретный узел плохой, то я всегда прекращаю его и позволяю Terraform в любом случае создать мне новый, здоровый.