From e375c890d3c1eedbc078d88ab4c16cff8c76d72a Mon Sep 17 00:00:00 2001 From: gaima8 <7595658+gaima8@users.noreply.github.com> Date: Sun, 7 Dec 2025 12:37:16 +0000 Subject: [PATCH 1/7] feat: added security_and_analysis block support --- README.md | 31 +++++++++++++++++++++++++++++++ main.tf | 16 ++++++++++++++++ variables.tf | 21 +++++++++++++++++++++ 3 files changed, 68 insertions(+) diff --git a/README.md b/README.md index 0f2af72..d1978c6 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ A [Terraform] module for creating a public or private repository on [Github]. - [Resources](#resources) - [Inputs](#inputs) - [Outputs](#outputs) + - [Security And Analysis Configuration](#security-and-analysis-configuration) - [External Documentation](#external-documentation) - [Terraform Github Provider Documentation](#terraform-github-provider-documentation) - [Module Versioning](#module-versioning) @@ -178,6 +179,7 @@ See [variables.tf] and [examples/] for details and use-cases. | [push\_team\_ids](#input\_push\_team\_ids) | (Optional) A list of teams (by id) to grant push (read-write) permission to. | `list(string)` | `[]` | no | | [push\_teams](#input\_push\_teams) | (Optional) A list of teams (by name/slug) to grant push (read-write) permission to. | `list(string)` | `[]` | no | | [rulesets](#input\_rulesets) | (Optional) A list of branch rulesets to apply to the repository. Default is [].

It is very likely removal of any section will require setting it to an empty list/map.
This is due to limitations in the API whereby components are not destroyed upon removal. |
list(
object({
enforcement = string
name = string
target = string

rules = list(
object({
creation = optional(bool)
deletion = optional(bool)
non_fast_forward = optional(bool)
required_signatures = optional(bool)
required_linear_history = optional(bool)
update = optional(bool)
update_allows_fetch_and_merge = optional(bool)

branch_name_pattern = optional(
object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
})
)

commit_author_email_pattern = optional(
object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
})
)

commit_message_pattern = optional(
object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
})
)

committer_email_pattern = optional(
object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
})
)

tag_name_pattern = optional(
object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
})
)

required_status_checks = optional(
object({
strict_required_status_checks_policy = optional(bool)
do_not_enforce_on_create = optional(bool)
required_check = list(
object({
context = string
integration_id = optional(number)
})
)
})
)

pull_request = optional(
object({
dismiss_stale_reviews_on_push = optional(bool)
require_code_owner_review = optional(bool)
require_last_push_approval = optional(bool)
required_approving_review_count = optional(number)
required_review_thread_resolution = optional(bool)
})
)

required_workflows = optional(
object({
required_workflow = list(
object({
repository_id = number
ref = string
path = string
})
)
})
)

required_deployments = optional(
object({
required_deployment_environments = list(string)
})
)

required_code_scanning = optional(
object({
required_code_scanning_tool = list(
object({
tool = string
alerts_threshold = string
security_alerts_threshold = string
})
)
})
)

merge_queue = optional(
object({
check_response_timeout_minutes = optional(number)
grouping_strategy = optional(string)
max_entries_to_build = optional(number)
max_entries_to_merge = optional(number)
merge_method = optional(string)
min_entries_to_merge = optional(number)
min_entries_to_merge_wait_minutes = optional(number)
})
)
})
)

bypass_actors = optional(
list(
object({
actor_id = optional(number)
actor_type = string
bypass_mode = optional(string)
})
)
)

conditions = optional(
object({
ref_name = object({
include = list(string)
exclude = list(string)
})
})
)
})
)
| `[]` | no | +| [security\_and\_analysis](#input\_security\_and\_analysis) | (Optional) Security and analysis configuration block |
object({
advanced_security = optional(string, "disabled")
secret_scanning = optional(string, "disabled")
secret_scanning_push_protection = optional(string, "disabled")
})
| `{}` | no | | [squash\_merge\_commit\_message](#input\_squash\_merge\_commit\_message) | (Optional) Can be `PR_BODY`, `COMMIT_MESSAGES`, or `BLANK` for a default squash merge commit message. | `string` | `"COMMIT_MESSAGES"` | no | | [squash\_merge\_commit\_title](#input\_squash\_merge\_commit\_title) | (Optional) Can be `PR_BODY`, `COMMIT_MESSAGES`, or `BLANK` for a default squash merge commit message. | `string` | `"COMMIT_OR_PR_TITLE"` | no | | [template](#input\_template) | (Optional) Template repository to use. (Default: {}) |
object({
owner = string
repository = string
})
| `null` | no | @@ -210,6 +212,35 @@ See [variables.tf] and [examples/] for details and use-cases. | [webhooks](#output\_webhooks) | All attributes and arguments as returned by the github\_repository\_webhook resource. | +### Security And Analysis Configuration + +- [**`security_and_analysis`**](#var-security_and_analysis): *(Optional `object(security_and_analysis)`)* + + (Optional) The repository's [security and analysis](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-security-and-analysis-settings-for-your-repository) configuration. + See [Security and Analysis Configuration](#security-and-analysis-configuration) below for details. + + Default is `{}`. + + The `security_and_analysis` object accepts the following attributes: + + - [**`advanced_security`**](#attr-security_and_analysis-advanced_security): *(**Required** `string`)* + + The advanced security configuration for the repository. See [Advanced Security Configuration](#advanced-security-configuration) below for details. + + Default is `"disabled"`. + + - [**`secret_scanning`**](#attr-security_and_analysis-secret_scanning): *(**Required** `string`)* + + The secret scanning configuration for the repository. See [Secret Scanning Configuration](#secret-scanning-configuration) below for details. + + Default is `"disabled"`. + + - [**`secret_scanning_push_protection`**](#attr-security_and_analysis-secret_scanning_push_protection): *(**Required** `string`)* + + The secret scanning push protection configuration for the repository. See [Secret Scanning Push Protection Configuration](#secret-scanning-push-protection-configuration) below for details. + + Default is `"disabled"`. + ## External Documentation ### Terraform Github Provider Documentation diff --git a/main.tf b/main.tf index 022a731..375418c 100644 --- a/main.tf +++ b/main.tf @@ -153,6 +153,22 @@ resource "github_repository" "repository" { } } + dynamic "security_and_analysis" { + for_each = var.security_and_analysis != null ? [true] : [] + + content { + advanced_security { + status = var.security_and_analysis.advanced_security + } + secret_scanning { + status = var.security_and_analysis.secret_scanning + } + secret_scanning_push_protection { + status = var.security_and_analysis.secret_scanning_push_protection + } + } + } + lifecycle { ignore_changes = [ auto_init, diff --git a/variables.tf b/variables.tf index e234490..272bb10 100644 --- a/variables.tf +++ b/variables.tf @@ -398,6 +398,27 @@ variable "branch_protections_v4" { } } +variable "security_and_analysis" { + description = "(Optional) Security and analysis configuration block" + type = object({ + advanced_security = optional(string, "disabled") + secret_scanning = optional(string, "disabled") + secret_scanning_push_protection = optional(string, "disabled") + }) + default = {} + validation { + condition = alltrue( + [ + for key, value in var.security_and_analysis : contains(["enabled", "disabled"], value) + ] + ) + error_message = < Date: Tue, 13 Jun 2023 11:54:21 +0100 Subject: [PATCH 2/7] trailing period norm --- variables.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/variables.tf b/variables.tf index 272bb10..f7b76a9 100644 --- a/variables.tf +++ b/variables.tf @@ -414,7 +414,7 @@ variable "security_and_analysis" { ) error_message = < Date: Sun, 7 Dec 2025 15:50:33 +0000 Subject: [PATCH 3/7] rework to support v6.9 and enforce much more strict validation and preconditions --- README.md | 23 +++++++++++++++-------- locals.tf | 5 ----- main.tf | 30 +++++++++++++++++++++++++----- rulesets_resources.tf | 6 ++++++ securityanalysis_resources.tf | 23 +++++++++++++++++++++++ securityanalysis_variables.tf | 32 ++++++++++++++++++++++++++++++++ variables.tf | 21 --------------------- versions.tf | 6 +++++- 8 files changed, 106 insertions(+), 40 deletions(-) delete mode 100644 locals.tf create mode 100644 securityanalysis_resources.tf create mode 100644 securityanalysis_variables.tf diff --git a/README.md b/README.md index d1978c6..60787e1 100644 --- a/README.md +++ b/README.md @@ -88,13 +88,14 @@ See [variables.tf] and [examples/] for details and use-cases. | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.3 | -| [github](#requirement\_github) | >= 6.2, < 7.0 | +| [github](#requirement\_github) | >= 6.2, < 6.9 | +| [null](#requirement\_null) | >= 3.2 | ### Providers | Name | Version | |------|---------| -| [github](#provider\_github) | >= 6.2, < 7.0 | +| [github](#provider\_github) | >= 6.2, < 6.9 | ### Resources @@ -179,7 +180,7 @@ See [variables.tf] and [examples/] for details and use-cases. | [push\_team\_ids](#input\_push\_team\_ids) | (Optional) A list of teams (by id) to grant push (read-write) permission to. | `list(string)` | `[]` | no | | [push\_teams](#input\_push\_teams) | (Optional) A list of teams (by name/slug) to grant push (read-write) permission to. | `list(string)` | `[]` | no | | [rulesets](#input\_rulesets) | (Optional) A list of branch rulesets to apply to the repository. Default is [].

It is very likely removal of any section will require setting it to an empty list/map.
This is due to limitations in the API whereby components are not destroyed upon removal. |
list(
object({
enforcement = string
name = string
target = string

rules = list(
object({
creation = optional(bool)
deletion = optional(bool)
non_fast_forward = optional(bool)
required_signatures = optional(bool)
required_linear_history = optional(bool)
update = optional(bool)
update_allows_fetch_and_merge = optional(bool)

branch_name_pattern = optional(
object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
})
)

commit_author_email_pattern = optional(
object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
})
)

commit_message_pattern = optional(
object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
})
)

committer_email_pattern = optional(
object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
})
)

tag_name_pattern = optional(
object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
})
)

required_status_checks = optional(
object({
strict_required_status_checks_policy = optional(bool)
do_not_enforce_on_create = optional(bool)
required_check = list(
object({
context = string
integration_id = optional(number)
})
)
})
)

pull_request = optional(
object({
dismiss_stale_reviews_on_push = optional(bool)
require_code_owner_review = optional(bool)
require_last_push_approval = optional(bool)
required_approving_review_count = optional(number)
required_review_thread_resolution = optional(bool)
})
)

required_workflows = optional(
object({
required_workflow = list(
object({
repository_id = number
ref = string
path = string
})
)
})
)

required_deployments = optional(
object({
required_deployment_environments = list(string)
})
)

required_code_scanning = optional(
object({
required_code_scanning_tool = list(
object({
tool = string
alerts_threshold = string
security_alerts_threshold = string
})
)
})
)

merge_queue = optional(
object({
check_response_timeout_minutes = optional(number)
grouping_strategy = optional(string)
max_entries_to_build = optional(number)
max_entries_to_merge = optional(number)
merge_method = optional(string)
min_entries_to_merge = optional(number)
min_entries_to_merge_wait_minutes = optional(number)
})
)
})
)

bypass_actors = optional(
list(
object({
actor_id = optional(number)
actor_type = string
bypass_mode = optional(string)
})
)
)

conditions = optional(
object({
ref_name = object({
include = list(string)
exclude = list(string)
})
})
)
})
)
| `[]` | no | -| [security\_and\_analysis](#input\_security\_and\_analysis) | (Optional) Security and analysis configuration block |
object({
advanced_security = optional(string, "disabled")
secret_scanning = optional(string, "disabled")
secret_scanning_push_protection = optional(string, "disabled")
})
| `{}` | no | +| [security\_and\_analysis](#input\_security\_and\_analysis) | (Optional) Security and analysis configuration for the repository.

- All fields except org\_advanced\_security are strings: "enabled" or "disabled".
- org\_advanced\_security is a bool indicating whether the org has split licensing for Advanced Security. |
object({
org_advanced_security = optional(bool, false)
advanced_security = optional(string, "disabled")
code_security = optional(string, "disabled")
secret_scanning = optional(string, "disabled")
secret_scanning_push_protection = optional(string, "disabled")
secret_scanning_ai_detection = optional(string, "disabled")
secret_scanning_non_provider_patterns = optional(string, "disabled")
})
| `null` | no | | [squash\_merge\_commit\_message](#input\_squash\_merge\_commit\_message) | (Optional) Can be `PR_BODY`, `COMMIT_MESSAGES`, or `BLANK` for a default squash merge commit message. | `string` | `"COMMIT_MESSAGES"` | no | | [squash\_merge\_commit\_title](#input\_squash\_merge\_commit\_title) | (Optional) Can be `PR_BODY`, `COMMIT_MESSAGES`, or `BLANK` for a default squash merge commit message. | `string` | `"COMMIT_OR_PR_TITLE"` | no | | [template](#input\_template) | (Optional) Template repository to use. (Default: {}) |
object({
owner = string
repository = string
})
| `null` | no | @@ -219,23 +220,29 @@ See [variables.tf] and [examples/] for details and use-cases. (Optional) The repository's [security and analysis](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-security-and-analysis-settings-for-your-repository) configuration. See [Security and Analysis Configuration](#security-and-analysis-configuration) below for details. - Default is `{}`. + Default is `null`. The `security_and_analysis` object accepts the following attributes: - - [**`advanced_security`**](#attr-security_and_analysis-advanced_security): *(**Required** `string`)* + - [**`org_advanced_security`**](#attr-security_and_analysis-org_advanced_security: *(**Optional** `bool`)* + + If your GitHub Organization has split licensing for Advanced Security you can have Security and Analysis on non-public repositories. Otherwise Security and Analysis operates on all public repositories. + + Define `org_advanced_security` as true to give more visibility options. + + - [**`advanced_security`**](#attr-security_and_analysis-advanced_security): *(**Optional** `string`)* The advanced security configuration for the repository. See [Advanced Security Configuration](#advanced-security-configuration) below for details. - Default is `"disabled"`. + Default is `"disabled"`, except if `org_advanced_security` is not true when it is `"enabled"`. - - [**`secret_scanning`**](#attr-security_and_analysis-secret_scanning): *(**Required** `string`)* + - [**`secret_scanning`**](#attr-security_and_analysis-secret_scanning): *(**Optional** `string`)* The secret scanning configuration for the repository. See [Secret Scanning Configuration](#secret-scanning-configuration) below for details. Default is `"disabled"`. - - [**`secret_scanning_push_protection`**](#attr-security_and_analysis-secret_scanning_push_protection): *(**Required** `string`)* + - [**`secret_scanning_push_protection`**](#attr-security_and_analysis-secret_scanning_push_protection): *(**Optional** `string`)* The secret scanning push protection configuration for the repository. See [Secret Scanning Push Protection Configuration](#secret-scanning-push-protection-configuration) below for details. diff --git a/locals.tf b/locals.tf deleted file mode 100644 index 2868abc..0000000 --- a/locals.tf +++ /dev/null @@ -1,5 +0,0 @@ -locals { - rulesets_by_name = { - for rs in var.rulesets : rs.name => rs - } -} diff --git a/main.tf b/main.tf index 375418c..801f0a0 100644 --- a/main.tf +++ b/main.tf @@ -154,18 +154,34 @@ resource "github_repository" "repository" { } dynamic "security_and_analysis" { - for_each = var.security_and_analysis != null ? [true] : [] + for_each = [local.security_and_analysis] content { - advanced_security { - status = var.security_and_analysis.advanced_security + dynamic "advanced_security" { + for_each = var.visibility == "public" ? [] : [local.advanced_security_status] + content { + status = advanced_security.value + } } + secret_scanning { - status = var.security_and_analysis.secret_scanning + status = local.security_and_analysis.secret_scanning } + secret_scanning_push_protection { - status = var.security_and_analysis.secret_scanning_push_protection + status = local.security_and_analysis.secret_scanning_push_protection } + + # code_security, secret_scanning_ai_detection, and secret_scanning_non_provider_patterns require integrations/github >= 6.9 + # code_security { + # status = local.security_and_analysis.code_security + # } + # secret_scanning_ai_detection { + # status = local.security_and_analysis.secret_scanning_ai_detection + # } + # secret_scanning_non_provider_patterns { + # status = local.security_and_analysis.secret_scanning_non_provider_patterns + # } } } @@ -176,6 +192,10 @@ resource "github_repository" "repository" { gitignore_template, template, ] + precondition { + condition = local.security_and_analysis.org_advanced_security || !local.saa_child_enabled || var.visibility == "public" + error_message = "security_and_analysis: Repository visibility must be 'public' if any security feature is enabled unless org_advanced_security is true." + } } } diff --git a/rulesets_resources.tf b/rulesets_resources.tf index cd5ab82..7a17d42 100644 --- a/rulesets_resources.tf +++ b/rulesets_resources.tf @@ -1,3 +1,9 @@ +locals { + rulesets_by_name = { + for rs in var.rulesets : rs.name => rs + } +} + resource "github_repository_ruleset" "ruleset" { for_each = local.rulesets_by_name diff --git a/securityanalysis_resources.tf b/securityanalysis_resources.tf new file mode 100644 index 0000000..53ba0a0 --- /dev/null +++ b/securityanalysis_resources.tf @@ -0,0 +1,23 @@ +locals { + security_and_analysis = var.security_and_analysis != null ? var.security_and_analysis : { + org_advanced_security = false + advanced_security = "disabled" + code_security = "disabled" + secret_scanning = "disabled" + secret_scanning_push_protection = "disabled" + secret_scanning_ai_detection = "disabled" + secret_scanning_non_provider_patterns = "disabled" + } + + saa_child_enabled = ( + local.security_and_analysis.code_security == "enabled" || + local.security_and_analysis.secret_scanning == "enabled" || + local.security_and_analysis.secret_scanning_push_protection == "enabled" || + local.security_and_analysis.secret_scanning_ai_detection == "enabled" || + local.security_and_analysis.secret_scanning_non_provider_patterns == "enabled" + ) + + advanced_security_status = ( + local.saa_child_enabled || local.security_and_analysis.advanced_security == "enabled" + ) ? "enabled" : "disabled" +} diff --git a/securityanalysis_variables.tf b/securityanalysis_variables.tf new file mode 100644 index 0000000..0273d66 --- /dev/null +++ b/securityanalysis_variables.tf @@ -0,0 +1,32 @@ +variable "security_and_analysis" { + description = < Date: Mon, 8 Dec 2025 19:23:38 +0000 Subject: [PATCH 4/7] drop unused --- README.md | 1 - securityanalysis_variables.tf | 1 - versions.tf | 4 ---- 3 files changed, 6 deletions(-) diff --git a/README.md b/README.md index 60787e1..86fe177 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,6 @@ See [variables.tf] and [examples/] for details and use-cases. |------|---------| | [terraform](#requirement\_terraform) | >= 1.3 | | [github](#requirement\_github) | >= 6.2, < 6.9 | -| [null](#requirement\_null) | >= 3.2 | ### Providers diff --git a/securityanalysis_variables.tf b/securityanalysis_variables.tf index 0273d66..656fe85 100644 --- a/securityanalysis_variables.tf +++ b/securityanalysis_variables.tf @@ -23,7 +23,6 @@ EOF for key, value in( var.security_and_analysis != null ? var.security_and_analysis : {} ) : - # Only validate string fields key != "org_advanced_security" ? contains(["enabled", "disabled"], value) : true ]) ) diff --git a/versions.tf b/versions.tf index a5f48f1..1e6b8cb 100644 --- a/versions.tf +++ b/versions.tf @@ -10,9 +10,5 @@ terraform { source = "integrations/github" version = ">= 6.2, < 6.9" } - null = { - source = "hashicorp/null" - version = ">= 3.2" - } } } From dad607022d217bbd405fd25b3c4734a3f2fa1396 Mon Sep 17 00:00:00 2001 From: gaima8 <7595658+gaima8@users.noreply.github.com> Date: Mon, 8 Dec 2025 19:50:28 +0000 Subject: [PATCH 5/7] security_and_analysis can't be defined at all if not available --- main.tf | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/main.tf b/main.tf index 801f0a0..e892348 100644 --- a/main.tf +++ b/main.tf @@ -154,7 +154,9 @@ resource "github_repository" "repository" { } dynamic "security_and_analysis" { - for_each = [local.security_and_analysis] + for_each = ( + var.visibility == "public" || local.security_and_analysis.org_advanced_security + ) ? [local.security_and_analysis] : [] content { dynamic "advanced_security" { @@ -193,8 +195,12 @@ resource "github_repository" "repository" { template, ] precondition { - condition = local.security_and_analysis.org_advanced_security || !local.saa_child_enabled || var.visibility == "public" - error_message = "security_and_analysis: Repository visibility must be 'public' if any security feature is enabled unless org_advanced_security is true." + condition = ( + var.visibility == "public" + || local.security_and_analysis.org_advanced_security + || !local.saa_child_enabled + ) + error_message = "security_and_analysis cannot be used for private/internal repositories unless org_advanced_security is true." } } } From a67d82c7a7fffadb2acd384ba44f2352e482fc0b Mon Sep 17 00:00:00 2001 From: gaima8 <7595658+gaima8@users.noreply.github.com> Date: Mon, 8 Dec 2025 19:50:45 +0000 Subject: [PATCH 6/7] clarify org_advanced_security --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 86fe177..58fe43b 100644 --- a/README.md +++ b/README.md @@ -225,7 +225,7 @@ See [variables.tf] and [examples/] for details and use-cases. - [**`org_advanced_security`**](#attr-security_and_analysis-org_advanced_security: *(**Optional** `bool`)* - If your GitHub Organization has split licensing for Advanced Security you can have Security and Analysis on non-public repositories. Otherwise Security and Analysis operates on all public repositories. + If your GitHub Organization has split licensing for Advanced Security you can have Security and Analysis on non-public repositories. Otherwise Security and Analysis operates on all public repositories. Currently there is no known way to automatically detect this. Define `org_advanced_security` as true to give more visibility options. From 5cf89720fbb23f123b9bd44a964fb13c1686eb7c Mon Sep 17 00:00:00 2001 From: gaima8 <7595658+gaima8@users.noreply.github.com> Date: Mon, 8 Dec 2025 20:06:37 +0000 Subject: [PATCH 7/7] more precondition --- main.tf | 16 ++++++++++++---- securityanalysis_resources.tf | 6 ++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/main.tf b/main.tf index e892348..ceb3dbf 100644 --- a/main.tf +++ b/main.tf @@ -196,11 +196,19 @@ resource "github_repository" "repository" { ] precondition { condition = ( - var.visibility == "public" - || local.security_and_analysis.org_advanced_security - || !local.saa_child_enabled + ( + var.visibility == "public" + || local.security_and_analysis.org_advanced_security + || !local.saa_child_enabled + ) + && + local.push_protection_valid + ) + error_message = ( + local.push_protection_valid + ? "security_and_analysis cannot be used for private/internal repositories unless org_advanced_security is true." + : "secret_scanning_push_protection requires secret_scanning to also be enabled." ) - error_message = "security_and_analysis cannot be used for private/internal repositories unless org_advanced_security is true." } } } diff --git a/securityanalysis_resources.tf b/securityanalysis_resources.tf index 53ba0a0..c5fdc02 100644 --- a/securityanalysis_resources.tf +++ b/securityanalysis_resources.tf @@ -20,4 +20,10 @@ locals { advanced_security_status = ( local.saa_child_enabled || local.security_and_analysis.advanced_security == "enabled" ) ? "enabled" : "disabled" + + push_protection_valid = ( + local.security_and_analysis.secret_scanning_push_protection == "enabled" + ? local.security_and_analysis.secret_scanning == "enabled" + : true + ) }