Building Custom Components with the Alloy Module System
Alloy supports custom components via the declare block and module imports via import.file, import.git, and import.http. This lets you package repeatable pipelines and share them across projects.
Learning Goals
- Understand
declare,argument, andexport - Import custom components from files and Git
- Organize reusable component libraries
- Apply best practices for module development
Declaring a Custom Component
A declare block defines a reusable component. Here is a minimal example that scrapes Alloy's own metrics and forwards them to a receiver provided by the caller:
declare "self_collect" {
argument "metrics_output" {
optional = false
comment = "Where to send collected metrics."
}
prometheus.exporter.self "self" {}
prometheus.scrape "selfmonitor" {
targets = prometheus.exporter.self.self.targets
forward_to = [argument.metrics_output.value]
}
}
Importing and Using a Module
Use import.file to load a module file and then instantiate your declared component:
import.file "modules" {
filename = file.path_join(module_path, "modules/self_collect.alloy")
}
modules.self_collect "example" {
metrics_output = prometheus.remote_write.default.receiver
}
prometheus.remote_write "default" {
endpoint {
url = "http://prometheus:9090/api/v1/write"
}
}
Importing from Git or HTTP
You can also import modules from external sources:
import.git "shared" {
repository = "https://github.com/example/alloy-modules.git"
path = "modules/self_collect.alloy"
revision = "main"
}
import.http "shared" {
url = "https://example.com/alloy/self_collect.alloy"
}
Organizing Module Libraries
A simple structure keeps modules reusable and discoverable:
alloy-configs/
|-- config.alloy
\-- modules/
|-- metrics/
| |-- self_collect.alloy
| \-- redis_scrape.alloy
|-- logs/
| |-- docker_logs.alloy
| \-- system_logs.alloy
\-- traces/
\-- otlp_receiver.alloy
You can also split configuration into multiple .alloy files and run a directory directly, like the course examples in docs/grafanaalloy/examples.
Common Pitfalls
- Circular dependencies: Modules can't import each other in loops.
- Argument misuse:
argument.<name>.valueis the correct way to access argument values. - Path errors:
import.filepaths are resolved relative tomodule_pathor the current file. - Overly large modules: Keep modules focused and composable.
Summary
You now know how to build reusable custom components in Alloy:
declaredefines new componentsargumentandexportmanage inputs and outputsimport.file,import.git, andimport.httpload modules from different sources
These tools make Alloy configurations cleaner, more consistent, and easier to share across teams.
Quiz
Alloy Module System - Quick Check
What is the primary purpose of the `argument` block in an Alloy module?