Skip to content

Commit ce999eb

Browse files
authored
Document practices for writing Pulumi Policies for Dynamic Providers (#16522)
1 parent 0afe19b commit ce999eb

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)