# terraform graph: граф зависимостей ресурсов _Workflow · TerraformLab Knowledge Base_ **TL;DR:** `terraform graph` выводит directed graph (DAG) зависимостей ресурсов в формате Graphviz dot. Из него видно, что от чего зависит, и почему Terraform делает что-то именно в таком порядке. Используется при дебаге cycle-ошибок и для понимания крупных проектов. ## Зачем нужен граф Terraform, декларативный. Вы пишете «должен быть бакет, должен быть EC2 с user_data ссылающимся на этот бакет», а Terraform сам понимает порядок: сначала бакет, потом EC2. Этот «сам понимает», внутри **directed acyclic graph (DAG)**, направленного ациклического графа. Каждый ресурс, узел. Каждая ссылка `aws_s3_bucket.demo.arn` в коде другого ресурса, стрелка от потребителя к источнику. Terraform строит этот граф, ищет topological sort и применяет ресурсы в этом порядке. `terraform graph` показывает этот граф. Это окно во внутренности Terraform. ## Базовый вывод ```bash cd ~/myproject terraform graph ``` В stdout, текст в формате [Graphviz dot](https://graphviz.org/): ``` digraph { compound = "true" newrank = "true" subgraph "root" { "[root] aws_s3_bucket.demo (expand)" [label = "aws_s3_bucket.demo", shape = "box"] "[root] random_id.suffix (expand)" [label = "random_id.suffix", shape = "box"] "[root] aws_s3_bucket.demo (expand)" -> "[root] random_id.suffix (expand)" ... } } ``` Этот текст не для людей. Чтобы посмотреть. Нужно сконвертировать в картинку. ## Конвертация в PNG/SVG Если установлен `graphviz`: ```bash terraform graph | dot -Tpng > graph.png terraform graph | dot -Tsvg > graph.svg ``` Откройте картинку, увидите боксы-ресурсы со стрелками. Стрелка от `aws_s3_bucket.demo` к `random_id.suffix` означает «бакет зависит от random_id». В Linux/macOS: ```bash sudo apt install graphviz # Ubuntu/Debian brew install graphviz # macOS ``` На Windows: установите [Graphviz](https://graphviz.org/download/), добавьте `dot.exe` в PATH. ## Режимы графа По умолчанию `terraform graph` показывает плановый граф (что будет при apply). Есть и другие: ```bash terraform graph -type=plan # default, для будущего apply terraform graph -type=plan-destroy # для terraform destroy terraform graph -type=apply # пост-apply: что уже создано ``` Большинство случаев, `plan`. `apply`-тип показывает только реально изменённые узлы. ## Что искать в графе ### 1. Узлы без стрелок, изолированные Это ресурсы, у которых нет зависимостей. Они применятся первыми, параллельно. Если ожидали что ресурс ждёт другого, стрелки нет, значит зависимость не объявлена. Решение: либо ссылаться на атрибут (implicit dependency), либо `depends_on = [...]` (explicit). См. [tf-depends-on](/terraform/kb/tf-depends-on.md). ### 2. Циклы Если ресурс A зависит от B, а B, от A, граф **циклический**. Это невалидный DAG, и Terraform упадёт: ``` Error: Cycle: aws_iam_role.a, aws_iam_policy.b ``` В графе циклы видно глазами, две стрелки между узлами в обе стороны. См. [tf-common-errors](/terraform/kb/tf-common-errors.md) про разрешение циклов. ### 3. Длинные цепочки Если 10 ресурсов идут последовательно (a → b → c → ...): параллелизм Terraform теряется. Apply вместо 1 минуты будет 10. Иногда это неизбежно (RDS должен быть до EC2 который к нему коннектится), иногда, артефакт лишних `depends_on`. ## Использование с jq для анализа С Terraform 1.4+ есть `terraform graph -draw-cycles`, подсветка циклов. Но для машинного анализа удобнее JSON через `terraform show -json`: ```bash terraform plan -out=plan.bin terraform show -json plan.bin | jq '.resource_changes[].address' ``` Список адресов всех изменяемых ресурсов. Можно строить графики и отчёты. ## Rover, альтернатива Для интерактивной визуализации есть [Rover](https://github.com/im2nguyen/rover): поднимает локальный веб-сервер с графом, на который можно жмякать. ```bash rover -tfPath /path/to/terraform-binary ``` Для крупных проектов (50+ ресурсов): намного удобнее, чем dot-PNG. ## Подводные камни - **Граф из `terraform graph`, большой даже на маленьком проекте.** Каждый провайдер, локал, выходящие данные тоже узлы. Не пугайтесь 50 нод на 5 ресурсов, большинство служебные. - **DOT-формат не всегда красиво ложится.** Большие проекты, это спагетти на PNG. Альтернативы: Rover (интерактивно), [Inframap](https://github.com/cycloidio/inframap) (упрощённый cloud-граф), `terraform graph -type=plan` + ручная фильтрация `grep` по интересующим типам. - **Граф зависит от текущего state.** Если state пустой, граф показывает «всё добавить». Если что-то уже создано, только новое. Чтобы увидеть «полный граф» текущего проекта, `terraform refresh` сначала. - **`-type=plan-destroy` показывает обратный порядок.** Destroy идёт от листьев к корню (сначала зависимые, потом независимые). Если хочется понять что снесётся в каком порядке, этот режим. - **`-draw-cycles` появился в TF 1.4.** На старых версиях циклы придётся искать глазами в DOT-выводе или через `grep '->'`. ## Команды ```bash terraform graph ``` Вывести граф в формате Graphviz DOT в stdout. ```bash terraform graph | dot -Tpng > graph.png ``` Сохранить картинку. Требует установленный graphviz. ```bash terraform graph -type=plan-destroy | dot -Tpng > destroy.png ``` Граф для terraform destroy: видно в каком порядке будут сноситься ресурсы. ```bash terraform graph -draw-cycles ``` С TF 1.4+: подсветить циклы в графе. Помогает при разборе cycle-ошибок. ```bash terraform graph | grep '->' ``` Список всех зависимостей. Полезно когда хочется грепом по нужным типам. ## См. также - [Зависимости ресурсов: явные и неявные](/terraform/kb/tf-depends-on.md) - [Ссылки в HCL: как читать aws_s3_bucket.demo.bucket](/terraform/kb/tf-references.md) - [terraform plan: посмотреть, что Terraform собирается сделать](/terraform/kb/tf-plan.md)