Skip to content

Repository files navigation

Terraform AzAPI Security Copilot Compute Capacity

Microsoft Security Copilot compute capacities (billable SCUs), map-driven through azapi, with first-class overage and data-residency controls and cost checks on every plan.

CI Release Terraform Registry License


Overview

Microsoft.SecurityCopilot/capacities has no azurerm resource, so the module drives it through azapi. One map entry per capacity, keyed by resource name.

COST, first-class: the provisioned baseline (number_of_units) bills per SCU-hour for every hour the capacity EXISTS, used or not. The cost lever is capacity lifetime, not prompt volume: apply it last, destroy it first. Overage is optional and OMITTED from the request unless configured; overage units bill only for usage above the baseline, at the higher pay-as-you-go rate, so they are a throttling safety valve rather than a cost saver. Limited overage requires a bound; Unlimited overage and cross-geo compute are legal but each trips an informational check on every plan, so neither is ever a surprise.

Residency, explicit: geo pins where evaluation happens (EU, US or UK); cross_geo_compute = "NotAllowed" (the default) keeps it strict.

The capacity is the deployment half of Security Copilot only. Runtime prompting is delegated on-behalf-of by platform design (no application permission exists for the Graph data plane today), so automation prompts through the first-party securitycopilot Logic Apps connector, not through Terraform.

Usage

module "security_copilot_capacity" {
  source  = "libre-devops/security-copilot-compute-capacity/azapi"
  version = "~> 2.0"

  resource_group_id = module.rg.ids["rg-ldo-uks-prd-001"]
  location          = "uksouth"
  tags              = module.tags.tags

  compute_capacities = {
    "sccapldouksprd01" = {
      geo             = "UK"
      number_of_units = 1
      overage_state   = "Limited"
      overage_amount  = 1
    }
  }
}

Examples

  • examples/minimal - one capacity on defaults: 1 SCU, strict residency, no overage.
  • examples/complete - limited overage with a bound, module and per-capacity tags, and the exported properties as outputs.

The examples bill when applied. There is deliberately NO live self-test in CI: verification is the mocked terraform test suite plus the offline gates, and the live proof is a deliberate, human-attended window in a consuming estate. If you apply an example yourself, destroy it in the same sitting.

Developing

Local work needs PowerShell 7+ and just, because the recipes wrap the LibreDevOpsHelpers PowerShell module (the same engine the libre-devops/terraform-azure action runs in CI). Install just with brew install just, or uv tool add rust-just then uv run just <recipe>.

Run just to list recipes: just update-ldo-pwsh, just validate, just scan, just pwsh-analyze, just test, and just docs. The plan/apply/destroy/e2e recipes exist but REMEMBER THE BILL: an applied example provisions real SCUs, so just e2e (apply then always destroy) is the only sane live shape, run deliberately and attended. Releasing is also just: just increment-release [patch|minor|major] bumps, tags, and publishes a GitHub release, and the Terraform Registry picks up the tag.

Security scan exceptions

This module is scanned with Trivy; HIGH and CRITICAL findings fail the build. Any waiver is a deliberate, reviewed decision, never a way to quiet a finding that should be fixed. Waivers live in .trivyignore.yaml (the machine-applied source of truth, passed to Trivy with --ignorefile) and are mirrored in the table below so the reason is auditable.

Trivy ID Resource Finding Justification
None

To add an exception: add an entry to .trivyignore.yaml (id, optional paths to scope it, and a statement recording why), then add a matching row here. Both the file and this table are reviewed in the pull request.

Reference

The Requirements, Providers, Inputs, Outputs, and Resources below are generated by terraform-docs.

Requirements

Name Version
terraform >= 1.9.0, < 2.0.0
azapi >= 2.5.0, < 3.0.0

Providers

Name Version
azapi >= 2.5.0, < 3.0.0

Modules

No modules.

Resources

Name Type
azapi_resource.this resource

Inputs

Name Description Type Default Required
api_version API version for Microsoft.SecurityCopilot/capacities, without the '@' prefix. Preview only today; variablised so it is never pinned to a stale value. string "2024-11-01-preview" no
compute_capacities Security Copilot compute capacities (Microsoft.SecurityCopilot/capacities) keyed by resource name.

COST: the provisioned baseline (number_of_units) bills per SCU-hour for every hour the capacity
EXISTS, used or not; the cost lever is capacity lifetime, not prompt volume. Overage is optional
and OMITTED unless overage_state is set: overage units bill only for usage ABOVE the baseline, at
the higher pay-as-you-go rate, so they are a throttling safety valve rather than a cost saver.
Limited overage needs an overage_amount bound; Unlimited deliberately has none (a check makes that
visible on every plan).

geo pins data residency for evaluation; cross_geo_compute controls whether evaluation may burst
outside it when local capacity is constrained (NotAllowed, the default, keeps residency strict).
map(object({
number_of_units = optional(number, 1)
geo = string
cross_geo_compute = optional(string, "NotAllowed")
overage_state = optional(string)
overage_amount = optional(number)

tags = optional(map(string))

response_export_values = optional(list(string), ["*"])
ignore_missing_property = optional(bool, true)
ignore_null_property = optional(bool, true)
ignore_casing = optional(bool, true)
}))
{} no
location Azure region for the capacities. Verify the resource provider's supported regions; the geo (data residency) is set per capacity. string n/a yes
resource_group_id Resource id of the resource group the capacities deploy into. string n/a yes
schema_validation_enabled azapi schema validation for the resource body. Off by default: the API is preview and its published schema lags the accepted properties. bool false no
tags Tags applied to every capacity; per-capacity tags merge over them by key. map(string) {} no

Outputs

Name Description
capacities Map of capacity name to { id, name, location, units, geo, cross_geo_compute, overage_state, overage_amount, and the raw exported properties }.
capacity_ids Map of capacity name to its resource id.

About

A module used to deploy Security Copilot

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages