$30 off During Our Annual Pro Sale. View Details »

Enabling DevOps and Team Topologies Through Arc...

Enabling DevOps and Team Topologies Through Architecture: Architecting for Fast Flow

In order to thrive in today’s volatile and uncertain world, businesses needs to innovate at a much faster pace. Recognizing this, IT organizations are adopting the principles and practices of DevOps and the organizational patterns defined by Team Topologies. But while DevOps and Team topologies are vital for delivering the fast flow of changes that today’s businesses need, they are insufficient. To prevent applications from becoming obstacles to rapid change, IT must also create architectures that support fast flow.

In this presentation, I describe a collection of architectural patterns that enable DevOps and Team Topologies to deliver a fast flow of changes. You will learn about how to decide between the monolithic and microservice architecture. I’ll discuss patterns for designing a monolithic architecture that minimize the various kinds of coupling that inhibit fast flow. You will learn how to design an architecture that enables your organization to thrive in today’s uncertain world.

Chris Richardson

November 14, 2024
Tweet

More Decks by Chris Richardson

Other Decks in Programming

Transcript

  1. @crichardson Enabling DevOps and Team Topologies thru architecture: architecting for

    fast fl ow Chris Richardson Founder of Eventuate.io Founder of the original CloudFoundry.com Author of POJOs in Action and Microservices Patterns @crichardson [email protected] adopt.microservices.io Copyright © 2024. Chris Richardson Consulting, Inc. All rights reserved
  2. @crichardson Agenda Introduction to fast fl ow, DevOps and Team

    Topologies Architecting for fast fl ow Architectural styles for fast fl ow About modular monoliths Designing a microservice architecture
  3. @crichardson Traditional software delivery, especially outsourced IT projects Changes Feedback

    Long Infrequent Occasional e.g. every 1 or 2 years Development Production Feedback Users
  4. @crichardson Volatile Uncertain Complex Ambiguous Building complex applications Often using

    new, unfamiliar technologies + Slow feedback loops = Build the wrong application, the wrong way
  5. @crichardson Fast fl ow for business succe$$ Development Production Continuous

    stream of small changes, many times a day Continuous feedback and learning https://www.mckinsey.com/industries/technology-media-and-telecommunications/our-insights/developer-velocity-how-software-excellence-fuels-business-performance Users
  6. @crichardson O VID -19 https://www.ft.com/content/f9356bdc-3102-11ea-a329-0bcf87a328f2 https://www.ft.com/content/3f498e64-1aa6-11ea-97df-cc63de1d73f4 https://techcrunch.com/2019/06/18/the-rise-of-the-gig-economy-helps-london-based-insurtech-zego-to-raise-42m/ The success triangle

    Process: DevOps/Continuous Delivery & Deployment Organization: Network of small, loosely coupled, product teams IT must continuously deliver a stream of small changes to customers Businesses must be nimble, agile and innovate faster S/W VUCA Architecture: ??? Enables Enables
  7. About DevOps Set of principles and practices where developers, testers

    (dev) and IT operations (ops) collaborate and communicate to deliver software rapidly, frequently, and reliably http://itrevolution.com/devops-handbook Three ways Flow Feedback Learning
  8. @crichardson Have a fast deployment pipeline Production Fast, automated deployment

    pipeline Developer laptop Application repository 15 minutes Must scale to support rate of Git pushes Measure using the DORA metrics https://dora.dev/ >= 1 push / developer / day
  9. About Team Topologies: organizing for fast fl ow https://teamtopologies.com/key-concepts Stream-aligned

    team, e.g. Order Management Team Requirements Develop Test Deploy Code in production Work High trust/psychological safety: Small 5-9 people, long lived Stream-aligned team Platform team Facilitating Collaboration Sometimes Sometimes Enabling Team Platform team API Tools Complicated Subsystem team Stream-aligned team API XaaS Mostly
  10. @crichardson Agenda Introduction to fast fl ow, DevOps and Team

    Topologies Architecting for fast fl ow Architectural styles for fast fl ow About modular monoliths Designing a microservice architecture
  11. @crichardson About software architecture “The software architecture of a computing

    system is the set of structures needed to reason about the system, which comprise software elements, relations among them, and properties of both.” Documenting Software Architectures, Bass et al Development • Maintainability • Testability • Deployability • … Non-functional requirements Runtime • Scalability • Performance • Availability • … Satis fi es Architecture Focus
  12. @crichardson Architectural requirement: loose design-time coupling Order Management Customer Management

    Owns Owns Unaffected by changes to the other Conway’s law Autonomous Loosely coupled Degree of design-time coupling = probability of lockstep changes
  13. @crichardson Software elements should be like icebergs* Implementation Small and

    stable Larger and unstable * Modules should be deep - J. Ousterhout. A Philosophy of Software Design
  14. @crichardson Architectural requirement: testable Production Automated deployment pipeline (Build, test

    and deploy) Must be fast running Must be testable using automated tests deployment Must be locally testable commit Handle >= 1 push / developer / day Edit Build Test
  15. @crichardson Architectural requirement: deployable Handle >= 1 push / developer

    / day Automated Fast Reliable Incremental Undoable Production Automated deployment pipeline (Build, test and deploy) deployment commit
  16. @crichardson Agenda Introduction to fast fl ow, DevOps and Team

    Topologies Architecting for fast fl ow Architectural styles for fast fl ow About modular monoliths Designing a microservice architecture
  17. @crichardson Teams develop loosely design- time coupled subdomains… Team-sized slice

    of business functionality Necessary for fast fl ow BUT insuf fi cient
  18. @crichardson … but architecture is multi-dimensional https://microservices.io/post/architecture/2024/04/14/architecture-is-multi-dimensional.html • Loose design-time

    coupling • Testable • Deployable Determines: Domain «Service» Order Management «Service» Consumer Management «Service» Credit Card Payments «Service» Restaurant Management «Service» Accounting «Service» Kitchen Management «Service» Service «Database» Database Uses API Legend Part-of «Service» API Gateway «async» «subscribes to» «async» «async» «async» «async» «sync» «sync» «sync» «sync» «sync» Scenarios Domain «Service» Order Management «Service» Consumer Management «Service» Credit Card Payments «Service» Restaurant Management «Service» Accounting «Service» Kitchen Management «Service» Service «Database» Database Uses API Legend Part-of «Service» API Gateway «async» «subscribes to» «async» «async» «async» «async» «sync» «sync» «sync» «sync» «sync» Component Repository & Pipeline 3 AZ EKS cluster Ingress managed ALB 3 AZ RDS Aurora React application static resources S3 bucket api.app.acme.com app.acme.com Browser Cloudfront <<service>> Order management API Gateway Managed Apache Kafka React SPA CircleCI deployment pipeline «AWS ECR repository» ftgo-XYZ-service «Github Repository» ftgo/ftgo-XYZ-service Commit Push Image «Github Repository» Kubernetes YAML Kubernetes API EKS cluster Commit Deployment Scenarios
  19. @crichardson Component Component Component view: organizes subdomains into components Subdomain

    Executable/deployable unit, e.g. executable JAR • Loose design-time coupling • Testable • Deployable Determines:
  20. @crichardson Repository and Pipeline view: source code => components •

    Testable • Deployable Component Git Repository Build project Subdomain Deployment pipeline Determines: Component Component
  21. @crichardson Runtime (monitoring and management) infrastructure Component Instance (Process) Deployment

    view: de fi nes runtime infrastructure • Deployable Component Instance (Process) Component Determines:
  22. @crichardson Simple yet risk of outgrowing architecture Loose design- time

    coupling Single component => any coupling is internal ✅ Testable • Test execution time ∝size of code base • Commit frequency ∝organization size => bottleneck • Too complex to test locally ✅→❌ Deployable • Commit frequency ∝organization size => bottleneck? ✅→❌
  23. @crichardson Microservice architecture: two or more components Production Deployment pipeline

    Service Repo Deployment pipeline Service Repo Deployment pipeline Service Repo Independently deployable Loosely coupled Svc Svc Svc Some system operations span multiple services
  24. @crichardson Enables large scale development BUT more complicated* distributed architecture

    Loose design-time coupling ✅ BUT careful design required to ensure services are loosely design-time coupled Testable ✅ • Smaller components => faster test execution + test locally • Multiple deployment pipelines => fast feedback Deployable ✅ • Multiple deployment pipelines => concurrent, fast deployments * Eventual consistency, consequences of inter-service communication
  25. @crichardson Selecting an architectural style What’s the architecture style? Application

    size/complexity + Organization size Fast fl ow architecture • Loosely coupled • Testable • Deployable
  26. @crichardson Agenda Introduction to fast fl ow, DevOps and Team

    Topologies Architecting for fast fl ow Architectural styles for fast fl ow About modular monoliths Designing a microservice architecture
  27. @crichardson Teams Code repository Designing a monolith: key goals Large

    monolith Production Deployment pipeline App Maximize team autonomy Minimizing build times
  28. @crichardson Monolithic architecture patterns The Monolithic Architecture Pattern Language Monolithic

    architecture Layered monolith Modular monolith API project Segregated implementation projects Segregated API projects Motivating Pattern Solution Pattern Solution A Solution B General Specific
  29. @crichardson Pattern: Traditional layered monolith Application «layer» Web «layer» Domain

    «layer» Persistance/infrastructure Organized around technical layers Consumer team Order team Delivery team DevOps (Stream-aligned) team Consumers Orders Deliveries … Consumers Orders Deliveries … Consumers Orders Deliveries … $ mkdir web $ mkdir domain $ mkdir infrastructure Low autonomy ❌ Poor encapsulation ❌ Long builds ❌
  30. @crichardson Pattern: modular monolith «Module» Main System operations: createOrder() cancelOrder()

    findOrderHistory() createConsumer() «Module» Consumer Management «Subdomain» Consumer Management «Aggregate» Consumer «Module» Delivery Management «Subdomain» Delivery Management «Aggregate» Delivery «Aggregate» Courier Consumer team Order team Delivery team Owns Owns Owns «Module» Order Management «Subdomain» Order Management «Aggregate» Order DevOps (Stream-aligned) team Application Owned by all teams Organized around subdomains rather than technology $ mkdir orders $ mkdir consumers $ mkdir deliveries High autonomy ✅ Subdomain
  31. @crichardson About domain modules «package» com.acme.application «domain module» «package» consumers

    «domain module» «package» orders «domain module» «package» deliveries «package» web «package» domain «package» infrastructure «package» web «package» domain «package» infrastructure «package» web «package» domain «package» infrastructure Top-level package Vertical slice
  32. @crichardson Domain module has a facade- style API • Iceberg

    like • Good encapsulation ✅ • Mockable No inter-domain module aggregate references
  33. Prefer private domain module DB schema Essential for loose design-

    time coupling Violate encapsulation at your peril But be pragmatic: cross- domain module SQL - sometimes simple, ef fi cient, … Database Server «Module» Order Management «Table» Order «Table» OrderLineItem Order Management tables Order Management tables «Module» Customer Management Customer Management tables «Table» Customer «FK» API API-based collaboration X
  34. Minimizing build-time coupling to accelerate builds… Software element X is

    build- time coupled to software element Y if it must be rebuilt (i.e. tested) whenever Y changes Exists within components but not between components Less build-time coupling = fast builds X Y Build-time coupling Retest Change
  35. … Minimizing build-time coupling to accelerate builds Gradle project structure

    determines build-time coupling Project is graph of inter-dependent sub- projects Build is graph of inter-dependent tasks Incremental task execution => rerun task only if inputs or outputs have changed Test task is re-executed when the following change: Project’s classes Project’s transitive (test classpath) dependencies Project X Project Y Test Task Project Z classpath Project … Main classes Test classes Minimize to reduce build- time coupling
  36. Pattern: Domain API sub- project Clients only depend on API

    project Test clients using a mock API Less build-time coupling ✅ «Gradle project» Customer API «Gradle project» Client «Gradle project» Customer Domain Split «Facade» CustomerService «Facade» CustomerServiceImpl «DTO» CustomerInfo ClientTest Tests Mocks createCustomer() getCustomer() reserveCredit() releaseCredit() «Service» Customer ServiceClient «Gradle project» Customer Domain «Facade» CustomerServiceImpl «DTO» CustomerInfo «Facade» CustomerService createCustomer() getCustomer() reserveCredit() releaseCredit()
  37. Pattern: Segregated API projects Apply Interface Segregation Principle De fi

    ne multiple API (Gradle) sub-projects Clients are build-time coupled to only what they need Customer API Credit Management API Customer Implementation Client A Client B
  38. Pattern: Segregated implementation projects De fi ne a (Gradle) sub-project

    for the domain and each adapter Adapters are only build-time coupled the domain - not to each other Customer Web Customer Infrastructure Customer Domain
  39. Key limitation: Single technology stack Tight design-time coupling e.g. single

    classpath = one version of a dependency Risk of change requiring new/upgraded dependency that requires other teams to change their code Upgrades are application-wide Prevents use of other technologies «Module» Main System operations: createOrder() cancelOrder() findOrderHistory() createConsumer() «Module» Consumer Management «Subdomain» Consumer Management «Aggregate» Consumer «Module» Delivery Management «Subdomain» Delivery Management «Aggregate» Delivery «Aggregate» Courier Consumer team Order team Delivery team Owns Owns Owns «Module» Order Management «Subdomain» Order Management «Aggregate» Order DevOps (Stream-aligned) team Application Owned by all teams Organized around subdomains rather than technology Tech stack • Global dependency • Owned by all teams
  40. @crichardson Key limitation: single deployment pipeline becomes a bottleneck Deployment

    pipeline Queued changes = slow feedback Batched changes = dif fi cult troubleshooting Slow build Change to widely used API or library Volume of changes
  41. @crichardson Agenda Introduction to fast fl ow, DevOps and Team

    Topologies Architecting for fast fl ow Architectural styles for fast fl ow About modular monoliths Designing a microservice architecture
  42. @crichardson Designing a microservice architecture: key challenge Designing services that

    loosely coupled and independently deployable WHILE Avoiding problems of a distributed architecture (aka. Dark matter forces)
  43. Rule #6: Design loosely (design-time*) coupled services * vs runtime

    and build-time coupling https://microservices.io/post/architecture/2023/03/28/microservice-architecture-essentials-loose-coupling.html Customer Service Customer Subdomain Order Service Order Subdomain API Stable Infrequent lock step changes
  44. @crichardson Rule #7: design independently deployable services https://microservices.io/post/architecture/2022/05/04/microservice-architecture-essentials-deployability.html Production Order

    Service Order Service Deployment pipeline Test in isolation Test Service Test Double Service Sole criteria for release Includes contract- testing to enforce API interoperability Deploy automatically
  45. @crichardson Avoid the Distributed monolith anti-pattern: Tightly design-time coupled services

    End-to-end testing before release Friction of the monolith + complexity of microservices
  46. @crichardson Microservice architecture = not only services AND Application «Subdomain»

    Consumer Management «Aggregate» Consumer «Subdomain» Delivery Management «Aggregate» Delivery «Aggregate» Courier Consumer team Order team Delivery team Owns Owns Owns Order Service «Subdomain» Order Management «Aggregate» Order Delivery Service Consumer Service API Gateway DevOps (Stream-aligned) team «Subdomain» Money «Value object» Money «Subdomain» Money «Value object» Money Consumer Service API Gateway createConsumer() Operations Local Distributed Services Process/transaction boundary Process/transaction boundary API Gateway Consumer Service createOrder() Order Service createOrder() reserveCredit() Spans
  47. Distributed operation design criteria Simplicity - maintainability (ease of understanding

    and development) Ef fi ciency - performance Runtime coupling - availability, latency Prefer ACID over BASE - maintainability https://microservices.io/post/architecture/2023/03/26/dark-energy-dark-matter-force-descriptions.html https://microservices.io/post/patterns/2023/07/29/service-collaboration-patterns.html
  48. @crichardson Designing an architecture = making trade-offs Application System operations:

    createOrder() cancelOrder() findOrderHistory() createConsumer() «Subdomain» Consumer Management «Aggregate» Consumer «Subdomain» Delivery Management «Aggregate» Delivery «Aggregate» Courier Order Service «Subdomain» Order Management «Aggregate» Order Delivery Service Consumer Service API Gateway «Subdomain» Money «Value object» Money «Subdomain» Money «Value object» Money Service design • Loose-coupling • Testability • Deployability Determines Process/transaction boundary Process/transaction boundary API Gateway Consumer Service createOrder() Order Service createOrder() reserveCredit() Operation design Determines • Simplicity • Ef fi ciency • Runtime coupling • Prefer ACID over BASE Determines Constrains Requirements for fast fl ow Con fl ict
  49. @crichardson Assemblage: design process Incrementally de fi nes One operation

    at a time https://microservices.io/post/architecture/2023/02/09/assemblage-architecture-de fi nition-process.html Subdomain A «Aggregate» X Subdomain B «Aggregate» Y Service A Service B Attraction Simple interactions Efficient interactions Prefer ACID over BASE Minimize runtime coupling Minimize design time coupling Simple components Team autonomy Fast deployment pipeline Support multiple technology stacks Segregate by characteristics Repulsion Dark energy Dark matter Metaphor for Metaphor for
  50. @crichardson Step 1: de fi ne system operations Application ≪commands≫

    createConsumer() createOrder() cancelOrder() … ≪queries≫ findOrder() findOrderHistory() … ≪entity≫ Order ≪entity≫ Customer ≪entity≫ Delivery Model application behavior Mutate and query
  51. @crichardson Step 2: design subdomains createOrder() Kitchen team Order team

    Accounting team … Implemented by Owns Owns Owns Owns
  52. @crichardson Step 3: incrementally de fi ne service architecture… How

    to implement someOperation() Work-in-progress architecture Subdomain A «Aggregate» X Subdomain B «Aggregate» Y Service A Service B Attraction Simple interactions Efficient interactions Prefer ACID over BASE Minimize runtime coupling Minimize design time coupling Simple components Team autonomy Fast deployment pipeline Support multiple technology stacks Segregate by characteristics Repulsion Dark energy Dark matter Metaphor for Metaphor for Group subdomains + Revised architecture Iterate Operation realization For each operation:
  53. @crichardson Summary Volatile Uncertain Complex Ambiguous Fast flow architecture Modular

    Monolithic architecture Microservice architecture Requires createOrder() createOrder() Subdomain A «Aggregate» X Service A Attraction Simple interactions Efficient interactions Prefer ACID over BASE Minimize runtime coupling Minimize design time coupling Simple components Team autonomy Fast deployment pipeline Support multiple technology stacks Segregate by characteristics Repulsion Dark matter Metaphor for M Creates Dark energy and dark m Is Fast flow: delivering a continuous stream of changes to customers Understand the context Define the problem Define evaluation criteria Find candidate solutions Evaluate the trade-offs Pick the best solution Document decision 1 2 3 4 5 6 7 Rational decision making Uses Architectural requirements: • Loosely coupled • Testable • Deployable • Observable Fast flow Success Triangle Assemblage Defines IS-A