Configure Azure Defender for Cloud Pricing

The azure-native:security:Pricing resource, part of the Pulumi Azure Native provider, controls Microsoft Defender for Cloud pricing tier (free or standard) at subscription or resource level. This guide focuses on three capabilities: subscription-wide standard tier activation, sub-plan selection and enforcement, and resource-level pricing for individual VMs.

Pricing configurations reference existing Azure subscriptions and, for resource-level pricing, specific VM resource paths. The examples are intentionally small. Combine them with your own subscription structure and resource targeting strategy.

Enable standard tier for subscription-wide coverage

Organizations typically start by enabling Defender for Cloud at the subscription level, applying protection across all resources.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const pricing = new azure_native.security.Pricing("pricing", {
    pricingName: "CloudPosture",
    pricingTier: azure_native.security.PricingTier.Standard,
    scopeId: "subscriptions/20ff7fc3-e762-44dd-bd96-b71116dcdc23",
});
import pulumi
import pulumi_azure_native as azure_native

pricing = azure_native.security.Pricing("pricing",
    pricing_name="CloudPosture",
    pricing_tier=azure_native.security.PricingTier.STANDARD,
    scope_id="subscriptions/20ff7fc3-e762-44dd-bd96-b71116dcdc23")
package main

import (
	security "github.com/pulumi/pulumi-azure-native-sdk/security/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := security.NewPricing(ctx, "pricing", &security.PricingArgs{
			PricingName: pulumi.String("CloudPosture"),
			PricingTier: pulumi.String(security.PricingTierStandard),
			ScopeId:     pulumi.String("subscriptions/20ff7fc3-e762-44dd-bd96-b71116dcdc23"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var pricing = new AzureNative.Security.Pricing("pricing", new()
    {
        PricingName = "CloudPosture",
        PricingTier = AzureNative.Security.PricingTier.Standard,
        ScopeId = "subscriptions/20ff7fc3-e762-44dd-bd96-b71116dcdc23",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.security.Pricing;
import com.pulumi.azurenative.security.PricingArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var pricing = new Pricing("pricing", PricingArgs.builder()
            .pricingName("CloudPosture")
            .pricingTier("Standard")
            .scopeId("subscriptions/20ff7fc3-e762-44dd-bd96-b71116dcdc23")
            .build());

    }
}
resources:
  pricing:
    type: azure-native:security:Pricing
    properties:
      pricingName: CloudPosture
      pricingTier: Standard
      scopeId: subscriptions/20ff7fc3-e762-44dd-bd96-b71116dcdc23

The scopeId property targets a subscription using the format subscriptions/{subscriptionId}. The pricingName identifies which Defender plan to configure (CloudPosture, VirtualMachines, Containers, etc.). Setting pricingTier to Standard activates advanced security features for that plan across the entire subscription.

Enforce standard tier with sub-plan selection

When multiple sub-plans exist, teams choose the feature set that matches their requirements and prevent child scopes from overriding the configuration.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const pricing = new azure_native.security.Pricing("pricing", {
    enforce: azure_native.security.Enforce.True,
    pricingName: "VirtualMachines",
    pricingTier: azure_native.security.PricingTier.Standard,
    scopeId: "subscriptions/20ff7fc3-e762-44dd-bd96-b71116dcdc23",
    subPlan: "P2",
});
import pulumi
import pulumi_azure_native as azure_native

pricing = azure_native.security.Pricing("pricing",
    enforce=azure_native.security.Enforce.TRUE,
    pricing_name="VirtualMachines",
    pricing_tier=azure_native.security.PricingTier.STANDARD,
    scope_id="subscriptions/20ff7fc3-e762-44dd-bd96-b71116dcdc23",
    sub_plan="P2")
package main

import (
	security "github.com/pulumi/pulumi-azure-native-sdk/security/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := security.NewPricing(ctx, "pricing", &security.PricingArgs{
			Enforce:     pulumi.String(security.EnforceTrue),
			PricingName: pulumi.String("VirtualMachines"),
			PricingTier: pulumi.String(security.PricingTierStandard),
			ScopeId:     pulumi.String("subscriptions/20ff7fc3-e762-44dd-bd96-b71116dcdc23"),
			SubPlan:     pulumi.String("P2"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var pricing = new AzureNative.Security.Pricing("pricing", new()
    {
        Enforce = AzureNative.Security.Enforce.True,
        PricingName = "VirtualMachines",
        PricingTier = AzureNative.Security.PricingTier.Standard,
        ScopeId = "subscriptions/20ff7fc3-e762-44dd-bd96-b71116dcdc23",
        SubPlan = "P2",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.security.Pricing;
import com.pulumi.azurenative.security.PricingArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var pricing = new Pricing("pricing", PricingArgs.builder()
            .enforce("True")
            .pricingName("VirtualMachines")
            .pricingTier("Standard")
            .scopeId("subscriptions/20ff7fc3-e762-44dd-bd96-b71116dcdc23")
            .subPlan("P2")
            .build());

    }
}
resources:
  pricing:
    type: azure-native:security:Pricing
    properties:
      enforce: True
      pricingName: VirtualMachines
      pricingTier: Standard
      scopeId: subscriptions/20ff7fc3-e762-44dd-bd96-b71116dcdc23
      subPlan: P2

The subPlan property selects a specific feature set within the plan. For VirtualMachines, P1 and P2 offer different capabilities. The enforce property, when set to True, prevents descendant scopes (like resource groups or individual resources) from overriding this pricing configuration, ensuring consistent protection.

Apply standard tier to individual resources

Some deployments require granular control, enabling protection on specific VMs rather than entire subscriptions.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const pricing = new azure_native.security.Pricing("pricing", {
    pricingName: "virtualMachines",
    pricingTier: azure_native.security.PricingTier.Standard,
    scopeId: "subscriptions/20ff7fc3-e762-44dd-bd96-b71116dcdc23/resourceGroups/DEMO/providers/Microsoft.Compute/virtualMachines/VM-1",
    subPlan: "P1",
});
import pulumi
import pulumi_azure_native as azure_native

pricing = azure_native.security.Pricing("pricing",
    pricing_name="virtualMachines",
    pricing_tier=azure_native.security.PricingTier.STANDARD,
    scope_id="subscriptions/20ff7fc3-e762-44dd-bd96-b71116dcdc23/resourceGroups/DEMO/providers/Microsoft.Compute/virtualMachines/VM-1",
    sub_plan="P1")
package main

import (
	security "github.com/pulumi/pulumi-azure-native-sdk/security/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := security.NewPricing(ctx, "pricing", &security.PricingArgs{
			PricingName: pulumi.String("virtualMachines"),
			PricingTier: pulumi.String(security.PricingTierStandard),
			ScopeId:     pulumi.String("subscriptions/20ff7fc3-e762-44dd-bd96-b71116dcdc23/resourceGroups/DEMO/providers/Microsoft.Compute/virtualMachines/VM-1"),
			SubPlan:     pulumi.String("P1"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var pricing = new AzureNative.Security.Pricing("pricing", new()
    {
        PricingName = "virtualMachines",
        PricingTier = AzureNative.Security.PricingTier.Standard,
        ScopeId = "subscriptions/20ff7fc3-e762-44dd-bd96-b71116dcdc23/resourceGroups/DEMO/providers/Microsoft.Compute/virtualMachines/VM-1",
        SubPlan = "P1",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.security.Pricing;
import com.pulumi.azurenative.security.PricingArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var pricing = new Pricing("pricing", PricingArgs.builder()
            .pricingName("virtualMachines")
            .pricingTier("Standard")
            .scopeId("subscriptions/20ff7fc3-e762-44dd-bd96-b71116dcdc23/resourceGroups/DEMO/providers/Microsoft.Compute/virtualMachines/VM-1")
            .subPlan("P1")
            .build());

    }
}
resources:
  pricing:
    type: azure-native:security:Pricing
    properties:
      pricingName: virtualMachines
      pricingTier: Standard
      scopeId: subscriptions/20ff7fc3-e762-44dd-bd96-b71116dcdc23/resourceGroups/DEMO/providers/Microsoft.Compute/virtualMachines/VM-1
      subPlan: P1

For resource-level pricing, the scopeId uses the full resource path format: subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. This targets a single VM. Resource-level pricing only supports the P1 sub-plan for VirtualMachines.

Beyond these examples

These snippets focus on specific pricing configuration features: subscription and resource-level pricing, and sub-plan selection and enforcement. They’re intentionally minimal rather than full security deployments.

The examples reference pre-existing infrastructure such as Azure subscriptions and virtual machines (for resource-level pricing). They focus on configuring Defender pricing rather than provisioning the underlying resources.

To keep things focused, common pricing patterns are omitted, including:

  • Extension configuration for additional features
  • Free tier downgrade scenarios
  • Multi-plan coordination across subscriptions
  • Inherited pricing from parent scopes

These omissions are intentional: the goal is to illustrate how each pricing feature is wired, not provide drop-in security modules. See the Pricing resource reference for all available configuration options.

Let's configure Azure Defender for Cloud Pricing

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Pricing Tiers & Plans
What are the available pricing tiers for Microsoft Defender for Cloud?
Two tiers are available: Free (basic security features) and Standard (advanced security capabilities). Set pricingTier to Standard to enable the Defender plan.
What's the difference between P1 and P2 subPlans for VirtualMachines?
Each subPlan enables a different set of security features. P1 is available at both subscription and resource levels, while P2 is only available at the subscription level.
Which Defender plans support subPlans?
VirtualMachines plans support P1 and P2 subPlans. Other plans like CloudPosture don’t use subPlans (the property is optional).
Scope & Configuration
What scopes can I configure Defender pricing for?
You can configure pricing at the subscription level (format: subscriptions/{subscriptionId}) or for specific resources like VirtualMachines (format: subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}).
How do I prevent child resources from overriding my pricing configuration?
Set enforce to True at the subscription level. This forces the pricing configuration on all descendants and prevents overrides. This property only works for subscription-level pricing.
How does pricing inheritance work for resources?
Resources can inherit pricing from their parent subscription. Check the inherited output property (read-only): True means inherited, False means explicitly configured. The inheritedFrom property shows the parent scope ID when inherited.
Constraints & Limitations
What properties can't I change after creating a pricing configuration?
Both pricingName and scopeId are immutable. You’ll need to delete and recreate the resource to change these values.
Why can't I use the P2 subPlan at the resource level?
P2 is only supported at the subscription level for VirtualMachines plans. Resource-level pricing only supports the P1 subPlan.
Can I use the enforce property on individual resources?
No, enforce is only available for subscription-level pricing. Setting it on resource-level configurations will have no effect.
How do I know if my subscription is still in the free trial period?
Check the freeTrialRemainingTime output property, which shows the remaining trial duration in ISO 8601 format (e.g., P3Y6M4DT12H30M5S).

Using a different cloud?

Explore security guides for other cloud providers: