From 63bae85b34430646b539e638679a29ea916ab693 Mon Sep 17 00:00:00 2001 From: Julio Diez Date: Thu, 2 Feb 2023 21:47:11 +0100 Subject: [PATCH] Identity-Aware Proxy configuration --- .../cloud-run-explore/config/secure.tfvars | 16 ++++-- .../serverless/cloud-run-explore/main.tf | 49 +++++++++++++++++-- .../serverless/cloud-run-explore/variables.tf | 18 ++++++- 3 files changed, 75 insertions(+), 8 deletions(-) diff --git a/blueprints/serverless/cloud-run-explore/config/secure.tfvars b/blueprints/serverless/cloud-run-explore/config/secure.tfvars index 8176c087..50a24f6d 100644 --- a/blueprints/serverless/cloud-run-explore/config/secure.tfvars +++ b/blueprints/serverless/cloud-run-explore/config/secure.tfvars @@ -2,7 +2,7 @@ ### Purpose of this configuration file. ### ### On top of custom-url configuration (wish list: 'include' directive), -### add security using Cloud Armor in the LB. +### add security using Cloud Armor and Identity-Aware Proxy in the LB. ### # Add an HTTPS Load Balancer in front of the Cloud Run service @@ -18,11 +18,19 @@ custom_domain = "cloud-run-explore.example.org" # To allow access through the default URL set this value to "all" ingress_settings = "internal-and-cloud-load-balancing" -# Security policy to enforce in the LB. The code and this configuration -# allow to block a list of IPs and a specific URL path. For example, you -# may want to block access to a login page to external users +# Cloud Armor security policy to enforce in the LB. The code and this +# configuration allow to block a list of IPs and a specific URL path. For +# example, you may want to block access to a login page to external users security_policy = { enabled = true ip_blacklist = ["79.149.0.0/16"] path_blocked = "/login.html" } + +# Identity-Aware Proxy config for Cloud Run in the LB +iap = { + enabled = true + support_email = "user@example.org" + app_title = "Cloud Run Explore Application" + oauth2_client_name = "Test Client" +} diff --git a/blueprints/serverless/cloud-run-explore/main.tf b/blueprints/serverless/cloud-run-explore/main.tf index ae8d212c..4b635d77 100644 --- a/blueprints/serverless/cloud-run-explore/main.tf +++ b/blueprints/serverless/cloud-run-explore/main.tf @@ -36,9 +36,14 @@ module "glb" { backends = [ { backend = "neg-0" } ] - health_checks = [] - port_name = "http" - security_policy = try(google_compute_security_policy.policy[0].name, null) + health_checks = [] + port_name = "http" + security_policy = try(google_compute_security_policy.policy[0].name, + null) + iap_config = try({ + oauth2_client_id = google_iap_client.iap_client[0].client_id, + oauth2_client_secret = google_iap_client.iap_client[0].secret + }, null) } } health_check_configs = {} @@ -62,6 +67,7 @@ module "glb" { } } +# Cloud Armor configuration resource "google_compute_security_policy" "policy" { count = var.glb_create ? (var.security_policy.enabled ? 1 : 0) : 0 name = "cloud-run-policy" @@ -99,3 +105,40 @@ resource "google_compute_security_policy" "policy" { description = "Default rule" } } + +# Identity-Aware Proxy (IAP) or OAuth brand (see OAuth consent screen) +# Note: +# Only "Organization Internal" brands can be created programmatically +# via API. To convert it into an external brand please use the GCP +# Console. +# Brands can only be created once for a Google Cloud project and the +# underlying Google API doesn't support DELETE or PATCH methods. +# Destroying a Terraform-managed Brand will remove it from state but +# will not delete it from Google Cloud. +resource "google_iap_brand" "iap_brand" { + count = var.glb_create ? (var.iap.enabled ? 1 : 0) : 0 + project = var.project_id + support_email = var.iap.support_email + application_title = var.iap.app_title +} + +# IAP owned OAuth2 client +# Note: +# Only internal org clients can be created via declarative tools. +# External clients must be manually created via the GCP console. +# Warning: +# All arguments including secret will be stored in the raw state as plain-text. +resource "google_iap_client" "iap_client" { + count = var.glb_create ? (var.iap.enabled ? 1 : 0) : 0 + display_name = var.iap.oauth2_client_name + brand = google_iap_brand.iap_brand[0].name +} + +# IAM policy for IAP +# For simplicity we use the support_email as authorized member +resource "google_iap_web_iam_member" "iap_iam" { + count = var.glb_create ? (var.iap.enabled ? 1 : 0) : 0 + project = var.project_id + role = "roles/iap.httpsResourceAccessor" + member = "user:${var.iap.support_email}" +} diff --git a/blueprints/serverless/cloud-run-explore/variables.tf b/blueprints/serverless/cloud-run-explore/variables.tf index a8e5567f..4e01e454 100644 --- a/blueprints/serverless/cloud-run-explore/variables.tf +++ b/blueprints/serverless/cloud-run-explore/variables.tf @@ -40,7 +40,7 @@ variable "ingress_settings" { } variable "security_policy" { - description = "Security policy to enforce in the LB" + description = "Security policy (Cloud Armor) to enforce in the LB" type = object({ enabled = bool ip_blacklist = list(string) @@ -52,3 +52,19 @@ variable "security_policy" { path_blocked = null } } + +variable "iap" { + description = "Identity-Aware Proxy for Cloud Run in the LB" + type = object({ + enabled = bool + support_email = string + app_title = string + oauth2_client_name = string + }) + default = { + enabled = false + support_email = null + app_title = null + oauth2_client_name = null + } +}