From 0ca216e3d4aaac86159e22365b1af5f708d33dc4 Mon Sep 17 00:00:00 2001 From: James McDuffie Date: Wed, 17 Jul 2024 16:06:08 -0700 Subject: [PATCH 1/8] Add initial changes to handle setting up an entry in the venue's ECS proxy. --- dev_env/jupyterhub/frontend.tf | 56 +++++++++++++++++++++++-- dev_env/jupyterhub/jupyter_variables.tf | 4 +- dev_env/jupyterhub/outputs.tf | 18 ++++++-- dev_env/jupyterhub/security_group.tf | 4 +- 4 files changed, 72 insertions(+), 10 deletions(-) diff --git a/dev_env/jupyterhub/frontend.tf b/dev_env/jupyterhub/frontend.tf index 0adebce..2068c99 100644 --- a/dev_env/jupyterhub/frontend.tf +++ b/dev_env/jupyterhub/frontend.tf @@ -27,6 +27,27 @@ # autoscaling_group_name = module.eks.eks_managed_node_groups_autoscaling_group_names[0] # } +################################################################# +# Set up these data values to allow overriding of values by variables + +data "aws_ssm_parameter" proxy_url { + name = "/unity/${var.project}/${var.venue}/management/httpd/loadbalancer-url" +} + +locals { + # Extract info on the proxy from the SSM parameter + proxy_proto = lower(replace(regex("[[:alpha:]]+://", data.aws_ssm_parameter.proxy_url.value), "://", "")) + proxy_address = replace(replace(replace(data.aws_ssm_parameter.proxy_url.value, "/[[:alpha:]]+:///", ""), "//.*$/", ""), "/:.*$/", "") + proxy_port = replace(replace(replace(data.aws_ssm_parameter.proxy_url.value, "/[[:alpha:]]+:///", ""), "//.*$/", ""), "/^.*:/", "") + + # Allow overriding from variables + url_terminus_path = "jupyter" + load_balancer_port = var.load_balancer_port != null ? var.load_balancer_port : local.proxy_port + jupyter_base_url = var.jupyter_base_url != null ? var.jupyter_base_url : "${local.proxy_proto}://${local.proxy_address}:${local.proxy_port}" + #jupyter_base_path = var.jupyter_base_path != null ? var.jupyter_base_path : "${var.project}/${var.venue}/${local.url_terminus_path}" + jupyter_base_path = var.jupyter_base_path != null ? var.jupyter_base_path : "${local.url_terminus_path}" +} + ################################################################# # Use only a Application Load Balancer as the Jupyterhub Frontend @@ -37,14 +58,43 @@ module "frontend" { venue = var.venue venue_prefix = var.venue_prefix resource_prefix = var.resource_prefix - load_balancer_port = var.load_balancer_port + load_balancer_port = local.load_balancer_port jupyter_proxy_port = var.jupyter_proxy_port - jupyter_base_url = var.jupyter_base_url - jupyter_base_path = var.jupyter_base_path + jupyter_base_url = local.jupyter_base_url + jupyter_base_path = local.jupyter_base_path vpc_id = data.aws_ssm_parameter.vpc_id.value lb_subnet_ids = local.subnet_map["public"] security_group_id = aws_security_group.jupyter_lb_sg.id autoscaling_group_name = module.eks.eks_managed_node_groups_autoscaling_group_names[0] } + +################################################################# +# Initialize connection to HTTP proxy +resource "aws_ssm_parameter" "serviceproxy_config" { + depends_on = [module.frontend] + name = "/unity/${var.project}/${var.venue}/cs/management/proxy/configurations/042-jupyterlab" + type = "String" + value = <<-EOT + + + Header always set Strict-Transport-Security "max-age=63072000" + ProxyPass "${module.frontend.internal_base_url}/${local.jupyter_base_path}" upgrade=websocket + ProxyPassReverse "${module.frontend.internal_base_url}/${local.jupyter_base_path}" + ProxyPreserveHost on + RequestHeader set "X-Forwarded-Proto" expr=%%{REQUEST_SCHEME} + +EOT +} + +resource "aws_lambda_invocation" "unity_proxy_lambda_invocation" { + depends_on = [aws_ssm_parameter.serviceproxy_config] + function_name = "${var.project}-${var.venue}-httpdproxymanagement" + input = "{}" + triggers = { + redeployment = sha1(jsonencode([ + aws_ssm_parameter.serviceproxy_config + ])) + } +} diff --git a/dev_env/jupyterhub/jupyter_variables.tf b/dev_env/jupyterhub/jupyter_variables.tf index 3193115..9137ba1 100644 --- a/dev_env/jupyterhub/jupyter_variables.tf +++ b/dev_env/jupyterhub/jupyter_variables.tf @@ -6,7 +6,7 @@ variable "component_cost_name" { variable "load_balancer_port" { description = "Incoming port where load balancer will accept traffic" type = number - default = 8000 + default = null } # Should be an integer between 30000 and 32767 @@ -29,7 +29,7 @@ variable "jupyter_base_url" { variable "jupyter_base_path" { description = "Base path for Jupyter as accessed at its public facing location" type = string - default = "" + default = null } variable "cognito_oauth_base_url" { diff --git a/dev_env/jupyterhub/outputs.tf b/dev_env/jupyterhub/outputs.tf index 9d52894..adb79cb 100644 --- a/dev_env/jupyterhub/outputs.tf +++ b/dev_env/jupyterhub/outputs.tf @@ -1,11 +1,23 @@ +output "proxy_proto" { + value = nonsensitive(local.proxy_proto) +} + +output "proxy_address" { + value = nonsensitive(local.proxy_address) +} + +output "proxy_port" { + value = nonsensitive(local.proxy_port) +} + output "jupyter_base_path" { - value = module.frontend.jupyter_base_path + value = nonsensitive(module.frontend.jupyter_base_path) } output "jupyter_base_url" { - value = module.frontend.jupyter_base_url + value = nonsensitive(module.frontend.jupyter_base_url) } output "internal_base_url" { - value = module.frontend.internal_base_url + value = nonsensitive(module.frontend.internal_base_url) } diff --git a/dev_env/jupyterhub/security_group.tf b/dev_env/jupyterhub/security_group.tf index 89b4402..f9b0b81 100644 --- a/dev_env/jupyterhub/security_group.tf +++ b/dev_env/jupyterhub/security_group.tf @@ -18,8 +18,8 @@ resource "aws_security_group" "jupyter_lb_sg" { # Allow from variable defined input port ingress { - from_port = "${var.load_balancer_port}" - to_port = "${var.load_balancer_port}" + from_port = "${local.load_balancer_port}" + to_port = "${local.load_balancer_port}" protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } From c8102f689351df2eca3897f67bf0a0677742be3d Mon Sep 17 00:00:00 2001 From: James McDuffie Date: Thu, 25 Jul 2024 10:24:51 -0700 Subject: [PATCH 2/8] Use project/venu in cognito_client.tf --- dev_env/cognito/cognito_client.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_env/cognito/cognito_client.tf b/dev_env/cognito/cognito_client.tf index 249b820..835a56a 100644 --- a/dev_env/cognito/cognito_client.tf +++ b/dev_env/cognito/cognito_client.tf @@ -3,7 +3,7 @@ data "aws_cognito_user_pools" "unity_user_pool" { } resource "aws_cognito_user_pool_client" "jupyter_cognito_client" { - name = "${var.resource_prefix}-jupyter-${var.tenant_identifier}-client" + name = "${var.resource_prefix}-jupyter-${var.venue_prefix}${var.venue}-client" user_pool_id = tolist(data.aws_cognito_user_pools.unity_user_pool.ids)[0] callback_urls = var.jupyter_base_url != null ? ["${var.jupyter_base_url}/${var.jupyter_base_path}/hub/oauth_callback"] : null From a1fcd2f8cac4263d3a115377ee44be8662c14e56 Mon Sep 17 00:00:00 2001 From: James McDuffie Date: Thu, 25 Jul 2024 11:58:45 -0700 Subject: [PATCH 3/8] Remove venue/project variable verification. --- common/variables.tf | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/common/variables.tf b/common/variables.tf index 0c18256..4ea0098 100644 --- a/common/variables.tf +++ b/common/variables.tf @@ -26,26 +26,3 @@ variable "efs_identifier" { type = string # Example value:uads-development-efs-fs" } - -# These are for validation of the input variables -data "aws_ssm_parameter" "project" { - name = "/unity/${var.project}/${var.venue}/project-name" - - lifecycle { - postcondition { - condition = self.value == var.project - error_message = "project variable value ${var.project} does not match SSM parameter value in /unity/${var.project}/${var.venue}/project-name: {$data.aws_ssm_parameter.project}" - } - } -} - -data "aws_ssm_parameter" "venue" { - name = "/unity/${var.project}/${var.venue}/venue-name" - - lifecycle { - postcondition { - condition = self.value == var.venue - error_message = "venue variable value ${var.venue} does not match SSM parameter value in /unity/${var.project}/${var.venue}/venue-name: {$data.aws_ssm_parameter.venue}" - } - } -} From e564ab02b8d91a27ed3f4371757e38af2d0a846f Mon Sep 17 00:00:00 2001 From: James McDuffie Date: Thu, 25 Jul 2024 11:59:23 -0700 Subject: [PATCH 4/8] Change frontend for Jupyterhub to determine domain for the proxy in a more robust manner. --- dev_env/jupyterhub/frontend.tf | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/dev_env/jupyterhub/frontend.tf b/dev_env/jupyterhub/frontend.tf index 2068c99..74be8b2 100644 --- a/dev_env/jupyterhub/frontend.tf +++ b/dev_env/jupyterhub/frontend.tf @@ -30,15 +30,19 @@ ################################################################# # Set up these data values to allow overriding of values by variables -data "aws_ssm_parameter" proxy_url { - name = "/unity/${var.project}/${var.venue}/management/httpd/loadbalancer-url" +data "aws_ssm_parameter" "ssAcctNum" { + name = "/unity/shared-services/aws/account" +} + +data "aws_ssm_parameter" "proxy_url" { + name = "arn:aws:ssm:us-west-2:${data.aws_ssm_parameter.ssAcctNum.value}:parameter/unity/shared-services/domain" } locals { # Extract info on the proxy from the SSM parameter - proxy_proto = lower(replace(regex("[[:alpha:]]+://", data.aws_ssm_parameter.proxy_url.value), "://", "")) - proxy_address = replace(replace(replace(data.aws_ssm_parameter.proxy_url.value, "/[[:alpha:]]+:///", ""), "//.*$/", ""), "/:.*$/", "") - proxy_port = replace(replace(replace(data.aws_ssm_parameter.proxy_url.value, "/[[:alpha:]]+:///", ""), "//.*$/", ""), "/^.*:/", "") + proxy_proto = "https" + proxy_address = data.aws_ssm_parameter.proxy_url.value + proxy_port = 4443 # Allow overriding from variables url_terminus_path = "jupyter" @@ -77,8 +81,8 @@ resource "aws_ssm_parameter" "serviceproxy_config" { name = "/unity/${var.project}/${var.venue}/cs/management/proxy/configurations/042-jupyterlab" type = "String" value = <<-EOT - - + #SSLProxyEngine on + Header always set Strict-Transport-Security "max-age=63072000" ProxyPass "${module.frontend.internal_base_url}/${local.jupyter_base_path}" upgrade=websocket ProxyPassReverse "${module.frontend.internal_base_url}/${local.jupyter_base_path}" From 457204e480dece6986128a8ec4b1fdab28155204 Mon Sep 17 00:00:00 2001 From: James McDuffie Date: Tue, 30 Jul 2024 09:48:40 -0700 Subject: [PATCH 5/8] Enable SSL proxying in unity-proxy config for Jupyterhub --- dev_env/jupyterhub/frontend.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_env/jupyterhub/frontend.tf b/dev_env/jupyterhub/frontend.tf index 74be8b2..66fd49c 100644 --- a/dev_env/jupyterhub/frontend.tf +++ b/dev_env/jupyterhub/frontend.tf @@ -81,7 +81,7 @@ resource "aws_ssm_parameter" "serviceproxy_config" { name = "/unity/${var.project}/${var.venue}/cs/management/proxy/configurations/042-jupyterlab" type = "String" value = <<-EOT - #SSLProxyEngine on + SSLProxyEngine on Header always set Strict-Transport-Security "max-age=63072000" ProxyPass "${module.frontend.internal_base_url}/${local.jupyter_base_path}" upgrade=websocket From 4473e2415be301dbc17873e1c0374e40544c050c Mon Sep 17 00:00:00 2001 From: James McDuffie Date: Tue, 30 Jul 2024 09:55:52 -0700 Subject: [PATCH 6/8] Modify the frontend to create it's ALB on the private subnets now that unity-proxy is working. --- dev_env/jupyterhub/frontend.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_env/jupyterhub/frontend.tf b/dev_env/jupyterhub/frontend.tf index 66fd49c..51dd656 100644 --- a/dev_env/jupyterhub/frontend.tf +++ b/dev_env/jupyterhub/frontend.tf @@ -69,7 +69,7 @@ module "frontend" { jupyter_base_path = local.jupyter_base_path vpc_id = data.aws_ssm_parameter.vpc_id.value - lb_subnet_ids = local.subnet_map["public"] + lb_subnet_ids = local.subnet_map["private"] security_group_id = aws_security_group.jupyter_lb_sg.id autoscaling_group_name = module.eks.eks_managed_node_groups_autoscaling_group_names[0] } From 8a98349248f18fa318a9c7935e2e52b84d2837dc Mon Sep 17 00:00:00 2001 From: James McDuffie Date: Wed, 31 Jul 2024 10:21:25 -0700 Subject: [PATCH 7/8] Switch to using an internal load balancer using HTTP. Comment out HTTPS stuff that was there for internal testing before proxy was available. --- dev_env/jupyterhub/frontend.tf | 32 +-- dev_env/jupyterhub/jupyter_variables.tf | 2 +- .../jupyterhub/modules/api_gateway/main.tf | 254 ------------------ .../jupyterhub/modules/api_gateway/outputs.tf | 7 - .../modules/api_gateway/variables.tf | 77 ------ .../jupyterhub/modules/load_balancer/main.tf | 98 +++---- .../modules/load_balancer/outputs.tf | 2 +- .../modules/load_balancer/variables.tf | 5 + 8 files changed, 62 insertions(+), 415 deletions(-) delete mode 100644 dev_env/jupyterhub/modules/api_gateway/main.tf delete mode 100644 dev_env/jupyterhub/modules/api_gateway/outputs.tf delete mode 100644 dev_env/jupyterhub/modules/api_gateway/variables.tf diff --git a/dev_env/jupyterhub/frontend.tf b/dev_env/jupyterhub/frontend.tf index 51dd656..3acaa09 100644 --- a/dev_env/jupyterhub/frontend.tf +++ b/dev_env/jupyterhub/frontend.tf @@ -4,29 +4,6 @@ # Only one of the two choices below can be enabled at a time # Run terraform init if changing between the two -################################################################### -# Use an API Gateway connected to a NLB as the Jupyterhub Frontend -# -# This options mostly works except that websockets fail to properly -# be routed through the REST API gateway, more work would be needed -# to get it working. - -# module "frontend" { -# source = "./modules/api_gateway" -# -# project = var.project -# venue = var.venue -# venue_prefix = var.venue_prefix -# resource_prefix = var.resource_prefix -# load_balancer_port = var.load_balancer_port -# jupyter_proxy_port = var.jupyter_proxy_port -# -# vpc_id = data.aws_ssm_parameter.vpc_id.value -# lb_subnet_ids = local.subnet_map["private"] -# security_group_id = aws_security_group.jupyter_lb_sg.id -# autoscaling_group_name = module.eks.eks_managed_node_groups_autoscaling_group_names[0] -# } - ################################################################# # Set up these data values to allow overriding of values by variables @@ -46,10 +23,9 @@ locals { # Allow overriding from variables url_terminus_path = "jupyter" - load_balancer_port = var.load_balancer_port != null ? var.load_balancer_port : local.proxy_port - jupyter_base_url = var.jupyter_base_url != null ? var.jupyter_base_url : "${local.proxy_proto}://${local.proxy_address}:${local.proxy_port}" - #jupyter_base_path = var.jupyter_base_path != null ? var.jupyter_base_path : "${var.project}/${var.venue}/${local.url_terminus_path}" - jupyter_base_path = var.jupyter_base_path != null ? var.jupyter_base_path : "${local.url_terminus_path}" + load_balancer_port = var.load_balancer_port + jupyter_base_url = var.jupyter_base_url != null ? var.jupyter_base_url : "${local.proxy_proto}://www.${local.proxy_address}:${local.proxy_port}" + jupyter_base_path = var.jupyter_base_path != null ? var.jupyter_base_path : "${var.project}/${var.venue}/${local.url_terminus_path}" } ################################################################# @@ -69,6 +45,7 @@ module "frontend" { jupyter_base_path = local.jupyter_base_path vpc_id = data.aws_ssm_parameter.vpc_id.value + internal = true lb_subnet_ids = local.subnet_map["private"] security_group_id = aws_security_group.jupyter_lb_sg.id autoscaling_group_name = module.eks.eks_managed_node_groups_autoscaling_group_names[0] @@ -81,7 +58,6 @@ resource "aws_ssm_parameter" "serviceproxy_config" { name = "/unity/${var.project}/${var.venue}/cs/management/proxy/configurations/042-jupyterlab" type = "String" value = <<-EOT - SSLProxyEngine on Header always set Strict-Transport-Security "max-age=63072000" ProxyPass "${module.frontend.internal_base_url}/${local.jupyter_base_path}" upgrade=websocket diff --git a/dev_env/jupyterhub/jupyter_variables.tf b/dev_env/jupyterhub/jupyter_variables.tf index 9137ba1..d659608 100644 --- a/dev_env/jupyterhub/jupyter_variables.tf +++ b/dev_env/jupyterhub/jupyter_variables.tf @@ -6,7 +6,7 @@ variable "component_cost_name" { variable "load_balancer_port" { description = "Incoming port where load balancer will accept traffic" type = number - default = null + default = 8080 } # Should be an integer between 30000 and 32767 diff --git a/dev_env/jupyterhub/modules/api_gateway/main.tf b/dev_env/jupyterhub/modules/api_gateway/main.tf deleted file mode 100644 index c9c7192..0000000 --- a/dev_env/jupyterhub/modules/api_gateway/main.tf +++ /dev/null @@ -1,254 +0,0 @@ -############################################################## -# Network Load Balancer connecting EKS cluster to API Gateway - -resource "aws_lb" "jupyter_nlb" { - name = "jupyter-${var.venue_prefix}${var.venue}-nlb" - load_balancer_type = "network" - security_groups = [ var.security_group_id ] - subnets = var.lb_subnet_ids - - tags = { - Name = "/${var.resource_prefix}-${var.venue_prefix}${var.venue}-jupyter-nlb" - } -} - -resource "aws_lb_target_group" "jupyter_nlb_target_group" { - name = "jupyter-${var.venue_prefix}${var.venue}-nlb-tg" - target_type = "instance" - vpc_id = var.vpc_id - - protocol = "TCP" - port = var.jupyter_proxy_port - - tags = { - name = "${var.resource_prefix}-${var.venue_prefix}${var.venue}-alb-target-group" - } - - # alter the destination of the health check - health_check { - path = "/${local.jupyter_base_path}/hub/health" - port = var.jupyter_proxy_port - } -} - -resource "aws_lb_listener" "jupyter_nlb_listener" { - load_balancer_arn = aws_lb.jupyter_nlb.arn - port = var.load_balancer_port - protocol = "TCP" - - tags = { - Name = "${var.resource_prefix}-${var.venue_prefix}${var.venue}-nlb-listener" - } - - default_action { - target_group_arn = aws_lb_target_group.jupyter_nlb_target_group.arn - type = "forward" - } -} - -# Attach eks node_group to load balancer through the autoscaling group -# Solution from here: https://github.com/aws/containers-roadmap/issues/709 -resource "aws_autoscaling_attachment" "nlb_autoscaling_attachment" { - autoscaling_group_name = var.autoscaling_group_name - lb_target_group_arn = aws_lb_target_group.jupyter_nlb_target_group.arn -} - -######################### -# VPC Link to Jupyter NLB - -resource "aws_api_gateway_vpc_link" "api_lb_link" { - name = "jupyter-${var.venue_prefix}${var.venue}-vpc-link" - description = "VPC Link to ${var.venue_prefix}${var.venue} Jupyter NLB" - target_arns = [aws_lb.jupyter_nlb.arn] - - # Need to wait for NLB - depends_on = [ - aws_lb.jupyter_nlb - ] -} - -# Retrieve the API gateway ID given the name -data "aws_api_gateway_rest_api" "unity_api_gateway" { - name = var.api_gateway_name -} - -######################## -# Base path /ads/jupyter - -data "aws_api_gateway_resource" "api_resource_ads" { - rest_api_id = data.aws_api_gateway_rest_api.unity_api_gateway.id - path = var.api_gateway_path_to_ads -} - -resource "aws_api_gateway_resource" "api_resource_jupyter" { - rest_api_id = data.aws_api_gateway_rest_api.unity_api_gateway.id - parent_id = data.aws_api_gateway_resource.api_resource_ads.id - path_part = "jupyter" -} - -###### -# Redirection of base URL /ads/jupyter - -# create the method GET and assign it to the resource /jupyter -resource "aws_api_gateway_method" "api_method_base" { - rest_api_id = data.aws_api_gateway_rest_api.unity_api_gateway.id - resource_id = aws_api_gateway_resource.api_resource_jupyter.id - - http_method = "GET" - authorization = "NONE" -} - -# create the mock integration which will returns the statusCode 301 on the previous method GET of the /jupyter -resource "aws_api_gateway_integration" "api_integration_base" { - rest_api_id = data.aws_api_gateway_rest_api.unity_api_gateway.id - resource_id = aws_api_gateway_resource.api_resource_jupyter.id - - http_method = aws_api_gateway_method.api_method_base.http_method - type = "MOCK" - - request_templates = { - "application/json" : "{ \"statusCode\": 301 }" - } -} - -# create the method response and enable the header Location -resource "aws_api_gateway_method_response" "api_response_base_301" { - rest_api_id = data.aws_api_gateway_rest_api.unity_api_gateway.id - resource_id = aws_api_gateway_resource.api_resource_jupyter.id - - http_method = aws_api_gateway_method.api_method_base.http_method - status_code = "301" - - response_parameters = { - "method.response.header.Location" : true - } -} - -# Fill the previous header with the destination. Notice the syntax of the location with single quotes wrapped by doubles. -resource "aws_api_gateway_integration_response" "api_response_redirect" { - rest_api_id = data.aws_api_gateway_rest_api.unity_api_gateway.id - resource_id = aws_api_gateway_resource.api_resource_jupyter.id - - http_method = aws_api_gateway_method.api_method_base.http_method - status_code = aws_api_gateway_method_response.api_response_base_301.status_code - - response_parameters = { - "method.response.header.Location" : "'/${local.jupyter_base_path}/hub/'" - } -} - -###### -# Directly handle / so that we avoid redirect loop - -resource "aws_api_gateway_resource" "api_resource_hub" { - rest_api_id = data.aws_api_gateway_rest_api.unity_api_gateway.id - parent_id = aws_api_gateway_resource.api_resource_jupyter.id - path_part = "hub" -} - -resource "aws_api_gateway_method" "api_method_hub" { - rest_api_id = data.aws_api_gateway_rest_api.unity_api_gateway.id - resource_id = aws_api_gateway_resource.api_resource_hub.id - - http_method = "ANY" - - api_key_required = "false" - authorization = "NONE" -} - -# proxying of end point to the nlb -resource "aws_api_gateway_integration" "api_integration_hub" { - rest_api_id = data.aws_api_gateway_rest_api.unity_api_gateway.id - resource_id = aws_api_gateway_resource.api_resource_hub.id - - http_method = "ANY" - integration_http_method = "ANY" - - type = "HTTP_PROXY" - uri = "${local.jupyter_proxy_dest}/hub/" - - connection_type = "VPC_LINK" - connection_id = aws_api_gateway_vpc_link.api_lb_link.id - - # need to wait for alb - depends_on = [ - aws_lb.jupyter_nlb - ] -} - -###### -# Proxy resources - -resource "aws_api_gateway_resource" "api_resource_proxy" { - rest_api_id = data.aws_api_gateway_rest_api.unity_api_gateway.id - parent_id = aws_api_gateway_resource.api_resource_jupyter.id - path_part = "{proxy+}" -} - -resource "aws_api_gateway_method" "api_method_proxy" { - rest_api_id = data.aws_api_gateway_rest_api.unity_api_gateway.id - resource_id = aws_api_gateway_resource.api_resource_proxy.id - - http_method = "ANY" - - api_key_required = "false" - authorization = "NONE" - - request_parameters = { - "method.request.path.proxy" = "true" - } - -} - -# proxying of end point to the nlb -resource "aws_api_gateway_integration" "api_integration_proxy" { - rest_api_id = data.aws_api_gateway_rest_api.unity_api_gateway.id - resource_id = aws_api_gateway_resource.api_resource_proxy.id - - http_method = "ANY" - integration_http_method = "ANY" - - type = "HTTP_PROXY" - uri = "${local.jupyter_proxy_dest}/{proxy}" - - connection_type = "VPC_LINK" - connection_id = aws_api_gateway_vpc_link.api_lb_link.id - - request_parameters = { - "integration.request.path.proxy" = "method.request.path.proxy" - } - - # need to wait for alb - depends_on = [ - aws_lb.jupyter_nlb, - aws_api_gateway_vpc_link.api_lb_link - ] -} - -###### -# Deployment - -resource "aws_api_gateway_deployment" "jupyter_api_deployment" { - stage_name = var.api_gateway_stage_name - rest_api_id = data.aws_api_gateway_rest_api.unity_api_gateway.id - - depends_on = [ - aws_api_gateway_integration.api_integration_proxy, - aws_api_gateway_integration.api_integration_hub - ] -} - -###### -# Variables - -locals { - jupyter_base_url = "${aws_api_gateway_deployment.jupyter_api_deployment.invoke_url}${aws_api_gateway_resource.api_resource_jupyter.path}" -} - -locals { - jupyter_base_path = "${var.api_gateway_stage_name}${aws_api_gateway_resource.api_resource_jupyter.path}" -} - -locals { - jupyter_proxy_dest = "http://${aws_lb.jupyter_nlb.dns_name}:${aws_lb_listener.jupyter_nlb_listener.port}/${local.jupyter_base_path}" -} diff --git a/dev_env/jupyterhub/modules/api_gateway/outputs.tf b/dev_env/jupyterhub/modules/api_gateway/outputs.tf deleted file mode 100644 index 2c16126..0000000 --- a/dev_env/jupyterhub/modules/api_gateway/outputs.tf +++ /dev/null @@ -1,7 +0,0 @@ -output "jupyter_base_path" { - value = local.jupyter_base_path -} - -output "jupyter_base_url" { - value = local.jupyter_base_url -} diff --git a/dev_env/jupyterhub/modules/api_gateway/variables.tf b/dev_env/jupyterhub/modules/api_gateway/variables.tf deleted file mode 100644 index 6cabab9..0000000 --- a/dev_env/jupyterhub/modules/api_gateway/variables.tf +++ /dev/null @@ -1,77 +0,0 @@ -############################# -# Jupyterlab common variables -# These come from the top level variables - -variable "project" { - description = "The name of the project matching the /unity/<{project>/ Date: Tue, 13 Aug 2024 11:41:37 -0700 Subject: [PATCH 8/8] =?UTF-8?q?Force=20internal=20ALB=20to=20use=20the=20s?= =?UTF-8?q?ame=20port=20as=20the=20external=20proxy=C2=A0to=20avoid=20cros?= =?UTF-8?q?s-domain=20issues?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dev_env/jupyterhub/frontend.tf | 12 +++++++----- dev_env/jupyterhub/jupyter_variables.tf | 6 ------ 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/dev_env/jupyterhub/frontend.tf b/dev_env/jupyterhub/frontend.tf index 3acaa09..4dbb0e7 100644 --- a/dev_env/jupyterhub/frontend.tf +++ b/dev_env/jupyterhub/frontend.tf @@ -23,7 +23,7 @@ locals { # Allow overriding from variables url_terminus_path = "jupyter" - load_balancer_port = var.load_balancer_port + load_balancer_port = local.proxy_port jupyter_base_url = var.jupyter_base_url != null ? var.jupyter_base_url : "${local.proxy_proto}://www.${local.proxy_address}:${local.proxy_port}" jupyter_base_path = var.jupyter_base_path != null ? var.jupyter_base_path : "${var.project}/${var.venue}/${local.url_terminus_path}" } @@ -58,11 +58,13 @@ resource "aws_ssm_parameter" "serviceproxy_config" { name = "/unity/${var.project}/${var.venue}/cs/management/proxy/configurations/042-jupyterlab" type = "String" value = <<-EOT - - Header always set Strict-Transport-Security "max-age=63072000" - ProxyPass "${module.frontend.internal_base_url}/${local.jupyter_base_path}" upgrade=websocket - ProxyPassReverse "${module.frontend.internal_base_url}/${local.jupyter_base_path}" + + # preserve Host header to avoid cross-origin problems ProxyPreserveHost on + Header always set Strict-Transport-Security "max-age=63072000" + # proxy to JupyterHub + ProxyPass "${module.frontend.internal_base_url}/${local.jupyter_base_path}/" upgrade=websocket + ProxyPassReverse "${module.frontend.internal_base_url}/${local.jupyter_base_path}/" RequestHeader set "X-Forwarded-Proto" expr=%%{REQUEST_SCHEME} EOT diff --git a/dev_env/jupyterhub/jupyter_variables.tf b/dev_env/jupyterhub/jupyter_variables.tf index d659608..9b71593 100644 --- a/dev_env/jupyterhub/jupyter_variables.tf +++ b/dev_env/jupyterhub/jupyter_variables.tf @@ -3,12 +3,6 @@ variable "component_cost_name" { default = "jupyterhub" } -variable "load_balancer_port" { - description = "Incoming port where load balancer will accept traffic" - type = number - default = 8080 -} - # Should be an integer between 30000 and 32767 variable "jupyter_proxy_port" { description = "Listening port for Jupyter kubernetes cluster"