My Workflow
TL;DR Big picture is split into service-level fragments and those fragments are delegated to service teams. Then fragments are automatically stitched together by a GitHub Action.
This way the heavy lifting of detailed description of service relations is deferred to the best experts - service owners.
Demo.
Documenting components and their relations in an ecosystem (such as a family of microservices) is very important. When the whole system grows it is easy to lose track of what's happening, where it is happening and why. Popular solution for this problem is high level documentation with diagrams.
C4 Model helps to describe the structure in a compact and clear way. Textual form of UML makes it a perfect fit for software repositories.
Syntax example:
@startuml "cart_components"
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
System_Boundary(cart_system, "[[https://github.com/acme-corp-tech/architecture/wiki/cart_system.svg Shopping cart]]") {
Container(cart_service, "Cart Service", "Go", "Tracks cart contents", $sprite="go")
ContainerDb(cart_storage, "Cart Service Storage", "Redis", "", $sprite="redis")
}
@enduml
@startuml "cart_relations"
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
Rel(cart_service, cart_storage, "Stores cart contents")
@enduml
@startuml "cart_system"
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
!include cart_components.puml
!include cart_relations.puml
@enduml
Documentation that is maintained separately from the actual system tends to lag behind or even becomes obsolete and misleading. Keeping documentation closer to documented entity helps to sync them.
This workflow implements distributed storage of documentation with centralized renderer.
Each documented entity (microservice repository) contains own diagram fragments at ./resources/diagrams
.
Centralized renderer is implemented in a separate architecture
repository. Renderer knows the names of fragment owners, but does not know the contents of fragments. Fragments are fetched with a script every time the diagrams are rendered.
Centralized renderer owns main frame that includes all fragments.
Every time any of the fragments changes, central renderer is triggered to rebuild the full picture, thus keeping the diagrams up to date without any manual effort.
Rendered SVG files are then pushed to wiki repository.
Submission Category:
DIY Deployments
Yaml File or Link to Code
Main workflow to collect UML fragments and render complete diagrams as SVG:
https://github.com/acme-corp-tech/architecture/blob/main/.github/workflows/diagrams.yml.
Template workflow to trigger an update whenever fragment is changed:
https://github.com/acme-corp-tech/service-starter-kit/blob/master/.github/workflows/diagrams.yml.
This workflow is configured for every service that owns a fragment, example.
Additional Resources / Info
- C4 PlantUML
- Docker image with PlantUML renderer
vearutop/plantuml
- GitHub Action for Dispatching Workflows
benc-uk/workflow-dispatch
Top comments (1)
Great write-up, we also published an article on C4 recently - packagemain.tech/p/software-archit...