archsight 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +7 -1
- data/docs/archimate.md +21 -1
- data/docs/configuration.md +1 -0
- data/docs/diagram.md +15 -3
- data/docs/docker.md +4 -1
- data/docs/icons.md +32 -0
- data/docs/import.md +178 -55
- data/docs/index.md.erb +31 -8
- data/docs/modeling.md +772 -24
- data/docs/pages.md +44 -13
- data/docs/search.md +21 -1
- data/docs/togaf.md +5 -1
- data/lib/archsight/analysis/result.rb +8 -2
- data/lib/archsight/analysis/sandbox.rb +8 -0
- data/lib/archsight/analysis/typst_renderer.rb +246 -0
- data/lib/archsight/analysis.rb +1 -0
- data/lib/archsight/annotations/annotation.rb +30 -3
- data/lib/archsight/annotations/architecture_annotations.rb +47 -0
- data/lib/archsight/annotations/asset_annotations.rb +34 -0
- data/lib/archsight/annotations/link_annotations.rb +15 -0
- data/lib/archsight/annotations/resource_reference.rb +12 -0
- data/lib/archsight/annotations/risk_annotations.rb +21 -0
- data/lib/archsight/cli.rb +124 -23
- data/lib/archsight/database.rb +40 -0
- data/lib/archsight/diagram/cli.rb +50 -2
- data/lib/archsight/diagram/formatter.rb +112 -0
- data/lib/archsight/diagram/routing/edge_router/orthogonal_path.rb +38 -10
- data/lib/archsight/diagram/routing/edge_router.rb +29 -4
- data/lib/archsight/diagram/routing/edge_routing.rb +61 -5
- data/lib/archsight/diagram/style/theme.rb +7 -2
- data/lib/archsight/documentation.rb +3 -2
- data/lib/archsight/editor/page_source.rb +13 -1
- data/lib/archsight/export/confluence/analysis_output.rb +101 -0
- data/lib/archsight/export/confluence/client.rb +13 -0
- data/lib/archsight/export/confluence/diagram_links.rb +1 -1
- data/lib/archsight/export/confluence/exporter.rb +40 -13
- data/lib/archsight/export/confluence/labels.rb +25 -0
- data/lib/archsight/export/confluence/page_properties.rb +4 -6
- data/lib/archsight/export/confluence/storage.rb +38 -2
- data/lib/archsight/helpers/embeds.rb +18 -7
- data/lib/archsight/helpers/resource_resolver.rb +25 -0
- data/lib/archsight/import/executor.rb +139 -16
- data/lib/archsight/import/handler.rb +55 -6
- data/lib/archsight/import/handler_loader.rb +64 -0
- data/lib/archsight/import/handlers/cache_pruner.rb +30 -7
- data/lib/archsight/import/handlers/command.rb +120 -0
- data/lib/archsight/import/handlers/github.rb +4 -1
- data/lib/archsight/import/handlers/gitlab.rb +4 -1
- data/lib/archsight/import/handlers/go_dep_resolver.rb +10 -2
- data/lib/archsight/import/handlers/go_grapher.rb +102 -5
- data/lib/archsight/import/handlers/go_module_parser.rb +88 -0
- data/lib/archsight/import/handlers/grapher.rb +40 -1
- data/lib/archsight/import/handlers/repository.rb +3 -0
- data/lib/archsight/import/handlers/rest_api_index.rb +3 -0
- data/lib/archsight/import/registry.rb +22 -1
- data/lib/archsight/import.rb +64 -1
- data/lib/archsight/linter/structure.rb +239 -0
- data/lib/archsight/linter.rb +217 -6
- data/lib/archsight/page_loader.rb +12 -1
- data/lib/archsight/query/evaluator.rb +13 -6
- data/lib/archsight/query/parser.rb +73 -6
- data/lib/archsight/query.rb +1 -1
- data/lib/archsight/references.rb +3 -3
- data/lib/archsight/renderer.rb +80 -23
- data/lib/archsight/resources/analysis.rb +3 -2
- data/lib/archsight/resources/application_component.rb +83 -8
- data/lib/archsight/resources/application_event.rb +79 -0
- data/lib/archsight/resources/application_service.rb +18 -2
- data/lib/archsight/resources/base.rb +58 -5
- data/lib/archsight/resources/business_actor.rb +14 -1
- data/lib/archsight/resources/business_contract.rb +72 -0
- data/lib/archsight/resources/business_control.rb +10 -2
- data/lib/archsight/resources/business_event.rb +79 -0
- data/lib/archsight/resources/business_process.rb +8 -1
- data/lib/archsight/resources/business_product.rb +12 -0
- data/lib/archsight/resources/business_role.rb +70 -0
- data/lib/archsight/resources/compliance_evidence.rb +8 -2
- data/lib/archsight/resources/data_object.rb +6 -1
- data/lib/archsight/resources/implementation_deliverable.rb +63 -0
- data/lib/archsight/resources/implementation_event.rb +52 -0
- data/lib/archsight/resources/implementation_gap.rb +49 -0
- data/lib/archsight/resources/implementation_plateau.rb +67 -0
- data/lib/archsight/resources/implementation_work_package.rb +84 -0
- data/lib/archsight/resources/import.rb +37 -11
- data/lib/archsight/resources/location.rb +56 -0
- data/lib/archsight/resources/motivation_assessment.rb +121 -0
- data/lib/archsight/resources/motivation_constraint.rb +7 -1
- data/lib/archsight/resources/motivation_driver.rb +50 -0
- data/lib/archsight/resources/motivation_goal.rb +13 -1
- data/lib/archsight/resources/motivation_principle.rb +75 -0
- data/lib/archsight/resources/motivation_requirement.rb +18 -2
- data/lib/archsight/resources/motivation_stakeholder.rb +21 -0
- data/lib/archsight/resources/page.rb +9 -7
- data/lib/archsight/resources/strategy_capability.rb +9 -0
- data/lib/archsight/resources/technology_artifact.rb +11 -4
- data/lib/archsight/resources/technology_communication_network.rb +89 -0
- data/lib/archsight/resources/technology_device.rb +88 -0
- data/lib/archsight/resources/technology_equipment.rb +75 -0
- data/lib/archsight/resources/technology_event.rb +80 -0
- data/lib/archsight/resources/technology_facility.rb +70 -0
- data/lib/archsight/resources/technology_node.rb +57 -1
- data/lib/archsight/resources/technology_service.rb +33 -0
- data/lib/archsight/resources/technology_system_software.rb +28 -0
- data/lib/archsight/resources.rb +12 -0
- data/lib/archsight/version.rb +1 -1
- data/lib/archsight/web/api/analysis_helpers.rb +55 -0
- data/lib/archsight/web/api/json_helpers.rb +3 -37
- data/lib/archsight/web/api/openapi/spec.yaml +10 -8
- data/lib/archsight/web/api/page_helpers.rb +1 -8
- data/lib/archsight/web/api/routes.rb +7 -2
- data/lib/archsight/web/application.rb +38 -2
- data/lib/archsight/web/editor/routes.rb +2 -1
- data/lib/archsight/web/public/vue/ApiDocsPage-COp4onwn.js +1 -0
- data/lib/archsight/web/public/vue/DocPage-D52OwaKc.js +1 -0
- data/lib/archsight/web/public/vue/EditorPage-3aqL7yVf.js +35 -0
- data/lib/archsight/web/public/vue/ErrorPage--b9XeSYa.js +2 -0
- data/lib/archsight/web/public/vue/GraphView-qh_EtRrQ.js +1 -0
- data/lib/archsight/web/public/vue/HomePage-C2TNh2U-.js +2 -0
- data/lib/archsight/web/public/vue/InstanceRouter-ZaCcjlIX.css +1 -0
- data/lib/archsight/web/public/vue/InstanceRouter-uzb_OMG0.js +1 -0
- data/lib/archsight/web/public/vue/KindList-CyJuP_uq.js +1 -0
- data/lib/archsight/web/public/vue/KindList-yYcRT2BV.css +1 -0
- data/lib/archsight/web/public/vue/PageView-B93woeN3.css +1 -0
- data/lib/archsight/web/public/vue/PageView-FyygrS-b.js +1 -0
- data/lib/archsight/web/public/vue/QueryError-B4Ex_csZ.js +1 -0
- data/lib/archsight/web/public/vue/ResourceList-BY6Z1Kcb.js +2 -0
- data/lib/archsight/web/public/vue/ResourceList-D75O87zG.css +1 -0
- data/lib/archsight/web/public/vue/{SearchResults-CyPUZZSC.css → SearchResults-BV6UHriJ.css} +1 -1
- data/lib/archsight/web/public/vue/SearchResults-CkFpHF8m.js +1 -0
- data/lib/archsight/web/public/vue/WikiPage-BoHNewCX.js +3 -0
- data/lib/archsight/web/public/vue/WikiPage-TpmM1VAF.css +1 -0
- data/lib/archsight/web/public/vue/architecture-7GRP2DOG-BvzKZE4e.js +1 -0
- data/lib/archsight/web/public/vue/cynefin-OW5HDTMX-D-xs_Hxh.js +1 -0
- data/lib/archsight/web/public/vue/eventmodeling-NTZA5JFV-nbjxG01S.js +1 -0
- data/lib/archsight/web/public/vue/gitGraph-4MIJSDKK-CW6mw2ab.js +1 -0
- data/lib/archsight/web/public/vue/index-BGlYCbi7.js +3 -0
- data/lib/archsight/web/public/vue/index-eUHmJ7K2.css +1 -0
- data/lib/archsight/web/public/vue/info-A6RAGUB7-C12sjlHe.js +1 -0
- data/lib/archsight/web/public/vue/{mermaid-BjEi5URd.js → mermaid-DjsXQ_XN.js} +35 -35
- data/lib/archsight/web/public/vue/packet-AYTQ26CC-wMwKwHmA.js +1 -0
- data/lib/archsight/web/public/vue/pie-WAS4IAKB-w1-sAU_K.js +1 -0
- data/lib/archsight/web/public/vue/radar-RG4KPBEZ-DpwqIFoy.js +1 -0
- data/lib/archsight/web/public/vue/railroad-74A4TZTK-Ce5XC24d.js +1 -0
- data/lib/archsight/web/public/vue/railroad-abnf-HS5TGJTU-BSQO2pds.js +1 -0
- data/lib/archsight/web/public/vue/railroad-ebnf-LZEXJU2U-Dq1c2YtD.js +1 -0
- data/lib/archsight/web/public/vue/railroad-peg-WCYAUIDC-DKj6dli0.js +1 -0
- data/lib/archsight/web/public/vue/rolldown-runtime-hePW80VL.js +1 -0
- data/lib/archsight/web/public/vue/treeView-Q6P3EWNA-BmHNTWxU.js +1 -0
- data/lib/archsight/web/public/vue/treemap-WGGIJYW6-DsEI7sSD.js +1 -0
- data/lib/archsight/web/public/vue/{useGraphviz-DweKV7Kg.js → useGraphviz-4evusK9i.js} +13 -1
- data/lib/archsight/web/public/vue/{useHighlight-D5Gf8DLl.js → useHighlight-DPguaxfm.js} +8 -8
- data/lib/archsight/web/public/vue/usePanZoom-seQE1TPk.js +12 -0
- data/lib/archsight/web/public/vue/wardley-WFR3VGLG-CSCW83-M.js +1 -0
- data/lib/archsight/web/public/vue.html +5 -5
- metadata +72 -38
- data/lib/archsight/web/public/vue/ApiDocsPage-DoOxKjG0.js +0 -1
- data/lib/archsight/web/public/vue/DocPage-CfsC3CeQ.js +0 -1
- data/lib/archsight/web/public/vue/EditorPage-CsJA0q8n.js +0 -35
- data/lib/archsight/web/public/vue/ErrorPage-OJpJz9df.js +0 -2
- data/lib/archsight/web/public/vue/GraphView-CBq6oFRV.js +0 -1
- data/lib/archsight/web/public/vue/HomePage-BwgMLgVC.js +0 -2
- data/lib/archsight/web/public/vue/InstanceRouter-DQz-SsQq.js +0 -1
- data/lib/archsight/web/public/vue/InstanceRouter-jeavM6PW.css +0 -1
- data/lib/archsight/web/public/vue/KindList-4q0K9Cll.js +0 -1
- data/lib/archsight/web/public/vue/PageView-DzeGnvoS.js +0 -1
- data/lib/archsight/web/public/vue/QueryError-kg6Yf-pW.js +0 -1
- data/lib/archsight/web/public/vue/ResourceList-B0FLaFR3.css +0 -1
- data/lib/archsight/web/public/vue/ResourceList-Df_0e0qt.js +0 -2
- data/lib/archsight/web/public/vue/SearchResults-CKgY6_wH.js +0 -1
- data/lib/archsight/web/public/vue/WikiPage-DoFJ0dbW.css +0 -1
- data/lib/archsight/web/public/vue/WikiPage-DrvCHwJ7.js +0 -13
- data/lib/archsight/web/public/vue/architecture-7GRP2DOG-BfA1TPxQ.js +0 -1
- data/lib/archsight/web/public/vue/cynefin-OW5HDTMX-BmgdUKVD.js +0 -1
- data/lib/archsight/web/public/vue/eventmodeling-NTZA5JFV-DbXDvAWF.js +0 -1
- data/lib/archsight/web/public/vue/gitGraph-4MIJSDKK-BkVhrKS1.js +0 -1
- data/lib/archsight/web/public/vue/index-D0Q5GZRs.js +0 -3
- data/lib/archsight/web/public/vue/index-oF-iyZvk.css +0 -1
- data/lib/archsight/web/public/vue/info-A6RAGUB7-BIlCVuUY.js +0 -1
- data/lib/archsight/web/public/vue/packet-AYTQ26CC-eoQTjY3j.js +0 -1
- data/lib/archsight/web/public/vue/pie-WAS4IAKB-DEOotGhh.js +0 -1
- data/lib/archsight/web/public/vue/radar-RG4KPBEZ-C2yucuUN.js +0 -1
- data/lib/archsight/web/public/vue/railroad-74A4TZTK-CzONK5VY.js +0 -1
- data/lib/archsight/web/public/vue/railroad-abnf-HS5TGJTU-9zRPsDsx.js +0 -1
- data/lib/archsight/web/public/vue/railroad-ebnf-LZEXJU2U-BJ4dkz9l.js +0 -1
- data/lib/archsight/web/public/vue/railroad-peg-WCYAUIDC-DFy_rqAj.js +0 -1
- data/lib/archsight/web/public/vue/treeView-Q6P3EWNA-2cq5CyD2.js +0 -1
- data/lib/archsight/web/public/vue/treemap-WGGIJYW6-DK-e9Ez4.js +0 -1
- data/lib/archsight/web/public/vue/wardley-WFR3VGLG-BQwqUqfB.js +0 -1
data/docs/modeling.md
CHANGED
|
@@ -7,17 +7,327 @@ This guide explains how to model your architecture using ArchiMate concepts and
|
|
|
7
7
|
Architecture modeling follows a layered approach, from business motivation down to technical implementation:
|
|
8
8
|
|
|
9
9
|
```
|
|
10
|
-
Motivation Layer
|
|
10
|
+
Motivation Layer Why we do things (goals, stakeholders, requirements, risks, policies)
|
|
11
11
|
|
|
|
12
|
-
Strategy Layer
|
|
12
|
+
Strategy Layer What capabilities we need
|
|
13
13
|
|
|
|
14
|
-
|
|
14
|
+
Implementation & Migration How the change happens (work packages, plateaus, gaps)
|
|
15
15
|
|
|
|
16
|
-
|
|
16
|
+
Business Layer How business operates (processes, actors, products)
|
|
17
17
|
|
|
|
18
|
-
|
|
18
|
+
Application Layer What software supports the business
|
|
19
|
+
|
|
|
20
|
+
Technology Layer How software is built and deployed, and where it runs (facilities, equipment, networks)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The sidebar, the search facets, the metamodel diagram and these guides list the layers in this order, top to bottom;
|
|
24
|
+
the tool's own kinds (pages, views, imports, analyses) come last under "Other".
|
|
25
|
+
|
|
26
|
+
## Direction of Relations
|
|
27
|
+
|
|
28
|
+
Model and read the architecture **top-down**: Motivation, Strategy, Business, Application, Technology; the
|
|
29
|
+
Implementation & Migration layer describes change across all of them. A relation is written on an element and points
|
|
30
|
+
to what that element depends on, is served by, or is answered by. Following relations from a high-level element
|
|
31
|
+
therefore walks down to people, code and infrastructure, and the relations form a DAG: nothing may lead back to where
|
|
32
|
+
it started. `archsight lint` reports every cycle (only `dependsOn` is exempt, because components and services may depend on each
|
|
33
|
+
other at runtime, and `connectedTo`, because cables between devices run both ways). `specializes`, `composedOf` and `aggregates` are checked per verb, see "Concept and Implementation" and "Deployment".
|
|
34
|
+
|
|
35
|
+
There are two families of verbs:
|
|
36
|
+
|
|
37
|
+
| Family | Verbs | Written on | Points to |
|
|
38
|
+
|--------|-------|------------|-----------|
|
|
39
|
+
| Responsibility and provider (down) | `performedBy`, `ownedBy`, `executedBy`, `servedBy`, `guidedBy`, `maintainedBy`, `contributedBy`, `hasConcern`, `representedBy`, `realizedThrough`, `exposes`, `connects`, `mitigatedBy`, `influences`, `triggers`, `affects`, `assesses`, `contains`, `closedBy`, `compares` | the element that needs, uses or is concerned with something | what provides it or is responsible for it |
|
|
40
|
+
| Realization (up) | `realizes`, `partiallyRealizes`, `plans`, `satisfies`, `evidencedBy` (on the evidenced element), `provides` | the concrete element | the abstract element it answers to (requirement, goal, capability, plateau) |
|
|
41
|
+
|
|
42
|
+
Rules:
|
|
43
|
+
|
|
44
|
+
- A pair of kinds never has the same relation in both directions: a goal `realizes` a requirement, a requirement does not
|
|
45
|
+
`realize` a goal. Reverse relations are shown for free as incoming relations.
|
|
46
|
+
- Responsibility ends at the actor: process, control, risk, policy, work package point to a `BusinessRole`, the role
|
|
47
|
+
points to the `BusinessActor` that holds it, and the actor points to nothing further.
|
|
48
|
+
- The docs draw realization chains top-down ("Requirement, down to Service") while the data is stored on the concrete
|
|
49
|
+
element, so the file of a service says what it realizes.
|
|
50
|
+
- `mentions` and `depicts` are not part of this structure. They are derived from the text and diagrams of a resource
|
|
51
|
+
(never written in a file) and show how things are linked sideways, in prose and pictures. They neither follow nor
|
|
52
|
+
contradict the direction above and are left out of the cycle check.
|
|
53
|
+
|
|
54
|
+
## Choosing the Kind
|
|
55
|
+
|
|
56
|
+
Four kinds carry most of a model: StrategyCapability, BusinessProduct, ApplicationService and ApplicationComponent.
|
|
57
|
+
Each answers one question. The test decides the kind, not the name.
|
|
58
|
+
|
|
59
|
+
| Kind | Question | Test | Name |
|
|
60
|
+
|------|----------|------|------|
|
|
61
|
+
| StrategyCapability | What must the organization be *able* to do? | Survives swapping product, team and technology; not a certificate or quality | ability noun phrase ("Payment Processing"), never a product, team or technology |
|
|
62
|
+
| BusinessProduct | What does a customer buy or contract? | Appears on a price list, catalog or customer documentation | market name ("Online Checkout") |
|
|
63
|
+
| ApplicationService | What behaviour does software offer a consumer? | Describable without naming repos, deployments or runtime objects; one owning actor | the function, not the technology or deployment object ("Payment Authorization") |
|
|
64
|
+
| ApplicationComponent | What is built, deployed and versioned? | Has artifacts and a `component/type`; can be deployed or linked | the part, by runtime role (API, Operator, Worker), not by repo category ("Payments:API") |
|
|
65
|
+
|
|
66
|
+
**Decision questions**, asked in order for any new element:
|
|
67
|
+
|
|
68
|
+
1. Is it something the organization must be able to do, whoever or whatever does it? Capability.
|
|
69
|
+
2. Is it something a customer selects, buys or signs a contract for? Product. The contract itself (framework, call-off,
|
|
70
|
+
SLA, amendment) is a `BusinessContract` the product aggregates, not a DataObject and not text in a description.
|
|
71
|
+
3. Is it a function another system or a user calls or consumes, nameable without saying how it is built? Service.
|
|
72
|
+
4. Is it something that is built, versioned and deployed or linked? Component.
|
|
73
|
+
5. Is it a repository, package, image or binary? Artifact.
|
|
74
|
+
6. Is it a proof, rule or obligation (certificate, regulation, policy)? Motivation or Compliance, not one of the above.
|
|
75
|
+
7. Is it another name or id of something already modeled? `architecture/aliases` or `link/*` on that element, not a
|
|
76
|
+
new element.
|
|
77
|
+
8. Does the same name already exist as a different kind? Check whether the two are really different. If they are not,
|
|
78
|
+
keep the element at the highest level where the test holds and link the others to it.
|
|
79
|
+
|
|
80
|
+
**Rules**
|
|
81
|
+
|
|
82
|
+
1. One path up: Product `realizes` Capability, Product `servedBy` Service, Service `realizedThrough` Component,
|
|
83
|
+
Component `realizedThrough` Artifact. Capability `servedBy` Service only for internal capabilities that no product
|
|
84
|
+
carries.
|
|
85
|
+
2. A component belongs to exactly one service; one service using another is `dependsOn` between the services (see
|
|
86
|
+
[Service Chain](#service-chain)), not the same component listed twice.
|
|
87
|
+
3. An artifact is realized by exactly one component. When one repository holds several finer components (a monorepo),
|
|
88
|
+
the larger logical component (`component/type: module`) is realized by the artifact and the finer components
|
|
89
|
+
`dependsOn` it; the services use the finer components, and their rollups still reach the repository.
|
|
90
|
+
4. A service whose only component has the same name is a smell: name the service by its function, or fold it into the
|
|
91
|
+
service it belongs to.
|
|
92
|
+
5. Test, tooling and infrastructure-as-code repositories are not components of their own. They go on the component
|
|
93
|
+
they build, test or deploy.
|
|
94
|
+
6. A product served by nearly every service is a catalog, not a product. A service that serves many products is a
|
|
95
|
+
shared service and is modeled once.
|
|
96
|
+
7. Certifications and regulations are Motivation (requirement or constraint) with Compliance evidence, not
|
|
97
|
+
capabilities.
|
|
98
|
+
8. Other identifiers of an element (register ids, wiki or ticket pages) are `architecture/aliases` and `link/*` on the
|
|
99
|
+
element itself, never a parallel element.
|
|
100
|
+
|
|
101
|
+
**Checked by `archsight lint`**
|
|
102
|
+
|
|
103
|
+
Rules 1 to 4 are checked on every `archsight lint` run and reported as **warnings** (section "Modeling warnings"),
|
|
104
|
+
never as errors, so they do not make the lint fail: they point at decisions to review and have legitimate exceptions,
|
|
105
|
+
such as an internal service or a capability that no product carries yet.
|
|
106
|
+
|
|
107
|
+
| Warning | Rule |
|
|
108
|
+
|---------|------|
|
|
109
|
+
| `ApplicationComponent 'Payments:API' is realized by 2 services: 'Payment Authorization', 'Refunds'` | 2 |
|
|
110
|
+
| `TechnologyArtifact 'Repo:payments-api' is realized by 2 components: ...` | 3 |
|
|
111
|
+
| `ApplicationService 'Billing' has one component with the same name` | 4 |
|
|
112
|
+
| `BusinessProduct 'Online Checkout' is served by no ApplicationService` | 1 |
|
|
113
|
+
| `ApplicationService 'Ledger' is not served to any product or process` | 1 |
|
|
114
|
+
| `StrategyCapability 'Payment Processing' is realized by no product` | 1 |
|
|
115
|
+
| `ApplicationComponent 'alice:shop' is generated from 2 repositories with the same module path: ...` | import, see [Classifying components](#classifying-components) |
|
|
116
|
+
|
|
117
|
+
A service counts as served when a product or a process is `servedBy` it, directly or through other services that
|
|
118
|
+
`dependsOn` it. Each finding starts with the file and line of the resource, like the errors.
|
|
119
|
+
|
|
120
|
+
**Example chain**
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
StrategyCapability "Payment Processing"
|
|
124
|
+
↑ realizes
|
|
125
|
+
BusinessProduct "Online Checkout"
|
|
126
|
+
↓ servedBy
|
|
127
|
+
ApplicationService "Payment Authorization"
|
|
128
|
+
↓ realizedThrough
|
|
129
|
+
ApplicationComponent "Payments:API"
|
|
130
|
+
↓ realizedThrough
|
|
131
|
+
TechnologyArtifact "Repo:payments-api"
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The chain is part of `examples/archsight` (`strategy/`, `business/`, `services/`, `components/`, `technology/`).
|
|
135
|
+
|
|
136
|
+
**Anti-patterns**
|
|
137
|
+
|
|
138
|
+
| Anti-pattern | Fix |
|
|
139
|
+
|--------------|-----|
|
|
140
|
+
| A service named after a deployment object (ingress route, Helm release, admin endpoint) | Name it by the function it offers; the deployment object is part of the component or artifact |
|
|
141
|
+
| Components named after repo categories ("Testing", "Tools", "Infrastructure") | Name components by runtime role; put test, tooling and infrastructure repositories on the component they belong to |
|
|
142
|
+
| A catalog product that everything serves | Model the products customers really buy; the catalog is a view or page |
|
|
143
|
+
| A certificate modeled as a capability | Requirement or constraint with Compliance evidence |
|
|
144
|
+
| A parallel set of services that re-groups the same components for an inventory or register | `architecture/aliases` and `link/*` on the real service |
|
|
145
|
+
|
|
146
|
+
## Choosing the Kind: Infrastructure
|
|
147
|
+
|
|
148
|
+
Infrastructure is modeled in five tiers: **where** (Location, TechnologyFacility), **physical** (TechnologyEquipment),
|
|
149
|
+
**device** (TechnologyDevice), **network** (TechnologyCommunicationNetwork) and **compute** (TechnologyNode,
|
|
150
|
+
TechnologySystemSoftware, TechnologyService, TechnologyArtifact). The same principle holds as above: the test decides the kind, not the name.
|
|
151
|
+
|
|
152
|
+
| Kind | Question | Test | Name |
|
|
153
|
+
|------|----------|------|------|
|
|
154
|
+
| Location | In which region or country is it? | A place on a map, not a building; holds facilities | the place ("Location:Germany:Frankfurt") |
|
|
155
|
+
| TechnologyFacility | In which building or site does hardware stand? | Has an address and can be visited; can be nested (campus, hall) | the site ("Facility:Frankfurt:HallA") |
|
|
156
|
+
| TechnologyEquipment | Which physical thing can you touch? | Racks, fabrics, fibre routes, carrier circuits; no software of its own | the thing and its place ("Equipment:Link:Frankfurt-Madrid") |
|
|
157
|
+
| TechnologyDevice | Which single machine stands in the room? | One server, switch, router, firewall or appliance with a serial number; it is cabled | the host ("Device:Frankfurt:Server01") |
|
|
158
|
+
| TechnologyCommunicationNetwork | What carries data between nodes? | Has a network role (`network/type`); exists beyond any single link | role and scope ("Network:Management:Frankfurt") |
|
|
159
|
+
| TechnologyNode | On which machine does software run? | A VM, host role or logical group of machines with a lifecycle of its own | the host or host role ("Node:Frankfurt:Web01") |
|
|
160
|
+
| TechnologySystemSoftware | What software hosts other software or data? | An operating system, database cluster, routing stack, platform | the product and role ("Tech:Routing:EVPN") |
|
|
161
|
+
| TechnologyService | What does infrastructure offer to its consumers? | Consumed without knowing which nodes run it | the offering ("Network:Backbone", "Postgres") |
|
|
162
|
+
| TechnologyArtifact | Which file is built and deployed? | A repository, image, package or binary | the artifact ("Repo:payments-api") |
|
|
163
|
+
|
|
164
|
+
**Decision questions**, asked in order for any new infrastructure element:
|
|
165
|
+
|
|
166
|
+
1. Is it a country, metro or region? Location.
|
|
167
|
+
2. Is it a building, campus, hall or site that can be visited? TechnologyFacility.
|
|
168
|
+
3. Is it a physical thing (rack, switch fabric, fibre, circuit) without software of its own? TechnologyEquipment.
|
|
169
|
+
4. Is it one physical machine (server, switch, router, firewall, appliance) whose room or cabling matters?
|
|
170
|
+
TechnologyDevice.
|
|
171
|
+
5. Does it carry data between nodes, with a role such as underlay, overlay, management, public or VPN?
|
|
172
|
+
TechnologyCommunicationNetwork.
|
|
173
|
+
6. Is it a machine (virtual, or a host role) that software runs on? TechnologyNode.
|
|
174
|
+
7. Is it software that hosts other software, data or traffic? TechnologySystemSoftware.
|
|
175
|
+
8. Is it something consumed by others without them knowing how it is run? TechnologyService.
|
|
176
|
+
9. Is it a file that is built and deployed? TechnologyArtifact.
|
|
177
|
+
|
|
178
|
+
**Rules**
|
|
179
|
+
|
|
180
|
+
1. One element per thing, many `locatedAt`: a service, network or cluster that runs in three data centers is one
|
|
181
|
+
element with three relations, never a copy per site.
|
|
182
|
+
2. A link between sites is one TechnologyEquipment (`equipment/type: link`) `locatedAt` exactly its two facilities. A backbone
|
|
183
|
+
is TechnologyEquipment `composedOf` its links.
|
|
184
|
+
3. Physical before logical: a network is `realizedBy` the TechnologyEquipment it runs over and the system software that
|
|
185
|
+
implements it; an overlay or VPN is `servedBy` the network it runs over.
|
|
186
|
+
4. No element per tenant or customer network: the overlay is one network, its tenants are instances of it.
|
|
187
|
+
5. A mesh is `network/topology: mesh` on one network, not an element per pair of sites. Single tunnels are
|
|
188
|
+
sub-networks only when they have their own owner or capacity.
|
|
189
|
+
6. Concept and implementation with `specializes` (management network → management network of one site), structure
|
|
190
|
+
with `composedOf` (metro network → site networks, campus → halls, backbone → links).
|
|
191
|
+
7. A network that supports a metro region is `locatedAt` the Location and `composedOf` the networks of its sites.
|
|
192
|
+
8. Nodes attach to networks with `servedBy` and stand in facilities with `locatedAt`.
|
|
193
|
+
9. An overlay that software builds (an SDN agent wiring tenant networks on each host, an operator creating VXLAN
|
|
194
|
+
segments, a load-balancer controller announcing public addresses) is `realizedBy` that `ApplicationComponent` or
|
|
195
|
+
`ApplicationService` (ArchiMate cross-layer realization). This holds even when the software runs on the nodes the
|
|
196
|
+
network serves: point at the application component, not at the node's system software, which would close a cycle
|
|
197
|
+
(network → system software → node → network).
|
|
198
|
+
10. One `TechnologyDevice` per physical machine, `locatedAt` its room (a TechnologyFacility of `facility/type: room`
|
|
199
|
+
the data center is `composedOf`). A group of machines with one role stays a logical `TechnologyNode` that is
|
|
200
|
+
`realizedBy` its devices; a rack or hardware block is TechnologyEquipment `composedOf` them; a virtual chassis or
|
|
201
|
+
stack is a device `composedOf` its members.
|
|
202
|
+
11. A network is `realizedBy` the devices that build it (switches, routers) and `connects` the devices attached to it.
|
|
203
|
+
Both are written on the network, so a switch attached to the network it builds closes no cycle.
|
|
204
|
+
12. Cables are `connectedTo` between devices, declared once on one of the two ends. Cabling runs both ways by nature
|
|
205
|
+
and is left out of the cycle check.
|
|
206
|
+
13. Devices, equipment, nodes and networks are `ownedBy` the team (BusinessActor) or BusinessRole that operates
|
|
207
|
+
them. Devices, equipment and nodes are `servedBy` the team they are dedicated to (ArchiMate serving: the
|
|
208
|
+
technology serves the actor), such as the servers of a shared test cluster partitioned among teams;
|
|
209
|
+
`device/purpose` and `equipment/purpose` say what for ("kernel regression tests"). A partition is equipment
|
|
210
|
+
`servedBy` its team and `composedOf` its devices, which then need no team of their own. Both relations point
|
|
211
|
+
down to the team, which points to nothing further. On a TechnologyFacility, `servedBy` stays the operator of
|
|
212
|
+
the site.
|
|
213
|
+
|
|
214
|
+
**Checked by `archsight lint`**
|
|
215
|
+
|
|
216
|
+
As above, these are **warnings** in the "Modeling warnings" section and never fail the lint:
|
|
217
|
+
|
|
218
|
+
| Warning | Rule |
|
|
219
|
+
|---------|------|
|
|
220
|
+
| `TechnologyEquipment 'Equipment:Link:A-B' is a link located at 1 facility, not 2` | 2 |
|
|
221
|
+
| `TechnologyCommunicationNetwork 'Network:Overlay:EVPN' is an overlay network served by no network` | 3 |
|
|
222
|
+
| `TechnologyFacility 'Facility:Madrid:DC' is located at no Location` | where |
|
|
223
|
+
| `TechnologyEquipment 'Equipment:Rack01' is located at no TechnologyFacility` | where |
|
|
224
|
+
| `TechnologyDevice 'Device:Server01' is located at no TechnologyFacility` | 10 |
|
|
225
|
+
| `TechnologyDevice 'Device:Switch01' is connectedTo itself` | 12 |
|
|
226
|
+
| `TechnologyDevice 'Device:Router01' is a router that realizes no TechnologyCommunicationNetwork` | 11 |
|
|
227
|
+
| `TechnologyDevice 'Device:a:server-3' is servedBy 'Kernel:Team', not by the team of its equipment ('Compute:Team')` | 13 |
|
|
228
|
+
|
|
229
|
+
Nested facilities need no location of their own (the outermost facility has it), and TechnologyEquipment that is part of other
|
|
230
|
+
TechnologyEquipment, or composed of placed parts, needs no facility of its own. The same holds for a device inside a
|
|
231
|
+
rack or a virtual chassis, and for a chassis whose members are placed; the members of a chassis realize the network
|
|
232
|
+
through the chassis.
|
|
233
|
+
|
|
234
|
+
**Example chain**
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
Location "Location:Germany:Frankfurt"
|
|
238
|
+
↑ locatedAt
|
|
239
|
+
TechnologyFacility "Facility:Frankfurt:Campus" ──composedOf──> TechnologyFacility "Facility:Frankfurt:HallA"
|
|
240
|
+
↑ locatedAt (both ends) ↑ locatedAt
|
|
241
|
+
TechnologyEquipment "Equipment:Link:Frankfurt-Madrid" (link) TechnologyNode "Node:Frankfurt:Web01"
|
|
242
|
+
↑ composedOf │ servedBy
|
|
243
|
+
TechnologyEquipment "Equipment:Backbone" ↓
|
|
244
|
+
↑ realizedBy TechnologyCommunicationNetwork "Network:Management:Frankfurt"
|
|
245
|
+
TechnologyService "Network:Backbone"
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Devices, one level further down (hall A of the example):
|
|
249
|
+
|
|
250
|
+
```
|
|
251
|
+
TechnologyCommunicationNetwork "Network:Management:Frankfurt"
|
|
252
|
+
│ realizedBy │ connects
|
|
253
|
+
↓ ↓
|
|
254
|
+
TechnologyDevice "Device:Frankfurt:Switch:Core" TechnologyDevice "Device:Frankfurt:Server01" ──locatedAt──> TechnologyFacility "Facility:Frankfurt:HallA:Room1"
|
|
255
|
+
│ composedOf │ connectedTo ↑ composedOf
|
|
256
|
+
↓ ↓ TechnologyFacility "Facility:Frankfurt:HallA"
|
|
257
|
+
TechnologyDevice "Device:Frankfurt:Switch:Core:n0" ←─┘
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
The physical machines of hall A, two rooms with their servers, switches, routers and firewalls, are in
|
|
261
|
+
`examples/archsight/technology/devices.yaml`, drawn room by room on the same example page.
|
|
262
|
+
|
|
263
|
+
The overlay `Network:Overlay:EVPN` is `servedBy` the underlay and `realizedBy` the routing software
|
|
264
|
+
`Tech:Routing:EVPN`. All of it is in `examples/archsight/technology/` (`facilities.yaml`, `networks.yaml`), walked
|
|
265
|
+
through on the example page "Infrastructure Modeling".
|
|
266
|
+
|
|
267
|
+
**Anti-patterns**
|
|
268
|
+
|
|
269
|
+
| Anti-pattern | Fix |
|
|
270
|
+
|--------------|-----|
|
|
271
|
+
| A data center modeled as a TechnologyNode | TechnologyFacility; the servers in it are nodes `locatedAt` it |
|
|
272
|
+
| Sites as annotations (`deployment/locations: dc-1,dc-2`) | TechnologyFacility elements and `locatedAt` |
|
|
273
|
+
| One copy of a service or cluster per site | One element `locatedAt` every site |
|
|
274
|
+
| A Location used for a building | TechnologyFacility `locatedAt` the Location |
|
|
275
|
+
| A link or fibre route as a TechnologyService | TechnologyEquipment `link`; the network service is `realizedBy` it |
|
|
276
|
+
| A network per tenant or customer | One overlay network; tenants stay out of the model |
|
|
277
|
+
| An element per pair of sites in a mesh | One network with `network/topology: mesh` |
|
|
278
|
+
| An overlay or VPN with nothing under it | `servedBy` the underlay or the network it tunnels through |
|
|
279
|
+
|
|
280
|
+
## Identity and Links
|
|
281
|
+
|
|
282
|
+
A resource has one **name**, the key everything refers to (relations, `[[wiki links]]`, URLs). Two annotations say more
|
|
283
|
+
about who it is and where else it lives. Both are available on every resource kind (pages have the links too).
|
|
284
|
+
|
|
285
|
+
### Aliases
|
|
286
|
+
|
|
287
|
+
`architecture/aliases` holds the other identifiers of a resource, comma-separated: `ApplicationService:Foo` can also be
|
|
288
|
+
`ITGS:A001`. Aliases are **unique among the resources of a kind** (`archsight lint` reports a duplicate with both
|
|
289
|
+
resources); the same alias on resources of different kinds is fine, like names. They are found by search and open a
|
|
290
|
+
resource by URL:
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
ITGS:A001 # the search box: the name shortcut also tests aliases
|
|
294
|
+
ApplicationService: architecture/aliases == "ITGS:A001"
|
|
295
|
+
name == "ITGS:A001"
|
|
296
|
+
/kinds/ApplicationService/instances/ITGS:A001 # redirects to /kinds/ApplicationService/instances/Foo
|
|
19
297
|
```
|
|
20
298
|
|
|
299
|
+
In a URL (and the instance API) a name always wins; when no resource has that name, the one resource of the kind
|
|
300
|
+
with that alias opens under its real name. An alias is an identifier, so each alias is shown as a chip without a link
|
|
301
|
+
and is not a facet in the sidebar (it would only ever point at one resource). It is not a name in the model: a
|
|
302
|
+
relation or a `[[wiki link]]` must use the name. When two documents describe the same resource, their aliases (and
|
|
303
|
+
tags) are added together instead of one replacing the other.
|
|
304
|
+
|
|
305
|
+
For kind authors: `annotation "key", unique: true` makes any annotation an identifier of this kind: unique per kind,
|
|
306
|
+
checked by `archsight lint`, shown as chips without links. `annotation "key", deprecated: "what to use instead"` keeps an
|
|
307
|
+
annotation working while `archsight lint` lists every use as a deprecation (with the text), without failing.
|
|
308
|
+
`annotation "key", default: "value"` gives every resource that does not set the annotation that value when the
|
|
309
|
+
resources are loaded (queries, filters and pages see it; the editor does not write it into the file).
|
|
310
|
+
|
|
311
|
+
### Links
|
|
312
|
+
|
|
313
|
+
`link/<name>` holds a URL on any resource. The name says which system: `link/confluence`, `link/jira`,
|
|
314
|
+
`link/servicenow`; a second link into the same system gets another name (`link/confluence-isms`). A link has **no
|
|
315
|
+
direction**: it is where the resource comes from, where it was published to, or just a related page. A page writes them
|
|
316
|
+
as `links:` in its frontmatter (see [Pages](/doc/pages)):
|
|
317
|
+
|
|
318
|
+
```yaml
|
|
319
|
+
kind: ApplicationService
|
|
320
|
+
metadata:
|
|
321
|
+
name: Foo
|
|
322
|
+
annotations:
|
|
323
|
+
architecture/aliases: ITGS:A001
|
|
324
|
+
link/confluence: https://confluence.example.com/spaces/ARCH/pages/12345/Foo
|
|
325
|
+
link/jira: https://jira.example.com/browse/ARCH-12
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
Links render with the icon of their system wherever a resource or page is shown. Artifacts also carry many generated
|
|
329
|
+
`link/*` entries (links found in the README); they are listed apart from the ones you write.
|
|
330
|
+
|
|
21
331
|
## Starting Points
|
|
22
332
|
|
|
23
333
|
### Top-Down Modeling
|
|
@@ -54,8 +364,41 @@ Model **why** the architecture exists.
|
|
|
54
364
|
| MotivationOutcome | For measurable results ("99.9% availability", "Sub-100ms response") |
|
|
55
365
|
| MotivationRequirement | For must-have capabilities (compliance, functional needs) |
|
|
56
366
|
| MotivationConstraint | For limitations (budget, regulations, technical debt) |
|
|
367
|
+
| MotivationDriver | For threats, opportunities, regulation and market forces that motivate action (`driver/type`) |
|
|
368
|
+
| MotivationAssessment | For risks, vulnerabilities, findings and supplier or protection-need analyses (`assessment/type`) |
|
|
369
|
+
| MotivationPrinciple | For policies, guidelines and architecture principles (`principle/type`) |
|
|
57
370
|
|
|
58
|
-
**Example chain:** Stakeholder "Security Team" → hasConcern → Goal "Achieve Compliance" → realizes → Requirement "Encrypt data at rest"
|
|
371
|
+
**Example chain:** Stakeholder "Security Team" → hasConcern → Goal "Achieve Compliance" → realizes → Requirement "Encrypt data at rest"; Stakeholder "Security Team" → representedBy → Actor "Security Office"
|
|
372
|
+
|
|
373
|
+
**Source of a requirement:** the stakeholder that `hasConcern` for a requirement (directly, or for the goal the requirement answers) is its source, and the stakeholder is `representedBy` the `BusinessActor` or `BusinessRole` behind it: the actual organisation, not a generic "customer". This follows ArchiMate, where a stakeholder is a motivation role associated with the actor or role that plays it, and TOGAF, where the requirements repository records each requirement's source and the stakeholder map links stakeholders to organisation units. The requirement's page shows its stakeholders, the actor's page the stakeholder roles it represents. A source is optional.
|
|
374
|
+
|
|
375
|
+
### Strategy Layer
|
|
376
|
+
|
|
377
|
+
Model strategic **capabilities**.
|
|
378
|
+
|
|
379
|
+
| Resource | When to Use |
|
|
380
|
+
|----------|-------------|
|
|
381
|
+
| StrategyCapability | For abilities the organization needs ("Payment Processing", "Data Analytics"); not a product, team or certificate |
|
|
382
|
+
|
|
383
|
+
**Example chain:** Product "Online Checkout" → realizes → Capability "Payment Processing" → realizes → Requirement "Card Payments" (see [Choosing the Kind](#choosing-the-kind))
|
|
384
|
+
|
|
385
|
+
### Implementation & Migration Layer
|
|
386
|
+
|
|
387
|
+
Model **change**: what is done, what it delivers and how the architecture looks before and after.
|
|
388
|
+
|
|
389
|
+
| Resource | When to Use |
|
|
390
|
+
|----------|-------------|
|
|
391
|
+
| ImplementationWorkPackage | For projects, measures, remediation of risks and findings, audit programmes (`workpackage/type`, status, due date) |
|
|
392
|
+
| ImplementationDeliverable | For the results of work packages: documents, systems, process changes, evidence (`deliverable/type`) |
|
|
393
|
+
| ImplementationEvent | For milestones, go-lives and deadlines (`event/type`) |
|
|
394
|
+
| ImplementationPlateau | For a state of the architecture: baseline, transition, target (`plateau/type`) |
|
|
395
|
+
| ImplementationGap | For the difference between two plateaus (`gap/status`, `gap/impact`) |
|
|
396
|
+
|
|
397
|
+
**Migration path:** Plateau "Baseline" → triggers → Plateau "Target"; Gap → compares → both plateaus; Work Package → realizes → Deliverable → realizes → Plateau "Target"; Gap → closedBy → Work Package.
|
|
398
|
+
|
|
399
|
+
**Platform migration:** a plateau `contains` the technology elements of its state: `technologyServices`, `technologySystemSoftware`, `technologyNodes` and (optionally) `technologyArtifacts`, next to application components and requirements. Model the past, current and target platform as three plateaus chained with `triggers`, with a Gap per step; the plateau page lists what it contains, the technology element shows (reverse lookup) in which plateaus it appears, and comparing the plateaus of a gap shows what is added or removed. See `examples/archsight/implementation/platform-migration.yaml`.
|
|
400
|
+
|
|
401
|
+
**Remediation:** Assessment "Risk" → mitigatedBy → Work Package → realizes → Deliverable (type `evidence`) → realizes → ComplianceEvidence. Group by `risk/domain` to see the plan of one domain, filter by `workpackage/status` and `workpackage/due` for what is open or late.
|
|
59
402
|
|
|
60
403
|
### Business Layer
|
|
61
404
|
|
|
@@ -64,23 +407,63 @@ Model **who** does **what** in business terms.
|
|
|
64
407
|
| Resource | When to Use |
|
|
65
408
|
|----------|-------------|
|
|
66
409
|
| BusinessActor | For teams, departments, or organizations |
|
|
410
|
+
| BusinessRole | For responsibilities held by actors: control owner, risk owner, information security officer (`role/type`) |
|
|
67
411
|
| BusinessProcess | For workflows that produce business value |
|
|
68
|
-
| BusinessProduct | For
|
|
412
|
+
| BusinessProduct | For what a customer buys or contracts, as on a price list ("Online Checkout", "Premium Support") |
|
|
413
|
+
| BusinessContract | For what a customer and a provider agreed: framework contracts, call-offs, SLAs, amendments (`contract/type`) |
|
|
69
414
|
| BusinessControl | For controls that guide a process (access review, change approval), with an owner and executors |
|
|
415
|
+
| BusinessEvent | For things that happen in the business: threat events, loss events, incidents, triggers (`event/type`) |
|
|
70
416
|
|
|
71
|
-
**Example chain:**
|
|
72
|
-
|
|
73
|
-
**Controls:** Process "Incident Response" → guidedBy → Control "Escalation Review" → ownedBy / executedBy → Actor "Platform Team". How controls, requirements and evidence fit together is described under Relation Patterns below.
|
|
417
|
+
**Example chain:** Process "Incident Response" → performedBy → Actor "Platform Team"; Process "Incident Response" → servedBy → Service "Monitoring"
|
|
74
418
|
|
|
75
|
-
|
|
419
|
+
**Roles:** Process "Incident Response" → performedBy → Role "Incident Manager" → performedBy → Actor "Platform Team". Controls, risks, policies and work packages use `ownedBy` (and controls `executedBy`) the same way. Use a role where the responsibility has a name of its own and should survive a change of team; pointing straight at an actor stays valid.
|
|
76
420
|
|
|
77
|
-
|
|
421
|
+
**Controls:** Process "Incident Response" → guidedBy → Control "Escalation Review" → ownedBy / executedBy → Role or Actor. How controls, requirements and evidence fit together is described under Relation Patterns below.
|
|
78
422
|
|
|
79
|
-
|
|
80
|
-
|----------|-------------|
|
|
81
|
-
| StrategyCapability | For abilities the organization needs ("Container Orchestration", "Data Analytics") |
|
|
423
|
+
**Contracts:** Product → aggregates → Contract (framework) → composedOf → Contract (call-off) → covers → Equipment, and the call-off → realizedThrough → Deliverable ← realizes ← Work Package → affects → Equipment. The contract is `agreedBy` the actual organisations (the customer and the provider), not a generic role. All relations are written on the more abstract element; the equipment, the actors and the deliverable show them as incoming ("covered by", "agreed contracts", "fulfils"). A contract is a `BusinessContract`, not a `DataObject` and not text in a description.
|
|
82
424
|
|
|
83
|
-
|
|
425
|
+
```yaml
|
|
426
|
+
kind: BusinessProduct
|
|
427
|
+
metadata:
|
|
428
|
+
name: PrivateCloudOffering
|
|
429
|
+
spec:
|
|
430
|
+
servedBy:
|
|
431
|
+
applicationServices: [ComputeService, ObjectStorage]
|
|
432
|
+
aggregates:
|
|
433
|
+
businessContracts: [Contract:Customer]
|
|
434
|
+
---
|
|
435
|
+
kind: BusinessContract
|
|
436
|
+
metadata:
|
|
437
|
+
name: Contract:Customer
|
|
438
|
+
annotations:
|
|
439
|
+
contract/type: framework
|
|
440
|
+
contract/from: '2024-01-01'
|
|
441
|
+
spec:
|
|
442
|
+
agreedBy:
|
|
443
|
+
businessActors: [CustomerOrg, ProviderOrg]
|
|
444
|
+
composedOf:
|
|
445
|
+
businessContracts: [Contract:Customer:Block1, Contract:Customer:Block2]
|
|
446
|
+
---
|
|
447
|
+
kind: BusinessContract
|
|
448
|
+
metadata:
|
|
449
|
+
name: Contract:Customer:Block2
|
|
450
|
+
annotations:
|
|
451
|
+
contract/type: call-off
|
|
452
|
+
spec:
|
|
453
|
+
covers:
|
|
454
|
+
technologyEquipment: [Block2]
|
|
455
|
+
realizedThrough:
|
|
456
|
+
implementationDeliverables: [Block2Delivered]
|
|
457
|
+
---
|
|
458
|
+
kind: ImplementationWorkPackage
|
|
459
|
+
metadata:
|
|
460
|
+
name: BuildBlock2
|
|
461
|
+
spec:
|
|
462
|
+
realizes:
|
|
463
|
+
implementationDeliverables: [Block2Delivered]
|
|
464
|
+
affects:
|
|
465
|
+
technologyEquipment: [Block2]
|
|
466
|
+
```
|
|
84
467
|
|
|
85
468
|
### Application Layer
|
|
86
469
|
|
|
@@ -88,12 +471,49 @@ Model **software** that supports the business.
|
|
|
88
471
|
|
|
89
472
|
| Resource | When to Use |
|
|
90
473
|
|----------|-------------|
|
|
91
|
-
| ApplicationService | For
|
|
92
|
-
| ApplicationComponent | For
|
|
474
|
+
| ApplicationService | For behaviour software offers to a consumer, named by its function ("Payment Authorization", "Document Search") |
|
|
475
|
+
| ApplicationComponent | For what is built, deployed and versioned, by runtime role ("Payments:API", "Payments:Worker") |
|
|
93
476
|
| ApplicationInterface | For APIs and integration points |
|
|
94
477
|
| DataObject | For data structures and schemas |
|
|
95
478
|
|
|
96
|
-
**Example chain:** Service "
|
|
479
|
+
**Example chain:** Service "Payment Authorization" → realizedThrough → Component "Payments:API" → exposes → Interface "Payments:RestAPI"
|
|
480
|
+
|
|
481
|
+
#### Classifying components
|
|
482
|
+
|
|
483
|
+
Components are not all alike: some are run, some are only imported, some bundle both. Say which with `component/type`
|
|
484
|
+
(`executable`, `library`, `module`, `plugin`, `frontend`, `other`) and, for executables and plugins, what they do with
|
|
485
|
+
`component/role` (`service`, `cli`, `job`, `operator`, `agent`). Importers set `component/type` and add machine tags
|
|
486
|
+
(`namespace:value`, such as `ecosystem:go`, `packaging:go-module`, `linkage:shared`) to the regular
|
|
487
|
+
`architecture/tags` from the manifests; the tags a person set stay, and a re-import only replaces the machine tags of
|
|
488
|
+
those namespaces. The entry points (main packages such as `cmd/api`) are written to `component/entrypoints`, a list
|
|
489
|
+
you query like a tag (`component/entrypoints == "cmd/api"`) that is not a sidebar filter, because there are too many
|
|
490
|
+
distinct values. `component/role` is set by hand and never overwritten. A generated component is named after its module path (`github.com/alice/shop` → `alice:shop`). When
|
|
491
|
+
two repositories declare the same module path (a prototype and its successor, a fork), each gets its own component:
|
|
492
|
+
the repository the module path names keeps the plain name (`github.com/acme/library` names `Repo:acme:library`),
|
|
493
|
+
then the one that is not archived, then the first by name; the other gets its repository appended
|
|
494
|
+
(`alice:shop@acme:shop-prototype`), and a dependency on the module path points at the plain name. A `go.mod` in a
|
|
495
|
+
subdirectory whose module path names another known repository is a copy of that repository's module and gets no
|
|
496
|
+
component at all. Neither does a nested `go.mod` below a test, tool, example or benchmark directory (`test/e2e`,
|
|
497
|
+
`tools`, `hack`, `examples/foo`, `internal/systemtest`): nothing realizes such code or depends on it, so its packages
|
|
498
|
+
only appear in the repository's module graph; `cmd/<name>/go.mod` stays a component. The importer only sees the other repository once both were imported, so the names separate on the
|
|
499
|
+
import after that; until then `archsight lint` warns about the merged component. A hand-written component that lists
|
|
500
|
+
several repositories is left as it is. The computed `component/dependents` counts the components that depend on a
|
|
501
|
+
component, which shows how widely a library or module is shared.
|
|
502
|
+
|
|
503
|
+
| Ecosystem | Executable | Library | Module (bundles both) |
|
|
504
|
+
|-----------|------------|---------|-----------------------|
|
|
505
|
+
| Go | `package main` (`component/entrypoints`: one per main package) | no `main` package | main packages plus importable packages outside `internal/` and `cmd/` |
|
|
506
|
+
| JavaScript, TypeScript | `bin`, a server entry point | `main`, `exports`, `types` | `workspaces` root |
|
|
507
|
+
| Ruby | gemspec `executables`, Rails app | gem without executables | monorepo of gems |
|
|
508
|
+
| Python | `[project.scripts]`, `__main__.py` | package published to an index | distribution of several packages |
|
|
509
|
+
| Rust | `[[bin]]`, `src/main.rs` | `[lib]` | Cargo workspace |
|
|
510
|
+
| Java | `Main-Class`, Spring Boot, application plugin | plain jar | Maven or Gradle multi-module parent |
|
|
511
|
+
| C, C++ | `add_executable`, `bin_PROGRAMS` | `add_library`, `lib_LTLIBRARIES` (`linkage:` shared, static, header-only) | none |
|
|
512
|
+
| Shell, Perl | scripts (`bin/`) | `.pm` distributions, sourced files | none |
|
|
513
|
+
|
|
514
|
+
Today the Go importer sets the type of the components it generates; the other ecosystems are classified by hand until
|
|
515
|
+
their importers emit components. Deployable forms (container image, Helm chart, deb, rpm) are `TechnologyArtifact`s
|
|
516
|
+
(`artifact/type`), not component types.
|
|
97
517
|
|
|
98
518
|
### Technology Layer
|
|
99
519
|
|
|
@@ -101,14 +521,126 @@ Model **infrastructure** and **code**.
|
|
|
101
521
|
|
|
102
522
|
| Resource | When to Use |
|
|
103
523
|
|----------|-------------|
|
|
104
|
-
| TechnologyArtifact | For source code repositories |
|
|
524
|
+
| TechnologyArtifact | For source code repositories, packages, images and binaries (`artifact/type`); `aggregates` its contents, nodes are `assignedTo` it |
|
|
105
525
|
| TechnologyService | For infrastructure services (Postgres, Redis, Kubernetes platform) |
|
|
106
526
|
| TechnologySystemSoftware | For logical infrastructure (database cluster, message queue) |
|
|
107
|
-
|
|
|
108
|
-
| TechnologyNode | For infrastructure instances |
|
|
527
|
+
| TechnologyNode | For infrastructure instances; `specializes` / `composedOf` another node |
|
|
109
528
|
| TechnologyInterface | For technical protocols and endpoints |
|
|
529
|
+
| TechnologyCommunicationNetwork | For logical networks: underlay, overlay, management, public, VPN (`network/type`) |
|
|
530
|
+
|
|
531
|
+
**Example chain:** Component "Payments:API" → realizedThrough → Artifact "Repo:payments-api" → maintainedBy → Actor "Platform Team"
|
|
532
|
+
|
|
533
|
+
#### Logical Networks
|
|
534
|
+
|
|
535
|
+
Which kind to pick is in [Choosing the Kind: Infrastructure](#choosing-the-kind-infrastructure). A logical network is a `TechnologyCommunicationNetwork` (ArchiMate Communication Network). Physical links and fabrics stay
|
|
536
|
+
`TechnologyEquipment`; the network is what runs over them.
|
|
537
|
+
|
|
538
|
+
| From | Verb | To |
|
|
539
|
+
|------|------|----|
|
|
540
|
+
| `TechnologyCommunicationNetwork` | `composedOf` | `TechnologyCommunicationNetwork` (a metro network of its site networks) |
|
|
541
|
+
| `TechnologyCommunicationNetwork` | `specializes` | `TechnologyCommunicationNetwork` (concept and implementation) |
|
|
542
|
+
| `TechnologyCommunicationNetwork` | `servedBy` | `TechnologyCommunicationNetwork` (the network it runs over) |
|
|
543
|
+
| `TechnologyCommunicationNetwork` | `locatedAt` | `TechnologyFacility`, `Location` (many) |
|
|
544
|
+
| `TechnologyCommunicationNetwork` | `realizedBy` | `TechnologyEquipment` (the fabric), `TechnologySystemSoftware` (routing stack, VPN software) |
|
|
545
|
+
| `TechnologyCommunicationNetwork` | `realizedBy` | `ApplicationComponent`, `ApplicationService` (software that builds the network: an SDN agent, a network operator) |
|
|
546
|
+
| `TechnologyCommunicationNetwork` | `realizedBy` | `TechnologyDevice` (the switches and routers that build it) |
|
|
547
|
+
| `TechnologyCommunicationNetwork` | `connects` | `TechnologyDevice` (the devices attached to it) |
|
|
548
|
+
| `TechnologyNode` | `servedBy` | `TechnologyCommunicationNetwork` |
|
|
549
|
+
|
|
550
|
+
- **Underlay and overlay:** the underlay *serves* the overlay, so the overlay is `servedBy` the underlay. A BGP-EVPN
|
|
551
|
+
network that carries customer workloads is one `overlay` network served by the underlay and realized by the routing
|
|
552
|
+
system software. Do not model a network per customer or tenant.
|
|
553
|
+
- **VPN:** a network of `network/type: vpn`, `servedBy` the network it tunnels through (usually the public network),
|
|
554
|
+
`locatedAt` the sites it joins and `realizedBy` the gateway software.
|
|
555
|
+
- **Mesh:** `network/topology: mesh` on **one** network that is `locatedAt` all its sites. Only when single tunnels
|
|
556
|
+
matter (capacity, owner) are they sub-networks, `composedOf` into the mesh.
|
|
557
|
+
- **Nesting and metro regions:** a network that supports a metro region is `locatedAt` the `Location` and
|
|
558
|
+
`composedOf` the networks of its sites. `composedOf` and `specializes` only point at networks and must not form a
|
|
559
|
+
cycle; `archsight lint` reports cycles of `composedOf`, `specializes` and `servedBy`.
|
|
560
|
+
- **Attachment:** a node is `servedBy` the networks it is attached to; the network page lists them. A physical
|
|
561
|
+
device is attached the other way round: the network `connects` it, so the network can also be `realizedBy` the
|
|
562
|
+
same switch without a cycle.
|
|
563
|
+
|
|
564
|
+
```
|
|
565
|
+
# all overlay networks
|
|
566
|
+
TechnologyCommunicationNetwork: network/type == "overlay"
|
|
567
|
+
|
|
568
|
+
# networks that reach TechnologyFacility X
|
|
569
|
+
TechnologyCommunicationNetwork: -> "Facility:Madrid:DC"
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
See `examples/archsight/technology/networks.yaml`.
|
|
573
|
+
|
|
574
|
+
### Where Technology Runs
|
|
575
|
+
|
|
576
|
+
Which kind to pick is in [Choosing the Kind: Infrastructure](#choosing-the-kind-infrastructure).
|
|
577
|
+
|
|
578
|
+
Model **where** technology runs with `TechnologyFacility` (a building, data center or site, nested with `composedOf`),
|
|
579
|
+
`Location` (a country, metro or region) and, when the physical grouping matters, `TechnologyEquipment` (racks, fabrics,
|
|
580
|
+
physical clusters). Do not model sites as annotations, as one service per site, or as `TechnologyNode`s: a data
|
|
581
|
+
center is not a computational resource.
|
|
582
|
+
|
|
583
|
+
| Resource | When to Use |
|
|
584
|
+
|----------|-------------|
|
|
585
|
+
| Location | For a country, metro or region |
|
|
586
|
+
| TechnologyFacility | For a data center, colocation, office or edge site (`facility/type`), also a campus or hall inside one |
|
|
587
|
+
| TechnologyEquipment | Optional: racks, network fabrics, physical clusters inside a facility (`equipment/type`) |
|
|
588
|
+
| TechnologyDevice | Optional: one physical machine, `locatedAt` its room (`facility/type: room`) |
|
|
589
|
+
|
|
590
|
+
Relations are written on the element that is placed (see [Direction of Relations](#direction-of-relations)):
|
|
591
|
+
|
|
592
|
+
| From | Verb | To |
|
|
593
|
+
|------|------|----|
|
|
594
|
+
| `TechnologyNode`, `TechnologyService`, `TechnologySystemSoftware`, `TechnologyEquipment`, `TechnologyDevice` | `locatedAt` | `TechnologyFacility` (many) |
|
|
595
|
+
| `TechnologyFacility` | `locatedAt` | `Location` |
|
|
596
|
+
| `TechnologyFacility` | `composedOf` | `TechnologyFacility` (nested sites, the rooms of a data center) |
|
|
597
|
+
| `TechnologyFacility` | `servedBy` | `BusinessActor` (the operator) |
|
|
598
|
+
| `TechnologyDevice`, `TechnologyEquipment`, `TechnologyNode`, `TechnologyCommunicationNetwork` | `ownedBy` | `BusinessActor`, `BusinessRole` (the team that operates it) |
|
|
599
|
+
| `TechnologyDevice`, `TechnologyEquipment`, `TechnologyNode` | `servedBy` | `BusinessActor` (the team it is dedicated to, e.g. a test partition) |
|
|
600
|
+
|
|
601
|
+
`locatedAt` with many targets is the point: a service that runs in three data centers is **one** service with three
|
|
602
|
+
`locatedAt` relations. A `locatedAt` target that is not a TechnologyFacility (or, from a facility, a Location) is rejected by
|
|
603
|
+
`archsight lint`. TechnologyFacility and Location pages list what is located there (incoming `locatedAt`), grouped by kind.
|
|
604
|
+
|
|
605
|
+
A service may run on different platforms in different facilities (a managed platform in site A, a self-hosted one in
|
|
606
|
+
site B). There is no qualifier on the relation: locate the nodes or system software of each platform at its
|
|
607
|
+
facilities too, and the pair (platform, facility) is derivable.
|
|
608
|
+
|
|
609
|
+
Queries:
|
|
610
|
+
|
|
611
|
+
```
|
|
612
|
+
# all technology services in TechnologyFacility X
|
|
613
|
+
TechnologyService: -> "DC:Alpha"
|
|
614
|
+
|
|
615
|
+
# facilities that host service Y
|
|
616
|
+
TechnologyFacility: <- "Orders:Cluster"
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
#### Backbone and links between facilities
|
|
110
620
|
|
|
111
|
-
|
|
621
|
+
The physical network between sites is `TechnologyEquipment`. A **link** (fibre route, carrier circuit) is one TechnologyEquipment with
|
|
622
|
+
`equipment/type: link` that is `locatedAt` **both** end facilities. A **backbone** is a TechnologyEquipment that is `composedOf`
|
|
623
|
+
its links (composition only points at TechnologyEquipment and must not form a cycle). The logical network is a
|
|
624
|
+
`TechnologyService` (and routers are `TechnologyNode`s) that is `realizedBy` the TechnologyEquipment it runs over, and is
|
|
625
|
+
`locatedAt` the facilities it reaches:
|
|
626
|
+
|
|
627
|
+
```
|
|
628
|
+
TechnologyService "Network:Backbone" --realizedBy--> TechnologyEquipment "Equipment:Backbone"
|
|
629
|
+
--composedOf--> TechnologyEquipment "Equipment:Link:Frankfurt-Madrid" (link)
|
|
630
|
+
--locatedAt--> TechnologyFacility Frankfurt, TechnologyFacility Madrid
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
```
|
|
634
|
+
# all links between facilities
|
|
635
|
+
TechnologyEquipment: equipment/type == "link"
|
|
636
|
+
|
|
637
|
+
# links that end in TechnologyFacility X
|
|
638
|
+
TechnologyEquipment: equipment/type == "link" & -> "Facility:Madrid:DC"
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
The TechnologyEquipment page lists what is realized by it (incoming `realizedBy`) and the backbones it belongs to (incoming
|
|
642
|
+
`composedOf`). A link has no endpoints of its own: it is placed at its facilities, so keep to two `locatedAt` targets
|
|
643
|
+
per link. See `examples/archsight/technology/facilities.yaml`.
|
|
112
644
|
|
|
113
645
|
## Relation Patterns
|
|
114
646
|
|
|
@@ -131,6 +663,8 @@ TechnologyArtifact
|
|
|
131
663
|
Shows how services depend on each other:
|
|
132
664
|
|
|
133
665
|
```
|
|
666
|
+
ApplicationService
|
|
667
|
+
↓ dependsOn (another ApplicationService)
|
|
134
668
|
ApplicationService
|
|
135
669
|
↓ servedBy
|
|
136
670
|
TechnologyService
|
|
@@ -138,7 +672,101 @@ TechnologyService
|
|
|
138
672
|
TechnologySystemSoftware
|
|
139
673
|
```
|
|
140
674
|
|
|
141
|
-
|
|
675
|
+
A service that uses another one says so with `dependsOn` on the service, the same verb components use between each
|
|
676
|
+
other. Do not add the other service's components to your own `realizedThrough`: the component would then belong to
|
|
677
|
+
two services, its owner is ambiguous and every rollup over the service's components counts it twice. Two services may
|
|
678
|
+
depend on each other, so `dependsOn` is exempt from the cycle check. In `examples/archsight`, "Refunds" depends on "Payment Authorization" (it refunds an authorized payment) and
|
|
679
|
+
"Payment Authorization" depends on "Refunds" (it asks to reverse a payment it cannot complete).
|
|
680
|
+
|
|
681
|
+
### Where a Component Runs
|
|
682
|
+
|
|
683
|
+
Three relations say what something runs on; each answers a different question:
|
|
684
|
+
|
|
685
|
+
| Relation | Means | Example |
|
|
686
|
+
|----------|-------|---------|
|
|
687
|
+
| ApplicationComponent `servedBy technologyServices` | the platform service the component is deployed on | `Payments:API` runs in `Payments:Cluster` |
|
|
688
|
+
| ApplicationComponent `servedBy technologySystemSoftware` | the runtime it runs on | a Kubernetes distribution, a JVM |
|
|
689
|
+
| ApplicationService `servedBy technologyServices` | a platform service the service as a whole uses | a managed database, the clusters of its own components |
|
|
690
|
+
|
|
691
|
+
Deployment importers (Argo CD, Helm, Cluster API) know every cluster a deployable runs in and write the relation per
|
|
692
|
+
component. Keep the service-level relation to the clusters of the service's own components: a sidecar or agent that
|
|
693
|
+
the products deploy into their own clusters (a DNS or monitoring agent) is `servedBy` each of those clusters, and its
|
|
694
|
+
owning service is not, so it does not look like it runs everywhere. The TechnologyService page lists the components
|
|
695
|
+
deployed on it as incoming `servedBy` from ApplicationComponent. The `deployment/cluster` annotation is deprecated in
|
|
696
|
+
favour of the relation, which the graph, views and analyses see; it still loads, and `archsight lint` lists every use
|
|
697
|
+
as a deprecation without failing. See
|
|
698
|
+
`examples/archsight/technology/payments-platform.yaml`.
|
|
699
|
+
|
|
700
|
+
### Concept and Implementation
|
|
701
|
+
|
|
702
|
+
One technology *concept* often has several *implementations*: a "regional cluster" is implemented by a hypervisor
|
|
703
|
+
platform on some sites and by bare metal on others. Model the concept as an element and let every implementation
|
|
704
|
+
**specialize** it (ArchiMate specialization). The specialization is written on the specific element and always points
|
|
705
|
+
to an element of the **same kind**:
|
|
706
|
+
|
|
707
|
+
| Kind | Verb | Target | ArchiMate |
|
|
708
|
+
|------|------|--------|-----------|
|
|
709
|
+
| `TechnologyNode` | `specializes` | `TechnologyNode` | specialization |
|
|
710
|
+
| `TechnologySystemSoftware` | `specializes` | `TechnologySystemSoftware` | specialization |
|
|
711
|
+
| `TechnologyService` | `specializes` | `TechnologyService` | specialization |
|
|
712
|
+
| `TechnologyNode` | `composedOf` | `TechnologyNode` | composition (a cluster made of hosts) |
|
|
713
|
+
| `TechnologySystemSoftware` | `composedOf` | `TechnologySystemSoftware` | composition (a platform bundles components) |
|
|
714
|
+
|
|
715
|
+
```yaml
|
|
716
|
+
kind: TechnologyNode
|
|
717
|
+
metadata:
|
|
718
|
+
name: Tech:RegionalCluster # the concept
|
|
719
|
+
spec: {}
|
|
720
|
+
---
|
|
721
|
+
kind: TechnologyNode
|
|
722
|
+
metadata:
|
|
723
|
+
name: Tech:RegionalCluster:Hypervisor # one implementation
|
|
724
|
+
spec:
|
|
725
|
+
specializes:
|
|
726
|
+
technologyNodes:
|
|
727
|
+
- Tech:RegionalCluster
|
|
728
|
+
composedOf:
|
|
729
|
+
technologyNodes:
|
|
730
|
+
- Tech:RegionalCluster:Host
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
The page of the concept shows the implementations as incoming `specializes`, the implementation shows what it
|
|
734
|
+
`specializes`. A target of another kind is rejected when the resources are loaded, and `archsight lint` reports a
|
|
735
|
+
`specializes` or `composedOf` chain that leads back to where it started. Do not use `realizedBy` between elements of
|
|
736
|
+
one kind: realization goes from concrete to abstract across layers. See `examples/archsight/technology/platforms.yaml`.
|
|
737
|
+
|
|
738
|
+
### Deployment
|
|
739
|
+
|
|
740
|
+
An artifact (`TechnologyArtifact`) describes what reaches a host; three relations connect it to the rest:
|
|
741
|
+
|
|
742
|
+
| Kind | Verb | Target | ArchiMate | Meaning |
|
|
743
|
+
|------|------|--------|-----------|---------|
|
|
744
|
+
| `TechnologyArtifact` | `aggregates` | `TechnologyArtifact` | aggregation | an image contains packages, a chart references container images |
|
|
745
|
+
| `TechnologyNode` | `assignedTo` | `TechnologyArtifact` | assignment | the artifact is deployed on the node |
|
|
746
|
+
| `TechnologySystemSoftware` | `assignedTo` | `TechnologyArtifact` | assignment | the artifact is executed by the system software |
|
|
747
|
+
|
|
748
|
+
`assignedTo` is written on the node or system software, which owns the deployment. A bootable OS image, VM template or
|
|
749
|
+
disk image is an artifact of `artifact/type: image` (`binary` and `archive` exist as well).
|
|
750
|
+
|
|
751
|
+
```
|
|
752
|
+
ApplicationComponent
|
|
753
|
+
↓ realizedThrough (what the component is built from)
|
|
754
|
+
TechnologyArtifact (image)
|
|
755
|
+
↓ aggregates (what the image contains)
|
|
756
|
+
TechnologyArtifact (package)
|
|
757
|
+
|
|
758
|
+
TechnologyNode
|
|
759
|
+
↓ assignedTo (where the artifact is deployed)
|
|
760
|
+
TechnologyArtifact
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
The artifact's page shows `aggregates` as incoming "contained in" and `assignedTo` as incoming "deployed on"; the node's
|
|
764
|
+
page shows what it `assignedTo`. This answers "which hosts get package X" with a reverse lookup instead of a package list in
|
|
765
|
+
an annotation. `archsight lint` reports an `aggregates` chain that leads back to where it started. Example: a host role
|
|
766
|
+
boots an image that contains two packages, and configuration management installs a third on the same hosts, see
|
|
767
|
+
`examples/archsight/technology/deployment.yaml`. Do not use `servedBy` between artifacts for contents: it reads as
|
|
768
|
+
"is served by", not "contains".
|
|
769
|
+
|
|
142
770
|
|
|
143
771
|
A requirement is the point where the process side and the application side of compliance meet:
|
|
144
772
|
|
|
@@ -189,6 +817,100 @@ spec:
|
|
|
189
817
|
evidencedBy: { complianceEvidences: [Evidence:DeploymentAuditLog] }
|
|
190
818
|
```
|
|
191
819
|
|
|
820
|
+
### Security and Risk
|
|
821
|
+
|
|
822
|
+
Security and risk are modelled with the elements above, following the risk and security overlay of the Open Group
|
|
823
|
+
white paper [Modeling Enterprise Risk Management and Security with the ArchiMate Language](#reference). There is no
|
|
824
|
+
separate security layer: a concept is an ordinary element that carries a **type** (a specialization, the paper's
|
|
825
|
+
"stereotype") plus profile annotations. The type is a filterable annotation, so views, queries and lists can group by it.
|
|
826
|
+
|
|
827
|
+
| Security concept | Kind | Type annotation | Notes |
|
|
828
|
+
|------------------|------|-----------------|-------|
|
|
829
|
+
| Threat (circumstance) | `MotivationDriver` | `driver/type: threat` | also opportunity, regulation, market |
|
|
830
|
+
| Threat agent | `BusinessActor`, `ApplicationComponent`, `TechnologyNode` | none | the `causedBy` of an event |
|
|
831
|
+
| Threat event | `BusinessEvent`, `ApplicationEvent`, `TechnologyEvent` | `event/type: threat-event` or `attack` | `attack` = intentional |
|
|
832
|
+
| Loss event, incident | the three event kinds | `event/type: loss-event` or `incident` | the layer says where it happens |
|
|
833
|
+
| Risk | `MotivationAssessment` | `assessment/type: risk` | initial and residual profile, `risk/treatment` |
|
|
834
|
+
| Vulnerability | `MotivationAssessment` | `assessment/type: vulnerability` | `assesses` the assets it is found on |
|
|
835
|
+
| Control objective | `MotivationGoal` | `goal/type: control-objective` | the risk is `mitigatedBy` it |
|
|
836
|
+
| Control measure | `MotivationRequirement` | `requirement/type: control-measure` | a goal `realizes` it; the risk can be `mitigatedBy` it |
|
|
837
|
+
| Control implementation | `BusinessControl`, applications, nodes, processes | none | `satisfies` / `realizes` the measure |
|
|
838
|
+
| Proof of the control | `ComplianceEvidence` | `evidence/type` | `evidence/status: not-applicable` where the requirement does not apply |
|
|
839
|
+
| Asset at risk | any application, technology, data or process kind | `asset/value`, `asset/confidentiality`, `asset/integrity`, `asset/availability` | the protection need (BSI Schutzbedarf) |
|
|
840
|
+
| Policy (design level) | `MotivationPrinciple` | `principle/type: security-policy` or `risk-policy` | status, validity, framework mapping |
|
|
841
|
+
| Operational policy, regulation | `MotivationConstraint` | none | the paper has no element for operational policy |
|
|
842
|
+
| Risk domain | none; annotation `risk/domain` | `risk/domain`, `risk/category` | group by it with a query or a `View` |
|
|
843
|
+
|
|
844
|
+
The chain, as in the paper's Coldhard Steel example:
|
|
845
|
+
|
|
846
|
+
```
|
|
847
|
+
MotivationDriver (threat) ──influences──→ MotivationAssessment (risk) ──mitigatedBy──→ MotivationGoal (control objective)
|
|
848
|
+
│ triggers │ assesses │ realizes
|
|
849
|
+
↓ ↓ ↓
|
|
850
|
+
BusinessEvent (loss event) ←──influences── MotivationAssessment (vulnerability) MotivationRequirement (control measure)
|
|
851
|
+
↑ triggers ↑ satisfies / realizes
|
|
852
|
+
TechnologyEvent / ApplicationEvent (threat event, attack) BusinessControl / asset ──evidencedBy──→ ComplianceEvidence
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
```yaml
|
|
856
|
+
kind: MotivationDriver
|
|
857
|
+
metadata: { name: Threat:Intrusion, annotations: { driver/type: threat } }
|
|
858
|
+
spec:
|
|
859
|
+
influences: { motivationAssessments: [Risk:Intrusion] }
|
|
860
|
+
triggers: { businessEvents: [Loss:DataLeak] }
|
|
861
|
+
---
|
|
862
|
+
kind: MotivationAssessment
|
|
863
|
+
metadata:
|
|
864
|
+
name: Risk:Intrusion
|
|
865
|
+
annotations:
|
|
866
|
+
assessment/type: risk
|
|
867
|
+
risk/initial-likelihood: high
|
|
868
|
+
risk/residual-likelihood: low
|
|
869
|
+
risk/treatment: mitigate
|
|
870
|
+
risk/domain: customer-data
|
|
871
|
+
spec:
|
|
872
|
+
ownedBy: { businessRoles: [Role:RiskOwner] }
|
|
873
|
+
assesses: { technologyNodes: [Node:Web1] }
|
|
874
|
+
mitigatedBy: { goals: [Objective:ReduceExposure], businessControls: [Control:FirewallReview] }
|
|
875
|
+
---
|
|
876
|
+
kind: MotivationGoal
|
|
877
|
+
metadata: { name: Objective:ReduceExposure, annotations: { goal/type: control-objective } }
|
|
878
|
+
spec:
|
|
879
|
+
realizes: { motivationRequirements: [Measure:Firewall] }
|
|
880
|
+
---
|
|
881
|
+
kind: MotivationRequirement
|
|
882
|
+
metadata: { name: Measure:Firewall, annotations: { requirement/type: control-measure } }
|
|
883
|
+
spec: {}
|
|
884
|
+
---
|
|
885
|
+
kind: BusinessControl
|
|
886
|
+
metadata: { name: Control:FirewallReview }
|
|
887
|
+
spec:
|
|
888
|
+
ownedBy: { businessRoles: [Role:ControlOwner] }
|
|
889
|
+
satisfies: { motivationRequirements: [Measure:Firewall] }
|
|
890
|
+
```
|
|
891
|
+
|
|
892
|
+
How to model it:
|
|
893
|
+
|
|
894
|
+
- **Events and their types.** A threat event `triggers` a loss event; the three event kinds (business, application,
|
|
895
|
+
technology) say on which level it happens and a technology event may trigger an application or business event. Use
|
|
896
|
+
`event/type` to tell threat events, attacks, loss events, incidents, opportunity events, audits, scans and changes apart.
|
|
897
|
+
- **Vulnerability scan.** One `MotivationAssessment` of type `vulnerability` per finding, `assesses` every node it was
|
|
898
|
+
found on, `influences` the loss events and risks it makes possible. Business impact follows from the model: the node
|
|
899
|
+
serves services, services serve processes.
|
|
900
|
+
- **Grouping (risk domains).** ArchiMate has no domain element; set `risk/domain` (and `risk/category`: hazard,
|
|
901
|
+
financial, operational, strategic, compliance, security) on events, assessments, drivers, requirements, controls and
|
|
902
|
+
assets, and query or build a `View` per domain to see its threats, risks, measures and assets together.
|
|
903
|
+
- **Policies.** The text of a policy is a `Page`; the structured statement (owner, validity, status, framework) is a
|
|
904
|
+
`MotivationPrinciple` that links to the page with `[[Page]]`.
|
|
905
|
+
- **Initial and residual risk.** Record both on the assessment (`risk/initial-*`, `risk/residual-*`) and the decision
|
|
906
|
+
in `risk/treatment`.
|
|
907
|
+
|
|
908
|
+
<a id="reference"></a>
|
|
909
|
+
**Reference:** Band, Engelsman, Feltus, González Paredes, Hietala, Jonkers, Massart,
|
|
910
|
+
[Modeling Enterprise Risk Management and Security with the ArchiMate Language](https://pure.unamur.be/ws/files/12366722/Modeling_Enterprise_Risk_Management_and_Secutity_with_the_ArchiMate_Language.pdf),
|
|
911
|
+
The Open Group white paper (ArchiMate 2.1). For the NIST OSCAL vocabulary used for names of assessment and evidence
|
|
912
|
+
fields see [OSCAL](https://pages.nist.gov/OSCAL/learn/concepts/layer/).
|
|
913
|
+
|
|
192
914
|
### Compliance Chain
|
|
193
915
|
|
|
194
916
|
Shows how requirements are satisfied:
|
|
@@ -254,6 +976,32 @@ Use annotations to capture metadata:
|
|
|
254
976
|
- `architecture/diagram` - A hand-drawn [`.asd` diagram](diagram.md#the-architecturediagram-annotation), shown next to the generated dependency graph
|
|
255
977
|
(`.asd` code blocks also render inside `architecture/description` markdown). Nodes can link to resources with `resource "Name"`.
|
|
256
978
|
|
|
979
|
+
### Lifecycle
|
|
980
|
+
|
|
981
|
+
`lifecycle/status` marks any resource with `architecture/*` annotations (products, components, services, artifacts, ...) as
|
|
982
|
+
`planned` (not yet in use), `active`, `deprecated` (do not start new uses), `sunset` (being phased out) or `end-of-life`
|
|
983
|
+
(no longer operated or supported). A resource without the annotation is `active`: the annotation's default, so
|
|
984
|
+
`lifecycle/status == "active"` finds it and the sidebar filter counts it (the editor does not write the default into the
|
|
985
|
+
file). The status shows as a badge (blue for `planned`, yellow for `deprecated`, red for `sunset` and `end-of-life`) and
|
|
986
|
+
is a sidebar filter and query term (`lifecycle/status == "deprecated"`).
|
|
987
|
+
|
|
988
|
+
| Annotation | Purpose |
|
|
989
|
+
|------------|---------|
|
|
990
|
+
| `lifecycle/status` | The state above |
|
|
991
|
+
| `lifecycle/activeAt`, `lifecycle/deprecatedAt`, `lifecycle/sunsetAt`, `lifecycle/endOfLifeAt` | When it happened or will happen (ISO 8601 date or time, checked by `archsight lint`) |
|
|
992
|
+
| `lifecycle/replacedBy` | The resource that replaces it: a name for a resource of the same kind, `Kind/Name` for another kind (a component replaced by an `ApplicationService/...`). Shown as a link, `archsight lint` checks that it exists |
|
|
993
|
+
| `lifecycle/reason` | Why, in markdown |
|
|
994
|
+
|
|
995
|
+
```yaml
|
|
996
|
+
kind: ApplicationService
|
|
997
|
+
metadata:
|
|
998
|
+
name: LegacyExport
|
|
999
|
+
annotations:
|
|
1000
|
+
lifecycle/status: sunset
|
|
1001
|
+
lifecycle/sunsetAt: 2027-03-31
|
|
1002
|
+
lifecycle/replacedBy: ApplicationService/ExportV2
|
|
1003
|
+
```
|
|
1004
|
+
|
|
257
1005
|
## Common Patterns
|
|
258
1006
|
|
|
259
1007
|
### Microservice
|