Provision Machine Learning resources using Terraform
Use the Grafana Terraform provider to manage Grafana Machine Learning resources as code. This lets you create, version, and maintain forecasts, outlier detectors, and their alert rules with the rest of your infrastructure as code.
Forecasts
The following example creates a forecast with custom training settings:
resource "grafana_machine_learning_job" "cpu_forecast" {
name = "CPU usage forecast"
metric = "cpu_usage_forecast"
datasource_type = "prometheus"
datasource_uid = grafana_data_source.prometheus.uid
query_params = {
expr = "avg(rate(node_cpu_seconds_total{mode!=\"idle\"}[5m])) * 100"
}
description = "Forecasts average CPU usage across all nodes"
training_window = 7776000 # 90 days
interval = 300 # 5 minutes
holidays = ["US"]
custom_labels = {
team = "infrastructure"
}
hyper_params = {
weekly_seasonality = "10"
daily_seasonality = "15"
}
}The following table describes the available forecast properties. Hyperparameters are configured separately in the hyper_params field and are detailed in the sections below.
Prophet hyperparameters
The following are hyperparameters that can be tuned for the Prophet model.
The ‘Terraform’ bullet points indicate the key of the hyperparameter to use in the hyper_params field of the grafana_machine_learning_job resource when provisioning with Terraform.
Changepoint Prior Scale
- Default: 0.05
- Minimum: 0.001
- Maximum: 10.0
- Terraform:
changepoint_prior_scale
Determines the flexibility of the trend and in particular how much the trend changes at the trend changepoints. If it is too small the trend will be underfit and variance that should have been modeled with trend changes will instead end up being handled with the noise term. If it is too large the trend will overfit and in the most extreme case you can end up with the trend capturing yearly seasonality. A range of [0.001, 0.5] would likely be about right.
Changepoint Range
- Default: 0.8
- Minimum: 0.01
- Maximum: 1.0
- Terraform:
changepoint_range
Controls what portion of the training data to check for changepoints. For the default value of 0.8, the first 80% of the data is checked for changepoints, and changepoints in the remaining 20% of data are ignored.
Seasonality Prior Scale
- Default: 10.0
- Minimum: 0.01
- Maximum: 10.0
- Terraform:
seasonality_prior_range
Controls the flexibility to fit the seasonality. A large value allows the seasonality to fit large fluctuations, whereas a small value shrinks the magnitude of the seasonality.
Uncertainty Interval Width
- Default: 0.95
- Minimum: 0.01
- Maximum: 1
- Terraform:
interval_width
Uncertainty intervals (yhat_upper, yhat_lower) are computed as quantiles of the predicted value to use. The default value of 0.95 provides a 95% confidence interval. 95% of future data should be expected to be between (yhat_upper, yhat_lower).
Seasonality Mode
- Default: additive
- Options: additive, multiplicative
- Terraform:
seasonality_mode
Set to multiplicative if it appears that the magnitude of seasonal fluctuations grows with the magnitude of the time series.
Growth
- Default: linear
- Options: flat, linear, logistic
- Terraform:
growth
The type of model used for the growth trend component. The available options are:
flat: Use only when you’re certain the trend is constant and the time series mostly exhibits seasonality patterns rather than trend changes. Reduces the width of uncertainty intervals in such cases.linear: Use when the metric grows at a constant rate. For example, disk space consumed by a steady rate of write operations.logistic: Use when the metric has a known maximum value. The forecast saturates at the specified cap. An optional floor may also be specified.
Logistic Cap
- Terraform:
logistic_growth_cap
Expected maximum achievable value (required if and only if growth is logistic).
Logistic Floor
- Terraform:
logistic_growth_floor
Expected minimum achievable value (optional).
Weekly Fourier Order
- Default: 3
- Minimum: 0 (disabled)
- Maximum: 25
- Terraform:
weekly_seasonality
How many Fourier orders to use to calculate weekly seasonality. If you leave the value empty, the value defaults to 3 when the training data range is larger than two weeks, and seasonality is then disabled on training data ranges under two weeks. Setting the Fourier order to 0 will disable weekly seasonality. Note that if a separate weekly seasonality for a holiday is configured, it is not possible to disable weekly seasonality.
If there is a strong weekday vs weekend component to your data it is recommended to use a Fourier order between 10 and 25.
Separate weekly seasonality for holiday
Optionally, a holiday for which weekly seasonality should be modelled separately. This allows the model to capture the fact that the holiday may have a different day-of-week effects to non-holidays. For example, public holidays may not show the same weekday effects as non-holidays.
- Terraform:
conditional_weekly_seasonality(must be set to the ID of a linked holiday)
Daily Fourier Order
- Default: 4
- Minimum: 0 (disabled)
- Maximum: 25
- Terraform:
daily_seasonality
How many Fourier orders to use when calculating daily seasonality. Leaving this value empty will use the default of 4 when the training data range is larger than two days, and disable seasonality on smaller training data ranges. Setting the Fourier order to 0 will disable daily seasonality. Note that if a separate daily seasonality for a holiday is configured it is not possible to disable daily seasonality.
Separate daily seasonality for holiday
Optionally, a holiday for which daily seasonality should be modelled separately. This allows the model to capture the fact that the holiday may have a different hour-of-day effects to non-holidays. For example, public holidays may not show the same spike during work hours as non-holidays.
- Terraform:
conditional_daily_seasonality(must be set to the ID of a linked holiday)
Holidays Prior Scale
- Default: 10.0
- Minimum: 0.01
- Maximum: 10.0
- Terraform:
holidays_prior_scale
Controls the flexibility to fit holidays. A large value allows fitting to large fluctuations on holidays, whereas a small value shrinks the impact of those fluctuations on the fit.
Holidays
The following example creates a holiday to define time periods where the signal is expected to behave differently from normal.
resource "grafana_machine_learning_holiday" "company_shutdown" {
name = "Company shutdown"
description = "End-of-year company shutdown"
custom_periods {
name = "Winter shutdown 2025"
start_time = "2025-12-24T00:00:00Z"
end_time = "2026-01-02T00:00:00Z"
}
}You can then reference holidays in a grafana_machine_learning_job resources using the holidays property. A holiday requires either ical_url or at least one custom_periods block.
Outlier detectors
The following examples create outlier detectors using the MAD and DBSCAN algorithms:
resource "grafana_machine_learning_outlier_detector" "mad_detector" {
name = "Memory usage outlier detector"
metric = "memory_usage_outliers"
datasource_type = "prometheus"
datasource_uid = grafana_data_source.prometheus.uid
query_params = {
expr = "avg by (instance) (node_memory_MemUsed_bytes)"
}
interval = 300
description = "Detects instances with abnormal memory usage"
algorithm {
name = "mad"
sensitivity = 0.7
}
}
resource "grafana_machine_learning_outlier_detector" "dbscan_detector" {
name = "Request rate outlier detector"
metric = "request_rate_outliers"
datasource_type = "prometheus"
datasource_uid = grafana_data_source.prometheus.uid
query_params = {
expr = "sum by (service) (rate(http_requests_total[5m]))"
}
interval = 300
algorithm {
name = "dbscan"
sensitivity = 0.5
config {
epsilon = 1.0
}
}
}

