Skip to content

Commit

Permalink
Merge pull request #172 from unity-sds/jupyterhub-proxy
Browse files Browse the repository at this point in the history
Add support for using Jupyterhub behind the Unity Proxy
  • Loading branch information
mcduffie authored Aug 16, 2024
2 parents cb1fa25 + 8262018 commit 51af59c
Show file tree
Hide file tree
Showing 12 changed files with 134 additions and 448 deletions.
23 changes: 0 additions & 23 deletions common/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
}
}
}
2 changes: 1 addition & 1 deletion dev_env/cognito/cognito_client.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
84 changes: 58 additions & 26 deletions dev_env/jupyterhub/frontend.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,29 @@
# 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

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 = "https"
proxy_address = data.aws_ssm_parameter.proxy_url.value
proxy_port = 4443

# Allow overriding from variables
url_terminus_path = "jupyter"
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}"
}
#################################################################
# Use only a Application Load Balancer as the Jupyterhub Frontend
Expand All @@ -37,14 +38,45 @@ 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"]
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]
}

#################################################################
# 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
<Location /${var.project}/${var.venue}/${local.url_terminus_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}
</Location>
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
]))
}
}
8 changes: 1 addition & 7 deletions dev_env/jupyterhub/jupyter_variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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 = 8000
}

# Should be an integer between 30000 and 32767
variable "jupyter_proxy_port" {
description = "Listening port for Jupyter kubernetes cluster"
Expand All @@ -29,7 +23,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" {
Expand Down
Loading

0 comments on commit 51af59c

Please sign in to comment.