Skip to content

Commit

Permalink
Merge pull request #378 from vmware/bangerar/custom-policy-guide-fix
Browse files Browse the repository at this point in the history
Update the doc link and add the example link to the cutom policy guide
  • Loading branch information
ramya-bangera authored Feb 13, 2024
2 parents 0ac792a + 7df2dcd commit 95cef99
Show file tree
Hide file tree
Showing 4 changed files with 281 additions and 5 deletions.
140 changes: 138 additions & 2 deletions docs/guides/tanzu-mission-control_policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ resource "tanzu-mission-control_iam_policy" "namespace_scoped_iam_policy" {
}
```

## Custom Policy on a CLuster Group
## Custom Policy on a Cluster Group

```terraform
/*
Expand Down Expand Up @@ -278,5 +278,141 @@ resource "tanzu-mission-control_custom_policy" "cluster_group_scoped_tmc-block-r
## Custom Template and Custom Policy

Template provides a declarative definition of a policy, which can be used to apply custom constraints on managed kubernetes resources.
Custom policy consumes these declared custom templates to enforce specific policies. One must create the custom template before consuming it the custom policy.
Custom policy consumes these declared custom templates to enforce specific policies. One must create the [custom template][custom-policy-template] before consuming it in the custom policy.
Please refer to custom policy template and custom policy terraform scripts within examples.

[custom-policy-template]: https://docs.vmware.com/en/VMware-Tanzu-Mission-Control/services/tanzumc-using/GUID-F147492B-04FD-4CFD-8D1F-66E36D40D49C.html

## Refer the following example for creating custom policy template and assign it to custom policy

```terraform
/*
NOTE: Creation of custom policy depends on cluster group and custom policy template.
*/
terraform {
required_providers {
tanzu-mission-control = {
source = "vmware/tanzu-mission-control"
}
}
}
# Create cluster group.
resource "tanzu-mission-control_cluster_group" "create_cluster_group" {
name = "tf-demo-cluster-group"
}
# Create custom policy template.
resource "tanzu-mission-control_custom_policy_template" "sample_template" {
name = "tf-custom-template-test"
spec {
object_type = "ConstraintTemplate"
template_type = "OPAGatekeeper"
data_inventory {
kind = "ConfigMap"
group = "admissionregistration.k8s.io"
version = "v1"
}
data_inventory {
kind = "Deployment"
group = "extensions"
version = "v1"
}
template_manifest = <<YAML
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: tf-custom-template-test
annotations:
description: Requires Pods to have readiness and/or liveness probes.
spec:
crd:
spec:
names:
kind: tf-custom-template-test
validation:
openAPIV3Schema:
properties:
probes:
type: array
items:
type: string
probeTypes:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredprobes
probe_type_set = probe_types {
probe_types := {type | type := input.parameters.probeTypes[_]}
}
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
probe := input.parameters.probes[_]
probe_is_missing(container, probe)
msg := get_violation_message(container, input.review, probe)
}
probe_is_missing(ctr, probe) = true {
not ctr[probe]
}
probe_is_missing(ctr, probe) = true {
probe_field_empty(ctr, probe)
}
probe_field_empty(ctr, probe) = true {
probe_fields := {field | ctr[probe][field]}
diff_fields := probe_type_set - probe_fields
count(diff_fields) == count(probe_type_set)
}
get_violation_message(container, review, probe) = msg {
msg := sprintf("Container <%v> in your <%v> <%v> has no <%v>", [container.name, review.kind.kind, review.object.metadata.name, probe])
}
YAML
}
}
# Cluster group scoped custom template assigned Custom Policy
resource "tanzu-mission-control_custom_policy" "cluster_group_scoped_custom_template_assigned_custom_policy" {
name = "tf-custom-template-policy-test"
scope {
cluster_group {
cluster_group = tanzu-mission-control_cluster_group.create_cluster_group.name
}
}
spec {
input {
custom {
template_name = tanzu-mission-control_custom_policy_template.sample_template.name
audit = false
target_kubernetes_resources {
api_groups = [
"apps",
]
kinds = [
"Deployment"
]
}
target_kubernetes_resources {
api_groups = [
"apps",
]
kinds = [
"StatefulSet",
]
}
}
}
}
}
```
129 changes: 129 additions & 0 deletions examples/usecases/custom_policy_with_custom_template_usecase.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
NOTE: Creation of custom policy depends on cluster group and custom policy template.
*/

terraform {
required_providers {
tanzu-mission-control = {
source = "vmware/tanzu-mission-control"
}
}
}

# Create cluster group.
resource "tanzu-mission-control_cluster_group" "create_cluster_group" {
name = "tf-demo-cluster-group"
}

# Create custom policy template.
resource "tanzu-mission-control_custom_policy_template" "sample_template" {
name = "tf-custom-template-test"

spec {
object_type = "ConstraintTemplate"
template_type = "OPAGatekeeper"

data_inventory {
kind = "ConfigMap"
group = "admissionregistration.k8s.io"
version = "v1"
}

data_inventory {
kind = "Deployment"
group = "extensions"
version = "v1"
}

template_manifest = <<YAML
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: tf-custom-template-test
annotations:
description: Requires Pods to have readiness and/or liveness probes.
spec:
crd:
spec:
names:
kind: tf-custom-template-test
validation:
openAPIV3Schema:
properties:
probes:
type: array
items:
type: string
probeTypes:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredprobes
probe_type_set = probe_types {
probe_types := {type | type := input.parameters.probeTypes[_]}
}
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
probe := input.parameters.probes[_]
probe_is_missing(container, probe)
msg := get_violation_message(container, input.review, probe)
}
probe_is_missing(ctr, probe) = true {
not ctr[probe]
}
probe_is_missing(ctr, probe) = true {
probe_field_empty(ctr, probe)
}
probe_field_empty(ctr, probe) = true {
probe_fields := {field | ctr[probe][field]}
diff_fields := probe_type_set - probe_fields
count(diff_fields) == count(probe_type_set)
}
get_violation_message(container, review, probe) = msg {
msg := sprintf("Container <%v> in your <%v> <%v> has no <%v>", [container.name, review.kind.kind, review.object.metadata.name, probe])
}
YAML
}
}


# Cluster group scoped custom template assigned Custom Policy
resource "tanzu-mission-control_custom_policy" "cluster_group_scoped_custom_template_assigned_custom_policy" {
name = "tf-custom-template-policy-test"

scope {
cluster_group {
cluster_group = tanzu-mission-control_cluster_group.create_cluster_group.name
}
}

spec {
input {
custom {
template_name = tanzu-mission-control_custom_policy_template.sample_template.name
audit = false

target_kubernetes_resources {
api_groups = [
"apps",
]
kinds = [
"Deployment"
]
}

target_kubernetes_resources {
api_groups = [
"apps",
]
kinds = [
"StatefulSet",
]
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/pkg/errors"

"github.com/vmware/terraform-provider-tanzu-mission-control/internal/authctx"
clienterrors "github.com/vmware/terraform-provider-tanzu-mission-control/internal/client/errors"
"github.com/vmware/terraform-provider-tanzu-mission-control/internal/helper"
openapiv3 "github.com/vmware/terraform-provider-tanzu-mission-control/internal/helper/openapi_v3_schema_validator"
policyrecipecustommodel "github.com/vmware/terraform-provider-tanzu-mission-control/internal/models/policy/recipe/custom"
Expand Down Expand Up @@ -117,7 +118,11 @@ func ValidateCustomRecipe(config authctx.TanzuContext, customRecipe map[string]i
recipeData, err := config.TMCConnection.RecipeResourceService.RecipeResourceServiceGet(recipeModel)

if err != nil {
errMessages = append(errMessages, err.Error())
// NOTE: If error is 404 not found then do not fail the planning. This fix ensures that if user tries to create the new custom template
// and assign the same template to the custom policy in a single terraform apply operation will be able to proceed, instead of failing in the planning phase.
if !clienterrors.IsNotFoundError(err) {
errMessages = append(errMessages, err.Error())
}
} else {
errs := ValidateRecipeParameters(recipeData.Recipe.Spec.InputSchema, customRecipe[ParametersKey].(string))

Expand Down
10 changes: 8 additions & 2 deletions templates/guides/tanzu-mission-control_policy.md.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,18 @@ In the following example, there are multiple dependencies shown.

{{ tffile "examples/usecases/access_policy_usecase.tf" }}

## Custom Policy on a CLuster Group
## Custom Policy on a Cluster Group

{{ tffile "examples/usecases/custom_policy_usecase.tf" }}

## Custom Template and Custom Policy

Template provides a declarative definition of a policy, which can be used to apply custom constraints on managed kubernetes resources.
Custom policy consumes these declared custom templates to enforce specific policies. One must create the custom template before consuming it the custom policy.
Custom policy consumes these declared custom templates to enforce specific policies. One must create the [custom template][custom-policy-template] before consuming it in the custom policy.
Please refer to custom policy template and custom policy terraform scripts within examples.

[custom-policy-template]: https://docs.vmware.com/en/VMware-Tanzu-Mission-Control/services/tanzumc-using/GUID-F147492B-04FD-4CFD-8D1F-66E36D40D49C.html

## Refer the following example for creating custom policy template and assign it to custom policy

{{ tffile "examples/usecases/custom_policy_with_custom_template_usecase.tf" }}

0 comments on commit 95cef99

Please sign in to comment.