Grafana Cloud

Load configuration from remote sources

Alloy provides several methods to load an Alloy configuration from remote sources. Loading a configuration from a remote source doesn’t mean you point Alloy directly at a URL for a complete configuration file. You always start with a local configuration file. From that file, you import modules from remote sources or connect to a remote configuration API, such as Fleet Management in Grafana Cloud. The method you choose depends on your use case and infrastructure.

Before you begin

You should have a basic understanding of Alloy configuration syntax and modules.

How remote configuration works

Alloy supports two patterns for remote configuration.

  • Module imports: import.http, import.git, and import.file load Alloy modules into your local root configuration. Alloy fetches or watches the source. It reads the returned Alloy text as module content. It reevaluates the local configuration when the module changes.
  • Remote configuration API: remotecfg connects to a compatible remote configuration API. Alloy identifies the collector, sends its attributes, and polls the API for updates. The server decides which configuration to return.

If you want to read Alloy configuration text from a generic HTTP endpoint, use import.http. If you want a server to choose configuration based on collector identity or attributes, use remotecfg.

Choose a method

Use the following table to choose the appropriate method for your use case:

MethodUse case
import.httpLoad configuration from an HTTP server hosting static files.
import.gitLoad configuration from a Git repository with version control.
import.fileLoad configuration from a local file or directory.
remotecfgDynamically manage configuration through a remote configuration management API server.

Load from an HTTP server

Use import.http to load configuration modules from an HTTP server. This is the recommended approach when you have configuration modules hosted on a web server.

Alloy periodically makes HTTP requests to the configured URL and treats the response body as Alloy module content. The response doesn’t need a special API, a standard HTTP server that returns Alloy text is enough.

Alloy loads remote content with import.http and treats it as a module, not as a complete top-level configuration file. Modules define reusable components in declare blocks. After you import a module, add the components you need in your local configuration, or they won’t run.

Note

You can’t point Alloy directly at a remote URL on startup. At a minimum, you must have a local configuration file that uses import.http to import modules from the remote server.

The HTTP response body must contain Alloy module content, not a complete top-level configuration file.

Alloy periodically polls the URL to detect and apply configuration changes.

Module requirements

Modules can contain top-level declare blocks and nested import.* blocks. They can’t contain top-level configuration blocks such as logging or remotecfg. Set CLI flags when you start Alloy. You can’t set CLI flags inside modules.

The following example shows an invalid module. It includes a logging block, which isn’t allowed in modules:

Alloy
logging {
  level = "debug"
}

declare "pipeline" {
  prometheus.scrape "default" {
    targets = [{"__address__" = "localhost:9090"}]
  }
}

The following module is valid because it only contains declare blocks which is the simplest module pattern:

Alloy
declare "pipeline" {
  prometheus.scrape "default" {
    targets = [{"__address__" = "localhost:9090"}]
  }
}

Global configuration such as logging must remain in the local configuration file that imports the module.

Create the remote configuration file

Create a configuration file on your HTTP server. The file must be a valid Alloy module, using top-level declare blocks to define a reusable configuration that you import and instantiate locally.

The following example creates a reusable Prometheus scrape configuration:

Alloy
declare "scrape" {
  argument "targets" {}
  argument "forward_to" {}

  prometheus.scrape "default" {
    targets    = argument.targets.value
    forward_to = argument.forward_to.value
  }
}

Import the remote configuration

In your local configuration, import the remote file and use the declared component:

Alloy
import.http "remote" {
  url            = "http://<CONFIG_SERVER_ADDRESS>/prometheus_scrape.alloy"
  poll_frequency = "5m"
}

prometheus.remote_write "default" {
  endpoint {
    url = "http://<MIMIR_ADDRESS>/api/v1/push"
  }
}

remote.scrape "app" {
  targets    = [{"__address__" = "localhost:8080"}]
  forward_to = [prometheus.remote_write.default.receiver]
}

Replace the following:

  • <CONFIG_SERVER_ADDRESS>: The address of your HTTP server hosting the configuration file.
  • <MIMIR_ADDRESS>: The address of your Prometheus-compatible remote write endpoint.

You can load multiple remote modules by defining multiple import.http blocks in your local configuration file. Each block can point to a different module file on the remote server.

For example:

Alloy
import.http "metrics" {
  url = "http://config-server.example.com/metrics.alloy"
}

import.http "logs" {
  url = "http://config-server.example.com/logs.alloy"
}

Each imported module can define its own declare blocks and components.

If you need to manage many configuration files or directories, consider using import.git to load modules from a version-controlled repository.

Refer to import.http for more information.

Load from a Git repository

Use import.git to load configuration from a Git repository. This approach provides version control and supports authentication for private repositories. Alloy periodically pulls the repository to detect and apply configuration changes.

Alloy
import.git "modules" {
  repository     = "https://github.com/<ORGANIZATION>/<REPOSITORY>.git"
  revision       = "main"
  path           = "modules/prometheus.alloy"
  pull_frequency = "5m"
}

modules.scrape "app" {
  targets    = [{"__address__" = "localhost:8080"}]
  forward_to = [prometheus.remote_write.default.receiver]
}

prometheus.remote_write "default" {
  endpoint {
    url = "http://<MIMIR_ADDRESS>/api/v1/push"
  }
}

Replace the following:

  • <ORGANIZATION>: Your GitHub organization or username.
  • <REPOSITORY>: The name of your Git repository.
  • <MIMIR_ADDRESS>: The address of your Prometheus-compatible remote write endpoint.

Refer to import.git for more information.

Load from a local file

Use import.file to load configuration from a local file or directory. This is useful when you want to organize your configuration into separate files on the local filesystem. Alloy watches the file for changes and automatically applies updates.

Alloy
import.file "modules" {
  filename = "/etc/alloy/modules/prometheus.alloy"
}

modules.scrape "app" {
  targets    = [{"__address__" = "localhost:8080"}]
  forward_to = [prometheus.remote_write.default.receiver]
}

prometheus.remote_write "default" {
  endpoint {
    url = "http://<MIMIR_ADDRESS>/api/v1/push"
  }
}

Replace <MIMIR_ADDRESS> with the address of your Prometheus-compatible remote write endpoint.

Refer to import.file for more information.

Use dynamic remote configuration management

Use remotecfg when you need a configuration management server that can serve different configurations based on collector identity and attributes. This approach requires implementing or using a server that supports the alloy-remote-config API.

Note

The remotecfg block isn’t for loading static configuration files from an HTTP server. If you want to load a static configuration file from an HTTP server, use import.http instead.

The remotecfg block sends the collector’s id and attributes to the server, allowing the server to dynamically decide which configuration to serve.

Alloy
remotecfg {
  url            = "http://<REMOTECFG_SERVER_ADDRESS>"
  id             = constants.hostname
  attributes     = {"cluster" = "production", "environment" = "us-east-1"}
  poll_frequency = "5m"
}

logging {
  level  = "info"
  format = "logfmt"
}

Replace <REMOTECFG_SERVER_ADDRESS> with the address of your remote configuration management server.

Refer to remotecfg for more information.