Skip to content

Instantly share code, notes, and snippets.

@olliefr
Created April 1, 2022 00:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save olliefr/7a5c0d700d50fa120c38a0fbe4925b43 to your computer and use it in GitHub Desktop.
Save olliefr/7a5c0d700d50fa120c38a0fbe4925b43 to your computer and use it in GitHub Desktop.
Making sense of Terraform Google provider's google_organization_policy and compute.vmExternalIpAccess constraint.
terraform {
required_version = "~> 1.1.7"
required_providers {
google = "~>4.12.0"
}
experiments = [module_variable_optional_attrs]
}
variable "gcp_organisation" {
default = "1054101600813"
}
# "gcp.resourceLocations" = {
# list_policy = {
# allow = {
# values = [
# "in:europe-locations"
# ]
# }
# }
# }
locals {
project_id = "pj-terraform-master-rsid"
zone = "europe-west2-c"
list_policy = {
# allow = {
# values = [
# "projects/${project_id}/zones/${zone}/instances/instance-a",
# "in:europe-locations",
# ]
# all = true
# }
deny = {
# values = [
# "projects/${local.project_id}/zones/${local.zone}/instances/instance-a",
## "in:europe-locations"
# ]
all = true
}
}
new_list_policy = {
for k,v in local.list_policy: (lookup(v, "all", false) ? "${k}_all" : k) => v
}
}
#output "result" {
# value = local.new_list_policy
#}
# This resource has been superseded by `google_org_policy_policy`.
# `google_org_policy_policy` uses Organization Policy API V2 instead of
# Cloud Resource Manager API V1 and it supports additional features such as tags and conditions.
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_organization_policy
# Google constraint documentation
# https://cloud.google.com/compute/docs/ip-addresses/reserve-static-external-ip-address#disableexternalip
resource "google_organization_policy" "compute_vm_external_ip_access" {
org_id = var.gcp_organisation
constraint = "compute.vmExternalIpAccess"
# WARNING! This is hackish but it suits the need right now.
dynamic "list_policy" {
for_each = local.new_list_policy[*]
content {
dynamic "allow" {
for_each = lookup(list_policy.value, "allow", null)[*]
content {
values = allow.value.values
}
}
dynamic "allow" {
for_each = lookup(list_policy.value, "allow_all", null)[*]
content {
all = true
}
}
dynamic "deny" {
for_each = lookup(list_policy.value, "deny", null)[*]
content {
values = deny.value.values
}
}
dynamic "deny" {
for_each = lookup(list_policy.value, "deny_all", null)[*]
content {
all = true
}
}
}
}
# list_policy {
#
## # Enable for 'all': plan OK, apply OK
## allow {
## all = true
## }
#
## # Enable for 'all': plan OK, apply ERROR
## deny {
## all = false
## }
#
## # Disable for 'all': plan OK, apply OK
## deny {
## all = true
## }
#
## # Disable for 'all': plan OK, apply ERROR
## allow {
## all = false
## }
#
# ##
# ## Conclusion: when `all` keyword is used, the only valid value is `true`. Pair with `allow` or `deny`.
# ##
#
## # Disable for 'all': plan OK, apply ERROR
## # This translates into `all = false` in the plan.
## allow {
## values = []
## }
#
## # Enable for 'all': plan OK, apply ERROR
## # This translates into `all = false` in the plan.
## deny {
## values = []
## }
#
# ##
# ## Conclusion: empty list of values plans OK but does not work
# ##
# }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment