The azure-native:authorization:PolicyAssignment resource, part of the Pulumi Azure Native provider, links Azure Policy definitions to scopes and configures their enforcement behavior. This guide focuses on four capabilities: parameterized policy assignments, managed identity for remediation, conditional enforcement with overrides and selectors, and audit mode for testing.
Policy assignments reference existing policy definitions or policy sets and apply to Azure scopes that must already exist. The examples are intentionally small. Combine them with your own policy definitions and organizational scope structure.
Assign a policy with parameters and compliance messages
Organizations enforce governance rules by assigning policies to subscriptions, resource groups, or management groups, providing parameter values that customize the policy’s behavior.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const policyAssignment = new azure_native.authorization.PolicyAssignment("policyAssignment", {
description: "Force resource names to begin with given DeptA and end with -LC",
displayName: "Enforce resource naming rules",
metadata: {
assignedBy: "Special Someone",
},
nonComplianceMessages: [{
message: "Resource names must start with 'DeptA' and end with '-LC'.",
}],
parameters: {
prefix: {
value: "DeptA",
},
suffix: {
value: "-LC",
},
},
policyAssignmentName: "EnforceNaming",
policyDefinitionId: "/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policyDefinitions/ResourceNaming",
scope: "subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2",
});
import pulumi
import pulumi_azure_native as azure_native
policy_assignment = azure_native.authorization.PolicyAssignment("policyAssignment",
description="Force resource names to begin with given DeptA and end with -LC",
display_name="Enforce resource naming rules",
metadata={
"assignedBy": "Special Someone",
},
non_compliance_messages=[{
"message": "Resource names must start with 'DeptA' and end with '-LC'.",
}],
parameters={
"prefix": {
"value": "DeptA",
},
"suffix": {
"value": "-LC",
},
},
policy_assignment_name="EnforceNaming",
policy_definition_id="/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policyDefinitions/ResourceNaming",
scope="subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2")
package main
import (
authorization "github.com/pulumi/pulumi-azure-native-sdk/authorization/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := authorization.NewPolicyAssignment(ctx, "policyAssignment", &authorization.PolicyAssignmentArgs{
Description: pulumi.String("Force resource names to begin with given DeptA and end with -LC"),
DisplayName: pulumi.String("Enforce resource naming rules"),
Metadata: pulumi.Any(map[string]interface{}{
"assignedBy": "Special Someone",
}),
NonComplianceMessages: authorization.NonComplianceMessageArray{
&authorization.NonComplianceMessageArgs{
Message: pulumi.String("Resource names must start with 'DeptA' and end with '-LC'."),
},
},
Parameters: authorization.ParameterValuesValueMap{
"prefix": &authorization.ParameterValuesValueArgs{
Value: pulumi.Any("DeptA"),
},
"suffix": &authorization.ParameterValuesValueArgs{
Value: pulumi.Any("-LC"),
},
},
PolicyAssignmentName: pulumi.String("EnforceNaming"),
PolicyDefinitionId: pulumi.String("/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policyDefinitions/ResourceNaming"),
Scope: pulumi.String("subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2"),
})
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 policyAssignment = new AzureNative.Authorization.PolicyAssignment("policyAssignment", new()
{
Description = "Force resource names to begin with given DeptA and end with -LC",
DisplayName = "Enforce resource naming rules",
Metadata = new Dictionary<string, object?>
{
["assignedBy"] = "Special Someone",
},
NonComplianceMessages = new[]
{
new AzureNative.Authorization.Inputs.NonComplianceMessageArgs
{
Message = "Resource names must start with 'DeptA' and end with '-LC'.",
},
},
Parameters =
{
{ "prefix", new AzureNative.Authorization.Inputs.ParameterValuesValueArgs
{
Value = "DeptA",
} },
{ "suffix", new AzureNative.Authorization.Inputs.ParameterValuesValueArgs
{
Value = "-LC",
} },
},
PolicyAssignmentName = "EnforceNaming",
PolicyDefinitionId = "/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policyDefinitions/ResourceNaming",
Scope = "subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.authorization.PolicyAssignment;
import com.pulumi.azurenative.authorization.PolicyAssignmentArgs;
import com.pulumi.azurenative.authorization.inputs.NonComplianceMessageArgs;
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 policyAssignment = new PolicyAssignment("policyAssignment", PolicyAssignmentArgs.builder()
.description("Force resource names to begin with given DeptA and end with -LC")
.displayName("Enforce resource naming rules")
.metadata(Map.of("assignedBy", "Special Someone"))
.nonComplianceMessages(NonComplianceMessageArgs.builder()
.message("Resource names must start with 'DeptA' and end with '-LC'.")
.build())
.parameters(Map.ofEntries(
Map.entry("prefix", ParameterValuesValueArgs.builder()
.value("DeptA")
.build()),
Map.entry("suffix", ParameterValuesValueArgs.builder()
.value("-LC")
.build())
))
.policyAssignmentName("EnforceNaming")
.policyDefinitionId("/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policyDefinitions/ResourceNaming")
.scope("subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2")
.build());
}
}
resources:
policyAssignment:
type: azure-native:authorization:PolicyAssignment
properties:
description: Force resource names to begin with given DeptA and end with -LC
displayName: Enforce resource naming rules
metadata:
assignedBy: Special Someone
nonComplianceMessages:
- message: Resource names must start with 'DeptA' and end with '-LC'.
parameters:
prefix:
value: DeptA
suffix:
value: -LC
policyAssignmentName: EnforceNaming
policyDefinitionId: /subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policyDefinitions/ResourceNaming
scope: subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2
The policyDefinitionId links to an existing policy definition, while scope determines where the policy applies. The parameters property passes values to the policy’s parameter placeholders (here, prefix and suffix for naming rules). The nonComplianceMessages array provides custom error text that appears when resources violate the policy.
Enable managed identity for policy remediation
Policies with DeployIfNotExists or Modify effects need permissions to create or modify resources. Managed identities provide these permissions without manual credential management.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const policyAssignment = new azure_native.authorization.PolicyAssignment("policyAssignment", {
description: "Force resource names to begin with given DeptA and end with -LC",
displayName: "Enforce resource naming rules",
enforcementMode: azure_native.authorization.EnforcementMode.Default,
identity: {
type: azure_native.authorization.ResourceIdentityType.SystemAssigned,
},
location: "eastus",
metadata: {
assignedBy: "Foo Bar",
},
parameters: {
prefix: {
value: "DeptA",
},
suffix: {
value: "-LC",
},
},
policyAssignmentName: "EnforceNaming",
policyDefinitionId: "/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policyDefinitions/ResourceNaming",
scope: "subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2",
});
import pulumi
import pulumi_azure_native as azure_native
policy_assignment = azure_native.authorization.PolicyAssignment("policyAssignment",
description="Force resource names to begin with given DeptA and end with -LC",
display_name="Enforce resource naming rules",
enforcement_mode=azure_native.authorization.EnforcementMode.DEFAULT,
identity={
"type": azure_native.authorization.ResourceIdentityType.SYSTEM_ASSIGNED,
},
location="eastus",
metadata={
"assignedBy": "Foo Bar",
},
parameters={
"prefix": {
"value": "DeptA",
},
"suffix": {
"value": "-LC",
},
},
policy_assignment_name="EnforceNaming",
policy_definition_id="/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policyDefinitions/ResourceNaming",
scope="subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2")
package main
import (
authorization "github.com/pulumi/pulumi-azure-native-sdk/authorization/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := authorization.NewPolicyAssignment(ctx, "policyAssignment", &authorization.PolicyAssignmentArgs{
Description: pulumi.String("Force resource names to begin with given DeptA and end with -LC"),
DisplayName: pulumi.String("Enforce resource naming rules"),
EnforcementMode: pulumi.String(authorization.EnforcementModeDefault),
Identity: &authorization.IdentityArgs{
Type: authorization.ResourceIdentityTypeSystemAssigned,
},
Location: pulumi.String("eastus"),
Metadata: pulumi.Any(map[string]interface{}{
"assignedBy": "Foo Bar",
}),
Parameters: authorization.ParameterValuesValueMap{
"prefix": &authorization.ParameterValuesValueArgs{
Value: pulumi.Any("DeptA"),
},
"suffix": &authorization.ParameterValuesValueArgs{
Value: pulumi.Any("-LC"),
},
},
PolicyAssignmentName: pulumi.String("EnforceNaming"),
PolicyDefinitionId: pulumi.String("/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policyDefinitions/ResourceNaming"),
Scope: pulumi.String("subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2"),
})
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 policyAssignment = new AzureNative.Authorization.PolicyAssignment("policyAssignment", new()
{
Description = "Force resource names to begin with given DeptA and end with -LC",
DisplayName = "Enforce resource naming rules",
EnforcementMode = AzureNative.Authorization.EnforcementMode.Default,
Identity = new AzureNative.Authorization.Inputs.IdentityArgs
{
Type = AzureNative.Authorization.ResourceIdentityType.SystemAssigned,
},
Location = "eastus",
Metadata = new Dictionary<string, object?>
{
["assignedBy"] = "Foo Bar",
},
Parameters =
{
{ "prefix", new AzureNative.Authorization.Inputs.ParameterValuesValueArgs
{
Value = "DeptA",
} },
{ "suffix", new AzureNative.Authorization.Inputs.ParameterValuesValueArgs
{
Value = "-LC",
} },
},
PolicyAssignmentName = "EnforceNaming",
PolicyDefinitionId = "/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policyDefinitions/ResourceNaming",
Scope = "subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.authorization.PolicyAssignment;
import com.pulumi.azurenative.authorization.PolicyAssignmentArgs;
import com.pulumi.azurenative.authorization.inputs.IdentityArgs;
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 policyAssignment = new PolicyAssignment("policyAssignment", PolicyAssignmentArgs.builder()
.description("Force resource names to begin with given DeptA and end with -LC")
.displayName("Enforce resource naming rules")
.enforcementMode("Default")
.identity(IdentityArgs.builder()
.type("SystemAssigned")
.build())
.location("eastus")
.metadata(Map.of("assignedBy", "Foo Bar"))
.parameters(Map.ofEntries(
Map.entry("prefix", ParameterValuesValueArgs.builder()
.value("DeptA")
.build()),
Map.entry("suffix", ParameterValuesValueArgs.builder()
.value("-LC")
.build())
))
.policyAssignmentName("EnforceNaming")
.policyDefinitionId("/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policyDefinitions/ResourceNaming")
.scope("subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2")
.build());
}
}
resources:
policyAssignment:
type: azure-native:authorization:PolicyAssignment
properties:
description: Force resource names to begin with given DeptA and end with -LC
displayName: Enforce resource naming rules
enforcementMode: Default
identity:
type: SystemAssigned
location: eastus
metadata:
assignedBy: Foo Bar
parameters:
prefix:
value: DeptA
suffix:
value: -LC
policyAssignmentName: EnforceNaming
policyDefinitionId: /subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policyDefinitions/ResourceNaming
scope: subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2
The identity property with type SystemAssigned creates a managed identity that Azure Policy uses to remediate non-compliant resources. The location property is required when using managed identities. The enforcementMode set to Default means the policy actively blocks or modifies resources during creation and updates.
Provide targeted messages for policy set violations
Policy sets (initiatives) bundle multiple policies together. When resources violate specific policies within the set, targeted messages help teams understand which requirement failed.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const policyAssignment = new azure_native.authorization.PolicyAssignment("policyAssignment", {
displayName: "Enforce security policies",
nonComplianceMessages: [
{
message: "Resources must comply with all internal security policies. See <internal site URL> for more info.",
},
{
message: "Resource names must start with 'DeptA' and end with '-LC'.",
policyDefinitionReferenceId: "10420126870854049575",
},
{
message: "Storage accounts must have firewall rules configured.",
policyDefinitionReferenceId: "8572513655450389710",
},
],
policyAssignmentName: "securityInitAssignment",
policyDefinitionId: "/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policySetDefinitions/securityInitiative",
scope: "subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2",
});
import pulumi
import pulumi_azure_native as azure_native
policy_assignment = azure_native.authorization.PolicyAssignment("policyAssignment",
display_name="Enforce security policies",
non_compliance_messages=[
{
"message": "Resources must comply with all internal security policies. See <internal site URL> for more info.",
},
{
"message": "Resource names must start with 'DeptA' and end with '-LC'.",
"policy_definition_reference_id": "10420126870854049575",
},
{
"message": "Storage accounts must have firewall rules configured.",
"policy_definition_reference_id": "8572513655450389710",
},
],
policy_assignment_name="securityInitAssignment",
policy_definition_id="/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policySetDefinitions/securityInitiative",
scope="subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2")
package main
import (
authorization "github.com/pulumi/pulumi-azure-native-sdk/authorization/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := authorization.NewPolicyAssignment(ctx, "policyAssignment", &authorization.PolicyAssignmentArgs{
DisplayName: pulumi.String("Enforce security policies"),
NonComplianceMessages: authorization.NonComplianceMessageArray{
&authorization.NonComplianceMessageArgs{
Message: pulumi.String("Resources must comply with all internal security policies. See <internal site URL> for more info."),
},
&authorization.NonComplianceMessageArgs{
Message: pulumi.String("Resource names must start with 'DeptA' and end with '-LC'."),
PolicyDefinitionReferenceId: pulumi.String("10420126870854049575"),
},
&authorization.NonComplianceMessageArgs{
Message: pulumi.String("Storage accounts must have firewall rules configured."),
PolicyDefinitionReferenceId: pulumi.String("8572513655450389710"),
},
},
PolicyAssignmentName: pulumi.String("securityInitAssignment"),
PolicyDefinitionId: pulumi.String("/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policySetDefinitions/securityInitiative"),
Scope: pulumi.String("subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2"),
})
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 policyAssignment = new AzureNative.Authorization.PolicyAssignment("policyAssignment", new()
{
DisplayName = "Enforce security policies",
NonComplianceMessages = new[]
{
new AzureNative.Authorization.Inputs.NonComplianceMessageArgs
{
Message = "Resources must comply with all internal security policies. See <internal site URL> for more info.",
},
new AzureNative.Authorization.Inputs.NonComplianceMessageArgs
{
Message = "Resource names must start with 'DeptA' and end with '-LC'.",
PolicyDefinitionReferenceId = "10420126870854049575",
},
new AzureNative.Authorization.Inputs.NonComplianceMessageArgs
{
Message = "Storage accounts must have firewall rules configured.",
PolicyDefinitionReferenceId = "8572513655450389710",
},
},
PolicyAssignmentName = "securityInitAssignment",
PolicyDefinitionId = "/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policySetDefinitions/securityInitiative",
Scope = "subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.authorization.PolicyAssignment;
import com.pulumi.azurenative.authorization.PolicyAssignmentArgs;
import com.pulumi.azurenative.authorization.inputs.NonComplianceMessageArgs;
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 policyAssignment = new PolicyAssignment("policyAssignment", PolicyAssignmentArgs.builder()
.displayName("Enforce security policies")
.nonComplianceMessages(
NonComplianceMessageArgs.builder()
.message("Resources must comply with all internal security policies. See <internal site URL> for more info.")
.build(),
NonComplianceMessageArgs.builder()
.message("Resource names must start with 'DeptA' and end with '-LC'.")
.policyDefinitionReferenceId("10420126870854049575")
.build(),
NonComplianceMessageArgs.builder()
.message("Storage accounts must have firewall rules configured.")
.policyDefinitionReferenceId("8572513655450389710")
.build())
.policyAssignmentName("securityInitAssignment")
.policyDefinitionId("/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policySetDefinitions/securityInitiative")
.scope("subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2")
.build());
}
}
resources:
policyAssignment:
type: azure-native:authorization:PolicyAssignment
properties:
displayName: Enforce security policies
nonComplianceMessages:
- message: Resources must comply with all internal security policies. See <internal site URL> for more info.
- message: Resource names must start with 'DeptA' and end with '-LC'.
policyDefinitionReferenceId: '10420126870854049575'
- message: Storage accounts must have firewall rules configured.
policyDefinitionReferenceId: '8572513655450389710'
policyAssignmentName: securityInitAssignment
policyDefinitionId: /subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policySetDefinitions/securityInitiative
scope: subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2
The nonComplianceMessages array includes a default message plus policy-specific messages. The policyDefinitionReferenceId ties each message to a specific policy within the set, so violations show contextual guidance. Without reference IDs, the default message applies to all violations.
Override policy effects and versions conditionally
Large organizations sometimes need to adjust policy behavior for specific regions or scenarios without creating separate policy definitions.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const policyAssignment = new azure_native.authorization.PolicyAssignment("policyAssignment", {
definitionVersion: "1.*.*",
description: "Limit the resource location and resource SKU",
displayName: "Limit the resource location and resource SKU",
metadata: {
assignedBy: "Special Someone",
},
overrides: [
{
kind: azure_native.authorization.OverrideKind.PolicyEffect,
selectors: [{
"in": [
"Limit_Skus",
"Limit_Locations",
],
kind: azure_native.authorization.SelectorKind.PolicyDefinitionReferenceId,
}],
value: "Audit",
},
{
kind: azure_native.authorization.OverrideKind.DefinitionVersion,
selectors: [{
"in": [
"eastUSEuap",
"centralUSEuap",
],
kind: azure_native.authorization.SelectorKind.ResourceLocation,
}],
value: "2.*.*",
},
],
policyAssignmentName: "CostManagement",
policyDefinitionId: "/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policySetDefinitions/CostManagement",
scope: "subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2",
});
import pulumi
import pulumi_azure_native as azure_native
policy_assignment = azure_native.authorization.PolicyAssignment("policyAssignment",
definition_version="1.*.*",
description="Limit the resource location and resource SKU",
display_name="Limit the resource location and resource SKU",
metadata={
"assignedBy": "Special Someone",
},
overrides=[
{
"kind": azure_native.authorization.OverrideKind.POLICY_EFFECT,
"selectors": [{
"in_": [
"Limit_Skus",
"Limit_Locations",
],
"kind": azure_native.authorization.SelectorKind.POLICY_DEFINITION_REFERENCE_ID,
}],
"value": "Audit",
},
{
"kind": azure_native.authorization.OverrideKind.DEFINITION_VERSION,
"selectors": [{
"in_": [
"eastUSEuap",
"centralUSEuap",
],
"kind": azure_native.authorization.SelectorKind.RESOURCE_LOCATION,
}],
"value": "2.*.*",
},
],
policy_assignment_name="CostManagement",
policy_definition_id="/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policySetDefinitions/CostManagement",
scope="subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2")
package main
import (
authorization "github.com/pulumi/pulumi-azure-native-sdk/authorization/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := authorization.NewPolicyAssignment(ctx, "policyAssignment", &authorization.PolicyAssignmentArgs{
DefinitionVersion: pulumi.String("1.*.*"),
Description: pulumi.String("Limit the resource location and resource SKU"),
DisplayName: pulumi.String("Limit the resource location and resource SKU"),
Metadata: pulumi.Any(map[string]interface{}{
"assignedBy": "Special Someone",
}),
Overrides: authorization.OverrideArray{
&authorization.OverrideArgs{
Kind: pulumi.String(authorization.OverrideKindPolicyEffect),
Selectors: authorization.SelectorArray{
&authorization.SelectorArgs{
In: pulumi.StringArray{
pulumi.String("Limit_Skus"),
pulumi.String("Limit_Locations"),
},
Kind: pulumi.String(authorization.SelectorKindPolicyDefinitionReferenceId),
},
},
Value: pulumi.String("Audit"),
},
&authorization.OverrideArgs{
Kind: pulumi.String(authorization.OverrideKindDefinitionVersion),
Selectors: authorization.SelectorArray{
&authorization.SelectorArgs{
In: pulumi.StringArray{
pulumi.String("eastUSEuap"),
pulumi.String("centralUSEuap"),
},
Kind: pulumi.String(authorization.SelectorKindResourceLocation),
},
},
Value: pulumi.String("2.*.*"),
},
},
PolicyAssignmentName: pulumi.String("CostManagement"),
PolicyDefinitionId: pulumi.String("/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policySetDefinitions/CostManagement"),
Scope: pulumi.String("subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2"),
})
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 policyAssignment = new AzureNative.Authorization.PolicyAssignment("policyAssignment", new()
{
DefinitionVersion = "1.*.*",
Description = "Limit the resource location and resource SKU",
DisplayName = "Limit the resource location and resource SKU",
Metadata = new Dictionary<string, object?>
{
["assignedBy"] = "Special Someone",
},
Overrides = new[]
{
new AzureNative.Authorization.Inputs.OverrideArgs
{
Kind = AzureNative.Authorization.OverrideKind.PolicyEffect,
Selectors = new[]
{
new AzureNative.Authorization.Inputs.SelectorArgs
{
In = new[]
{
"Limit_Skus",
"Limit_Locations",
},
Kind = AzureNative.Authorization.SelectorKind.PolicyDefinitionReferenceId,
},
},
Value = "Audit",
},
new AzureNative.Authorization.Inputs.OverrideArgs
{
Kind = AzureNative.Authorization.OverrideKind.DefinitionVersion,
Selectors = new[]
{
new AzureNative.Authorization.Inputs.SelectorArgs
{
In = new[]
{
"eastUSEuap",
"centralUSEuap",
},
Kind = AzureNative.Authorization.SelectorKind.ResourceLocation,
},
},
Value = "2.*.*",
},
},
PolicyAssignmentName = "CostManagement",
PolicyDefinitionId = "/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policySetDefinitions/CostManagement",
Scope = "subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.authorization.PolicyAssignment;
import com.pulumi.azurenative.authorization.PolicyAssignmentArgs;
import com.pulumi.azurenative.authorization.inputs.OverrideArgs;
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 policyAssignment = new PolicyAssignment("policyAssignment", PolicyAssignmentArgs.builder()
.definitionVersion("1.*.*")
.description("Limit the resource location and resource SKU")
.displayName("Limit the resource location and resource SKU")
.metadata(Map.of("assignedBy", "Special Someone"))
.overrides(
OverrideArgs.builder()
.kind("policyEffect")
.selectors(SelectorArgs.builder()
.in(
"Limit_Skus",
"Limit_Locations")
.kind("policyDefinitionReferenceId")
.build())
.value("Audit")
.build(),
OverrideArgs.builder()
.kind("definitionVersion")
.selectors(SelectorArgs.builder()
.in(
"eastUSEuap",
"centralUSEuap")
.kind("resourceLocation")
.build())
.value("2.*.*")
.build())
.policyAssignmentName("CostManagement")
.policyDefinitionId("/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policySetDefinitions/CostManagement")
.scope("subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2")
.build());
}
}
resources:
policyAssignment:
type: azure-native:authorization:PolicyAssignment
properties:
definitionVersion: 1.*.*
description: Limit the resource location and resource SKU
displayName: Limit the resource location and resource SKU
metadata:
assignedBy: Special Someone
overrides:
- kind: policyEffect
selectors:
- in:
- Limit_Skus
- Limit_Locations
kind: policyDefinitionReferenceId
value: Audit
- kind: definitionVersion
selectors:
- in:
- eastUSEuap
- centralUSEuap
kind: resourceLocation
value: 2.*.*
policyAssignmentName: CostManagement
policyDefinitionId: /subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policySetDefinitions/CostManagement
scope: subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2
The overrides array changes policy behavior based on selectors. The first override sets the effect to Audit for specific policies (identified by policyDefinitionReferenceId). The second override pins certain regions to a different policy definition version. Each override’s selectors determine when it applies.
Limit policy scope to specific resource locations
When testing new policies or managing regional rollouts, you may want to apply policies only to resources in certain locations rather than the entire scope.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const policyAssignment = new azure_native.authorization.PolicyAssignment("policyAssignment", {
description: "Limit the resource location and resource SKU",
displayName: "Limit the resource location and resource SKU",
metadata: {
assignedBy: "Special Someone",
},
policyAssignmentName: "CostManagement",
policyDefinitionId: "/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policySetDefinitions/CostManagement",
resourceSelectors: [{
name: "SDPRegions",
selectors: [{
"in": [
"eastus2euap",
"centraluseuap",
],
kind: azure_native.authorization.SelectorKind.ResourceLocation,
}],
}],
scope: "subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2",
});
import pulumi
import pulumi_azure_native as azure_native
policy_assignment = azure_native.authorization.PolicyAssignment("policyAssignment",
description="Limit the resource location and resource SKU",
display_name="Limit the resource location and resource SKU",
metadata={
"assignedBy": "Special Someone",
},
policy_assignment_name="CostManagement",
policy_definition_id="/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policySetDefinitions/CostManagement",
resource_selectors=[{
"name": "SDPRegions",
"selectors": [{
"in_": [
"eastus2euap",
"centraluseuap",
],
"kind": azure_native.authorization.SelectorKind.RESOURCE_LOCATION,
}],
}],
scope="subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2")
package main
import (
authorization "github.com/pulumi/pulumi-azure-native-sdk/authorization/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := authorization.NewPolicyAssignment(ctx, "policyAssignment", &authorization.PolicyAssignmentArgs{
Description: pulumi.String("Limit the resource location and resource SKU"),
DisplayName: pulumi.String("Limit the resource location and resource SKU"),
Metadata: pulumi.Any(map[string]interface{}{
"assignedBy": "Special Someone",
}),
PolicyAssignmentName: pulumi.String("CostManagement"),
PolicyDefinitionId: pulumi.String("/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policySetDefinitions/CostManagement"),
ResourceSelectors: authorization.ResourceSelectorArray{
&authorization.ResourceSelectorArgs{
Name: pulumi.String("SDPRegions"),
Selectors: authorization.SelectorArray{
&authorization.SelectorArgs{
In: pulumi.StringArray{
pulumi.String("eastus2euap"),
pulumi.String("centraluseuap"),
},
Kind: pulumi.String(authorization.SelectorKindResourceLocation),
},
},
},
},
Scope: pulumi.String("subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2"),
})
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 policyAssignment = new AzureNative.Authorization.PolicyAssignment("policyAssignment", new()
{
Description = "Limit the resource location and resource SKU",
DisplayName = "Limit the resource location and resource SKU",
Metadata = new Dictionary<string, object?>
{
["assignedBy"] = "Special Someone",
},
PolicyAssignmentName = "CostManagement",
PolicyDefinitionId = "/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policySetDefinitions/CostManagement",
ResourceSelectors = new[]
{
new AzureNative.Authorization.Inputs.ResourceSelectorArgs
{
Name = "SDPRegions",
Selectors = new[]
{
new AzureNative.Authorization.Inputs.SelectorArgs
{
In = new[]
{
"eastus2euap",
"centraluseuap",
},
Kind = AzureNative.Authorization.SelectorKind.ResourceLocation,
},
},
},
},
Scope = "subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.authorization.PolicyAssignment;
import com.pulumi.azurenative.authorization.PolicyAssignmentArgs;
import com.pulumi.azurenative.authorization.inputs.ResourceSelectorArgs;
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 policyAssignment = new PolicyAssignment("policyAssignment", PolicyAssignmentArgs.builder()
.description("Limit the resource location and resource SKU")
.displayName("Limit the resource location and resource SKU")
.metadata(Map.of("assignedBy", "Special Someone"))
.policyAssignmentName("CostManagement")
.policyDefinitionId("/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policySetDefinitions/CostManagement")
.resourceSelectors(ResourceSelectorArgs.builder()
.name("SDPRegions")
.selectors(SelectorArgs.builder()
.in(
"eastus2euap",
"centraluseuap")
.kind("resourceLocation")
.build())
.build())
.scope("subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2")
.build());
}
}
resources:
policyAssignment:
type: azure-native:authorization:PolicyAssignment
properties:
description: Limit the resource location and resource SKU
displayName: Limit the resource location and resource SKU
metadata:
assignedBy: Special Someone
policyAssignmentName: CostManagement
policyDefinitionId: /subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policySetDefinitions/CostManagement
resourceSelectors:
- name: SDPRegions
selectors:
- in:
- eastus2euap
- centraluseuap
kind: resourceLocation
scope: subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2
The resourceSelectors array filters which resources the policy evaluates. Here, the selector with kind ResourceLocation limits evaluation to resources in eastus2euap and centraluseuap. Resources in other locations within the scope are ignored.
Audit compliance without blocking deployments
Before enforcing new policies, teams often run them in audit mode to understand the impact and identify non-compliant resources without disrupting operations.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const policyAssignment = new azure_native.authorization.PolicyAssignment("policyAssignment", {
description: "Force resource names to begin with given DeptA and end with -LC",
displayName: "Enforce resource naming rules",
enforcementMode: azure_native.authorization.EnforcementMode.DoNotEnforce,
metadata: {
assignedBy: "Special Someone",
},
parameters: {
prefix: {
value: "DeptA",
},
suffix: {
value: "-LC",
},
},
policyAssignmentName: "EnforceNaming",
policyDefinitionId: "/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policyDefinitions/ResourceNaming",
scope: "subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2",
});
import pulumi
import pulumi_azure_native as azure_native
policy_assignment = azure_native.authorization.PolicyAssignment("policyAssignment",
description="Force resource names to begin with given DeptA and end with -LC",
display_name="Enforce resource naming rules",
enforcement_mode=azure_native.authorization.EnforcementMode.DO_NOT_ENFORCE,
metadata={
"assignedBy": "Special Someone",
},
parameters={
"prefix": {
"value": "DeptA",
},
"suffix": {
"value": "-LC",
},
},
policy_assignment_name="EnforceNaming",
policy_definition_id="/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policyDefinitions/ResourceNaming",
scope="subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2")
package main
import (
authorization "github.com/pulumi/pulumi-azure-native-sdk/authorization/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := authorization.NewPolicyAssignment(ctx, "policyAssignment", &authorization.PolicyAssignmentArgs{
Description: pulumi.String("Force resource names to begin with given DeptA and end with -LC"),
DisplayName: pulumi.String("Enforce resource naming rules"),
EnforcementMode: pulumi.String(authorization.EnforcementModeDoNotEnforce),
Metadata: pulumi.Any(map[string]interface{}{
"assignedBy": "Special Someone",
}),
Parameters: authorization.ParameterValuesValueMap{
"prefix": &authorization.ParameterValuesValueArgs{
Value: pulumi.Any("DeptA"),
},
"suffix": &authorization.ParameterValuesValueArgs{
Value: pulumi.Any("-LC"),
},
},
PolicyAssignmentName: pulumi.String("EnforceNaming"),
PolicyDefinitionId: pulumi.String("/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policyDefinitions/ResourceNaming"),
Scope: pulumi.String("subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2"),
})
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 policyAssignment = new AzureNative.Authorization.PolicyAssignment("policyAssignment", new()
{
Description = "Force resource names to begin with given DeptA and end with -LC",
DisplayName = "Enforce resource naming rules",
EnforcementMode = AzureNative.Authorization.EnforcementMode.DoNotEnforce,
Metadata = new Dictionary<string, object?>
{
["assignedBy"] = "Special Someone",
},
Parameters =
{
{ "prefix", new AzureNative.Authorization.Inputs.ParameterValuesValueArgs
{
Value = "DeptA",
} },
{ "suffix", new AzureNative.Authorization.Inputs.ParameterValuesValueArgs
{
Value = "-LC",
} },
},
PolicyAssignmentName = "EnforceNaming",
PolicyDefinitionId = "/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policyDefinitions/ResourceNaming",
Scope = "subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.authorization.PolicyAssignment;
import com.pulumi.azurenative.authorization.PolicyAssignmentArgs;
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 policyAssignment = new PolicyAssignment("policyAssignment", PolicyAssignmentArgs.builder()
.description("Force resource names to begin with given DeptA and end with -LC")
.displayName("Enforce resource naming rules")
.enforcementMode("DoNotEnforce")
.metadata(Map.of("assignedBy", "Special Someone"))
.parameters(Map.ofEntries(
Map.entry("prefix", ParameterValuesValueArgs.builder()
.value("DeptA")
.build()),
Map.entry("suffix", ParameterValuesValueArgs.builder()
.value("-LC")
.build())
))
.policyAssignmentName("EnforceNaming")
.policyDefinitionId("/subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policyDefinitions/ResourceNaming")
.scope("subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2")
.build());
}
}
resources:
policyAssignment:
type: azure-native:authorization:PolicyAssignment
properties:
description: Force resource names to begin with given DeptA and end with -LC
displayName: Enforce resource naming rules
enforcementMode: DoNotEnforce
metadata:
assignedBy: Special Someone
parameters:
prefix:
value: DeptA
suffix:
value: -LC
policyAssignmentName: EnforceNaming
policyDefinitionId: /subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2/providers/Microsoft.Authorization/policyDefinitions/ResourceNaming
scope: subscriptions/ae640e6b-ba3e-4256-9d62-2993eecfa6f2
The enforcementMode property set to DoNotEnforce puts the policy in audit-only mode. Azure evaluates resources against the policy and records compliance state, but doesn’t block creation or modification of non-compliant resources. This lets you measure impact before switching to Default enforcement.
Beyond these examples
These snippets focus on specific policy assignment features: policy assignment with parameters and compliance messages, managed identity for remediation, and overrides and resource selectors for conditional enforcement. They’re intentionally minimal rather than full governance frameworks.
The examples reference pre-existing infrastructure such as policy definitions or policy set definitions, and Azure subscriptions, resource groups, or management groups for scope. They focus on configuring the assignment rather than creating the underlying policies.
To keep things focused, common assignment patterns are omitted, including:
- Exclusion scopes (notScopes)
- Custom metadata for tracking and auditing
- User-assigned managed identities
- Assignment type configuration (System, Custom)
These omissions are intentional: the goal is to illustrate how each assignment feature is wired, not provide drop-in governance modules. See the PolicyAssignment resource reference for all available configuration options.
Let's configure Azure Policy Assignments
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Scope & Assignment Basics
scope defines where the policy applies: management group, subscription, resource group, or individual resource. It’s immutable and cannot be changed after the assignment is created.scope and assignmentType are immutable. You must delete and recreate the assignment to change these properties.parameters property with key-value pairs matching the policy definition’s parameter names. Each parameter needs a value field.Enforcement & Compliance
Three modes control policy enforcement:
- Default: Enforces policy on all resources
- DoNotEnforce: Audits compliance without blocking operations
- Enroll: Enforces policy only on enrolled resources during create/update
enforcementMode to DoNotEnforce to audit compliance without blocking resource operations.nonComplianceMessages. Use policyDefinitionReferenceId to target specific policies within the set, or omit it for a general message.Identity & Permissions
identity with type SystemAssigned when the policy uses deployIfNotExists or modify effects. You must also specify a location for the identity.location property is required when using a managed identity, as the identity resource needs to be created in a specific Azure region.Advanced Configuration
overrides with kind set to policyEffect and selectors to target specific policies by policyDefinitionReferenceId. Set value to the desired effect like Audit.resourceSelectors with selectors of kind set to resourceLocation and specify the regions in the in array.resourceSelectors filter resources based on properties like location, while notScopes exclude entire scopes (subscriptions, resource groups) from the assignment.definitionVersion to specify which version to use. You can also override versions for specific resources using overrides with kind set to definitionVersion.