Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Architecture as Code in Practice

Architecture as Code in Practice

Avatar for Roland Weisleder

Roland Weisleder

October 07, 2025
Tweet

More Decks by Roland Weisleder

Other Decks in Programming

Transcript

  1. Whoever wishes to build high towers must spend much time

    near the foundation. Anton Bruckner
  2. The „as Code“ Approach </> Versioning Established change and review

    processes Automatable in CI/CD pipelines Reproducibility Machine- readable Artifacts closer to the code Scalability Reduction of manual errors
  3. Diagrams as Code @startuml package "Some Group" { HTTP -

    [First Component] [Another Component] } node "Other Groups" { FTP - [Second Component] [First Component] --> FTP } cloud { [Example 1] } database "MySql" { folder "This is my folder" { [Folder 3] } frame "Foo" { [Frame 4] } } [Another Component] --> [Example 1] [Example 1] --> [Folder 3] [Folder 3] --> [Frame 4] @enduml Source: https://plantuml.com/en/component-diagram
  4. Docs as Code === Whitebox HtmlSanityChecker [plantuml,whitbox-hsc-level-1,svg] .... include::../../plantuml/whitebox-hsc-level-1.puml[] ....

    Rationale:: We used _functional decomposition_ to separate responsibilities: * {xrefConceptCheckerCore} shall encapsulate checking logic and Html parsing/processing. * all kinds of outputs (console, html-file, graphical) shall be handled in a separate component (`Reporter`) * Implementation of Gradle specific stuff shall be encapsulated. Contained Blackboxes:: [cols="1,3" options=""] .HtmlSanityChecker building blocks |=== | <<sec:checker_blackbox, HSC Core>> | hsc core: html parsing and sanity checking, configuration, reporting. | HSC Gradle Plugin | integrates the Gradle build tool with HSC, enabling arbitrary gradle builds to use HSC functionality. | HSC Maven Plugin | integrates the Maven build tool with HSC, enabling arbitrary maven builds to use HSC functionality. | HSC Graphical Interface | (planned, not implemented) |=== Source: https://hsc.aim42.org/arc42/chapters/chap-05-BuildingBlocks.html
  5. Architecture as Code makes the architecture enforceable through executable source

    code Mark Richards Source: https://www.thoughtworks.com/insights/podcasts/technology-podcasts/architecture-as-code
  6. Architectural Decision Records https://adr.github.io/ # {short title, representative of solved

    problem and found solution} ## Context and Problem Statement {Describe the context and problem statement, e.g., in free form using two to three sentences or in the form of an illustrative story. You may want to articulate the problem in form of a question and add links to collaboration boards or issue management systems.} ## Considered Options * {title of option 1} * {title of option 2} * {title of option 3} * … <!-- numbers of options can vary --> ## Decision Outcome Chosen option: "{title of option 1}", because {justification. e.g., only option, which meets k.o. criterion decision driver | which resolves force {force} | … | comes out best (see below)}. <!-- This is an optional element. Feel free to remove. --> ### Consequences * Good, because {positive consequence, e.g., improvement of one or more desired qualities, …} * Bad, because {negative consequence, e.g., compromising one or more desired qualities, …} * … <!-- numbers of consequences can vary -->
  7. We’re doing clean architecture … or onion … or maybe

    hexagonal who knows … Random Developer
  8. @PrimaryAdapter class SamplePrimaryAdapter { SamplePrimaryPort primaryPort; } @PrimaryPort interface SamplePrimaryPort

    { } ArchRule hexagonalArchitecture = JMoleculesArchitectureRules.ensureHexagonal(); hexagonalArchitecture.check(javaClasses); Express architectural concepts in code jMolecules
  9. @startuml [Some Source] <<..some.source..>> [Some Target] <<..some.target..>> as target [Some

    Source] --> target @enduml Use Your Diagrams URL myDiagram = getClass().getResource("my-diagram.puml"); classes().should(adhereToPlantUmlDiagram(myDiagram, consideringAllDependencies())); Source: https://www.archunit.org/userguide/html/000_Index.html#_plantuml_component_diagrams_as_rules
  10. <groupId>org.springframework.modulith</groupId> <artifactId>spring-modulith</artifactId> <version>2.0.0-SNAPSHOT</version> <packaging>pom</packaging> <name>Spring Modulith</name> <description>Modular monoliths with Spring

    Boot</descripti <modules> <module>spring-modulith-actuator</module> <module>spring-modulith-api</module> <module>spring-modulith-apt</module> <module>spring-modulith-bom</module> <module>spring-modulith-core</module> <module>spring-modulith-docs</module> <module>spring-modulith-events</module> <module>spring-modulith-junit</module> <module>spring-modulith-moments</module> <module>spring-modulith-observability</module> <module>spring-modulith-runtime</module> <module>spring-modulith-starters</module> <module>spring-modulith-test</module> </modules> <parent> <groupId>org.springframework.modulith</groupId> <artifactId>spring-modulith</artifactId> <version>2.0.0-SNAPSHOT</version> </parent> <name>Spring Modulith - Runtime support</name> <artifactId>spring-modulith-runtime</artifactId> <dependencies> <dependency> <groupId>org.jspecify</groupId> <artifactId>jspecify</artifactId> </dependency> <dependency> <groupId>org.springframework.modulith</groupId> <artifactId>spring-modulith-core</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>com.tngtech.archunit</groupId> <artifactId>archunit</artifactId> <version>${archunit.version}</version> </dependency> Architectural support right in your build tool
  11. Example: Security • Approach: Role-based access control with Spring Security

    • Fitness Function: classes() .that().resideInAPackage("..admin..") .and().areAnnotatedWith(Service.class) .should().beAnnotatedWith(RequiresAdminRole.class)
  12. Example: Traceability • Scenario: User changes data. It is traceable

    when, by whom, and which data was changed. • Approaches: • Logging in services • Hibernate Envers for auditing • Fitness Function: classes() .that().areAnnotatedWith(Service.class) .should(log())
  13. Real Word Example: Document Generator Functional: • Multiple input/output channels

    • Programmable document individualization Non-functional: • Preview PDF visible <1s • Paper in printer <3s • Up to 500,000 documents in 24h • …
  14. Example: Performance • Scenario: Data to be printed are available

    → paper is in the printer within 3 seconds. • Fitness Function: • Collect end-to-end duration from test & production environments • Calculate average • Pass if <3s • Fail if consistently >3s
  15. Example: Maintainability • Scenario: A user story can be implemented

    within a single sprint. • Fitness Functions: • Track lead time from In Progress → Done in Jira • Analyze cycle times across stories • Checks median story lead time ≤ sprint length
  16. Fitness Functions … 1. check if the implementation fits the

    designed architecture Did we build the system right? 2. check if the implementation (and thus the architecture) fits the non-functional requirements Did we build the right system?
  17. Architecture in a Nutshell • What is the requirement? •

    How can we measure whether the requirement is fulfilled? • What is our solution strategy for fulfilling the requirement?
  18. Architecture as Code • What is the requirement? • How

    can we measure whether the requirement is fulfilled? • What is our solution strategy for fulfilling the requirement? • Automatically check whether the solution strategy is implemented consistently. • Automatically check whether the requirement is fulfilled.
  19. Architecture as Code in Practice Slides speakerdeck.com/rweisleder More https://www.thoughtworks.com/insights/podcasts/technology-podcasts/architecture-as-code https://www.thoughtworks.com/en-de/insights/articles/fitness-function-driven-development

    https://www.workingsoftware.dev/the-ultimate-guide-to-write-non-functional-requirements/ [email protected] in/roland-weisleder @rweisleder.de arcNdev Need help with your Legacy System? Let´s connect!