Skip to main content

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, and export
  • 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:

modules/self_collect.alloy
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:

config.alloy
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.alloy
import.git "shared" {
repository = "https://github.com/example/alloy-modules.git"
path = "modules/self_collect.alloy"
revision = "main"
}
import_http.alloy
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
note

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>.value is the correct way to access argument values.
  • Path errors: import.file paths are resolved relative to module_path or the current file.
  • Overly large modules: Keep modules focused and composable.

Summary

You now know how to build reusable custom components in Alloy:

  1. declare defines new components
  2. argument and export manage inputs and outputs
  3. import.file, import.git, and import.http load 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?

Question 1/5