Antora Architecture Reference

This reference explains how the Domus documentation system works - what each file does, how navigation is structured, and the rules for writing content.

The Three Layers

Antora documentation has three distinct layers:

Layer What It Provides Defined By

Playbook

Site aggregation, component sources, UI bundle

antora-playbook.yml (domus-docs)

Component

Content, attributes, left navigation

antora.yml + nav.adoc (each repo)

UI Bundle

Right-side TOC, styling, layout, search

domus-antora-ui (Handlebars templates)

File Responsibilities

antora-playbook.yml (Site Level)

Location: domus-docs/antora-playbook.yml

Defines:

  • Site title and URL

  • Which components to aggregate

  • UI bundle location

  • Global AsciiDoc extensions

site:
  title: Domus Digitalis
  url: https://docs.domusdigitalis.dev
  start_page: home::index.adoc

content:
  sources:
    - url: https://github.com/EvanusModestus/domus-ise-linux
      branches: main
      start_path: docs/asciidoc

ui:
  bundle:
    url: ./ui-bundle.zip    # domus-antora-ui output

antora.yml (Component Level)

Location: Each repo at docs/asciidoc/antora.yml

Defines:

  • Component name (used in URLs and xrefs)

  • Version

  • Navigation file reference

  • AsciiDoc attributes

name: ise-linux                    # URL: /ise-linux/...
title: ISE Linux 802.1X            # Display name
version: '2026'                    # URL: /ise-linux/2026/...
nav:
  - modules/ROOT/nav.adoc          # Left sidebar navigation

asciidoc:
  attributes:
    ad-dc-ip: 10.50.1.50           # Use as \{ad-dc-ip} in pages
    port-kerberos: 88

nav.adoc (Left Navigation)

Location: modules/ROOT/nav.adoc

Defines: Left sidebar navigation tree for this component only.

* xref:index.adoc[Overview]
* Runbooks
** xref:runbooks/linux-ad-auth-dacl.adoc[Linux AD Auth dACL]
** xref:runbooks/vault-pki.adoc[Vault PKI]
* Architecture
** xref:architecture/network.adoc[Network Design]

UI Bundle (Right TOC + Styling)

Location: domus-antora-ui/ (separate repo)

Provides:

  • Right-side page TOC - auto-generated from == headings

  • Site header and footer

  • Component selector dropdown

  • Search (Lunr integration)

  • Dark/light theme

  • All CSS styling

The UI bundle is built with npx gulp bundle and outputs ui-bundle.zip.

The Two TOCs

This is critical to understand:

Antora Page Layout
TOC Source Purpose

Left Navigation

nav.adoc referenced in antora.yml

Navigate between pages in this component

Right Page TOC

UI bundle (automatic from headings)

Jump to sections within current page

Why NO :toc: in Pages

Adding :toc: attributes in individual .adoc files creates a third TOC in the content area:

// WRONG - creates duplicate TOC
= My Page

== Section 1
...

This creates three TOCs instead of two - the inline TOC is redundant and clutters the content area.

Correct page header:

= My Page
:description: Brief description
:navtitle: Short Nav Title
:icons: font

== Section 1
...

URL to File Mapping

URLs map predictably to file paths:

https://docs.domusdigitalis.dev/ise-linux/2026/runbooks/linux-ad-auth-dacl.html
                                 │         │    │        └── pages/runbooks/linux-ad-auth-dacl.adoc
                                 │         │    └── pages/runbooks/
                                 │         └── version (antora.yml)
                                 └── name (antora.yml)

Formula:

{site-url}/{component-name}/{version}/{page-path}.html
     ↓            ↓             ↓           ↓
playbook    antora.yml     antora.yml   modules/ROOT/pages/\{path}.adoc
            name:          version:

Finding source from URL:

# URL: https://docs.domusdigitalis.dev/ise-linux/2026/runbooks/linux-ad-auth-dacl.html
# File: domus-ise-linux/docs/asciidoc/modules/ROOT/pages/runbooks/linux-ad-auth-dacl.adoc

# Pattern:
# domus-\{component}/docs/asciidoc/modules/ROOT/pages/\{url-path}.adoc

Attributes: Define Once, Use Everywhere

Where Attributes Are Defined

Location Scope Example

antora-playbook.yml

All components (global)

attribute-missing: skip

antora.yml (component)

This component only

ad-dc-ip: 10.50.1.50

Page header

This page only (avoid)

:myvar: value

Using Attributes

// In pages - use curly braces
The domain controller is at {ad-dc-ip}.

// In code blocks - works automatically
[source,bash]
----
ping {ad-dc-ip}
----

// In tables
|DC IP |{ad-dc-ip}

Common Attributes (domus-ise-linux)

Attribute Value

{domain}

inside.domusdigitalis.dev

{ad-dc-ip}

10.50.1.50

{ise-pan-ip}

10.50.1.20

{port-kerberos}

88

{port-ldap}

389

{port-dns}

53

{vlan-data}

10

{cert-dir}

/etc/ssl/certs

Cross-Component References

Same Component (single colon or none)

xref:runbooks/vault-pki.adoc[Vault PKI]
xref:architecture/network.adoc[Network Design]

Different Component (DOUBLE colon required)

xref:netapi::cli/ise/backup.adoc[ISE Backup Commands]
xref:infra-ops::runbooks/backup-strategy.adoc[Backup Strategy]
xref:ise-linux::runbooks/linux-ad-auth-dacl.adoc[Linux AD Auth]

Component Namespaces

Namespace Repository

home::

domus-docs

infra-ops::

domus-infra-ops

ise-linux::

domus-ise-linux

netapi::

domus-netapi-docs

linux-ops::

domus-linux-ops

secrets-infrastructure::

domus-secrets-ops

Directory Structure

Standard Antora component layout:

domus-ise-linux/
├── docs/asciidoc/                    # Antora start_path
│   ├── antora.yml                    # Component descriptor
│   └── modules/
│       └── ROOT/                     # Default module
│           ├── nav.adoc              # Left navigation
│           ├── pages/                # Content (becomes HTML)
│           │   ├── index.adoc
│           │   └── runbooks/
│           │       └── linux-ad-auth-dacl.adoc
│           ├── partials/             # Reusable fragments
│           │   └── common-prereqs.adoc
│           ├── examples/             # Code includes
│           │   └── script.sh
│           ├── images/               # Static images
│           │   └── diagram.svg
│           └── attachments/          # Downloadable files
│               └── template.xlsx

Include Patterns

Partials (reusable content)

include::partial$common-prereqs.adoc[]

Examples (code files)

[source,bash]

include::example$install-script.sh[]


With Tags

In the source file:

# tag::install[]
sudo apt install package
# end::install[]

In your page:

include::example$script.sh[tags=install]

Attribute Conversion Process

When auditing or creating documentation, follow this process to ensure no hardcoded values slip through.

What MUST Be Attributes

Category Examples Attribute Pattern

IP Addresses

10.50.1.50, 192.168.1.1

{ad-dc-ip}, {ise-pan-ip}

Hostnames

modestus-aw, ise-01.domain.com

{ws-aw-hostname}, {ise-01-hostname}

MAC Addresses

14:F6:D8:7B:31:80

{ws-aw-wired-mac}

Domain Names

inside.domusdigitalis.dev

{domain}, {kerberos-realm}

Port Numbers

88, 389, 636

{port-kerberos}, {port-ldap}

Usernames

Administrator, Evan

{ad-admin-user}, {person-evan}

Policy Names

Linux-Research-AD-Auth

{dacl-ad-auth}, {authz-profile-ad-auth}

VLAN Names/IDs

DATA_VLAN, 10

{vlan-name-data}, {vlan-data}

File Paths

/etc/ssl/certs

{cert-dir}

Audit Process (Per Page)

Step 1: Identify hardcoded values

# Search for IP addresses
grep -E '\b[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\b' page.adoc

# Search for MAC addresses
grep -Ei '[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}' page.adoc

# Search for known hostnames
grep -E 'modestus-|home-dc|ise-0' page.adoc

# Search for domain names
grep -i 'domusdigitalis\|inside\.' page.adoc

Step 2: Check if attribute exists

Look in the component’s antora.yml under asciidoc.attributes.

Step 3: Add missing attributes to antora.yml

asciidoc:
  attributes:
    new-attribute: value-here

Step 4: Replace hardcoded values in page

  • In prose: The DC is at {ad-dc-ip}

  • In code blocks: Add subs=attributes+ to the block

Step 5: Verify rendering

Build the site and confirm attributes expand correctly.

Code Block Attribute Substitution

Attributes in code blocks require explicit opt-in:

[source,bash,subs=attributes+]
----
ping {ad-dc-ip}
DC_IP="{ad-dc-ip}"
----

Without subs=attributes+, the literal {ad-dc-ip} appears in output.

Shell Variables + Attributes Pattern

For runbooks where the same value is used repeatedly, combine shell variables with attributes:

[source,bash,subs=attributes+]
----
# Set once at top
DACL_NAME="{dacl-ad-auth}"
DC_IP="{ad-dc-ip}"

# Use throughout
netapi ise get-dacl "$DACL_NAME"
ping $DC_IP
----

This pattern:

  1. Attribute expands at render time ({dacl-ad-auth}Linux-Research-AD-Auth)

  2. Shell variable holds the value for the session

  3. Subsequent commands use $DACL_NAME (shorter, cleaner)

Site-Wide Audit Checklist

Repo Audit Status Notes

domus-ise-linux

linux-ad-auth-dacl.adoc complete

Other pages need audit

domus-infra-ops

Not audited

Runbooks likely have hardcoded values

domus-netapi-docs

Not audited

CLI examples may have IPs

domus-linux-ops

Not audited

Scripts may have hardcoded paths

domus-secrets-ops

Not audited

Vault paths/IPs likely hardcoded

Quick Reference

Task How

Find source from URL

domus-{component}/docs/asciidoc/modules/ROOT/pages/{path}.adoc

Add left nav entry

Edit nav.adoc, add * xref:path/page.adoc[Title]

Use attribute

{attribute-name} in content

Link same component

xref:path/page.adoc[Title]

Link other component

xref:component::path/page.adoc[Title]

Include partial

\include::partial$file.adoc[]

Include example

\include::example$file.ext[]