11

Since version 1.3, Ansible has supported role dependencies to encourage reuse of role definitions. To audit and maintain larger orchestrations, it would be nice to have some way to easily generate a dependency graph of which roles depend on which other roles.

An example of dependency definitions might be roles/app_node/meta/main.yml:

---
dependencies:
  - { role: common, some_parameter: 3 }
  - { role: apache, port: 80 }
  - { role: postgres_client, 
      dbname: blarg, 
      other_parameter: 12 }

where roles/postgres_client/meta/main.yml might include something like

---
dependencies:
  - { role: postgres_common }
  - { role: stunnel, 
      client: yes,
      local_port: 5432
      remote_host: db_host
      remote_port: 15432 
    }

Such nested dependencies can get messy to maintain when the number of roles in an orchestration grows. I therefore wonder if anyone has found an easy way to generate a graph of such dependencies, either graphically (dot or neato?) or just as an indented text graph? Such a tool could help reduce the maintenance complexity.

Martin Thorsen Ranang
  • 2,394
  • 1
  • 28
  • 43

3 Answers3

4

The following python script worked for me:

#!/usr/bin/env python

import sys
import gv
from glob import glob
import yaml

g = gv.digraph('roles')

role_nodes = {}

def add_role(role):
    if role not in role_nodes:
        role_nodes[role] = gv.node(g, role)

def link_roles(dependent, depended):
    gv.edge(
        role_nodes[dependent_role],
        role_nodes[depended_role]
    )

for path in glob('roles/*/meta/main.yml'):
    dependent_role = path.split('/')[1]

    add_role(dependent_role)

    with open(path, 'r') as f:
        for dependency in yaml.load(f.read())['dependencies']:
            depended_role = dependency['role']

            add_role(depended_role)
            link_roles(dependent_role, depended_role)

gv.layout(g, 'dot')
gv.render(g, 'png', 'doc/ansible-roles.png')
Ikar Pohorský
  • 4,617
  • 6
  • 39
  • 56
sebn
  • 64
  • 2
  • This answer could be improved by explaining _how_ it addresses the problem stated in the question. –  Dec 03 '15 at 23:07
  • Running: "ImportError: No module named gv". pip install gv: "No distributions at all found for gv" – Travis Bear May 04 '16 at 16:03
  • 2
    @TravisBear The `gv` module is part of Graphviz, it is not distributed on PyPI. You can install it using the package manager of your linux distribution (apt, yum...). Package name may be something like `graphviz-python` or `python-graphviz`. – sebn May 08 '16 at 07:15
  • 1
    I've made an [alternative version](https://gist.github.com/sboisson/472c6af5c7e15bc24114b13f11456190) using [graphviz](https://pypi.org/project/graphviz/) python package – Le Hibou Jun 30 '20 at 11:29
1

You can use Graphviz to do this like the ginas project has.

ghr
  • 647
  • 4
  • 16
0
# install gv on ubuntu
sudo apt-get install python3-gv
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Mary Ciricean
  • 84
  • 1
  • 2