In a [previous blog post](/blog/announcing-crossguard-preview/), I introduced CrossGuard, Pulumi's Policy as Code solution. As part of our [2.0 release](/blog/pulumi-2-0/), CrossGuard is now generally available and has some awesome new features to improve the user experience around managing Policy Packs.
We have added richer CLI support for CrossGuard. Organization administrators can now manage their Policy Packs from the CLI. In addition to being able to publish Policy Packs, you may now enable a Policy Pack by simply running:
By default, the `enable` and `disable` commands use an organization's default Policy Group. Using the `--policy-group` flag, you can specify another Policy Group. You can also specify `latest` instead of a specific Policy Pack version to enable the latest version of that Policy Pack.
Policies now have access to more information about the resources under review. With access to the options, parent, and dependencies of a resource, you can now write even more thorough policies.
You may access a [resource's options](/docs/concepts/resources#options) via the `ResourceValidationArgs` parameter. In the below example, we enforce that all DynamoDB tables be `protected` to prevent data loss.
reportViolation(`DynamoDB tables must be protected to prevent data loss.`);
}
}),
},
],
});
```
Access to the parent and dependencies of a resource allows you to author policies about the relationship between resources. For example, you may want to make sure that each DynamoDB table in a stack has an attached scaling policy.
```typescript
new PolicyPack("aws-policies", {
policies: [
{
name: "dyanmodb-table-protected",
description: "DynamoDB tables should have an autoscaling policy.",
if (!scalingPolicies || scalingPolicies.length === 0) {
reportViolation(`DynamoDB table ${table.name} is missing a scaling policy.`);
}
}
}
},
],
});
```
## Python Support
As of our 2.0 launch, you can now author Policy Pack in Python. Our multi-language approach allows you to author a Policy Pack using our NodeJS or Python SDK and enforce the pack on a stack written in any language.
The Python-based Policy Pack prohibits public permission of Azure Storage Blob Containers.
And lastly, the feature I am most excited to share with you all is Configurable Policy Packs. Using configuration, you can author Policy Packs that are reusable and flexible for your organization's various needs.
For example, you may have a policy that restricts the allowed EC2 instance types. This set of instances may vary between your non-production stack and production stacks.
```typescript
new PolicyPack("aws-policies", {
policies: [
{
name: "allowed-ec2-instance-type",
description: "EC2 instance type must be of an approved type.",
reportViolation(`No EC2 instance types have been approved.`);
return;
}
if (!config.allowedTypes.includes(instance.instanceType)) {
reportViolation(`EC2 type must be an allowed instance type: ${config.allowedTypes}. ` +
`${instance.instanceType} is not allowed type.`);
}
}),
},
],
});
```
Using this configuration, you can make this deviation, allowing larger, more costly instances only in production. We can enable this configurable Policy Pack for our Policy Group `prod-stacks` using configuration that allows for other instance types.
```json
{
"allowed-ec2-instance-type": {
"allowedTypes": ["t2.medium", "t2.large"]
}
}
```
To enable the pack with this configuration, we can save the JSON to a file called `prod-policy-config.json` and then run:
Configuration allows organization administrators to quickly and easily tweak Policy Packs to meet a variety of use cases.
## Wrapping Up
We've invested in improving the user experience for authoring and managing policy. Whether you're an enterprise customer or an open source user, you can get started by taking CrossGuard for a spin.