Entities Overview¶
Entities are the core data model of the Amadla ecosystem. Each entity type defines a schema for a specific kind of requirement — applications, systems, infrastructure, secrets, etc.
What Are Entities?¶
In Amadla, an entity is a versioned, schema-validated YAML document that describes a requirement. Instead of writing imperative scripts ("install nginx, configure it like this"), you write declarative entities ("this application needs nginx >=1.24 with TLS").
Entity definitions live in the Entities/ directory structure, each with a <name>.hery.json schema file at its root (e.g., application.hery.json, package.hery.json):
Entities/
├── Application/ # + DB/, IAM/, WebServer/, Timekeeping/, Logging/,
│ # Monitoring/, Backup/, DNSResolver/, MailRelay/, LogShipping/
├── Container/
├── Cron/
├── Infrastructure/ # + Cloud/, Container/, VM/
├── Judge/
├── OS/ # + Preference/
├── Package/
├── ProgrammingLanguage/ # + PHP/
├── Secret/
├── Security/ # + Certificate/, Firewall/, IDS/, Network/, SELinux/
├── Service/
├── System/ # + CPU/, Filesystem/, Memory/, Network/
├── Template/
├── Tools/
└── User/
Entity Types¶
Top-level types¶
| Entity | Describes | Used By |
|---|---|---|
| Application | Application requirements (packages, services, healthchecks) | lay, waiter, judge |
| Container | Container/image definitions (Docker Compose-inspired) | lay, waiter |
| Cron | Scheduled tasks (cron expressions, systemd timers) | enjoin |
| Infrastructure | Infrastructure requirements (provider, region, SSH) | raise |
| Judge | Audit/validation rule definitions | judge |
| OS | Operating system identity (distro, version, arch, init) | lay, enjoin, raise, unravel |
| Package | System package installation (apt, yum, dnf, pacman, brew) | lay, garbage |
| ProgrammingLanguage | Language runtime requirements | lay |
| Secret | Secret references and metadata | doorman |
| Security | Security posture and baseline configuration | enjoin, judge |
| Service | Systemd service configuration | enjoin, weaver |
| System | System configuration (hostname, timezone, sysctl, limits) | enjoin, raise |
| Template | Template configuration (engine, source, output) | weaver |
| Tools | Tool inventory and discovery configuration | amadla |
| User | System users and groups | enjoin, doorman |
Sub-types¶
| Entity | Parent | Describes | Used By |
|---|---|---|---|
| Application/DB | Application | Database engine, auth, databases to create | lay, doorman |
| Application/DB/RDBMS | Application/DB | Migrations, replication, backup, connection pooling | lay, weaver |
| Application/IAM | Application | Identity providers, OAuth2/OIDC clients, users | lay, doorman |
| Application/WebServer | Application | Virtual hosts, locations, SSL, proxying | lay, weaver |
| Application/Timekeeping | Application | Time synchronization (common: servers, pools) | lay, enjoin-service |
| Application/Timekeeping/NTP | Application/Timekeeping | ntpd configuration | lay, weaver |
| Application/Timekeeping/Chrony | Application/Timekeeping | chrony configuration | lay, weaver |
| Application/Timekeeping/Timesyncd | Application/Timekeeping | systemd-timesyncd configuration | enjoin |
| Application/Timekeeping/OpenNTPD | Application/Timekeeping | OpenNTPD configuration | lay, weaver |
| Application/Timekeeping/PTP | Application/Timekeeping | Precision Time Protocol (linuxptp) | lay, weaver |
| Application/Logging | Application | Log management (common: log_dir, retention, remote) | lay, weaver |
| Application/Monitoring | Application | Monitoring agents (common: listen, interval, tags) | lay, weaver |
| Application/Backup | Application | Backup (common: schedule, retention, encryption, paths) | lay, weaver |
| Application/DNSResolver | Application | Local DNS resolution/caching | lay, weaver |
| Application/MailRelay | Application | System mail relay (common: relay_host, TLS, auth) | lay, weaver |
| Application/LogShipping | Application | Centralized log forwarding (common: inputs, output) | lay, weaver |
| Infrastructure/Cloud | Infrastructure | Cloud instances (AWS, Hetzner, DigitalOcean) | raise |
| Infrastructure/Container | Infrastructure | Container runtime setup, registry access | raise, lay |
| Infrastructure/VM | Infrastructure | Virtual machines (libvirt, VirtualBox, VMware) | raise |
| OS/Preference | OS | Preferred system tools per concern | lay, enjoin |
| ProgrammingLanguage/PHP | ProgrammingLanguage | PHP extensions, php.ini, FPM pools, Composer | lay, weaver |
| Security/Certificate | Security | TLS/SSL certificate provisioning | enjoin-certificate |
| Security/Firewall | Security | Firewall rules, default policies, NAT, rate limiting | enjoin-firewall |
| Security/IDS | Security | Intrusion detection/prevention (fail2ban, OSSEC) | enjoin |
| Security/Network | Security | Network security posture: TLS, isolation, hardening | enjoin-network |
| Security/SELinux | Security | SELinux policies, booleans, contexts | enjoin-selinux |
| System/CPU | System | CPU resource constraints | enjoin, raise |
| System/Filesystem | System | Volumes, mounts, tmpfs | enjoin-filesystem |
| System/Memory | System | Memory resource constraints | enjoin, raise |
| System/Network | System | Network configuration (IPAM, ports, DNS) | enjoin-network, raise |
Custom Entities¶
The built-in entity types listed above have direct support in Amadla's tools — each tool knows how to read and act on specific entity types via its info response. But you are not locked in to only using these types.
You can create your own entity types with your own JSON Schemas. Custom entities won't be handled by the built-in tools (they don't know about your schema), with one exception: weaver. Because weaver's routing is driven by the Template entity's entity_types field, you can write templates that target any entity type — including your own custom ones. Weaver doesn't care what the entity type is, only that a template declares it can render for it.
For anything beyond templating, you can write your own tools that understand your custom entities. These tools just need to follow the plugin protocol (stdin/stdout, info subcommand, exit codes) and can be added to your tools.hery so that the amadla orchestrator discovers and runs them alongside the built-in tools.
# Your custom entity
_type: myorg.com/entity/monitoring@v1.0.0
_body:
agent: datadog
api_key_secret: monitoring/datadog/api-key
checks:
- name: nginx
port: 80
# A template that targets your custom entity
_type: amadla.org/entity/template@v1.0.0
_body:
engine: jinja2
source: ./templates/datadog.yaml.j2
output: /etc/datadog-agent/conf.d/nginx.yaml
entity_types:
- myorg.com/entity/monitoring@^v1.0.0
# Your custom tool in tools.hery
_type: amadla.org/entity/tools@v1.0.0
_body:
tools:
- name: hery
- name: lay
- name: weaver
- name: my-monitoring-tool
path: /opt/myorg/bin/my-monitoring-tool
How Entities Connect¶
Entities compose via JSON Schema $ref. The schema declares which parts of _body correspond to other entity types. No HERY-specific markup is needed inside _body — composition is handled at the schema level.
Entities declare dependencies using _requires — the 5th reserved HERY property (Draft 3.5). amadla builds a dependency graph (DAG) from _requires declarations and topologically sorts to determine execution order.
Application (my-web-app)
├── _requires:
│ └── amadla.org/entity/application/db/rdbms@^v1.0.0
└── _body:
├── network (via $ref to Network schema)
├── database (via $ref to Database schema)
├── secrets (via $ref to Secret schema)
└── infrastructure (via $ref to Infrastructure schema)
The directory path determines merge behavior: same path = override (deep merge, child wins), different path = accumulate (new entry).
Entity identity is derived from the git path (directory position in repo), not declared in the document. One addressable element = one file — multi-document YAML is only for anonymous accumulation.
This graph is what makes Amadla resource-centric: each resource declares its own requirements, and those requirements flow outward to inform provisioning, configuration, deployment, and auditing.
Schema Validation¶
Every entity's _body is validated against a JSON Schema defined in the entity's repository. This ensures:
- Consistent data structure across all instances
- Early detection of configuration errors
- Machine-readable requirement definitions
Entity Development¶
Entity types are developed alongside tools, driven by quickstart demos:
- nginx-hello — static files, no container (hery, weaver, lay)
- nginx-container — single container (+ waiter, Quadlet)
- wordpress-compose — multi-container (+ doorman, multi-container entities)
- wordpress-multi — two nodes (+ conduct, topology entity)
Each quickstart reveals which entities are actually needed — no speculative entity design.