Using Modules
Reusing and Parameterizing rescile Configurations
Modules are a powerful feature for creating reusable, shareable, and parameter-driven rescile configurations. While a module can be a self-contained set of models, compliance, and output files, providing these is not a requirement. Modules are much more powerful and act as a rescile platform for logic.
A module can exist solely to provide a custom web application (via the app folder), scaffold starter assets and inputs, or enforce type validation. They are packaged with a manifest file (module.toml) that defines their interface and capabilities.
This allows you to encapsulate a standard architecture, a set of compliance controls, a custom graph visualization, or a data bootstrapping utility into a single unit that can be easily consumed by different projects.
Why Use Modules?
- Reusability: Define a common architecture (e.g., a standard Kubernetes application setup) once and reuse it across multiple projects.
- Standardization: Enforce organizational standards by providing modules for common components like networking, security, or application scaffolding.
- Parameterization: Create flexible blueprints that can be customized at runtime with parameters, avoiding the need to copy and paste configurations.
- Sharing: Modules can be versioned in Git, allowing teams to share and collaborate on best-practice configurations.
- Platform Apps: Deliver interactive visualizers, exporters, or custom dashboards directly through the
rescile-ce serveinterface, even without defining any graph transformations.
Using a Module (--module)
You tell rescile to use a module with the --module command-line argument. This argument can point to either a local directory or a remote Git repository.
When the --module argument is used, rescile will look for models, compliance, and output directories inside the module’s path instead of the local data directory. The local data/assets and data/input directories are still used, allowing you to feed project-specific data into the reusable module logic.
# Use a module from a local directory
rescile-ce --data-dir ./my-project/data --module ./path/to/my-module serve
# Use a module from a Git repository (fetches the 'main' branch by default)
rescile-ce --module https://github.com/my-org/rescile-modules/my-app
# Use a specific branch, tag, or commit hash from a Git repository
rescile-ce --module https://github.com/my-org/rescile-modules/my-app:v1.2.0
Providing Module Parameters (--module-params)
When you use a module, you provide values for its defined parameters using the --module-params command-line argument. The format is a semicolon-separated list of key=value pairs.
rescile-ce --module ./my-module \
--module-params "app_name=billing-api;environment=prod" \
serve
These parameters are made available as global variables in all Tera templates within the module’s models, compliance, and output files.
For example, a model inside the module could access the app_name and environment parameters like this:
# In a model inside the module (e.g., models/server.toml)
origin_resource = "application"
[[create_resource]]
resource_type = "server"
name = "server-{{ app_name }}-{{ origin_resource.name }}"
[create_resource.properties]
tier = "{{ environment }}"
The module.toml Manifest
Every module must contain a module.toml file at its root. This file serves as the manifest, defining metadata, parameters, inputs, assets, and generators.
Here is a simple example of a generic module.toml:
[module]
name = "standard-webapp"
url = "https://github.com/my-org/rescile-modules/standard-webapp"
version = "1.0.0"
description = "A standard module for deploying a web application."
rescile_version = ">=0.1.85"
[dependencies]
# Simple dependency string
base-security = "https://github.com/my-org/rescile-modules/base-security:v1.0.0"
# Detailed Git dependency
other-module = { git = "https://github.com/my-org/rescile-modules/other.git", tag = "v1.0.0" }
# Detailed release archive dependency with a version template
packaged-module = { url = "https://github.com/my-org/rescile-modules/releases/download/{version}/module.zip", version = "v1.2.0" }
[params.environment]
description = "The deployment environment (e.g., dev, staging, prod)."
required = false
default = "dev"
allowed_values = ["dev", "staging", "prod"]
Dependency Resource Aliasing
Instead of enforcing strict namespaces, rescile uses dependency aliasing. This allows you to safely compose third-party modules without needing to modify their internal code, even if their resource names clash.
For example, consider a public_dns module. In standalone mode, it expects an auth.csv file (representing authoritative DNS zones) and operates on auth resources. However, if you integrate this into a larger enterprise blueprint, an auth resource might already exist for a completely different purpose (e.g., Identity & Access Management authentication records).
With aliasing, you transparently instruct the imported module to remap its internal references. When the module’s TOML files are processed, they still “think” they are accessing auth, but rescile internally redirects all reads, writes, and relations to dns_auth in the global graph.
You define these rules using the resource_aliases map within a detailed dependency block in your module.toml:
[module]
name = "enterprise-blueprint"
version = "1.0.0"
description = "A combined architectural graph"
# Import the DNS module and remap its 'auth' resource to 'dns_auth'
[dependencies.public_dns]
url = "https://github.com/rescile/public_dns"
resource_aliases = { "auth" = "dns_auth" }
# Another module can now safely use the standard 'auth' resource
[dependencies.identity_access]
url = "https://github.com/rescile/iam_module"
This will automatically and transparently:
- Translate
origin_resource = "auth"todns_authin the imported models. - Translate any
link_resources.with = "auth"andcreate_resource.resource_type = "auth"directives in the imported models. - Apply the same translation to compliance targets and output definitions.
This guarantees sandboxed execution, avoiding physical file collisions and graph topology corruption without touching the core graph processing loops or rewriting third-party modules.
Module Dependencies and Lockfiles
A module can depend on other modules. These dependencies are recursively resolved and fetched by rescile before building the graph.
To ensure reproducible builds, rescile supports a module.lock file which pins dependencies to exact commit hashes or checksums. The rescile-ce mod subcommand provides utilities to manage dependencies and lockfiles:
For the full reference on dependency declaration formats, lockfile commands (mod lock, mod check, mod update, mod fetch), and resource aliasing, see Module Dependencies & Lockfiles.
For detailed information on configuring modules, explore the following sections:
For the complete module.toml manifest reference and distribution guidance, see the Module Packaging Guide.