|
1 | 1 | """JupyterHub application deployment for MIT Open Learning.""" |
2 | 2 |
|
3 | 3 | from pulumi import Config, StackReference |
| 4 | +from pulumi_aws import ec2 |
4 | 5 |
|
| 6 | +from bridge.lib.magic_numbers import DEFAULT_POSTGRES_PORT |
5 | 7 | from ol_infrastructure.applications.jupyterhub.deployment import ( |
6 | 8 | provision_jupyterhub_deployment, |
7 | 9 | ) |
| 10 | +from ol_infrastructure.components.aws.database import OLAmazonDB, OLPostgresDBConfig |
8 | 11 | from ol_infrastructure.lib.aws.eks_helper import ( |
9 | 12 | check_cluster_namespace, |
10 | 13 | setup_k8s_provider, |
|
22 | 25 | # Parse stack and setup providers |
23 | 26 | stack_info = parse_stack() |
24 | 27 | setup_vault_provider(stack_info) |
| 28 | +env_name = f"{stack_info.env_prefix}-{stack_info.env_suffix}" |
25 | 29 |
|
26 | 30 | # Configuration |
27 | 31 | jupyterhub_config = Config("jupyterhub") |
28 | 32 | vault_config = Config("vault") |
29 | 33 |
|
| 34 | + |
30 | 35 | # Stack references |
31 | 36 | network_stack = StackReference(f"infrastructure.aws.network.{stack_info.name}") |
32 | 37 | vault_stack = StackReference(f"infrastructure.vault.operations.{stack_info.name}") |
33 | 38 | cluster_stack = StackReference(f"infrastructure.aws.eks.applications.{stack_info.name}") |
34 | 39 |
|
35 | 40 | # AWS configuration |
| 41 | +apps_vpc = network_stack.require_output("applications_vpc") |
| 42 | +k8s_pod_subnet_cidrs = apps_vpc["k8s_pod_subnet_cidrs"] |
36 | 43 | aws_config = AWSBase( |
37 | 44 | tags={"OU": BusinessUnit.mit_learn, "Environment": stack_info.env_suffix} |
38 | 45 | ) |
|
68 | 75 | jupyterhub_config.get("db_instance_size") or rds_defaults["instance_size"] |
69 | 76 | ) |
70 | 77 | rds_defaults["use_blue_green"] = False |
| 78 | +rds_password = jupyterhub_config.require("rds_password") |
| 79 | + |
| 80 | +target_vpc_name = jupyterhub_config.get("target_vpc") or f"{stack_info.env_prefix}_vpc" |
| 81 | +target_vpc = network_stack.require_output(target_vpc_name) |
| 82 | +target_vpc_id = target_vpc["id"] |
71 | 83 |
|
72 | 84 | # Extra images for pre-pulling |
73 | 85 | COURSE_NAMES = [ |
|
108 | 120 | for course_name in COURSE_NAMES |
109 | 121 | } |
110 | 122 |
|
| 123 | +#### Database setup #### |
| 124 | +# The physical database for Jupyterhub is shared across both the main and authoring |
| 125 | +# deployments, but we create separate Vault backends for each to manage credentials |
| 126 | +# and roles separately. |
| 127 | +jupyterhub_db_security_group = ec2.SecurityGroup( |
| 128 | + f"jupyterhub-db-security-group-{env_name}", |
| 129 | + name=f"jupyterhub-db-{target_vpc_name}-{env_name}", |
| 130 | + description="Access from jupyterhub to its own postgres database.", |
| 131 | + ingress=[ |
| 132 | + ec2.SecurityGroupIngressArgs( |
| 133 | + security_groups=[ |
| 134 | + vault_stack.require_output("vault_server")["security_group"], |
| 135 | + ], |
| 136 | + cidr_blocks=[target_vpc["cidr"]], |
| 137 | + protocol="tcp", |
| 138 | + from_port=DEFAULT_POSTGRES_PORT, |
| 139 | + to_port=DEFAULT_POSTGRES_PORT, |
| 140 | + description="Access to Postgres from jupyterhub nodes.", |
| 141 | + ), |
| 142 | + ec2.SecurityGroupIngressArgs( |
| 143 | + cidr_blocks=k8s_pod_subnet_cidrs, |
| 144 | + description="Allow k8s cluster ipblocks to talk to DB", |
| 145 | + from_port=DEFAULT_POSTGRES_PORT, |
| 146 | + protocol="tcp", |
| 147 | + security_groups=[], |
| 148 | + to_port=DEFAULT_POSTGRES_PORT, |
| 149 | + ), |
| 150 | + ], |
| 151 | + tags=aws_config.tags, |
| 152 | + vpc_id=target_vpc_id, |
| 153 | +) |
| 154 | + |
| 155 | +jupyterhub_db_config = OLPostgresDBConfig( |
| 156 | + instance_name=f"jupyterhub-db-{stack_info.env_suffix}", |
| 157 | + password=rds_password, |
| 158 | + subnet_group_name=target_vpc["rds_subnet"], |
| 159 | + security_groups=[jupyterhub_db_security_group], |
| 160 | + tags=aws_config.tags, |
| 161 | + db_name="jupyterhub", |
| 162 | + **rds_defaults, |
| 163 | +) |
| 164 | +jupyterhub_db = OLAmazonDB(jupyterhub_db_config) |
| 165 | + |
| 166 | +jupyterhub_authoring_db_config = OLPostgresDBConfig( |
| 167 | + instance_name=f"jupyterhub-authoring-db-{stack_info.env_suffix}", |
| 168 | + password=rds_password, |
| 169 | + subnet_group_name=target_vpc["rds_subnet"], |
| 170 | + security_groups=[jupyterhub_db_security_group], |
| 171 | + tags=aws_config.tags, |
| 172 | + db_name="jupyterhub_authoring", |
| 173 | + **rds_defaults, |
| 174 | +) |
| 175 | + |
111 | 176 | # Provision main JupyterHub deployment |
112 | 177 | jupyterhub_deployment = provision_jupyterhub_deployment( |
113 | 178 | base_name="jupyterhub", |
|
116 | 181 | stack_info=stack_info, |
117 | 182 | jupyterhub_config=jupyterhub_config, |
118 | 183 | vault_config=vault_config, |
| 184 | + db_config=jupyterhub_db_config, |
| 185 | + app_db=jupyterhub_db, |
119 | 186 | network_stack=network_stack, |
120 | | - vault_stack=vault_stack, |
121 | 187 | cluster_stack=cluster_stack, |
122 | | - aws_config=aws_config, |
123 | 188 | application_labels=application_labels, |
124 | 189 | k8s_global_labels=k8s_global_labels, |
125 | 190 | extra_images=EXTRA_IMAGES, |
|
133 | 198 | stack_info=stack_info, |
134 | 199 | jupyterhub_config=jupyterhub_config, |
135 | 200 | vault_config=vault_config, |
| 201 | + db_config=jupyterhub_authoring_db_config, |
| 202 | + app_db=jupyterhub_db, |
136 | 203 | network_stack=network_stack, |
137 | | - vault_stack=vault_stack, |
138 | 204 | cluster_stack=cluster_stack, |
139 | | - aws_config=aws_config, |
140 | 205 | application_labels=application_labels, |
141 | 206 | k8s_global_labels=k8s_global_labels, |
142 | 207 | extra_images=EXTRA_IMAGES, |
|
0 commit comments