Можно ли попросить 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 в любом случае создать мне новый, здоровый.

Другие вопросы по тегам