forked from pulumi/examples
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add stack-validation examples (pulumi#1112)
* add stack-validation examples * Update readme with instructions on how to try it out
- Loading branch information
1 parent
569bcc4
commit 6bf0c30
Showing
11 changed files
with
190 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
*.pyc | ||
venv/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
runtime: | ||
name: python | ||
options: | ||
virtualenv: venv | ||
version: 0.0.1 | ||
description: A minimal Policy Pack for AWS using Python. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# Stack Validation Example - python | ||
This provides an example of a stack validation policy. | ||
See [Policy as Code Core Concepts](https://www.pulumi.com/docs/guides/crossguard/core-concepts/) for more information. | ||
|
||
In a nutshell, the key differences between stack validation policies and resource validation policies are: | ||
* Stack validation policies can check resource outputs that are unknown to Pulumi until the provider creates the resource. | ||
* Stack validation policies can run checks that cross the entire set of resources in the stack. | ||
|
||
The example in this folder checks two things: | ||
* S3 bucket region: Although a bit of a contrived example, the region is an output assigned by AWS and thus is not known before the resource is created and thus is not able to be tested in a resource validation policy. | ||
* S3 bucket count: Checks the number of S3 buckets created in the stack. This is to show that a stack validation policy has access to the entire stack and not just individual resources like resource valiation policies do. | ||
|
||
## Try It Out | ||
* `mkdir stack-validation && cd stack-validation` | ||
* `mkdir policy-pack && cd policy-pack` | ||
* Copy the stack validation policy pack here. | ||
* Set up python virtual environment. | ||
* `python3 -m venv ./venv` | ||
* `./venv/bin/python -m pip install --upgrade pip setuptools wheel` | ||
* `./venv/bin/python -m pip install -r ./requirements.txt` | ||
* `mkdir ../test-project && cd ../test-project` | ||
* `pulumi new aws-python` | ||
* Note that the Pulumi program and the policy do not need to be written in the same language. So, you can actually use `pulumi new aws-typescript` for the project and this policy will still work. | ||
* `pulumi config set aws:region us-east-1` | ||
* Or any region other than us-west-1, or change the policy accordingly. | ||
* Edit `__main__.py` and copy/paste the s3 bucket declaration so you are creating 2 buckets. | ||
* Run `pulumi up --policy-pack ../policy-pack` to preview and then provision the resources. | ||
* Note that the preview portion of the `pulumi up` will NOT trigger the "region" check but will trigger the "count" check. | ||
* Once you enter `yes` and the resources are actually provisioned, then you will see the "region" check is triggered. This is because the bucket `region` property being checked in the policy is not known until AWS responds with the resource outputs. | ||
* Clean Up | ||
* `pulumi destroy -y` to clean up resources | ||
* `pulumi stack rm dev` to completely remove the stack and project. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
from pulumi_policy import ( | ||
EnforcementLevel, | ||
PolicyPack, | ||
ReportViolation, | ||
StackValidationArgs, | ||
StackValidationPolicy, | ||
) | ||
|
||
required_region = "us-west-1" | ||
max_num_buckets = 1 | ||
|
||
def s3_region_check_validator(stack: StackValidationArgs, report_violation: ReportViolation): | ||
for resource in stack.resources: | ||
if resource.resource_type == "aws:s3/bucket:Bucket": | ||
if "region" in resource.props and resource.props["region"] != required_region: | ||
report_violation(f"Bucket, {resource.name}, must be in region {required_region}") | ||
|
||
s3_region_check = StackValidationPolicy( | ||
name="s3-region-check", | ||
description= "Checks the region the bucket was deployed in.", | ||
validate=s3_region_check_validator | ||
) | ||
|
||
def s3_count_check_validator(stack: StackValidationArgs, report_violation: ReportViolation): | ||
buckets = list(filter((lambda resource: resource.resource_type == "aws:s3/bucket:Bucket"), stack.resources)) | ||
if len(buckets) > max_num_buckets: | ||
report_violation(f"No more than {max_num_buckets} bucket(s) should be created.") | ||
|
||
s3_count_check = StackValidationPolicy( | ||
name="s3-count-check", | ||
description= "Checks the number of buckets created.", | ||
validate=s3_count_check_validator | ||
) | ||
|
||
PolicyPack( | ||
name="aws-python", | ||
enforcement_level=EnforcementLevel.ADVISORY, | ||
policies=[ | ||
s3_region_check, | ||
s3_count_check | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pulumi-policy>=1.3.0,<2.0.0 | ||
pulumi-aws>=4.0.0,<5.0.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/bin/ | ||
/node_modules/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
description: A minimal Policy Pack for AWS using TypeScript. | ||
runtime: nodejs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Stack Validation Example - Typescript | ||
This provides an example of a stack validation policy. | ||
See [Policy as Code Core Concepts](https://www.pulumi.com/docs/guides/crossguard/core-concepts/) for more information. | ||
|
||
In a nutshell, the key differences between stack validation policies and resource validation policies are: | ||
* Stack validation policies can check resource outputs that are unknown to Pulumi until the provider creates the resource. | ||
* Stack validation policies can run checks that cross the entire set of resources in the stack. | ||
|
||
The example in this folder checks two things: | ||
* S3 bucket region: Although a bit of a contrived example, the region is an output assigned by AWS and thus is not known before the resource is created and thus is not able to be tested in a resource validation policy. | ||
* S3 bucket count: Checks the number of S3 buckets created in the stack. This is to show that a stack validation policy has access to the entire stack and not just individual resources like resource valiation policies do. | ||
|
||
## Try It Out | ||
* `mkdir stack-validation && cd stack-validation` | ||
* `mkdir policy-pack && cd policy-pack` | ||
* Copy the stack validation policy pack here. | ||
* `npm i` | ||
* `mkdir ../test-project && cd ../test-project` | ||
* `pulumi new aws-typescript` | ||
* Note that the Pulumi program and the policy do not need to be written in the same language. So, you can actually use `pulumi new aws-python` for the project and this policy will still work. | ||
* `pulumi config set aws:region us-east-1` | ||
* Or any region other than us-west-1, or change the policy accordingly. | ||
* Edit `index.ts` and copy/paste the s3 bucket declaration so you are creating 2 buckets. | ||
* Run `pulumi up --policy-pack ../policy-pack` to preview and then provision the resources. | ||
* Note that the preview portion of the `pulumi up` will NOT trigger the "region" check but will trigger the "count" check. | ||
* Once you enter `yes` and the resources are actually provisioned, then you will see the "region" check is triggered. This is because the bucket `region` property being checked in the policy is not known until AWS responds with the resource outputs. | ||
* Clean Up | ||
* `pulumi destroy -y` to clean up resources | ||
* `pulumi stack rm dev` to completely remove the stack and project. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import * as aws from "@pulumi/aws"; | ||
import { PolicyPack, validateStackResourcesOfType } from "@pulumi/policy"; | ||
|
||
const requiredRegion = "us-west-1" | ||
const maxNumBuckets = 1 | ||
|
||
new PolicyPack("stackvalidation-ts", { | ||
policies: [ | ||
{ | ||
name: "s3-region-check", | ||
description: "Checks the region the bucket was deployed in.", | ||
enforcementLevel: "advisory", // "mandatory" | ||
validateStack: (stack, reportViolation) => { | ||
// stack contains all the resources created by the stack. So, loop through them to find S3 buckets and check the region output. | ||
for (const resource of stack.resources) { | ||
if (resource.type == "aws:s3/bucket:Bucket") { | ||
// Check if the region property has been set yet - which it won't on initial preview since AWS hasn't returned that output property yet. | ||
// But if is set which will be the case once the stack is created and for subsequent previews, check it. | ||
if (resource.props.hasOwnProperty("region") && resource.props.region != requiredRegion) { | ||
reportViolation(`Bucket, ${resource.name}, must be in region ${requiredRegion}`) | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
{ | ||
name: "s3-count-check", | ||
description: "Checks the number of S3 buckets created in the stack.", | ||
enforcementLevel: "advisory", // "mandatory" | ||
validateStack: (stack, reportViolation) => { | ||
// Gather up all the buckets in the stack. | ||
const buckets = stack.resources.filter((resource) => resource.isType(aws.s3.Bucket)) | ||
// Make sure there no more than the allowed number of buckets. | ||
if (buckets.length > maxNumBuckets) { | ||
reportViolation(`No more than ${maxNumBuckets} bucket(s) should be created.`) | ||
} | ||
} | ||
} | ||
], | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"name": "aws-typescript", | ||
"version": "0.0.1", | ||
"dependencies": { | ||
"@pulumi/aws": "^4.0.0", | ||
"@pulumi/pulumi": "^3.0.0", | ||
"@pulumi/policy": "^1.3.0" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^10.0.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"compilerOptions": { | ||
"outDir": "bin", | ||
"target": "es6", | ||
"module": "commonjs", | ||
"moduleResolution": "node", | ||
"declaration": true, | ||
"sourceMap": false, | ||
"stripInternal": true, | ||
"experimentalDecorators": true, | ||
"pretty": true, | ||
"noFallthroughCasesInSwitch": true, | ||
"noImplicitAny": true, | ||
"noImplicitReturns": true, | ||
"forceConsistentCasingInFileNames": true, | ||
"strictNullChecks": true, | ||
}, | ||
"files": [ | ||
"index.ts" | ||
] | ||
} |