terraform-google-modules / terraform-google-vpc-service-controls

Handles opinionated VPC Service Controls and Access Context Manager configuration and deployments
https://registry.terraform.io/modules/terraform-google-modules/vpc-service-controls/google
Apache License 2.0
59 stars 67 forks source link

Add detailed variable types for ingress and egress policy inputs in regular_service_perimeter #127

Closed 3sne closed 5 months ago

3sne commented 7 months ago

TL;DR

It would be beneficial to have detailed variable types for the variables egress_policies, egress_policies_dry_run, ingress_policies and ingress_policies_dry_run in the regular_service_perimeter module.

Terraform Resources

1. Ingress Rules Reference: https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference]
2. Egress Rules Reference: https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference
3. google_access_context_manager_service_perimeter: https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/access_context_manager_service_perimeter

Detailed design

No response

Additional information

With the optional type attribute generally available since Terraform version 1.3, the module users will find it very convenient to reference a concrete type for the above variables directly, rather than having to rely on referring the module code to understand what input structure for policy rules are expected by the module.

The current type for these variables only define a rough skeleton:

list(object({
  from = any
  to   = any
}))

The type design can use the ingress & egress rule references from links [1] and [2] to potentially create something like:

variable "ingress_policies" {
  default = []
  type = list(object({
    from = object({
      identity_type = optional(string)
      identities    = optional(list(string))
      sources = object({
        access_levels = optional(list(string), [])
        resources     = optional(list(string), [])
      })
    })
    to = object({
      resources = optional(list(string), ["*"])
      operations = map(object({
        methods     = optional(list(string), [])
        permissions = optional(list(string), [])
      }))
    })
  }))
  validation {
    # identity_type XOR identities
    condition = alltrue([
      for ingress_rule in var.ingress_policies: (
        (ingress_rule.from.identity_type == null && ingress_rule.from.identities != null)
        ||
        (ingress_rule.from.identity_type != null && ingress_rule.from.identities == null)
      )
    ])
    error_message = "Exactly one of from.identity_type OR from.identities must be configured."
  }
}

variable "egress_policies" {
  default = []
  type = list(object({
    to = object({
      resources = optional(list(string), ["*"])
      operations = map(object({
        methods     = optional(list(string), [])
        permissions = optional(list(string), [])
      }))
    })
    from = object({
      identity_type = optional(string)
      identities    = optional(list(string))
    })
  }))
  validation {
    # identity_type XOR identities
    condition = alltrue([
      for egress_rule in var.egress_policies : (
        (egress_rule.from.identity_type != null && egress_rule.from.identities == null)
        ||
        (egress_rule.from.identity_type == null && egress_rule.from.identities != null)
      )
    ])
    error_message = "Exactly one of from.identity_type OR from.identities must be configured."
  }
}

Similar types can be reused for egress_policies_dry_run & ingress_policies_dry_run. This should provide module users a good context on the general structure of the expected values!

github-actions[bot] commented 5 months ago

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days