Open Policy Agent (OPA) is a robust policy-as-code engine offering a systematic approach to defining and governing various aspects of cloud resources. Using it enables teams to establish clear guardrails for their cloud infrastructure, and ensure security, compliance, and operational excellence.

In this post, I want to talk about the magic that happens when OPA joins forces with the env0 to provide organizations with an advanced solution for streamlining cloud governance, automating policy enforcement, and maintaining control over cloud deployments.

Getting Started: Multiple Approvers

Let's jump right in, with our first example. 

When working on critical projects, applying some changes with only a single approval doesn’t suffice and we want the changes to be approved by another approver. This is something that we enable you to address with our input schema, which you can use to write a Rego to enforce such a policy.

In the example below you can see an approval flow that requires at least two approvals:

package env0

# METADATA
# title: require 2 approvals
# description: At least 2 approvals must be given.
pending[format(rego.metadata.rule())] {
	count(input.approvers) < 2
}

# METADATA
# title: At least 2 approvals
# description: Only allow if two or more approvals are given.
allow[format(rego.metadata.rule())] {
	count(input.approvers) >= 2
}

format(meta) := meta.description

The options for the Open Policy Agent run are: allow, pending, or deny.  The way it works is that a run will stay in pending mode, until it’s manually allowed. Also, if there is one rule (or more) with a deny option, the deployment will be canceled.

In the code above you can see that we leveraged this to create a count(input.approvers) >= 2 condition for the allow option to trigger. 

The next step is to push the code to our designated VCS and configure our project in env0 to enforce that policy, like so:

Once you do that, every environment in the project will have to comply with the “two approvers” policy:

Condition-based Policies

In the example above you saw how easy it is to set multiple approvals, but what if we want to kick it up a notch? In the next example, I’ll show how we can combine env0 and OPA to apply different policies for specific scenarios. This will provide you with a lot of flexibility for how (and when) rules are enforced, helping you strike the right balance between policy management and productivity.  

To make things simple, I’ll continue with the previous example of multiple approvers. Let’s assume that we don’t want to have that rule on every deployment in our project. Instead, we only want it to trigger when the financial stakes are high enough to justify the extra approval.

In the code below you can see how you can easily do that, leveraging our cost monitoring features to create a policy trigger based on a cost threshold. In this case, $100:

package env0

cost_threshold := 100
required_approvers := 2

has_key(x, k) {
	_ = x[k]
}

# METADATA
# title: require multiple approvals when cost difference is large
# description: require approval if cost difference is larger then our given threshold and less then 2 approvals given.
pending[format(rego.metadata.rule())] {
	has_key(input.costEstimation, "monthlyCostDiff")
	input.costEstimation.monthlyCostDiff > cost_threshold
	count(input.approvers) < required_approvers
}

# METADATA
# title: multiple approvals given for cost difference greater than threshold.
# description: allow if two or more approvals are given and the cost difference is greater than our threshold.
allow[format(rego.metadata.rule())] {
	count(input.approvers) >= required_approvers
}

# METADATA
# title: cost difference is smaller than threshold
# description: allow if the cost difference is smaller then threshold.

allow[format(rego.metadata.rule())] {
	has_key(input.costEstimation, "monthlyCostDiff")
	input.costEstimation.monthlyCostDiff <= cost_threshold
}

format(meta) := meta.description



Now users will be able to skip multiple approvers for their lower-cost deploys:

And only encounter the need to have multiple approvers for deploys that go above the threshold: 

Policies Based on Deployment Plans

But what happens when the numbers alone don't tell the whole story? After all, there are times when changes, even though below the cost threshold can still have a significant impact on your infrastructure.

To handle such situations, you’ll need policies that “understand” the intricacies of your deployment plans. This is where the OPA-env0 combo shines. For instance, imagine a scenario where the number of resources being modified exceeds a certain limit – let's say more than five.

To make sure such changes will not go unnoticed, we can craft a policy that mandates a minimum of two approvers here as well.

For that all we need is to add the following rule to our previously created trigger:

package env0

resource_limit := 5


# METADATA
# title: requires multiple approvals for more than planned resources limit
# description: require multiple approvals on more than planned resources limit
pending[format(rego.metadata.rule())] {
	count(input.plan.resource_changes) >= resource_limit
	count(input.approvers) < required_approvers
}

Pretty handy, right? Just like that now we will also have visibility of not only costs but also resource changes:

Summary

Wrapping up this journey into the world of OPA and env0, we've explored some practical use cases, from enforcing multiple approvals for critical changes to fine-tuning policies based on cost differentials and resource limits. 

These are just a few examples of how combining OPA with env0 can help you to tailor policies to your organization's specific needs, and modify them with ease as those needs continue to evolve.

I encourage you to explore, experiment, and harness the power of OPA to transform your cloud management experience. All examples can be found in our GitHub and you can also check out our Documentation to learn more about approval policies in env0.

Open Policy Agent (OPA) is a robust policy-as-code engine offering a systematic approach to defining and governing various aspects of cloud resources. Using it enables teams to establish clear guardrails for their cloud infrastructure, and ensure security, compliance, and operational excellence.

In this post, I want to talk about the magic that happens when OPA joins forces with the env0 to provide organizations with an advanced solution for streamlining cloud governance, automating policy enforcement, and maintaining control over cloud deployments.

Getting Started: Multiple Approvers

Let's jump right in, with our first example. 

When working on critical projects, applying some changes with only a single approval doesn’t suffice and we want the changes to be approved by another approver. This is something that we enable you to address with our input schema, which you can use to write a Rego to enforce such a policy.

In the example below you can see an approval flow that requires at least two approvals:

package env0

# METADATA
# title: require 2 approvals
# description: At least 2 approvals must be given.
pending[format(rego.metadata.rule())] {
	count(input.approvers) < 2
}

# METADATA
# title: At least 2 approvals
# description: Only allow if two or more approvals are given.
allow[format(rego.metadata.rule())] {
	count(input.approvers) >= 2
}

format(meta) := meta.description

The options for the Open Policy Agent run are: allow, pending, or deny.  The way it works is that a run will stay in pending mode, until it’s manually allowed. Also, if there is one rule (or more) with a deny option, the deployment will be canceled.

In the code above you can see that we leveraged this to create a count(input.approvers) >= 2 condition for the allow option to trigger. 

The next step is to push the code to our designated VCS and configure our project in env0 to enforce that policy, like so:

Once you do that, every environment in the project will have to comply with the “two approvers” policy:

Condition-based Policies

In the example above you saw how easy it is to set multiple approvals, but what if we want to kick it up a notch? In the next example, I’ll show how we can combine env0 and OPA to apply different policies for specific scenarios. This will provide you with a lot of flexibility for how (and when) rules are enforced, helping you strike the right balance between policy management and productivity.  

To make things simple, I’ll continue with the previous example of multiple approvers. Let’s assume that we don’t want to have that rule on every deployment in our project. Instead, we only want it to trigger when the financial stakes are high enough to justify the extra approval.

In the code below you can see how you can easily do that, leveraging our cost monitoring features to create a policy trigger based on a cost threshold. In this case, $100:

package env0

cost_threshold := 100
required_approvers := 2

has_key(x, k) {
	_ = x[k]
}

# METADATA
# title: require multiple approvals when cost difference is large
# description: require approval if cost difference is larger then our given threshold and less then 2 approvals given.
pending[format(rego.metadata.rule())] {
	has_key(input.costEstimation, "monthlyCostDiff")
	input.costEstimation.monthlyCostDiff > cost_threshold
	count(input.approvers) < required_approvers
}

# METADATA
# title: multiple approvals given for cost difference greater than threshold.
# description: allow if two or more approvals are given and the cost difference is greater than our threshold.
allow[format(rego.metadata.rule())] {
	count(input.approvers) >= required_approvers
}

# METADATA
# title: cost difference is smaller than threshold
# description: allow if the cost difference is smaller then threshold.

allow[format(rego.metadata.rule())] {
	has_key(input.costEstimation, "monthlyCostDiff")
	input.costEstimation.monthlyCostDiff <= cost_threshold
}

format(meta) := meta.description



Now users will be able to skip multiple approvers for their lower-cost deploys:

And only encounter the need to have multiple approvers for deploys that go above the threshold: 

Policies Based on Deployment Plans

But what happens when the numbers alone don't tell the whole story? After all, there are times when changes, even though below the cost threshold can still have a significant impact on your infrastructure.

To handle such situations, you’ll need policies that “understand” the intricacies of your deployment plans. This is where the OPA-env0 combo shines. For instance, imagine a scenario where the number of resources being modified exceeds a certain limit – let's say more than five.

To make sure such changes will not go unnoticed, we can craft a policy that mandates a minimum of two approvers here as well.

For that all we need is to add the following rule to our previously created trigger:

package env0

resource_limit := 5


# METADATA
# title: requires multiple approvals for more than planned resources limit
# description: require multiple approvals on more than planned resources limit
pending[format(rego.metadata.rule())] {
	count(input.plan.resource_changes) >= resource_limit
	count(input.approvers) < required_approvers
}

Pretty handy, right? Just like that now we will also have visibility of not only costs but also resource changes:

Summary

Wrapping up this journey into the world of OPA and env0, we've explored some practical use cases, from enforcing multiple approvals for critical changes to fine-tuning policies based on cost differentials and resource limits. 

These are just a few examples of how combining OPA with env0 can help you to tailor policies to your organization's specific needs, and modify them with ease as those needs continue to evolve.

I encourage you to explore, experiment, and harness the power of OPA to transform your cloud management experience. All examples can be found in our GitHub and you can also check out our Documentation to learn more about approval policies in env0.

Logo Podcast
With special guest
Andrew Brown

Schedule a technical demo. See env0 in action.

Footer Illustration