Skip to content

Commit d03ce7b

Browse files
jkodroffclaude
andcommitted
Document practices for writing Pulumi Policies for Dynamic Providers
Add comprehensive documentation on how to write policies for dynamic providers, addressing the challenge that all dynamic resources share the same resource type. Include examples in TypeScript and Python that demonstrate property-based filtering to identify specific dynamic providers, along with best practices for authoring such policies. Changes: - Add new section in policy authoring docs with complete examples - Add informational note in dynamic providers docs linking to guidance - Provide best practices for writing robust dynamic provider policies Fixes #14437 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent f5a840c commit d03ce7b

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

content/docs/iac/concepts/resources/dynamic-providers.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ The dynamic resource provider construct can be used to build a local provider fo
2323
**Note:** The Pulumi registry includes the [Command Provider](https://www.pulumi.com/registry/packages/command/) as an even lighter weight solution and can be used in place of a dynamic resource provider in some cases.
2424
{{% /notes %}}
2525

26+
{{% notes type="info" %}}
27+
**Note:** [Pulumi Policy Packs](/docs/insights/policy/) can be used to validate dynamic provider resources. However, since all dynamic resources share the same resource type (`pulumi-nodejs:dynamic:Resource` for TypeScript/JavaScript or `pulumi-python:dynamic:Resource` for Python), policies must identify specific dynamic providers by checking for unique properties. See [Writing policies for dynamic providers](/docs/insights/policy/policy-packs/authoring/#writing-policies-for-dynamic-providers) for examples and best practices.
28+
{{% /notes %}}
29+
2630
There are several reasons why you might want to write a dynamic resource provider. Here are some of them:
2731

2832
- You want to create some new custom resource types.

content/docs/insights/policy/policy-packs/authoring.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,98 @@ Use stack validation policies when you need to:
248248
249249
Most policies are resource validation policies. Stack validation policies are useful for more complex scenarios that require understanding the full context of your infrastructure.
250250
251+
## Writing policies for dynamic providers
252+
253+
[Dynamic providers](/docs/iac/concepts/resources/dynamic-providers/) allow you to create custom resource types directly in your Pulumi programs. When writing policies for dynamic providers, you need to account for a key constraint: **all dynamic resources share the same resource type** (`pulumi-nodejs:dynamic:Resource` for TypeScript/JavaScript or `pulumi-python:dynamic:Resource` for Python).
254+
255+
Since you cannot rely on the resource type alone to identify which dynamic provider a resource uses, you must inspect the resource's properties to differentiate between different dynamic provider implementations.
256+
257+
### Example: Validating a specific dynamic provider
258+
259+
This example shows how to write a policy that validates resources from a specific dynamic provider by checking for a unique property:
260+
261+
{{< chooser language "typescript,python" >}}
262+
263+
{{% choosable language typescript %}}
264+
265+
```typescript
266+
import * as pulumi from "@pulumi/pulumi";
267+
import { PolicyPack, ResourceValidationPolicy } from "@pulumi/policy";
268+
269+
new PolicyPack("dynamic-provider-policies", {
270+
policies: [{
271+
name: "environment-name-validation",
272+
description: "Validates that environment dynamic resources use the correct name.",
273+
enforcementLevel: "mandatory",
274+
validateResource: (args, reportViolation) => {
275+
// All dynamic resources in TypeScript/JavaScript have the type "pulumi-nodejs:dynamic:Resource".
276+
// To identify a specific dynamic provider, check for unique properties.
277+
if (args.type === "pulumi-nodejs:dynamic:Resource" && args.props.environmentName !== undefined) {
278+
const envName = args.props.environmentName;
279+
if (envName !== "myTestEnv") {
280+
reportViolation(
281+
`Environment name must be 'myTestEnv'. Current value: '${envName}'`);
282+
}
283+
}
284+
},
285+
}],
286+
});
287+
```
288+
289+
{{% /choosable %}}
290+
291+
{{% choosable language python %}}
292+
293+
```python
294+
from pulumi_policy import (
295+
EnforcementLevel,
296+
PolicyPack,
297+
ReportViolation,
298+
ResourceValidationArgs,
299+
ResourceValidationPolicy,
300+
)
301+
302+
def env_dynprov_check(args: ResourceValidationArgs, report_violation: ReportViolation):
303+
# All dynamic resources in Python have the type "pulumi-python:dynamic:Resource"
304+
# To identify a specific dynamic provider, check for unique properties
305+
# In this case, we look for resources with an "environment_name" property
306+
if args.resource_type == "pulumi-python:dynamic:Resource" and "environment_name" in args.props:
307+
environment_name = args.props["environment_name"]
308+
if environment_name != "myTestEnv":
309+
report_violation(
310+
f"Environment name must be 'myTestEnv'. Current value: '{environment_name}'")
311+
312+
dyn_prov_policy = ResourceValidationPolicy(
313+
name="environment-name-validation",
314+
description="Validates that environment dynamic resources use the correct name.",
315+
enforcement_level=EnforcementLevel.MANDATORY,
316+
validate=env_dynprov_check,
317+
)
318+
319+
PolicyPack(
320+
name="dynamic-provider-policies",
321+
policies=[
322+
dyn_prov_policy,
323+
],
324+
)
325+
```
326+
327+
{{% /choosable %}}
328+
329+
{{< /chooser >}}
330+
331+
### Best practices for dynamic provider policies
332+
333+
When writing policies for dynamic providers:
334+
335+
1. **Identify unique properties**: Determine which properties uniquely identify the dynamic provider you want to validate. In the example above, the `environment_name` (or `environmentName`) property indicates this is an environment resource.
336+
337+
1. **Be specific with property checks**: Since all dynamic resources share the same type, check for specific property names or combinations that distinguish your dynamic provider from others.
338+
339+
1. **Handle missing properties gracefully**: Use property existence checks (like `"environment_name" in args.props`) before accessing property values to avoid errors when the policy runs against other dynamic providers.
340+
341+
1. **Document your assumptions**: Clearly document which properties your policy uses to identify dynamic providers so that changes to the dynamic provider implementation don't inadvertently break policy enforcement.
342+
251343
## Running policies locally
252344
253345
Test your policy pack locally before publishing.

0 commit comments

Comments
 (0)