integrations.microsoft_defender_for_cloud — version 0.7
Source: presets
Purpose
Microsoft Defender for Cloud — GCP onboarding, the foundation.
Defender onboards a GCP organization through workload identity federation: no service-account keys leave the estate. Microsoft's portal generates a per-customer Terraform/gcloud script; this pack is that script as Satz, with the customer-specific values as params and Microsoft's own values inlined — they are the same for every customer and are not params.
This file is the foundation every Defender deployment needs: the management project, its APIs, the workload identity pool, and the auto-provisioner plan that Microsoft always creates. One fragment per LICENSED PLAN goes beside it:
use "presets/integrations/microsoft-defender-for-cloud-cspm.satz" when mdc_plan_cspm use "presets/integrations/microsoft-defender-for-cloud-cspm-role-default.satz" when mdc_cspm_default_access
Required from the estate: customer_organization_id. The management project
takes billing_account_infra unless the estate sets billing_account on it,
and it is created in the folder mdc_mgmt_project_folder names — under the
organisation while that param says nothing.
WHY the plans are separate files and not a list param: a pack cannot add to
another fragment's project — two fragments defining one project is a fold
conflict, and lists replace rather than concatenate. So this file owns the
project and its complete API list, and each plan fragment declares its own
resources at top level, naming the project through mdc_mgmt_project_id.
NO CLAIM is made here. Defender for Cloud is an external CSPM that READS the estate; it implements no CIS control and contributes to none.
BEFORE THE FIRST APPLY, one estate-side prerequisite: a deny-all on
iam blocks the providers below. The estate must allow
the sts.windows.net/<microsoft tenant> issuer, or document the exception.
The pack adds nothing to allowed: the service accounts it
grants roles to are created in the management project. The agentless-scanning plan
grants roles to
service,
which lives in a Microsoft-owned project; that plan is not in the library, and an estate
that onboards it another way adds that account to allowed
itself, or the managed §1.1 constraint refuses the grant.
Use it
params {
// the pack's own defaults — copy only the lines you change
mdc_workload_pool_id = ""
mdc_mgmt_project_id = ""
mdc_mgmt_project_folder = ""
mdc_plan_cspm = false
mdc_cspm_default_access = false
mdc_cspm_least_privilege = false
}
use "presets/integrations/microsoft-defender-for-cloud.satz"
Needs from outside the pack:
customer_organization_id— declared byestate_core; use one of them alongside, or declare it in the estate.
Params
| param | default |
|---|---|
mdc_workload_pool_id |
"" |
mdc_mgmt_project_id |
"" |
mdc_mgmt_project_folder |
"" |
mdc_plan_cspm |
false |
mdc_cspm_default_access |
false |
mdc_cspm_least_privilege |
false |
Questions
What to ask before this pack is configured, and what changing the answer costs.
| asks about | prompt | reversal | blast | recommends |
|---|---|---|---|---|
mdc_workload_pool_id |
The customer's Microsoft Entra tenant id without dashes — the workload identity pool id from Microsoft's generated onboarding script | recreate | high | — |
mdc_mgmt_project_id |
The management project Defender is onboarded through | recreate | high | — |
mdc_mgmt_project_folder |
The folder the Defender management project is created in — a folder the estate declares as google_folder.<label>.name, an existing one by its numeric id, or empty for the organisation |
edit | low | — |
mdc_plan_cspm |
Is the Defender CSPM plan licensed for this customer? | edit | low | — |
mdc_cspm_access (choice) |
Which access does CSPM get? | edit | low | — |
mdc_workload_pool_id — It is per customer and cannot be guessed. The pool is created with this id; a different id is a new pool, and Defender's connector has to be onboarded again.
mdc_mgmt_project_id — Customers name projects their own way, so there is no default. The pool, the provider and the service accounts are created in this project; moving them is a new onboarding.
mdc_mgmt_project_folder — It is the only thing that decides where the project lands. Left empty, the project is created directly under the organisation and inherits the organisation's policies and IAM alone. Changing it afterwards moves a live project between parents, which changes the policies and the grants the workload identity pool and the service accounts inside it inherit.
An empty answer, "", is an answer: the organisation itself; the project is created directly under it.
mdc_plan_cspm — Each licensed plan pulls in its fragment with the roles that plan needs. A plan that is on without a licence grants roles nothing uses; one that is off with a licence leaves the connector without access.
mdc_cspm_access — Switching later replaces the custom role and its binding; both modes true is a fold conflict on the role address, which is the loud failure it should be.
mdc_cspm_default_access— Default access — roles/viewer plus a five-permission custom role (Microsoft's default; the smaller surface to reason about.)mdc_cspm_least_privilege— Least privilege — a custom role enumerating 82 permissions instead of viewer (For a customer who will not grant roles/viewer to a third party.)
Contributes
| resource type | labels |
|---|---|
google |
mdc_auto_provisioner |
google |
MDCCustomRole |
google |
service |
google_project |
mdc_mgmt |
google |
service_account_id (grant map), principalSet: |
Claims
None — this pack proves no control by itself.
History
| version | date | change |
|---|---|---|
| 0.7 | 2026-10-14 | mdc_mgmt_project_folder says what an empty answer means — the organisation itself — so an estate that binds "" has answered the question; before, "" counted as unanswered although the prompt offered it. Nothing emitted changes |
| 0.6 | 2026-09-30 | contributes nothing to allowed: the agentless disk-scanning account it contributed is granted nothing by this pack — the grant belongs to the agentless-scanning plan, which the library does not ship. The header and the plan note say the per-plan audiences, service accounts and role sets are Microsoft's constants, identical in generated scripts for different tenants |
| 0.5 | 2026-09-22 | contributes the agentless disk-scanning account to allowed instead of naming it as a manual prerequisite in the header |
| 0.4 | 2026-09-21 | a question for mdc_mgmt_project_folder: the folder the Defender management project is created in. The param is now the only thing that decides — a use line no longer stands in a folder's body — so the interview asks for it. Answering it empty creates the project under the organisation, which is where every estate that binds nothing has it today |
| 0.3 | 2026-09-21 | mdc_mgmt_project_folder: the folder the Defender management project is created in, said by the estate instead of read from the node the use line stands in. The default is empty, which says nothing — the enclosing node decides, exactly as before — so no estate's plan moves. An estate whose use "presets stands inside a folder's body writes mdc_mgmt_project_folder = "google for that folder and may then move the use line to the top level: the emitted HCL is byte-identical either way. A folder that already exists rather than being declared here is named by its id, "123456789012" |
| 0.2 | 2026-09-10 | four question blocks: the two ids only Microsoft's wizard knows (both block until typed), whether CSPM is licensed, and — only when it is — the access mode as a oneof under ask_when, the library's first gated choice. Nothing emitted changes |
| 0.1 | 2026-09-03 | first cut — the foundation of Microsoft's GCP onboarding as Satz: management project + its API set, the workload identity pool, the auto-provisioner plan and its custom role. Transcribed from a customer's generated wizard Terraform; Microsoft's own tenant, application-id audiences, provider ids and role ids are inlined constants, the customer's Entra tenant and the management project id are params |
The whole library's history: the changelog in presets/CHANGELOG.md.
Notes
The scanning service account belongs to a Microsoft-owned project, so it must be in the CIS pack's allowed BEFORE any grant to it is applied — otherwise the domain-restriction policy refuses the grant and the connector never finishes.
This is the foundation: the project, the workload identity pool and the CSPM plan's oneof. The plan fragments themselves are added to the estate by hand — …cspm with one of the two role fragments.
Defender reads the estate; it makes no claims, and nothing here is a compliance witness.