From 5fc61e825b6145244d34475ffb36c88cab15181f Mon Sep 17 00:00:00 2001 From: ombellare <87096367+ombellare@users.noreply.github.com> Date: Fri, 18 Jul 2025 08:57:49 -0700 Subject: [PATCH 01/10] feat(secure-policies): support new fields in drift policy (#656) * Add support for additional secure drift policy fields * Address review comments * Fixed spacing issue --------- Co-authored-by: Fede Barcelona --- .../data_source_sysdig_secure_drift_policy.go | 21 +++-- ..._source_sysdig_secure_drift_policy_test.go | 89 +++++++++++++++++++ ...ata_source_sysdig_secure_malware_policy.go | 7 +- ...ource_sysdig_secure_malware_policy_test.go | 14 +-- sysdig/internal/client/v2/model.go | 4 + sysdig/resource_sysdig_secure_drift_policy.go | 1 + ...esource_sysdig_secure_drift_policy_test.go | 38 +++++--- .../resource_sysdig_secure_malware_policy.go | 8 +- ...ource_sysdig_secure_malware_policy_test.go | 54 +++++------ sysdig/schema.go | 20 +++++ sysdig/tfresource.go | 56 ++++++++---- website/docs/d/secure_drift_policy.md | 8 +- website/docs/d/secure_malware_policy.md | 11 +-- website/docs/r/secure_drift_policy.md | 4 +- website/docs/r/secure_malware_policy.md | 23 +++-- 15 files changed, 266 insertions(+), 92 deletions(-) diff --git a/sysdig/data_source_sysdig_secure_drift_policy.go b/sysdig/data_source_sysdig_secure_drift_policy.go index 108dd0ebf..8f7600eec 100644 --- a/sysdig/data_source_sysdig_secure_drift_policy.go +++ b/sysdig/data_source_sysdig_secure_drift_policy.go @@ -47,15 +47,18 @@ func createDriftPolicyDataSourceSchema() map[string]*schema.Schema { Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "id": ReadOnlyIntSchema(), - "name": ReadOnlyStringSchema(), - "description": DescriptionComputedSchema(), - "tags": TagsSchema(), - "version": VersionSchema(), - "enabled": BoolComputedSchema(), - "exceptions": ExceptionsComputedSchema(), - "prohibited_binaries": ExceptionsComputedSchema(), - "mounted_volume_drift_enabled": BoolComputedSchema(), + "id": ReadOnlyIntSchema(), + "name": ReadOnlyStringSchema(), + "description": DescriptionComputedSchema(), + "tags": TagsSchema(), + "version": VersionSchema(), + "enabled": BoolComputedSchema(), + "exceptions": ExceptionsComputedSchema(), + "prohibited_binaries": ExceptionsComputedSchema(), + "process_based_exceptions": ExceptionsComputedSchema(), + "process_based_prohibited_binaries": ExceptionsComputedSchema(), + "mounted_volume_drift_enabled": BoolComputedSchema(), + "use_regex": BoolComputedSchema(), }, }, }, diff --git a/sysdig/data_source_sysdig_secure_drift_policy_test.go b/sysdig/data_source_sysdig_secure_drift_policy_test.go index 50064436f..33b1fad9a 100644 --- a/sysdig/data_source_sysdig_secure_drift_policy_test.go +++ b/sysdig/data_source_sysdig_secure_drift_policy_test.go @@ -32,6 +32,12 @@ func TestAccDriftPolicyDataSource(t *testing.T) { { Config: driftPolicyDataSource(rText), }, + { + Config: driftPolicyWithUseRegexDataSource(rText), + }, + { + Config: driftPolicyWithProcessExceptionsDataSource(rText), + }, }, }) } @@ -47,6 +53,8 @@ resource "sysdig_secure_drift_policy" "policy_1" { rule { description = "Test Drift Rule Description" enabled = true + mounted_volume_drift_enabled = true + use_regex = true exceptions { items = ["/usr/bin/sh"] @@ -54,6 +62,87 @@ resource "sysdig_secure_drift_policy" "policy_1" { prohibited_binaries { items = ["/usr/bin/curl"] } + process_based_exceptions { + items = ["/usr/bin/curl"] + } + process_based_prohibited_binaries { + items = ["/usr/bin/sh"] + } + } + + actions { + prevent_drift = true + } + +} + +data "sysdig_secure_drift_policy" "policy_2" { + name = sysdig_secure_drift_policy.policy_1.name + depends_on = [sysdig_secure_drift_policy.policy_1] +} +`, name, name) +} + +func driftPolicyWithUseRegexDataSource(name string) string { + return fmt.Sprintf(` +resource "sysdig_secure_drift_policy" "policy_1" { + name = "Test Drift Policy %s" + description = "Test Drift Policy Description %s" + enabled = true + severity = 4 + + rule { + description = "Test Drift Rule Description" + enabled = true + mounted_volume_drift_enabled = true + use_regex = true + + exceptions { + items = ["/usr/bin/sh"] + } + prohibited_binaries { + items = ["/usr/bin/curl"] + } + process_based_exceptions { + items = ["/usr/bin/curl"] + } + process_based_prohibited_binaries { + items = ["/usr/bin/sh"] + } + } + + actions { + prevent_drift = true + } + +} + +data "sysdig_secure_drift_policy" "policy_2" { + name = sysdig_secure_drift_policy.policy_1.name + depends_on = [sysdig_secure_drift_policy.policy_1] +} +`, name, name) +} + +func driftPolicyWithProcessExceptionsDataSource(name string) string { + return fmt.Sprintf(` +resource "sysdig_secure_drift_policy" "policy_1" { + name = "Test Drift Policy %s" + description = "Test Drift Policy Description %s" + enabled = true + severity = 4 + + rule { + description = "Test Drift Rule Description" + enabled = true + mounted_volume_drift_enabled = true + + process_based_exceptions { + items = ["/usr/bin/curl"] + } + process_based_prohibited_binaries { + items = ["/usr/bin/sh"] + } } actions { diff --git a/sysdig/data_source_sysdig_secure_malware_policy.go b/sysdig/data_source_sysdig_secure_malware_policy.go index 37a0aeba9..790520e71 100644 --- a/sysdig/data_source_sysdig_secure_malware_policy.go +++ b/sysdig/data_source_sysdig_secure_malware_policy.go @@ -57,8 +57,11 @@ func createMalwarePolicyDataSourceSchema() map[string]*schema.Schema { "tags": TagsSchema(), "version": VersionSchema(), "use_managed_hashes": BoolComputedSchema(), - "additional_hashes": HashesComputedSchema(), - "ignore_hashes": HashesComputedSchema(), + "use_yara_rules": BoolComputedSchema(), + "additional_hashes": StringListComputedSchema(), + "ignore_hashes": StringListComputedSchema(), + "use_regex": BoolComputedSchema(), + "ignore_paths": StringListComputedSchema(), }, }, }, diff --git a/sysdig/data_source_sysdig_secure_malware_policy_test.go b/sysdig/data_source_sysdig_secure_malware_policy_test.go index aeca1de82..f571be2a8 100644 --- a/sysdig/data_source_sysdig_secure_malware_policy_test.go +++ b/sysdig/data_source_sysdig_secure_malware_policy_test.go @@ -49,13 +49,15 @@ resource "sysdig_secure_malware_policy" "policy_1" { use_managed_hashes = true - additional_hashes { - hash = "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6" - } + additional_hashes = [ + "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6", + "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae7" + ] - ignore_hashes { - hash = "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0e" - } + ignore_hashes = [ + "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0e", + "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0f" + ] } actions { diff --git a/sysdig/internal/client/v2/model.go b/sysdig/internal/client/v2/model.go index bf6ee3d81..db241d495 100644 --- a/sysdig/internal/client/v2/model.go +++ b/sysdig/internal/client/v2/model.go @@ -397,8 +397,11 @@ func (p MLRuleDetails) GetRuleType() ElementType { type MalwareRuleDetails struct { RuleType ElementType `json:"ruleType"` UseManagedHashes bool `json:"useManagedHashes"` + UseYaraRules bool `json:"usePolymorphicRules"` AdditionalHashes map[string][]string `json:"additionalHashes"` IgnoreHashes map[string][]string `json:"ignoreHashes"` + UseRegex bool `json:"useRegex"` + IgnorePaths map[string][]string `json:"ignorePaths"` Details `json:"-"` } @@ -419,6 +422,7 @@ type DriftRuleDetails struct { ProhibitedBinaries *RuntimePolicyRuleList `json:"prohibitedBinaries"` Mode string `json:"mode"` MountedVolumeDriftEnabled bool `json:"mountedVolumeDriftEnabled"` + UseRegex bool `json:"useRegex"` Details `json:"-"` } diff --git a/sysdig/resource_sysdig_secure_drift_policy.go b/sysdig/resource_sysdig_secure_drift_policy.go index d46202cbe..beafac2ab 100644 --- a/sysdig/resource_sysdig_secure_drift_policy.go +++ b/sysdig/resource_sysdig_secure_drift_policy.go @@ -67,6 +67,7 @@ func resourceSysdigSecureDriftPolicy() *schema.Resource { "process_based_exceptions": ExceptionsSchema(), "process_based_prohibited_binaries": ExceptionsSchema(), "mounted_volume_drift_enabled": BoolSchema(), + "use_regex": BoolSchema(), }, }, }, diff --git a/sysdig/resource_sysdig_secure_drift_policy_test.go b/sysdig/resource_sysdig_secure_drift_policy_test.go index 8916f1f3d..0134f8e9e 100644 --- a/sysdig/resource_sysdig_secure_drift_policy_test.go +++ b/sysdig/resource_sysdig_secure_drift_policy_test.go @@ -42,6 +42,9 @@ func TestAccDriftPolicy(t *testing.T) { { Config: driftPolicyWithMountedVolumeDriftEnabled(rText()), }, + { + Config: driftPolicyWithProcessBasedAndRegexEnabled(rText()), + }, }, }) } @@ -67,9 +70,6 @@ resource "sysdig_secure_drift_policy" "sample" { prohibited_binaries { items = ["/usr/bin/curl"] } - process_based_exceptions { - items = ["/usr/bin/curl"] - } } actions { @@ -96,6 +96,7 @@ resource "sysdig_secure_drift_policy" "sample" { description = "Test Drift Rule Description" enabled = true + use_regex = true exceptions { items = ["/usr/bin/sh"] @@ -103,9 +104,12 @@ resource "sysdig_secure_drift_policy" "sample" { prohibited_binaries { items = ["/usr/bin/curl"] } - process_based_exceptions { + process_based_exceptions { items = ["/usr/bin/curl"] - } + } + process_based_prohibited_binaries { + items = ["/usr/bin/sh"] + } } actions { @@ -138,6 +142,7 @@ resource "sysdig_secure_drift_policy" "sample" { description = "Test Drift Rule Description" enabled = true + use_regex = true exceptions { items = ["/usr/bin/sh"] @@ -145,9 +150,9 @@ resource "sysdig_secure_drift_policy" "sample" { prohibited_binaries { items = ["/usr/bin/curl"] } - process_based_exceptions { + process_based_exceptions { items = ["/usr/bin/curl"] - } + } } actions {} @@ -177,9 +182,12 @@ resource "sysdig_secure_drift_policy" "sample" { prohibited_binaries { items = ["/usr/bin/curl"] } - process_based_exceptions { + process_based_exceptions { items = ["/usr/bin/curl"] - } + } + process_based_prohibited_binaries { + items = ["/usr/bin/sh"] + } } actions { @@ -227,19 +235,25 @@ resource "sysdig_secure_drift_policy" "sample" { rule { description = "Test Drift Rule Description" - mounted_volume_drift_enabled = true + enabled = true + mounted_volume_drift_enabled = true + enabled = true + exceptions { items = ["/usr/bin/sh"] } prohibited_binaries { items = ["/usr/bin/curl"] } - process_based_exceptions { + process_based_exceptions { items = ["/usr/bin/curl"] } - } + process_based_prohibited_binaries { + items = ["/usr/bin/sh"] + } + } } `, name) } diff --git a/sysdig/resource_sysdig_secure_malware_policy.go b/sysdig/resource_sysdig_secure_malware_policy.go index 364ec673a..ce050e9c0 100644 --- a/sysdig/resource_sysdig_secure_malware_policy.go +++ b/sysdig/resource_sysdig_secure_malware_policy.go @@ -54,6 +54,7 @@ func resourceSysdigSecureMalwarePolicy() *schema.Resource { "rule": { Type: schema.TypeList, Required: true, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "id": ReadOnlyIntSchema(), @@ -64,8 +65,11 @@ func resourceSysdigSecureMalwarePolicy() *schema.Resource { "tags": TagsSchema(), "version": VersionSchema(), "use_managed_hashes": BoolSchema(), - "additional_hashes": HashesSchema(), - "ignore_hashes": HashesSchema(), + "use_yara_rules": BoolSchema(), + "additional_hashes": StringListSchema(), + "ignore_hashes": StringListSchema(), + "use_regex": BoolSchema(), + "ignore_paths": StringListSchema(), }, }, }, diff --git a/sysdig/resource_sysdig_secure_malware_policy_test.go b/sysdig/resource_sysdig_secure_malware_policy_test.go index 1e64efd36..b5a5f4c4b 100644 --- a/sysdig/resource_sysdig_secure_malware_policy_test.go +++ b/sysdig/resource_sysdig_secure_malware_policy_test.go @@ -61,13 +61,14 @@ resource "sysdig_secure_malware_policy" "sample" { use_managed_hashes = true - additional_hashes { - hash = "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6" - } - - ignore_hashes { - hash = "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0e" - } + additional_hashes = [ + "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6", + "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae7" + ] + + ignore_hashes = [ + "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0e" + ] } actions { @@ -96,9 +97,10 @@ resource "sysdig_secure_malware_policy" "sample" { use_managed_hashes = true - ignore_hashes { - hash = "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0e" - } + ignore_hashes = [ + "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0e", + "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0f" + ] } actions { @@ -127,9 +129,9 @@ resource "sysdig_secure_malware_policy" "sample" { use_managed_hashes = true - additional_hashes { - hash = "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6" - } + additional_hashes = [ + "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6" + ] } actions { @@ -183,13 +185,15 @@ resource "sysdig_secure_malware_policy" "sample" { use_managed_hashes = true - additional_hashes { - hash = "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6" - } + additional_hashes = [ + "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6", + "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae7" + ] - ignore_hashes { - hash = "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0e" - } + ignore_hashes = [ + "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0e", + "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0f" + ] } actions { @@ -222,13 +226,13 @@ resource "sysdig_secure_malware_policy" "sample" { use_managed_hashes = true - additional_hashes { - hash = "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6" - } + additional_hashes = [ + "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6" + ] - ignore_hashes { - hash = "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0e" - } + ignore_hashes = [ + "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0e" + ] } actions { diff --git a/sysdig/schema.go b/sysdig/schema.go index de31a66dc..c083ae56c 100644 --- a/sysdig/schema.go +++ b/sysdig/schema.go @@ -326,6 +326,26 @@ func HashesComputedSchema() *schema.Schema { } } +func StringListSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + } +} + +func StringListComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + } +} + func TagsSchema() *schema.Schema { // Tags are always set automatically by Sysdig return &schema.Schema{ diff --git a/sysdig/tfresource.go b/sysdig/tfresource.go index c9e975f20..4a6e5a5c1 100644 --- a/sysdig/tfresource.go +++ b/sysdig/tfresource.go @@ -2,6 +2,7 @@ package sysdig import ( "errors" + "slices" "strconv" "strings" @@ -109,19 +110,25 @@ func setTFResourcePolicyRulesMalware(d *schema.ResourceData, policy v2.PolicyRul rules := []map[string]any{} for _, rule := range policy.Rules { - additionalHashes := []map[string]any{} - for k := range rule.Details.(*v2.MalwareRuleDetails).AdditionalHashes { - additionalHashes = append(additionalHashes, map[string]any{ - "hash": k, - }) + malwareRuleDetails := rule.Details.(*v2.MalwareRuleDetails) + + additionalHashes := []string{} + for k := range malwareRuleDetails.AdditionalHashes { + additionalHashes = append(additionalHashes, k) + } + slices.Sort(additionalHashes) + + ignoreHashes := []string{} + for k := range malwareRuleDetails.IgnoreHashes { + ignoreHashes = append(ignoreHashes, k) } + slices.Sort(ignoreHashes) - ignoreHashes := []map[string]any{} - for k := range rule.Details.(*v2.MalwareRuleDetails).IgnoreHashes { - ignoreHashes = append(ignoreHashes, map[string]any{ - "hash": k, - }) + ignorePaths := []string{} + for k := range malwareRuleDetails.IgnorePaths { + ignorePaths = append(ignorePaths, k) } + slices.Sort(ignorePaths) rules = append(rules, map[string]any{ "id": rule.ID, @@ -129,9 +136,12 @@ func setTFResourcePolicyRulesMalware(d *schema.ResourceData, policy v2.PolicyRul "description": rule.Description, "version": rule.Version, "tags": rule.Tags, - "use_managed_hashes": rule.Details.(*v2.MalwareRuleDetails).UseManagedHashes, + "use_managed_hashes": malwareRuleDetails.UseManagedHashes, + "use_yara_rules": malwareRuleDetails.UseYaraRules, "additional_hashes": additionalHashes, "ignore_hashes": ignoreHashes, + "use_regex": malwareRuleDetails.UseRegex, + "ignore_paths": ignorePaths, }) } @@ -216,6 +226,7 @@ func setTFResourcePolicyRulesDrift(d *schema.ResourceData, policy v2.PolicyRules "tags": rule.Tags, "enabled": enabled, "mounted_volume_drift_enabled": driftDetails.MountedVolumeDriftEnabled, + "use_regex": driftDetails.UseRegex, } if exceptionsBlock != nil { @@ -419,9 +430,8 @@ func setPolicyRulesMalware(policy *v2.PolicyRulesComposite, d *schema.ResourceDa additionalHashes := map[string][]string{} if items, ok := d.GetOk("rule.0.additional_hashes"); ok { // TODO: Do not hardcode the indexes for _, item := range items.([]any) { - item := item.(map[string]any) - k := item["hash"].(string) - additionalHashes[k] = []string{} + hash := item.(string) + additionalHashes[hash] = []string{} } } @@ -429,9 +439,8 @@ func setPolicyRulesMalware(policy *v2.PolicyRulesComposite, d *schema.ResourceDa ignoreHashes := map[string][]string{} if items, ok := d.GetOk("rule.0.ignore_hashes"); ok { // TODO: Do not hardcode the indexes for _, item := range items.([]any) { - item := item.(map[string]any) - k := item["hash"].(string) - ignoreHashes[k] = []string{} + hash := item.(string) + ignoreHashes[hash] = []string{} } } @@ -441,6 +450,14 @@ func setPolicyRulesMalware(policy *v2.PolicyRulesComposite, d *schema.ResourceDa tags = []string{defaultMalwareTag} } + ignorePaths := map[string][]string{} + if items, ok := d.GetOk("rule.0.ignore_paths"); ok { // TODO: Do not hardcode the indexes + for _, item := range items.([]any) { + path := item.(string) + ignorePaths[path] = []string{} + } + } + rule := &v2.RuntimePolicyRule{ // TODO: Do not hardcode the indexes Name: d.Get("rule.0.name").(string), @@ -449,8 +466,11 @@ func setPolicyRulesMalware(policy *v2.PolicyRulesComposite, d *schema.ResourceDa Details: v2.MalwareRuleDetails{ RuleType: v2.ElementType("MALWARE"), // TODO: Use const UseManagedHashes: d.Get("rule.0.use_managed_hashes").(bool), + UseYaraRules: d.Get("rule.0.use_yara_rules").(bool), AdditionalHashes: additionalHashes, IgnoreHashes: ignoreHashes, + UseRegex: d.Get("rule.0.use_regex").(bool), + IgnorePaths: ignorePaths, }, } @@ -498,6 +518,7 @@ func setPolicyRulesDrift(policy *v2.PolicyRulesComposite, d *schema.ResourceData } mountedVolumeDriftEnabled := d.Get("rule.0.mounted_volume_drift_enabled").(bool) + useRegex := d.Get("rule.0.use_regex").(bool) rule := &v2.RuntimePolicyRule{ // TODO: Do not hardcode the indexes @@ -512,6 +533,7 @@ func setPolicyRulesDrift(policy *v2.PolicyRulesComposite, d *schema.ResourceData ProcessBasedExceptions: &processBasedExceptions, ProcessBasedDenylist: &processBasedProhibitedBinaries, MountedVolumeDriftEnabled: mountedVolumeDriftEnabled, + UseRegex: useRegex, }, } diff --git a/website/docs/d/secure_drift_policy.md b/website/docs/d/secure_drift_policy.md index 76e1b42cb..cebd5677b 100644 --- a/website/docs/d/secure_drift_policy.md +++ b/website/docs/d/secure_drift_policy.md @@ -78,5 +78,9 @@ The rule block is required and supports: * `items` - (Required) Specify comma separated list of exceptions, e.g. `/usr/bin/rm, /usr/bin/curl`. * `prohibited_binaries` - (Optional) A prohibited binary can be a known harmful binary or one that facilitates discovery of your environment. * `items` - (Required) Specify comma separated list of prohibited binaries, e.g. `/usr/bin/rm, /usr/bin/curl`. - - +* `process_based_exceptions` - (Optional) List of processes that will be able to execute a drifted file + * `items` - (Required) Specify comma separated list of processes, e.g. `/usr/bin/rm, /usr/bin/curl`. +* `process_based_prohibited_binaries` - (Optional) List of processes that will be prohibited to execute a drifted file + * `items` - (Required) Specify comma separated list of processes, e.g. `/usr/bin/rm, /usr/bin/curl`. +* `mounted_volume_drift_enabled` - (Optional) Treat all binaries from mounted volumes as drifted. Default value is false/disabled. +* `use_regex` - (Optional) Pass exceptions and prohibited binaries as regex strings. Requires agent version 13.2.0 and above diff --git a/website/docs/d/secure_malware_policy.md b/website/docs/d/secure_malware_policy.md index 591d1e9c9..b3b8ff9ec 100644 --- a/website/docs/d/secure_malware_policy.md +++ b/website/docs/d/secure_malware_policy.md @@ -71,9 +71,10 @@ The actions block is optional and supports: The rule block is required and supports: * `description` - (Required) The description of the malware rule. -* `use_managed_hashes` - (Required) Should Sysdig's managed hashes be used? The possible values are `true` or `false`. -* `additional_hashes` - (Optional) The block contains a single hash that should be matched. - * `hash` - (Required) The hash value that should be matched. -* `ignore_hashes` - (Optional) The block contains a single hash that should be matched. - * `hash` - (Required) The hash value that should be matched. +* `use_managed_hashes` - (Optional) Should Sysdig's managed hashes be used? The possible values are `true` or `false`. +* `use_yara_rules` - (Optional) Should use Sysdig's managed YARA rules to detect malware and malicious scripts? The possible values are `true` or `false`. +* `additional_hashes` - (Optional) List of additional hashes that should be matched. +* `ignore_hashes` - (Optional) List of hashes that should be ignored. +* `use_regex` - (Optional) Should use regex for ignore_paths matching? The possible values are `true` or `false`. +* `ignore_paths` - (Optional) The list of file paths to be excluded from malware matching diff --git a/website/docs/r/secure_drift_policy.md b/website/docs/r/secure_drift_policy.md index 45419233d..4e2700510 100644 --- a/website/docs/r/secure_drift_policy.md +++ b/website/docs/r/secure_drift_policy.md @@ -123,6 +123,4 @@ The rule block is required and supports: * `process_based_prohibited_binaries` - (Optional) List of processes that will be prohibited to execute a drifted file * `items` - (Required) Specify comma separated list of processes, e.g. `/usr/bin/rm, /usr/bin/curl`. * `mounted_volume_drift_enabled` - (Optional) Treat all binaries from mounted volumes as drifted. Default value is false/disabled. - - - +* `use_regex` - (Optional) Pass exceptions and prohibited binaries as regex strings. Requires agent version 13.2.0 and above diff --git a/website/docs/r/secure_malware_policy.md b/website/docs/r/secure_malware_policy.md index baf2159ff..7c6ef0df7 100644 --- a/website/docs/r/secure_malware_policy.md +++ b/website/docs/r/secure_malware_policy.md @@ -34,13 +34,17 @@ resource "sysdig_secure_malware_policy" "prevent_malware" { description = "Test Malware Rule Description" use_managed_hashes = true - additional_hashes { - hash = "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6" + additional_hashes = [ + "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6", + "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae7" } - ignore_hashes { - hash = "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0e" - } + ignore_hashes = [ + "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0e", + "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0f" + ] + + ignore_paths = ["/usr/lib/abc", "/usr/bin/bcd"] } actions { @@ -109,7 +113,8 @@ The rule block is required and supports: * `description` - (Required) The description of the malware rule. * `use_managed_hashes` - (Required) Should Sysdig's managed hashes be used? The possible values are `true` or `false`. -* `additional_hashes` - (Optional) The block contains a single hash that should be matched. - * `hash` - (Required) The hash value that should be matched. -* `ignore_hashes` - (Optional) The block contains a single hash that should be matched. - * `hash` - (Required) The hash value that should be matched. +* `use_yara_rules` - (Optional) Should use Sysdig's managed YARA rules to detect malware and malicious scripts? The possible values are `true` or `false`. +* `additional_hashes` - (Optional) List of additional hashes that should be matched. +* `ignore_hashes` - (Optional) List of hashes that should be ignored. +* `use_regex` - (Optional) Should use regex for ignore_paths matching? The possible values are `true` or `false`. +* `ignore_paths` - (Optional) The list of file paths to be excluded from malware matching From b82e81699c27c0c51d5ee1050ff47f4e863093fb Mon Sep 17 00:00:00 2001 From: ombellare Date: Fri, 18 Jul 2025 09:14:14 -0700 Subject: [PATCH 02/10] Revert changes to drift test files --- ..._source_sysdig_secure_drift_policy_test.go | 83 ------------------- ...esource_sysdig_secure_drift_policy_test.go | 2 - 2 files changed, 85 deletions(-) diff --git a/sysdig/data_source_sysdig_secure_drift_policy_test.go b/sysdig/data_source_sysdig_secure_drift_policy_test.go index 4a2909a99..c24752918 100644 --- a/sysdig/data_source_sysdig_secure_drift_policy_test.go +++ b/sysdig/data_source_sysdig_secure_drift_policy_test.go @@ -53,8 +53,6 @@ resource "sysdig_secure_drift_policy" "policy_1" { rule { description = "Test Drift Rule Description" enabled = true - mounted_volume_drift_enabled = true - use_regex = true exceptions { items = ["/usr/bin/sh"] @@ -62,87 +60,6 @@ resource "sysdig_secure_drift_policy" "policy_1" { prohibited_binaries { items = ["/usr/bin/curl"] } - process_based_exceptions { - items = ["/usr/bin/curl"] - } - process_based_prohibited_binaries { - items = ["/usr/bin/sh"] - } - } - - actions { - prevent_drift = true - } - -} - -data "sysdig_secure_drift_policy" "policy_2" { - name = sysdig_secure_drift_policy.policy_1.name - depends_on = [sysdig_secure_drift_policy.policy_1] -} -`, name, name) -} - -func driftPolicyWithUseRegexDataSource(name string) string { - return fmt.Sprintf(` -resource "sysdig_secure_drift_policy" "policy_1" { - name = "Test Drift Policy %s" - description = "Test Drift Policy Description %s" - enabled = true - severity = 4 - - rule { - description = "Test Drift Rule Description" - enabled = true - mounted_volume_drift_enabled = true - use_regex = true - - exceptions { - items = ["/usr/bin/sh"] - } - prohibited_binaries { - items = ["/usr/bin/curl"] - } - process_based_exceptions { - items = ["/usr/bin/curl"] - } - process_based_prohibited_binaries { - items = ["/usr/bin/sh"] - } - } - - actions { - prevent_drift = true - } - -} - -data "sysdig_secure_drift_policy" "policy_2" { - name = sysdig_secure_drift_policy.policy_1.name - depends_on = [sysdig_secure_drift_policy.policy_1] -} -`, name, name) -} - -func driftPolicyWithProcessExceptionsDataSource(name string) string { - return fmt.Sprintf(` -resource "sysdig_secure_drift_policy" "policy_1" { - name = "Test Drift Policy %s" - description = "Test Drift Policy Description %s" - enabled = true - severity = 4 - - rule { - description = "Test Drift Rule Description" - enabled = true - mounted_volume_drift_enabled = true - - process_based_exceptions { - items = ["/usr/bin/curl"] - } - process_based_prohibited_binaries { - items = ["/usr/bin/sh"] - } } actions { diff --git a/sysdig/resource_sysdig_secure_drift_policy_test.go b/sysdig/resource_sysdig_secure_drift_policy_test.go index b96fbfcff..5c3346a7f 100644 --- a/sysdig/resource_sysdig_secure_drift_policy_test.go +++ b/sysdig/resource_sysdig_secure_drift_policy_test.go @@ -99,7 +99,6 @@ resource "sysdig_secure_drift_policy" "sample" { description = "Test Drift Rule Description" enabled = true - use_regex = true exceptions { items = ["/usr/bin/sh"] @@ -142,7 +141,6 @@ resource "sysdig_secure_drift_policy" "sample" { description = "Test Drift Rule Description" enabled = true - use_regex = true exceptions { items = ["/usr/bin/sh"] From b234ece30d6506422aaa0c9e61b798e0d5e9ca77 Mon Sep 17 00:00:00 2001 From: ombellare Date: Fri, 18 Jul 2025 12:21:03 -0700 Subject: [PATCH 03/10] Revert test changes and add test for new fields support --- ...ource_sysdig_secure_malware_policy_test.go | 40 ++++++++++++-- ...ource_sysdig_secure_malware_policy_test.go | 53 ++++++++++++++++--- 2 files changed, 81 insertions(+), 12 deletions(-) diff --git a/sysdig/data_source_sysdig_secure_malware_policy_test.go b/sysdig/data_source_sysdig_secure_malware_policy_test.go index f571be2a8..3aa5be462 100644 --- a/sysdig/data_source_sysdig_secure_malware_policy_test.go +++ b/sysdig/data_source_sysdig_secure_malware_policy_test.go @@ -32,6 +32,9 @@ func TestAccMalwarePolicyDataSource(t *testing.T) { { Config: malwarePolicyDataSource(rText), }, + { + Config: malwarePolicyWithAdditionalFields(rText), + }, }, }) } @@ -49,6 +52,38 @@ resource "sysdig_secure_malware_policy" "policy_1" { use_managed_hashes = true + additional_hashes = [ + "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6" + ] + } + + actions { + prevent_malware = true + } + +} + +data "sysdig_secure_malware_policy" "policy_2" { + name = sysdig_secure_malware_policy.policy_1.name +} +`, name, name) +} + +func malwarePolicyWithAdditionalFields(name string) string { + return fmt.Sprintf(` +resource "sysdig_secure_malware_policy" "policy_1" { + name = "Test Malware Policy %s" + description = "Test Malware Policy Description %s" + enabled = true + severity = 4 + + rule { + description = "Test Malware Rule Description" + + use_managed_hashes = true + use_yara_rules = true + use_regex = true + additional_hashes = [ "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6", "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae7" @@ -58,12 +93,9 @@ resource "sysdig_secure_malware_policy" "policy_1" { "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0e", "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0f" ] - } - actions { - prevent_malware = true + ignore_paths = ["/usr/bin/curl", "/usr/bin/sh"] } - } data "sysdig_secure_malware_policy" "policy_2" { diff --git a/sysdig/resource_sysdig_secure_malware_policy_test.go b/sysdig/resource_sysdig_secure_malware_policy_test.go index b5a5f4c4b..c3e518643 100644 --- a/sysdig/resource_sysdig_secure_malware_policy_test.go +++ b/sysdig/resource_sysdig_secure_malware_policy_test.go @@ -42,6 +42,9 @@ func TestAccMalwarePolicy(t *testing.T) { { Config: malwarePolicyWithoutNotificationChannel(rText()), }, + { + Config: malwarePolicyWithAdditionalFields(rText()), + }, }, }) } @@ -62,8 +65,7 @@ resource "sysdig_secure_malware_policy" "sample" { use_managed_hashes = true additional_hashes = [ - "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6", - "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae7" + "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6" ] ignore_hashes = [ @@ -98,8 +100,7 @@ resource "sysdig_secure_malware_policy" "sample" { use_managed_hashes = true ignore_hashes = [ - "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0e", - "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0f" + "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0e" ] } @@ -186,13 +187,11 @@ resource "sysdig_secure_malware_policy" "sample" { use_managed_hashes = true additional_hashes = [ - "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6", - "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae7" + "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6" ] ignore_hashes = [ - "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0e", - "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0f" + "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0e" ] } @@ -244,3 +243,41 @@ resource "sysdig_secure_malware_policy" "sample" { `, name) } + +func malwarePolicyWithAdditionalFields(name string) string { + return fmt.Sprintf(` +resource "sysdig_secure_malware_policy" "sample" { + name = "Test Malware Policy %s" + description = "Test Malware Policy Description" + enabled = true + severity = 4 + + rule { + description = "Test Malware Rule Description" + + use_managed_hashes = true + use_yara_rules = true + use_regex = true + + additional_hashes = [ + "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6", + "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae7" + ] + + ignore_hashes = [ + "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0e", + "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0f" + ] + + ignore_paths = ["/usr/bin/curl", "/usr/bin/sh"] + } + + actions { + prevent_malware = true + container = "stop" + } + +} + +`, name) +} From 0b941613be6798521309101b507c33fc8b57729c Mon Sep 17 00:00:00 2001 From: ombellare Date: Fri, 18 Jul 2025 12:22:52 -0700 Subject: [PATCH 04/10] Revert test change --- sysdig/data_source_sysdig_secure_malware_policy_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sysdig/data_source_sysdig_secure_malware_policy_test.go b/sysdig/data_source_sysdig_secure_malware_policy_test.go index 3aa5be462..c5752cf12 100644 --- a/sysdig/data_source_sysdig_secure_malware_policy_test.go +++ b/sysdig/data_source_sysdig_secure_malware_policy_test.go @@ -55,6 +55,10 @@ resource "sysdig_secure_malware_policy" "policy_1" { additional_hashes = [ "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6" ] + + ignore_hashes = [ + "6ac3c336e4094835293a3fed8a4b5fedde1b5e2626d9838fed50693bba00af0e" + ] } actions { From 03774a3e422b9982095d25d3fc1a735b41b4e45e Mon Sep 17 00:00:00 2001 From: ombellare Date: Fri, 18 Jul 2025 12:27:39 -0700 Subject: [PATCH 05/10] Fix compile issue --- sysdig/data_source_sysdig_secure_malware_policy_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sysdig/data_source_sysdig_secure_malware_policy_test.go b/sysdig/data_source_sysdig_secure_malware_policy_test.go index c5752cf12..aab2e7f73 100644 --- a/sysdig/data_source_sysdig_secure_malware_policy_test.go +++ b/sysdig/data_source_sysdig_secure_malware_policy_test.go @@ -73,7 +73,7 @@ data "sysdig_secure_malware_policy" "policy_2" { `, name, name) } -func malwarePolicyWithAdditionalFields(name string) string { +func malwarePolicyWithAdditionalFieldsDataSource(name string) string { return fmt.Sprintf(` resource "sysdig_secure_malware_policy" "policy_1" { name = "Test Malware Policy %s" From b8da8ef21579577b2b2ac87aa9b39625975bac0d Mon Sep 17 00:00:00 2001 From: ombellare Date: Fri, 18 Jul 2025 15:01:35 -0700 Subject: [PATCH 06/10] Fix test issue --- sysdig/data_source_sysdig_secure_malware_policy_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sysdig/data_source_sysdig_secure_malware_policy_test.go b/sysdig/data_source_sysdig_secure_malware_policy_test.go index aab2e7f73..850a4f3c4 100644 --- a/sysdig/data_source_sysdig_secure_malware_policy_test.go +++ b/sysdig/data_source_sysdig_secure_malware_policy_test.go @@ -33,7 +33,7 @@ func TestAccMalwarePolicyDataSource(t *testing.T) { Config: malwarePolicyDataSource(rText), }, { - Config: malwarePolicyWithAdditionalFields(rText), + Config: malwarePolicyWithAdditionalFieldsDataSource(rText), }, }, }) From 7e18c66e44e78bd65109c2f37357fe5c2c0b5079 Mon Sep 17 00:00:00 2001 From: ombellare Date: Fri, 18 Jul 2025 17:13:48 -0700 Subject: [PATCH 07/10] Update resource and data names in malware policy test Renamed resource from 'policy_1' to 'policy_3' and data source from 'policy_2' to 'policy_4' in malware policy test to improve clarity and avoid naming conflicts. --- sysdig/data_source_sysdig_secure_malware_policy_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sysdig/data_source_sysdig_secure_malware_policy_test.go b/sysdig/data_source_sysdig_secure_malware_policy_test.go index 850a4f3c4..47ff38c0a 100644 --- a/sysdig/data_source_sysdig_secure_malware_policy_test.go +++ b/sysdig/data_source_sysdig_secure_malware_policy_test.go @@ -75,8 +75,8 @@ data "sysdig_secure_malware_policy" "policy_2" { func malwarePolicyWithAdditionalFieldsDataSource(name string) string { return fmt.Sprintf(` -resource "sysdig_secure_malware_policy" "policy_1" { - name = "Test Malware Policy %s" +resource "sysdig_secure_malware_policy" "policy_3" { + name = "Test Malware Policy 2 %s" description = "Test Malware Policy Description %s" enabled = true severity = 4 @@ -102,8 +102,8 @@ resource "sysdig_secure_malware_policy" "policy_1" { } } -data "sysdig_secure_malware_policy" "policy_2" { - name = sysdig_secure_malware_policy.policy_1.name +data "sysdig_secure_malware_policy" "policy_4" { + name = sysdig_secure_malware_policy.policy_3.name } `, name, name) } From b7819d48d14309ecdcb5c0fd5a54d1054ff984ee Mon Sep 17 00:00:00 2001 From: ombellare Date: Mon, 21 Jul 2025 11:02:33 -0700 Subject: [PATCH 08/10] Migration document --- website/docs/r/secure_malware_policy.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/website/docs/r/secure_malware_policy.md b/website/docs/r/secure_malware_policy.md index 7c6ef0df7..11c1ab2ae 100644 --- a/website/docs/r/secure_malware_policy.md +++ b/website/docs/r/secure_malware_policy.md @@ -12,6 +12,19 @@ Retrieves the information of an existing Sysdig Secure Malware Policy. -> **Note:** Sysdig Terraform Provider is under rapid development at this point. If you experience any issue or discrepancy while using it, please make sure you have the latest version. If the issue persists, or you have a Feature Request to support an additional set of resources, please open a [new issue](https://github.com/sysdiglabs/terraform-provider-sysdig/issues/new) in the GitHub repository. +-> **Note:** Due to a bug in the schema for `additional_hashes` and `ignore_hashes`, you might have faced issues with multiple hash values for these fields with the older version of the provider. After updating to the latest provider version, please update the `additional_hashes` and `ignore_hashes` fields in the malware policy definition in your terraform files to use a list of hashes like shown below, which should now allow multiple hashes: +``` +additional_hashes = { + hash = "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6" +} + +to + +additional_hashes = [ + "304ef4cdda3463b24bf53f9cdd69ad3ecdab0842e7e70e2f3cfbb9f14e1c4ae6" +] +``` + ## Example Usage ```terraform From f12a9b80c749c5ca3dafb3b61787ccef5baeb61d Mon Sep 17 00:00:00 2001 From: ombellare Date: Mon, 21 Jul 2025 11:43:02 -0700 Subject: [PATCH 09/10] Fix document issue --- website/docs/r/secure_malware_policy.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/website/docs/r/secure_malware_policy.md b/website/docs/r/secure_malware_policy.md index 11c1ab2ae..dbbd73e81 100644 --- a/website/docs/r/secure_malware_policy.md +++ b/website/docs/r/secure_malware_policy.md @@ -12,6 +12,8 @@ Retrieves the information of an existing Sysdig Secure Malware Policy. -> **Note:** Sysdig Terraform Provider is under rapid development at this point. If you experience any issue or discrepancy while using it, please make sure you have the latest version. If the issue persists, or you have a Feature Request to support an additional set of resources, please open a [new issue](https://github.com/sysdiglabs/terraform-provider-sysdig/issues/new) in the GitHub repository. +## Example Usage + -> **Note:** Due to a bug in the schema for `additional_hashes` and `ignore_hashes`, you might have faced issues with multiple hash values for these fields with the older version of the provider. After updating to the latest provider version, please update the `additional_hashes` and `ignore_hashes` fields in the malware policy definition in your terraform files to use a list of hashes like shown below, which should now allow multiple hashes: ``` additional_hashes = { @@ -25,8 +27,7 @@ additional_hashes = [ ] ``` -## Example Usage - +To create a new malware policy: ```terraform data "sysdig_secure_notification_channel" "email_notification_channel" { name = "Test Email Channel" From d4e415670b6e734b4d5f00cdf41d85afe13c6723 Mon Sep 17 00:00:00 2001 From: ombellare Date: Mon, 21 Jul 2025 12:04:11 -0700 Subject: [PATCH 10/10] Fix docs to add new section --- website/docs/r/secure_malware_policy.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/website/docs/r/secure_malware_policy.md b/website/docs/r/secure_malware_policy.md index dbbd73e81..ac7df86d4 100644 --- a/website/docs/r/secure_malware_policy.md +++ b/website/docs/r/secure_malware_policy.md @@ -12,7 +12,7 @@ Retrieves the information of an existing Sysdig Secure Malware Policy. -> **Note:** Sysdig Terraform Provider is under rapid development at this point. If you experience any issue or discrepancy while using it, please make sure you have the latest version. If the issue persists, or you have a Feature Request to support an additional set of resources, please open a [new issue](https://github.com/sysdiglabs/terraform-provider-sysdig/issues/new) in the GitHub repository. -## Example Usage +## Migration/Troubleshooting -> **Note:** Due to a bug in the schema for `additional_hashes` and `ignore_hashes`, you might have faced issues with multiple hash values for these fields with the older version of the provider. After updating to the latest provider version, please update the `additional_hashes` and `ignore_hashes` fields in the malware policy definition in your terraform files to use a list of hashes like shown below, which should now allow multiple hashes: ``` @@ -27,7 +27,8 @@ additional_hashes = [ ] ``` -To create a new malware policy: +## Example Usage + ```terraform data "sysdig_secure_notification_channel" "email_notification_channel" { name = "Test Email Channel"