pulumi / pulumi-policy

Pulumi's Policy as Code SDK, CrossGuard. Define infrastructure checks in code to enforce security, compliance, cost, and other practices, enforced at deployment time.
https://www.pulumi.com/docs/guides/crossguard/
Apache License 2.0
32 stars 4 forks source link

Make it easier to write a single tagging rule #301

Open jkodroff opened 1 year ago

jkodroff commented 1 year ago

Hello!

Issue details

It's currently difficult to write a single policy that allows the user to enforce tagging across all (or at least most) resources. ResourceValidationArgs.props are the supplied values for properties, not the list of all possible properties. props["tags"] will be null if it's not supplied and thus there's no obvious way to check whether a tags property can exist on the resource - only what value, if any, was supplied.

It looks like, at present, that our best option is to keep a maintained list of taggable resources per this back code from @joeduffy's blog post.

Possible solutions:

  1. Add ResourceValidationArgs.availableProps or similar so that we can check whether a property exists. (Could be a function rather than a property.)
  2. If the previous option is particularly difficult, we could maybe improve this in pulumi-policy-aws: create an automated process to query the list of taggable resources from the AWS provider on a schedule and make this easily available to the user, either as a simple list or giving some abstraction that makes it easy to write a tagging policy rule. (Would be enthused to either help write this or at least give design and testing feedback.)

Affected area/feature

Policy

joeduffy commented 1 year ago

This is probably different in all languages, but what I tried and hoped would work was:

if (res.hasOwnProperty("tags")) {
    // ...
}

This is in TypeScript, and the idea was to depend on the presence of a tags property -- which works in many languages (e.g., in for Python, reflection for Go/C#/etc) -- but given the way we initialize resources today, it doesn't work as-is.

Notably, if we actually initialized the property bag (in TypeScript at least) with tags: undefined, versus skipping it altogether in the generated ctors, I think it would work. This depends a lot on our RPC serialization, however, I think.

It's also super fragile so maybe not the best approach but I'm guessing a handful of surgical fixes could get us there.

jkodroff commented 1 year ago

@joeduffy The second suggestion above would likely be good enough from a user's perspective, even if it requires some manual maintenance/scheduled updates. Even if it doesn't cover all resources, the most commonly used ones would clearly be covered, and that's a major improvement.

Is there any connection today between the policy SDK and the schema, or is it just "here's what the user entered for this arbitrary resource"?