Vorbereitung
Einschränkungs-Framework
gcloud beta terraform vet
verwendet Constraint Framework-Richtlinien, die aus Einschränkungen und Einschränkungsvorlagen bestehen. So unterscheiden sich die beiden:
- Eine Einschränkungsvorlage kann man sich vorstellen wie eine Funktionsdeklaration. Sie definiert eine Regel und kann optional Variablen als Eingaben verwenden.
- Eine Einschränkung ist eine Datei, die auf eine Einschränkungsvorlage verweist und die Werte definiert, die damit verwendet werden sollen.
Einschränkungsvorlage erstellen
1. Beispieldaten erfassen
Um eine Einschränkungsvorlage schreiben zu können, benötigen Sie Beispieldaten. Terraform-basierte Einschränkungen arbeiten mit Daten zu Ressourcenänderungen, die aus dem Schlüssel resource_changes
von Terraform-Plan JSON stammen.
Ihre JSON-Datei könnte beispielsweise so aussehen:
// tfplan.json
{
"format_version": "0.2",
"terraform_version": "1.0.10",
"resource_changes": [
{
"address": "google_compute_address.internal_with_subnet_and_address",
"mode": "managed",
"type": "google_compute_address",
"name": "internal_with_subnet_and_address",
"provider_name": "registry.terraform.io/hashicorp/google",
"change": {
"actions": [
"create"
],
"before": null,
"after": {
"address": "10.0.42.42",
"address_type": "INTERNAL",
"description": null,
"name": "my-internal-address",
"network": null,
"prefix_length": null,
"region": "us-central1",
"timeouts": null
},
"after_unknown": {
"creation_timestamp": true,
"id": true,
"network_tier": true,
"project": true,
"purpose": true,
"self_link": true,
"subnetwork": true,
"users": true
},
"before_sensitive": false,
"after_sensitive": {
"users": []
}
}
}
],
// other data
}
2. Rego schreiben
Nachdem Sie Beispieldaten haben, können Sie die Logik für Ihre Einschränkungsvorlage in Rego schreiben.
Ihr Rego muss eine violations
-Regel enthalten. Die geprüfte Ressourcenänderung ist als input.review
verfügbar. Einschränkungsparameter sind als input.parameters
verfügbar. Wenn Sie beispielsweise anfordern möchten, dass google_compute_address
-Ressourcen einen zulässigen address_type
haben, schreiben Sie:
# validator/tf_compute_address_address_type_allowlist_constraint_v1.rego
package templates.gcp.TFComputeAddressAddressTypeAllowlistConstraintV1
violation[{
"msg": message,
"details": metadata,
}] {
resource := input.review
resource.type == "google_compute_address"
allowed_address_types := input.parameters.allowed_address_types
count({resource.after.address_type} & allowed_address_types) >= 1
message := sprintf(
"Compute address %s has a disallowed address_type: %s",
[resource.address, resource.after.address_type]
)
metadata := {"resource": resource.name}
}
Einschränkungsvorlage benennen
Im vorherigen Beispiel wird der Name TFComputeAddressAddressTypeAllowlistConstraintV1
verwendet.
Dies ist eine eindeutige Kennung für jede Einschränkungsvorlage. Wir empfehlen, diese Richtlinien für Namen zu verwenden:
- Allgemeines Format:
TF{resource}{feature}Constraint{version}
. CamelCase verwenden. Schreiben Sie also jedes neue Wort in Großbuchstaben. - Beachten Sie bei Einschränkungen für einzelne Ressourcen die Konventionen für Terraform-Anbieter für die Produktbenennung. Bei
google_tags_tag
lautet der Produktname beispielsweisetags
, obwohl der API-Nameresourcemanager
lautet. - Wenn eine Vorlage für mehr als einen Ressourcentyp gilt, lassen Sie den Ressourcenteil weg und fügen Sie nur das Feature ein (Beispiel: "TFAddressTypeAllowlistConstraintV1").
- Die Versionsnummer folgt nicht der semver-Form. nur eine einzige Zahl. Dadurch wird jede Version einer Vorlage zu einer eindeutigen Vorlage.
Wir empfehlen, für Ihre Rego-Datei einen Namen zu verwenden, der mit dem Namen der Einschränkungsvorlage übereinstimmt, aber "snake_case" verwendet. Mit anderen Worten, konvertieren Sie den Namen mit _
in Kleinbuchstaben. Im obigen Beispiel lautet der empfohlene Dateiname tf_compute_address_address_type_allowlist_constraint_v1.rego
3. Rego testen
Sie können Ihr Rego manuell mit Rego Playground testen. Verwenden Sie nicht vertrauliche Daten.
Wir empfehlen, automatisierte Tests zu schreiben.
Fügen Sie Ihre gesammelten Beispieldaten in validator/test/fixtures/<constraint filename>/resource_changes/data.json
ein und verweisen Sie in Ihrer Testdatei so darauf:
# validator/tf_compute_address_address_type_allowlist_constraint_v1_test.rego
package templates.gcp.TFComputeAddressAddressTypeAllowlistConstraintV1
import data.test.fixtures.tf_compute_address_address_type_allowlist_constraint_v1_test.resource_changes as resource_changes
test_violation_with_disallowed_address_type {
parameters := {
"allowed_address_types": "EXTERNAL"
}
violations := violation with input.review as resource_changes[_]
with input.parameters as parameters
count(violations) == 1
}
Platzieren Sie den Rego und den Test im Ordner validator
Ihrer Richtlinienbibliothek.
4. Basis-Einschränkungsvorlage einrichten
Nachdem Sie eine funktionierende und getestete Rego-Regel haben, müssen Sie diese als Einschränkungsvorlage verpacken. Constraint Framework verwendet benutzerdefinierte Kubernetes-Ressourcendefinitionen als Container für den Richtlinien-Rego.
Die Einschränkungsvorlage definiert mithilfe des Schemas OpenAPI V3 auch, welche Parameter als Eingaben von Einschränkungen zulässig sind.
Verwenden Sie für das Skelett denselben Namen wie für den Rego. Beispiele:
- Verwenden Sie denselben Dateinamen wie für Ihren Rego. Beispiel:
tf_compute_address_address_type_allowlist_constraint_v1.yaml
spec.crd.spec.names.kind
muss den Vorlagennamen enthaltenmetadata.name
muss den Vorlagennamen enthalten, muss aber kleingeschrieben werden
Platzieren Sie das Basisschema der Einschränkungsvorlage in policies/templates
.
Für das obige Beispiel:
# policies/templates/tf_compute_address_address_type_allowlist_constraint_v1.yaml
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: tfcomputeaddressaddresstypeallowlistconstraintv1
spec:
crd:
spec:
names:
kind: TFComputeAddressAddressTypeAllowlistConstraintV1
validation:
openAPIV3Schema:
properties:
allowed_address_types:
description: "A list of address_types allowed, for example: ['INTERNAL']"
type: array
items:
type: string
targets:
- target: validation.resourcechange.terraform.cloud.google.com
rego: |
#INLINE("validator/tf_compute_address_address_type_allowlist_constraint_v1.rego")
#ENDINLINE
5 Ihr Rego einbinden
In Anlehnung an das vorherige Beispiel sieht Ihr Verzeichnislayout nun folgendermaßen aus:
| policy-library/
|- validator/
||- tf_compute_address_address_type_allowlist_constraint_v1.rego
||- tf_compute_address_address_type_allowlist_constraint_v1_test.rego
|- policies
||- templates
|||- tf_compute_address_address_type_allowlist_constraint_v1.yaml
Wenn Sie das von Google bereitgestellte Repository für die Richtlinienbibliothek geklont haben, können Sie make build
ausführen, um Ihre Einschränkungsvorlagen in policies/templates
automatisch mit den in validator
definierten rego zu aktualisieren.
6. Eine Einschränkung einrichten
Einschränkungen enthalten drei Informationen, die gcloud beta terraform vet
ordnungsgemäß erzwingen und Verstöße melden muss:
severity
:low
,medium
oderhigh
match
: Parameter, um zu bestimmen, ob eine Einschränkung für eine bestimmte Ressource gilt. Die folgenden Übereinstimmungsparameter werden unterstützt:addresses
: Eine Liste der Ressourcenadressen, die mithilfe des Glob-Stils einbezogen werden sollenexcludedAddresses
: (Optional) Eine Liste von Ressourcenadressen, die mithilfe des Glob-Stils ausgeschlossen werden sollen.
parameters
: Werte für die Eingabeparameter der Einschränkungsvorlage.
Achten Sie darauf, dass kind
den Namen der Einschränkungsvorlage enthält. Wir empfehlen, metadata.name
auf eine beschreibende Slug festzulegen.
Wenn Sie beispielsweise nur INTERNAL
-Adresstypen mit der vorherigen Beispieleinschränkungsvorlage zulassen möchten, schreiben Sie:
# policies/constraints/tf_compute_address_internal_only.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: TFComputeAddressAddressTypeAllowlistConstraintV1
metadata:
name: tf_compute_address_internal_only
spec:
severity: high
match:
addresses:
- "**"
parameters:
allowed_address_types:
- "INTERNAL"
Beispiele für Übereinstimmungen:
Adress-Matcher | Beschreibung |
---|---|
"module.**" | Alle Ressourcen in einem beliebigen Modul |
"module.my_module.**" | Alles im Modul "my_module" |
"**.google_compute_global_forwarding_rule.*" | Alle google_compute_global_forwarding_rule-Ressourcen in einem beliebigen Modul |
"module.my_module.google_compute_global_forwarding_rule.*" | Alle google_compute_global_forwarding_rule-Ressourcen in "my_module" |
Wenn eine Ressourcenadresse mit den Werten in addresses
und excludedAddresses
übereinstimmt, wird sie ausgeschlossen.
Beschränkungen
Die Daten eines Terraform-Plans liefern nach dem Anwenden die beste verfügbare Darstellung des tatsächlichen Status. In vielen Fällen ist der Zustand nach dem Anwenden jedoch möglicherweise nicht bekannt, da er serverseitig berechnet wird.
Unterstützte Ressourcen
Sie können Einschränkungen für die Ressourcenänderung für alle Ressourcen von den Terraform-Anbietern google und google-beta erstellen.