Можно ли попросить 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-адреса?


person ddd    schedule 06.02.2017    source источник


Ответы (1)


Я думаю, вы неправильно понимаете, как работает Terraform.

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

Итак, если у вас есть конфигурация с кластером из 6 узлов и новым полем (без файла состояния, ничего, созданного Terraform в AWS), Terraform создаст 6 узлов. Если вы затем установите для него 8 узлов, Terraform попытается построить план, содержащий 8 узлов, поймет, что у него уже есть 6, а затем создаст план для добавления 2 недостающих узлов. Когда вы затем измените свою конфигурацию обратно на 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 подумал бы, что вместо этого следует удалить этот экземпляр.

Однако вы попадаете на очень сложную территорию, как только начинаете делать такие вещи и взламывать файл состояния. Хотя это то, что вы можете сделать (а иногда и может потребоваться), вам следует серьезно подумать о том, как вы работаете, если это что-то иное, кроме разового случая по особой причине (например, перемещение необработанных ресурсов в модули - теперь стало проще с помощью команды state mv Terraform).

В вашем случае я бы спросил, почему вам нужно удалить два конкретных узла в кластере Mesos, а не просто указать размер кластера Mesos. Если конкретный узел неисправен, я бы всегда его прекращал и позволял Terraform построить мне новый, здоровый узел.

person ydaetskcoR    schedule 07.02.2017
comment
Причина отключения определенных узлов в том, что я хотел сначала подключиться к узлам по ssh и выполнить очистку. Есть команда для уничтожения мезо-подчиненных сервисов, которая должна переместить задачи в другое место и отменить регистрацию агента из кластера. Все, что мне нужно от Terraform, - это уничтожить агентов. Конечно, завершение можно выполнить через консоль AWS, но проще написать сценарий с помощью Terraform. Я нашел способ удалить агент, запустив terraform destroy -target с предоставленным идентификатором агента. Это не совсем то, что я искал (IP-адреса), но я думаю, что на данный момент это должно сработать. - person ddd; 07.02.2017
comment
Это совсем другой вопрос о том, как запустить что-то против экземпляра перед его завершением. Ваш подход к ручному уничтожению целевых узлов, подобных этому, также на самом деле не отвечает на ваш вопрос, потому что, если вы, например, уничтожите узел 4, а затем уменьшите конфигурацию с 8 до 6 и планируете / примените, он затем захочет перестроить узел 4 и удалить узлы 7 и 8. - person ydaetskcoR; 07.02.2017
comment
Вы подняли верную точку зрения. terraform destroy не работает с файлом конфигурации. Он уничтожает агентов без изменения конфигурации, что вызовет проблемы в будущем applys. Может быть, лучше всего манипулировать файлом состояния, как вы сказали, а затем уменьшить счетчики в .tf и запустить terraform apply. - person ddd; 07.02.2017