Sebelum memulai
Framework Batasan
gcloud beta terraform vet
menggunakan
kebijakan Framework Batasan,
yang terdiri dari batasan dan template batasan. Perbedaan
antara keduanya adalah sebagai berikut:
- Template batasan itu seperti deklarasi fungsi; yaitu menetapkan aturan di Rego dan secara opsional mengambil parameter input.
- Batasan adalah file yang mereferensikan template batasan dan menentukan parameter input yang akan diteruskan ke template tersebut serta resource yang dicakup oleh kebijakan.
Ini memungkinkan Anda untuk menghindari pengulangan. Anda dapat menulis template batasan dengan kebijakan umum, lalu menulis sejumlah batasan yang memberikan parameter input berbeda atau aturan pencocokan resource yang berbeda.
Membuat template batasan
Untuk membuat template batasan, ikuti langkah-langkah berikut:
- Kumpulkan data sampel.
- Tulis Rego.
- Uji Rego Anda.
- Siapkan kerangka template batasan.
- Sejajarkan Rego Anda.
- Siapkan batasan.
Mengumpulkan data sampel
Untuk menulis template batasan, Anda harus memiliki contoh data untuk
beroperasi. Batasan berbasis Terraform beroperasi pada data perubahan resource, yang berasal
dari kunci resource_changes
pada
JSON paket Terraform.
Contohnya, JSON Anda mungkin terlihat seperti ini:
// 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
}
Tulis Rego
Setelah memiliki data contoh, Anda dapat menulis logika untuk template batasan
di
Rego.
Rego Anda harus memiliki aturan violations
. Perubahan resource yang sedang ditinjau
tersedia sebagai input.review
. Parameter batasan tersedia sebagai
input.parameters
. Contohnya, untuk mengharuskan resource google_compute_address
memiliki address_type
yang diizinkan, tulis:
# 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}
}
Beri nama template batasan Anda
Contoh sebelumnya menggunakan nama
TFComputeAddressAddressTypeAllowlistConstraintV1
. Ini adalah ID unik
untuk setiap template batasan. Sebaiknya ikuti panduan penamaan berikut:
- Format umum:
TF{resource}{feature}Constraint{version}
. Gunakan CamelCase. (Dengan kata lain, gunakan huruf besar untuk setiap kata baru.) - Untuk batasan resource tunggal, ikuti konvensi
penyedia Terraform
untuk penamaan produk. Contoh, untuk
google_tags_tag
, nama produknya adalahtags
meskipun nama API-nyaresourcemanager
. - Jika template berlaku untuk lebih dari satu jenis resource, hapus bagian resource dan hanya sertakan fiturnya (contoh: "TFAddressTypeAllowlistConstraintV1").
- Nomor versi tidak mengikuti format semver; itu hanya satu angka. Cara ini secara efektif membuat setiap versi template menjadi template yang unik.
Sebaiknya gunakan nama untuk file Rego yang cocok dengan nama template
batasan, tetapi gunakan snake_case. Dengan kata lain, konversi nama menjadi
kata-kata yang menggunakan huruf kecil dan terpisah dengan _
. Untuk contoh sebelumnya, nama file
yang direkomendasikan adalah tf_compute_address_address_type_allowlist_constraint_v1.rego
Uji Rego Anda
Anda dapat menguji Rego secara manual dengan Rego Playground. Pastikan untuk menggunakan data yang tidak sensitif.
Sebaiknya tulis
pengujian otomatis.
Masukkan contoh data yang dikumpulkan di validator/test/fixtures/<constraint
filename>/resource_changes/data.json
dan referensikan data tersebut dalam file pengujian Anda seperti
ini:
# 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
}
Tempatkan Rego dan pengujian Anda dalam folder validator
di library kebijakan Anda.
Menyiapkan kerangka template batasan
Setelah memiliki aturan Rego yang berfungsi dan diuji, Anda harus mengemasnya sebagai template batasan. Framework Batasan menggunakan Definisi Resource Kustom Kubernetes sebagai container untuk kebijakan Rego.
Template batasan juga menentukan parameter yang diizinkan sebagai input dari batasan, menggunakan skema OpenAPI V3.
Gunakan nama yang sama untuk kerangka seperti yang Anda gunakan untuk Rego. Pada khususnya:
- Gunakan nama file yang sama seperti untuk Rego Anda. Contoh:
tf_compute_address_address_type_allowlist_constraint_v1.yaml
spec.crd.spec.names.kind
harus berisi nama templatemetadata.name
harus berisi nama template, tetapi ditulis dengan huruf kecil
Tempatkan kerangka template batasan di policies/templates
.
Untuk contoh di atas:
# 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
Sejajarkan Rego Anda
Pada tahap ini, mengikuti contoh sebelumnya, tata letak direktori Anda akan terlihat seperti ini:
| 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
Jika meng-clone
repositori library kebijakan yang disediakan Google,
Anda dapat menjalankan make build
untuk mengupdate template batasan secara otomatis di
policies/templates
dengan Rego yang ditentukan di validator
.
Menyiapkan batasan
Batasan berisi tiga informasi yang diperlukan gcloud beta terraform vet
untuk menerapkan dan melaporkan pelanggaran dengan benar:
severity
:low
,medium
, atauhigh
match
: Parameter untuk menentukan apakah batasan berlaku untuk resource tertentu. Parameter pencocokan berikut didukung:addresses
: Daftar alamat resource yang akan disertakan menggunakan pencocokan gaya globexcludedAddresses
: (Opsional) Daftar alamat resource yang akan dikecualikan menggunakan pencocokan gaya glob.
parameters
: Nilai untuk parameter input template batasan.
Pastikan kind
berisi nama template batasan. Sebaiknya
setel metadata.name
ke slug deskriptif.
Contohnya, untuk hanya mengizinkan jenis alamat INTERNAL
menggunakan contoh template
batasan sebelumnya, tulis:
# 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"
Contoh yang cocok:
Pencocok alamat | Deskripsi |
---|---|
`module.**` | Semua resource dalam modul apa pun |
`module.my_module.**` | Semuanya dalam modul `my_module` |
`**.google_compute_global_forwarding_rule.*` | Semua resource google_compute_global_forwarding_rule di modul mana pun |
`module.my_module.google_compute_global_forwarding_rule.*` | Semua resource google_compute_global_forwarding_rule di `my_module` |
Jika alamat resource cocok dengan nilai di addresses
dan excludedAddresses
, alamat tersebut
akan dikecualikan.
Batasan
Data paket Terraform memberikan representasi terbaik dari status sebenarnya setelah penerapan. Namun, dalam banyak kasus, status setelah penerapan mungkin tidak diketahui karena dihitung di sisi server.
Membuat jalur ancestry CAI adalah bagian dari proses saat memvalidasi kebijakan. Gunakan
project default yang disediakan untuk menyiasati project ID yang tidak dikenal. Jika
project default tidak disediakan, jalur ancestry akan ditetapkan secara default ke
organizations/unknown
.
Anda dapat melarang ancestry yang tidak diketahui dengan menambahkan batasan berikut:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: GCPAlwaysViolatesConstraintV1
metadata:
name: disallow_unknown_ancestry
annotations:
description: |
Unknown ancestry is not allowed; use --project=<project> to set a
default ancestry
spec:
severity: high
match:
ancestries:
- "organizations/unknown"
parameters: {}
Resource yang didukung
Anda dapat membuat batasan perubahan resource untuk setiap resource Terraform dari penyedia Terraform mana pun.