Authoring a Policy Pack
CrossGuard is a beta feature and is subject to breaking changes. The open
source --policy-pack
flag is free and available for all to use. A preview of CrossGuard
is also available in the Pulumi Console, which enables you to enforce policies across an
organization. To get access, submit a request here.
Install prerequisites.
Verify your version of Pulumi.
$ pulumi version # should be v1.6.1 or later
Create a directory for your new Policy Pack, and change into it.
$ mkdir policypack && cd policypack
Run the
pulumi policy new
command. Since Policy as Code is a beta feature, you will need to setPULUMI_EXPERIMENTAL=true
as an environment variable or simply pre-append it to your commands as shown.On macOS, you can run
export PULUMI_EXPERIMENTAL=true
or simply prepend it to your commands as shown.$ PULUMI_EXPERIMENTAL=true pulumi policy new aws-typescript
On Linux, you can run
export PULUMI_EXPERIMENTAL=true
or simply prepend it to your commands as shown.$ PULUMI_EXPERIMENTAL=true pulumi policy new aws-typescript
On Windows, you must first set the environment variable before running the command.
Windows cmd.exe
set PULUMI_EXPERIMENTAL=true pulumi policy new aws-typescript
Windows PowerShell
$env:PULUMI_EXPERIMENTAL = 'true' pulumi policy new aws-typescript
Tweak the Policy Pack in the
index.ts
file as desired. The existing policy in the template (which is annotated below) mandates that an AWS S3 bucket not have public read or write permissions enabled. Each Policy must have a unique name, an enforcement level, and a validation function. Here we usevalidateTypedResource
that allows us to validate S3 Bucket resources.// Create a new Policy Pack. new PolicyPack("policy-pack-typescript", { // Specify the Policies in the Policy Pack. policies: [{ // The name for the Policy must be unique within the Pack. name: "s3-no-public-read", // The description should document what the Policy does and why it exists. description: "Prohibits setting the publicRead or publicReadWrite permission on AWS S3 buckets.", // The enforcement level can either be "advisory" or "mandatory". An "advisory" enforcement level // simply prints a warning for users, while a "mandatory" policy will block an update from proceeding. enforcementLevel: "mandatory", // The validateTypedResource function allows you to filter resources. In this case, the rule only // applies to S3 buckets and reports a violation if the acl is "public-read" or "public-read-write". validateResource: validateTypedResource(aws.s3.Bucket, (bucket, args, reportViolation) => { if (bucket.acl === "public-read" || bucket.acl === "public-read-write") { reportViolation( "You cannot set public-read or public-read-write on an S3 bucket. " + "Read more about ACLs here: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html"); } }), }], });
You can find more example Policy Packs in the examples repo. Policy Pack best practices documentation details the best practices for writing a Policy Pack.
Testing the Policy Pack Locally
Policy Packs can be tested on a user’s local workstation to facilitate rapid development and testing of policies. This removes the step of publishing and applying policy packs to the Pulumi Console and lets developers reference a policy pack on their local workstation.
Run
npm install
in the Policy Pack directory.Use the
--policy-pack
flag withpulumi preview
orpulumi up
to specify the path to the directory containing your Policy Pack when previewing/updating a Pulumi project.If you don’t have a Pulumi project readily available, you can create a new project for testing by running
pulumi new aws-typescript
in an empty directory. This AWS example will create an S3 bucket, which is perfect for testing our Policy.In the Pulumi project’s directory run:
$ PULUMI_EXPERIMENTAL=true pulumi preview --policy-pack <path-to-policy-pack-directory>
$ PULUMI_EXPERIMENTAL=true pulumi preview --policy-pack <path-to-policy-pack-directory>
Windows cmd.exe
set PULUMI_EXPERIMENTAL=true pulumi preview --policy-pack <path-to-policy-pack-directory>
Windows PowerShell
$env:PULUMI_EXPERIMENTAL = 'true' pulumi preview --policy-pack <path-to-policy-pack-directory>
If the stack is in compliance, we expect the output to simply tell us which Policy Packs were run.
Previewing update (dev): Type Name Plan + pulumi:pulumi:Stack test-dev create + └─ aws:s3:Bucket my-bucket create Resources: + 2 to create
We can then edit the stack code to specify the ACL to be public-read.
const bucket = new aws.s3.Bucket("my-bucket", { acl: "public-read", });
We then run the
pulumi preview
command again and this time get an error message indicating we failed the preview because of a policy violation.Previewing update (dev): Type Name Plan Info + pulumi:pulumi:Stack test-dev create 1 error + └─ aws:s3:Bucket my-bucket create 1 error Diagnostics: pulumi:pulumi:Stack (test-dev): error: preview failed aws:s3:Bucket (my-bucket): mandatory: [s3-no-public-read] Prohibits setting the publicRead or publicReadWrite permission on AWS S3 buckets. You cannot set public-read or public-read-write on an S3 bucket. Read more about ACLs here: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html
Now that your Policy Pack is ready to go, let’s enforce the pack across your organization.