diff --git a/.github/workflows/deploy-grafana-dashboards.yaml b/.github/workflows/deploy-grafana-dashboards.yaml index d161d8bcf0..9ef67d99e7 100644 --- a/.github/workflows/deploy-grafana-dashboards.yaml +++ b/.github/workflows/deploy-grafana-dashboards.yaml @@ -28,6 +28,7 @@ jobs: - cluster_name: nasa-esdis - cluster_name: nasa-veda - cluster_name: openscapes + - cluster_name: opensci - cluster_name: pangeo-hubs - cluster_name: qcl - cluster_name: smithsonian diff --git a/.github/workflows/deploy-hubs.yaml b/.github/workflows/deploy-hubs.yaml index e32014b434..0e55c1ce00 100644 --- a/.github/workflows/deploy-hubs.yaml +++ b/.github/workflows/deploy-hubs.yaml @@ -205,6 +205,7 @@ jobs: failure_hhmi: "${{ env.failure_hhmi }}" failure_nasa-esdis: "${{ env.failure_nasa-esdis }}" failure_earthscope: "${{ env.failure_earthscope }}" + failure_opensci: "${{ env.failure_opensci }}" # Only run this job on pushes to the default branch and when the job output is not # an empty list diff --git a/config/clusters/2i2c/imagebuilding-demo.values.yaml b/config/clusters/2i2c/imagebuilding-demo.values.yaml index 19c42a9519..e6ac20b8e6 100644 --- a/config/clusters/2i2c/imagebuilding-demo.values.yaml +++ b/config/clusters/2i2c/imagebuilding-demo.values.yaml @@ -137,40 +137,10 @@ jupyterhub: setup_ui(c) binderhub-service: - nodeSelector: - hub.jupyter.org/node-purpose: core enabled: true - service: - port: 8090 - # The DaemonSet at https://github.com/2i2c-org/binderhub-service/blob/main/binderhub-service/templates/docker-api/daemonset.yaml - # will start a docker-api pod on a user node. - # It starts the [dockerd](https://docs.docker.com/engine/reference/commandline/dockerd/) daemon, - # that will be accessible via a unix socket, mounted by the build. - # The docker-api pod must run on the same node as the builder pods. - dockerApi: - nodeSelector: - hub.jupyter.org/node-purpose: user - tolerations: - # Tolerate tainted jupyterhub user nodes - - key: hub.jupyter.org_dedicated - value: user - effect: NoSchedule - - key: hub.jupyter.org/dedicated - value: user - effect: NoSchedule config: BinderHub: - base_url: /services/binder - use_registry: true - # Re-uses the registry created for the `binderhub-staging` hub - # but pushes images under a different prefix image_prefix: us-central1-docker.pkg.dev/two-eye-two-see/binder-staging-registry/binderhub-service- - KubernetesBuildExecutor: - # Get ourselves a newer repo2docker! - build_image: quay.io/jupyterhub/repo2docker:2023.06.0-8.gd414e99 - node_selector: - # Schedule builder pods to run on user nodes only - hub.jupyter.org/node-purpose: user # The password to the registry is stored encrypted in the hub's encrypted config file buildPodsRegistryCredentials: server: "https://us-central1-docker.pkg.dev" diff --git a/config/clusters/opensci/cluster.yaml b/config/clusters/opensci/cluster.yaml new file mode 100644 index 0000000000..e1b7de05b8 --- /dev/null +++ b/config/clusters/opensci/cluster.yaml @@ -0,0 +1,23 @@ +name: opensci +provider: aws # https://2i2c.awsapps.com/start#/ +aws: + key: enc-deployer-credentials.secret.json + clusterType: eks + clusterName: opensci + region: us-west-2 +support: + helm_chart_values_files: + - support.values.yaml + - enc-support.secret.values.yaml +hubs: + - name: sciencecore + display_name: "Sciencecore " + domain: sciencecore.opensci.2i2c.cloud + helm_chart: basehub + helm_chart_values_files: + # The order in which you list files here is the order the will be passed + # to the helm upgrade command in, and that has meaning. Please check + # that you intend for these files to be applied in this order. + - common.values.yaml + - sciencecore.values.yaml + - enc-sciencecore.secret.values.yaml diff --git a/config/clusters/opensci/common.values.yaml b/config/clusters/opensci/common.values.yaml new file mode 100644 index 0000000000..5a18248077 --- /dev/null +++ b/config/clusters/opensci/common.values.yaml @@ -0,0 +1,14 @@ +nfs: + enabled: true + pv: + enabled: true + # from https://docs.aws.amazon.com/efs/latest/ug/mounting-fs-nfs-mount-settings.html + mountOptions: + - rsize=1048576 + - wsize=1048576 + - timeo=600 + - soft # We pick soft over hard, so NFS lockups don't lead to hung processes + - retrans=2 + - noresvport + serverIP: fs-065fcb5bb0ad79b25.efs.us-west-2.amazonaws.com + baseShareName: / diff --git a/config/clusters/opensci/enc-deployer-credentials.secret.json b/config/clusters/opensci/enc-deployer-credentials.secret.json new file mode 100644 index 0000000000..8130dd5fca --- /dev/null +++ b/config/clusters/opensci/enc-deployer-credentials.secret.json @@ -0,0 +1,25 @@ +{ + "AccessKey": { + "AccessKeyId": "ENC[AES256_GCM,data:MtyZwyAG9hUN2TZmVBY99AUkTzk=,iv:X1yxWvoAR4qlzPGDr9sh5fI5/nPqsKezibr/gJ6sGyI=,tag:JkExYO+KJxqrBep71B+tpw==,type:str]", + "SecretAccessKey": "ENC[AES256_GCM,data:k5ZOOtSBK6GQG60fkcuVju/zuIzyXSmou+lMpbqI9KXj/70nK2vMxw==,iv:rxPpG9bTHAFB6TbtZoJQ6CglXHnDk0d6+3OV3//TqUs=,tag:CksFoyD6jh7Bd3tIZHQvug==,type:str]", + "UserName": "ENC[AES256_GCM,data:POvIw42gLg8qNOAQeZsvyi+Zma/I5Jo=,iv:uMiKk7ONZxSMm5K/rSEgOL1ZusHy8VgFD9C2D2ezEcg=,tag:oDJTF8RmGwpCBpEjvqL+PA==,type:str]" + }, + "sops": { + "kms": null, + "gcp_kms": [ + { + "resource_id": "projects/two-eye-two-see/locations/global/keyRings/sops-keys/cryptoKeys/similar-hubs", + "created_at": "2024-02-21T15:39:23Z", + "enc": "CiUA4OM7eF5o6mB9Vayi+puvS7aVXCANRtsaycfD68b7ISp9B6drEkkAXoW3JtPtnpYszaNYGfUeJiDVthqBYPcRJjtmCPqm6DEVL9Uyyordh2F636IlremL8X5LedANy3V6JQfofNHug3SiOYSzTqaj" + } + ], + "azure_kv": null, + "hc_vault": null, + "age": null, + "lastmodified": "2024-02-21T15:39:24Z", + "mac": "ENC[AES256_GCM,data:mX6G6KmXOkBiUMT/robJTZ2L8KozL2S8av0UIBhO7lNWo4BJJYLNx9fQL6wzjgWkclE8NI6AiZg57qo6u8SCIV+Fg1veJjsTv9mxOtuV1NbSH8vLs8FOCq0Qp/qDUTFCTIATqqIGPaTB6oUeM7TkBAlwS3SedRn/GTVMAFFDjbY=,iv:zncrRM8g/aC+oh/Hoogil+kUSst/GXOrQbKOwtbw1G4=,tag:V4wlwuxyDLVdLn9t1No41Q==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.7.3" + } +} \ No newline at end of file diff --git a/config/clusters/opensci/enc-grafana-token.secret.yaml b/config/clusters/opensci/enc-grafana-token.secret.yaml new file mode 100644 index 0000000000..dbe09afae5 --- /dev/null +++ b/config/clusters/opensci/enc-grafana-token.secret.yaml @@ -0,0 +1,15 @@ +grafana_token: ENC[AES256_GCM,data:FUDyTxRjgJ3FrEzZ4FJeNCVOYtfAVGtz82Xjzlq0JSDrcDSdcOVc5VRZAixo6g==,iv:wP1WsvpXh4T6i0zKQatAmYS/+GRa5vwmRtOUz82VUWY=,tag:WY1AuW4YhYE54ij6pIjmZQ==,type:str] +sops: + kms: [] + gcp_kms: + - resource_id: projects/two-eye-two-see/locations/global/keyRings/sops-keys/cryptoKeys/similar-hubs + created_at: "2024-02-27T08:21:10Z" + enc: CiUA4OM7eJwLqe0B1wFs4I0fTW9ca4t9EVaupRu6drh9jlu2BMxSEkkAXoW3JoVJBEtoW1U21/GHpWilS78im8nQUr/+YbIpFgHLJO1hsEbVqIjhJQ82ZfYryz9ozn/4/Fwxlzx6XymhncSnR/1KllE1 + azure_kv: [] + hc_vault: [] + age: [] + lastmodified: "2024-02-27T08:21:11Z" + mac: ENC[AES256_GCM,data:dgsHlAhpVrM3246Mmk+Hiemmh4MVrkd75LYNx7ffyw0ojThJ8/wTLL8Bio25Py7vzQR10r3qVtj1+TNnDXE3cGHPTpXBuBS4RfdI63/+SAdoONL8T0J0zUM58opWfkhp3XaB5JAKJH4JTP+WGVDGmYWiyRC6kbxvn7fhLqq509U=,iv:SZ+s+LU+EJHNPbfGpHpkOzS4aTUWT0fHGyX5om0jH2w=,tag:F0vuPTXtXVUqlpCOKcLaAA==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.7.3 diff --git a/config/clusters/opensci/enc-sciencecore.secret.values.yaml b/config/clusters/opensci/enc-sciencecore.secret.values.yaml new file mode 100644 index 0000000000..de65d96a18 --- /dev/null +++ b/config/clusters/opensci/enc-sciencecore.secret.values.yaml @@ -0,0 +1,28 @@ +binderhub-service: + buildPodsRegistryCredentials: + password: ENC[AES256_GCM,data:8SoSbjJQoxjSvjiWMv2isnKD1tNWzQEijO7KGQG7L3VBFrqHTn00vE5k8kiiNfVDh1fcrnVMbTp4h414mTrtsg==,iv:s58wLbD13dRyYyg0RAKBjq4AuFNauU+MeTEP9fUYoZU=,tag:bHFEG8hRXmQ60XGe4G1n7A==,type:str] +jupyterhub: + imagePullSecret: + create: ENC[AES256_GCM,data:aJ5t7w==,iv:mdiodKbsYFnfzFkwCBbgQ6B/myJcL/z1+f15vTgSQwQ=,tag:mmuYSMXreRi2O4nwAzaZsw==,type:bool] + registry: ENC[AES256_GCM,data:iGtOHQXDhw==,iv:YXdzdemCE+6B5sA437zaUFKDhb2xj2X7gMZNzu3tTqM=,tag:Bqn2k57b6RYQJYB5v1Li2A==,type:str] + username: ENC[AES256_GCM,data:ii7f/N3KXNmkvv5Sh2wsPlqRRh0LHjjExQkm+kK+lRCVwe8FDNI=,iv:rqk6+iWqGYh/fgDPGqcRZ/fyRROM6a144PCrVWokm+o=,tag:9krQyW6n7QCiQ5vNM/wozQ==,type:str] + password: ENC[AES256_GCM,data:CjC/nUzk/7LH5oSA3cF4KRjmzLMa3QAIodKxAKTTB8ruEFHdQAUDCfm9m2zco4lLykwG6JX5JiWClI26C2O+wg==,iv:KzXdwlH0EeI79hgTEL0iRSsPxHeZTXusuRqQQe+YbG4=,tag:5xIfUhfUS2qUFLoiRYwTlw==,type:str] + hub: + config: + GitHubOAuthenticator: + client_id: ENC[AES256_GCM,data:dhNb/AwKFr/2s1+RUIsndJ5EKC4=,iv:6Rzm5NBgBZcHrOyWFYi1qib1iraWoRpeoPCo42wUD10=,tag:JIKjxJQ8I8fM+Z+MFRfsEA==,type:str] + client_secret: ENC[AES256_GCM,data:LQedpZelm6SO8KAFBpV5fHFYmTOXyzz75HoKC+N9D3/lH7TXZFxl9w==,iv:isCaLvhi3aU/mOLEtsRegzSVxcMh4HRV2kCB3Klrsq0=,tag:c3zZ2190eyzsuK1Mv2t6CQ==,type:str] +sops: + kms: [] + gcp_kms: + - resource_id: projects/two-eye-two-see/locations/global/keyRings/sops-keys/cryptoKeys/similar-hubs + created_at: "2023-09-18T19:00:41Z" + enc: CiUA4OM7eFioG9yDgVwKtc0cYrU65GNcqMSDuUgnuXuq3KW9dRI6EkkAq2nhVV2TFrZOq5jktjMd4TQF1lwH/08tAyGd3vMfBmdd3Xdy3bAUUHhrPXcK6QabMRYdXPzQzgB+oBGaqOsJO7D7jT9NpeCn + azure_kv: [] + hc_vault: [] + age: [] + lastmodified: "2024-03-01T09:20:50Z" + mac: ENC[AES256_GCM,data:/H85LAsXQBVCUly595+EGHmTN7jw8Mspsj1GFfyVBjUj/QYJResChPxuDfEf02PD+h0Va9UK0xQVBLVJFuO8nVKLY9WAGG5agAiTHYudhHGsPpzGSL5jkjDkQrqNhyAWunkh7euqbMIDKLU8Yn4LXVU1JaD6DrbNXQJcnJbAbAM=,iv:jDS6yvbuz57WixC/5qKrZztd0IXeLsAJXzYj8zsOBzI=,tag:O9JM6fBZuD8quswUFe7cJQ==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.7.3 diff --git a/config/clusters/opensci/enc-support.secret.values.yaml b/config/clusters/opensci/enc-support.secret.values.yaml new file mode 100644 index 0000000000..d19f4384f8 --- /dev/null +++ b/config/clusters/opensci/enc-support.secret.values.yaml @@ -0,0 +1,17 @@ +prometheusIngressAuthSecret: + username: ENC[AES256_GCM,data:NAA8fg7Oin4CLlFAR0/q9I0FpqHHsyXntce7by5Fg4B4PVGnmboc6hiHKbcvq4gkhFu3JkSPO/UZOnAi/vPXVA==,iv:t21nYjrvFgJ5vRM/8FDGwMrlGiLYsE9R4+BFxjDf91c=,tag:gnyjHQCSfouHljf6AzQKiw==,type:str] + password: ENC[AES256_GCM,data:Dcu0hyudGn0a51p8yutj2MbMv0ydSS/ewXqDF1xAVsWV75DUikNjnqxKZWbBDmjZisi+lMiRHZEUrxaszcGE9w==,iv:AM/9clOgMS80/JdZb1UC9fZNliQwhD8BJdZmSk7+Xow=,tag:kV4UPf5vPkTjESJGNusS9A==,type:str] +sops: + kms: [] + gcp_kms: + - resource_id: projects/two-eye-two-see/locations/global/keyRings/sops-keys/cryptoKeys/similar-hubs + created_at: "2024-02-21T14:04:13Z" + enc: CiUA4OM7eH9GfolTeTic397lI94/FljLr1s7Hz77OOck8EsW/8pvEkkAXoW3JqTtm0UrLSlLBrebh+OQ+6ik5KFXmY8Xxl9ICv9kSnbz7CFBvAHlhrP7W7/NK8ZP5+6NnOivp0SZlghOW9M5Lv5ZpnQc + azure_kv: [] + hc_vault: [] + age: [] + lastmodified: "2024-02-21T14:04:13Z" + mac: ENC[AES256_GCM,data:IlvuWpEYx2Qjp12hXHSnQdS9RYU1lwH2L8CgE1Js2cXRzhFr+cRalpJ68h/G8uzJOowb/WI5svSBB372HoX0FSf3kRmUPBdj0nI0Leb7kzZoOWJfVsCNh+Z7KVqs7iBnCWRtIr5v00eD6WUf1Q93qgxgcuZgAewd8rzaiixN0GE=,iv:I6/qm0v3/kBt+zFXm/jM29wo3ZW8p6xT9cfI+ruJGCQ=,tag:F2rZt0kHoHSsdECq0IY7eQ==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.7.3 diff --git a/config/clusters/opensci/sciencecore.values.yaml b/config/clusters/opensci/sciencecore.values.yaml new file mode 100644 index 0000000000..60688b0691 --- /dev/null +++ b/config/clusters/opensci/sciencecore.values.yaml @@ -0,0 +1,144 @@ +jupyterhub: + ingress: + hosts: + - sciencecore.opensci.2i2c.cloud + tls: + - secretName: https-auto-tls + hosts: + - sciencecore.opensci.2i2c.cloud + custom: + 2i2c: + add_staff_user_ids_to_admin_users: true + add_staff_user_ids_of_type: "github" + jupyterhubConfigurator: + enabled: false + homepage: + templateVars: + org: + name: Sciencecore + url: https://2i2c.org + logo_url: https://2i2c.org/media/logo.png + designed_by: + name: 2i2c + url: https://2i2c.org + operated_by: + name: 2i2c + url: https://2i2c.org + funded_by: + name: "" + url: "" + singleuser: + profileList: + - display_name: "Only Profile Available, this info is not shown in the UI" + slug: only-choice + profile_options: + image: + display_name: Image + unlisted_choice: &profile_list_unlisted_choice + enabled: True + display_name: "Custom image" + validation_regex: "^.+:.+$" + validation_message: "Must be a publicly available docker image, of form :" + display_name_in_choices: "Specify an existing docker image" + description_in_choices: "Use a pre-existing docker image from a public docker registry (dockerhub, quay, etc)" + kubespawner_override: + image: "{value}" + choices: + pangeo: + display_name: Pangeo Notebook Image + description: "Python image with scientific, dask and geospatial tools" + kubespawner_override: + image: pangeo/pangeo-notebook:2023.09.11 + geospatial: + display_name: Rocker Geospatial + description: "R image with RStudio, the tidyverse & Geospatial tools" + default: true + slug: geospatial + kubespawner_override: + image: rocker/binder:4.3 + # Launch into RStudio after the user logs in + default_url: /rstudio + # Ensures container working dir is homedir + # https://github.com/2i2c-org/infrastructure/issues/2559 + working_dir: /home/rstudio + scipy: + display_name: Jupyter SciPy Notebook + slug: scipy + kubespawner_override: + image: jupyter/scipy-notebook:2023-06-26 + resources: + display_name: Resource Allocation + choices: + mem_3_7: + display_name: 3.7 GB RAM, upto 3.7 CPUs + kubespawner_override: + mem_guarantee: 3982682624 + mem_limit: 3982682624 + cpu_guarantee: 0.46875 + cpu_limit: 3.75 + node_selector: + node.kubernetes.io/instance-type: r5.xlarge + default: true + mem_7_4: + display_name: 7.4 GB RAM, upto 3.7 CPUs + kubespawner_override: + mem_guarantee: 7965365248 + mem_limit: 7965365248 + cpu_guarantee: 0.9375 + cpu_limit: 3.75 + node_selector: + node.kubernetes.io/instance-type: r5.xlarge + mem_14_8: + display_name: 14.8 GB RAM, upto 3.7 CPUs + kubespawner_override: + mem_guarantee: 15930730496 + mem_limit: 15930730496 + cpu_guarantee: 1.875 + cpu_limit: 3.75 + node_selector: + node.kubernetes.io/instance-type: r5.xlarge + mem_29_7: + display_name: 29.7 GB RAM, upto 3.7 CPUs + kubespawner_override: + mem_guarantee: 31861460992 + mem_limit: 31861460992 + cpu_guarantee: 3.75 + cpu_limit: 3.75 + node_selector: + node.kubernetes.io/instance-type: r5.xlarge + + hub: + allowNamedServers: true + services: + binder: + # FIXME: ref https://github.com/2i2c-org/binderhub-service/issues/57 + # for something more readable and requiring less copy-pasting + url: http://sciencecore-binderhub-service:8090 + image: + name: quay.io/2i2c/dynamic-image-building-experiment + tag: "0.0.1-0.dev.git.7567.ha4162031" + config: + JupyterHub: + authenticator_class: github + GitHubOAuthenticator: + oauth_callback_url: https://sciencecore.opensci.2i2c.cloud/hub/oauth_callback + allowed_organizations: + - 2i2c-demo-hub-access + - ScienceCore + scope: + - read:org + + extraConfig: + enable-fancy-profiles: | + from jupyterhub_fancy_profiles import setup_ui + setup_ui(c) + +binderhub-service: + enabled: true + config: + BinderHub: + image_prefix: quay.io/2i2c-opensci-sciencecore/binderhub-service- + # The password to the registry is stored encrypted in the hub's encrypted config file + buildPodsRegistryCredentials: + server: "https://quay.io" + username: "2i2c-opensci-sciencecore+image_manager" diff --git a/config/clusters/opensci/support.values.yaml b/config/clusters/opensci/support.values.yaml new file mode 100644 index 0000000000..d1d7ba1c91 --- /dev/null +++ b/config/clusters/opensci/support.values.yaml @@ -0,0 +1,34 @@ +prometheusIngressAuthSecret: + enabled: true + +cluster-autoscaler: + enabled: true + autoDiscovery: + clusterName: opensci + awsRegion: us-west-2 + +prometheus: + server: + ingress: + enabled: true + hosts: + - prometheus.opensci.2i2c.cloud + tls: + - secretName: prometheus-tls + hosts: + - prometheus.opensci.2i2c.cloud + +grafana: + grafana.ini: + server: + root_url: https://grafana.opensci.2i2c.cloud/ + auth.github: + enabled: true + allowed_organizations: 2i2c-org + ingress: + hosts: + - grafana.opensci.2i2c.cloud + tls: + - secretName: grafana-tls + hosts: + - grafana.opensci.2i2c.cloud diff --git a/docs/helper-programs/generate-hub-features-table.py b/docs/helper-programs/generate-hub-features-table.py index fc7a15e31b..8e7e1e1e5c 100644 --- a/docs/helper-programs/generate-hub-features-table.py +++ b/docs/helper-programs/generate-hub-features-table.py @@ -96,7 +96,7 @@ def retrieve_jupyterhub_config_dict(hub_config): return hub_config["binderhub"]["jupyterhub"] return hub_config["jupyterhub"] except KeyError: - return + return {} def parse_yaml_config_value_files_for_features(cluster_path, hub_values_files): @@ -168,20 +168,20 @@ def build_options_list_entry(hub, hub_count, values_files_features, terraform_fe return { "domain": domain, "dedicated cluster": False if hub_count else True, - "dedicated nodepool": values_files_features["dedicated_nodepool"], + "dedicated nodepool": values_files_features.get("dedicated_nodepool", False), "user buckets (scratch/persistent)": terraform_features.get( hub["name"], {} ).get("user_buckets", False), "requester pays for buckets storage": terraform_features.get( hub["name"], {} ).get("requestor_pays", False), - "authenticator": values_files_features["authenticator"], - "user anonymisation": values_files_features["anonymization"], - "admin access to allusers dirs": values_files_features["allusers"], + "authenticator": values_files_features.get("authenticator", None), + "user anonymisation": values_files_features.get("anonymization", False), + "admin access to allusers dirs": values_files_features.get("allusers", False), "community domain": False if "2i2c.cloud" in domain else True, - "custom login page": values_files_features["custom_homepage"], - "custom html pages": values_files_features["custom_html"], - "gh-scoped-creds": values_files_features["gh_scoped_creds"], + "custom login page": values_files_features.get("custom_homepage", False), + "custom html pages": values_files_features.get("custom_html", False), + "gh-scoped-creds": values_files_features.get("gh_scoped_creds", False), # "static web pages": # "GPUs": # "profile lists": diff --git a/docs/topic/access-creds/cloud-auth.md b/docs/topic/access-creds/cloud-auth.md index f05d3326d9..50b41bbd23 100644 --- a/docs/topic/access-creds/cloud-auth.md +++ b/docs/topic/access-creds/cloud-auth.md @@ -102,11 +102,12 @@ To do so, follow these steps: after logging in for current set of IAM users. 2. Go to the [SSO users](https://console.aws.amazon.com/singlesignon/identity/home?region=us-east-1#!/users) page, and create an appropriate entry for the new user. - a. Their username should match their `2i2c.org` email address. - b. Use their `2i2c.org` address as email address. - c. Other than email and username, provide as little info as possible. This would be + + - Their username should match their `2i2c.org` email address. + - Use their `2i2c.org` address as email address. + - Other than email and username, provide as little info as possible. This would be just first name, last name and display name. - d. "Send an email to the user with password setup instructions". + - "Send an email to the user with password setup instructions". 3. Add them to the `2i2c-engineers` group. This gives them access to all the other AWS accounts we create. 4. Create the account! They'll receive an email with appropriate instructions. diff --git a/eksctl/opensci.jsonnet b/eksctl/opensci.jsonnet new file mode 100644 index 0000000000..f81a65c043 --- /dev/null +++ b/eksctl/opensci.jsonnet @@ -0,0 +1,128 @@ +/* + This file is a jsonnet template of a eksctl's cluster configuration file, + that is used with the eksctl CLI to both update and initialize an AWS EKS + based cluster. + + This file has in turn been generated from eksctl/template.jsonnet which is + relevant to compare with for changes over time. + + To use jsonnet to generate an eksctl configuration file from this, do: + + jsonnet opensci.jsonnet > opensci.eksctl.yaml + + References: + - https://eksctl.io/usage/schema/ +*/ +local ng = import "./libsonnet/nodegroup.jsonnet"; + +// place all cluster nodes here +local clusterRegion = "us-west-2"; +local masterAzs = ["us-west-2a", "us-west-2b", "us-west-2c"]; +local nodeAz = "us-west-2a"; + +// Node definitions for notebook nodes. Config here is merged +// with our notebook node definition. +// A `node.kubernetes.io/instance-type label is added, so pods +// can request a particular kind of node with a nodeSelector +local notebookNodes = [ + { instanceType: "r5.xlarge" }, + { instanceType: "r5.4xlarge" }, + { instanceType: "r5.16xlarge" }, +]; +local daskNodes = []; + + +{ + apiVersion: 'eksctl.io/v1alpha5', + kind: 'ClusterConfig', + metadata+: { + name: "opensci", + region: clusterRegion, + version: "1.28", + }, + availabilityZones: masterAzs, + iam: { + withOIDC: true, + }, + // If you add an addon to this config, run the create addon command. + // + // eksctl create addon --config-file=opensci.eksctl.yaml + // + addons: [ + { + // aws-ebs-csi-driver ensures that our PVCs are bound to PVs that + // couple to AWS EBS based storage, without it expect to see pods + // mounting a PVC failing to schedule and PVC resources that are + // unbound. + // + // Related docs: https://docs.aws.amazon.com/eks/latest/userguide/managing-ebs-csi.html + // + name: 'aws-ebs-csi-driver', + version: "latest", + wellKnownPolicies: { + ebsCSIController: true, + }, + }, + ], + nodeGroups: [ + ng + { + namePrefix: 'core', + nameSuffix: 'a', + nameIncludeInstanceType: false, + availabilityZones: [nodeAz], + ssh: { + publicKeyPath: 'ssh-keys/opensci.key.pub' + }, + instanceType: "r5.xlarge", + minSize: 1, + maxSize: 6, + labels+: { + "hub.jupyter.org/node-purpose": "core", + "k8s.dask.org/node-purpose": "core" + }, + }, + ] + [ + ng + { + namePrefix: 'nb', + availabilityZones: [nodeAz], + minSize: 0, + maxSize: 500, + instanceType: n.instanceType, + ssh: { + publicKeyPath: 'ssh-keys/opensci.key.pub' + }, + labels+: { + "hub.jupyter.org/node-purpose": "user", + "k8s.dask.org/node-purpose": "scheduler" + }, + taints+: { + "hub.jupyter.org_dedicated": "user:NoSchedule", + "hub.jupyter.org/dedicated": "user:NoSchedule" + }, + } + n for n in notebookNodes + ] + ( if daskNodes != null then + [ + ng + { + namePrefix: 'dask', + availabilityZones: [nodeAz], + minSize: 0, + maxSize: 500, + ssh: { + publicKeyPath: 'ssh-keys/opensci.key.pub' + }, + labels+: { + "k8s.dask.org/node-purpose": "worker" + }, + taints+: { + "k8s.dask.org_dedicated" : "worker:NoSchedule", + "k8s.dask.org/dedicated" : "worker:NoSchedule" + }, + instancesDistribution+: { + onDemandBaseCapacity: 0, + onDemandPercentageAboveBaseCapacity: 0, + spotAllocationStrategy: "capacity-optimized", + }, + } + n for n in daskNodes + ] else [] + ) +} \ No newline at end of file diff --git a/eksctl/ssh-keys/opensci.key.pub b/eksctl/ssh-keys/opensci.key.pub new file mode 100644 index 0000000000..0a3046478f --- /dev/null +++ b/eksctl/ssh-keys/opensci.key.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCronsz3J+j6Lbp8BJ/mpTn25/1dgmpZQpoLjEqflTtK0Ur/JBZ+P05aD6eLKy89ANyD9RC/x1oHgDwIAtN7zoCG6QJA+8dWUhqlESYzfQ4ieSW36oi1k4VxPLVUU4zVMPr71tdBaFPOsE3jTEWJxSeDZ8YjzHa0sr5X8HzuACO0V5HG8FnSxsXCPAAtwR1VdZF9xRjhQ8u4yLhDz/kTb1vXCjgz0CcHIs7b7ZSxY/tLxIeCTjfyw3SSvHPTZRgZgoqY5mXwgxq4mLQ96u19u6T9zW1qTjHqVQ2OhuAfIC7LzKtZq2S+RlPiv9xoP1+vK2OULZMtdH/u8VHXGGws4iiPVo+xuADtIKAVZCXgrkvHP//bN4pFObzxsxWa2w1m+mGcXKLmHWy3sqSYZHIJwYhcXQXSSiZF56fFKKtCoT/0Ddk6FdMr9WqNjc3Tq12AfXQgobn0JbDUhYRl5bLVfIo7urshDEfTN+fRvcMnDKCNEmnT/ihn5Ki9BPP+Q8NTOU= georgiana@georgiana.local diff --git a/eksctl/ssh-keys/secret/opensci.key b/eksctl/ssh-keys/secret/opensci.key new file mode 100644 index 0000000000..98a5dff54a --- /dev/null +++ b/eksctl/ssh-keys/secret/opensci.key @@ -0,0 +1,21 @@ +{ + "data": "ENC[AES256_GCM,data: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,iv:MGI6Z8r7iSq607tG9zNZro9vcm1QyQfonvPDALwcGos=,tag:M50exMUMyB/XP/g74gNCwQ==,type:str]", + "sops": { + "kms": null, + "gcp_kms": [ + { + "resource_id": "projects/two-eye-two-see/locations/global/keyRings/sops-keys/cryptoKeys/similar-hubs", + "created_at": "2024-02-21T14:04:12Z", + "enc": "CiUA4OM7eKhKM5t1tiyTheQFNUS/u/5AvlqlPcTYNvKLlsPgIhHAEkkAXoW3JqdiQg/3FWiPJ9Gww+hh66YZI5UEaRalxl93S47xW0YbFcL3NFirOHbZXflEHW6Wtp+Wco9XoyL7uBmeQBKcOzLTivvo" + } + ], + "azure_kv": null, + "hc_vault": null, + "age": null, + "lastmodified": "2024-02-21T14:04:13Z", + "mac": "ENC[AES256_GCM,data:ZPkBK+cIm8zAW8Zji/bk5GzlAnz2H3maYzgiHw+dssSyAf2gVZPl8fy5+jHFfg0GfG2Cy2dwEgURNYg7Aa4UsVUq1Xkr/ppl0ZtjMqjCxs0DPK5K3jXjpA7vgvhgPCGBAaZOsA2camkAFPQrUtzWUkLq5D0LmdJGyg1bvCHKVPg=,iv:XvtMDUT3uHmw6moSNcrhhIpPHE8t8FLZl6dtkywAl6c=,tag:peyJkyp/sjAegeOnpyVllQ==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.7.3" + } +} \ No newline at end of file diff --git a/helm-charts/basehub/values.yaml b/helm-charts/basehub/values.yaml index 0a0679d1b6..2195ce12db 100644 --- a/helm-charts/basehub/values.yaml +++ b/helm-charts/basehub/values.yaml @@ -7,6 +7,36 @@ userServiceAccount: binderhub-service: enabled: false + nodeSelector: + hub.jupyter.org/node-purpose: core + service: + port: 8090 + # The DaemonSet at https://github.com/2i2c-org/binderhub-service/blob/main/binderhub-service/templates/docker-api/daemonset.yaml + # will start a docker-api pod on a user node. + # It starts the [dockerd](https://docs.docker.com/engine/reference/commandline/dockerd/) daemon, + # that will be accessible via a unix socket, mounted by the build. + # The docker-api pod must run on the same node as the builder pods. + dockerApi: + nodeSelector: + hub.jupyter.org/node-purpose: user + tolerations: + # Tolerate tainted jupyterhub user nodes + - key: hub.jupyter.org_dedicated + value: user + effect: NoSchedule + - key: hub.jupyter.org/dedicated + value: user + effect: NoSchedule + config: + BinderHub: + base_url: /services/binder + use_registry: true + KubernetesBuildExecutor: + # Get ourselves a newer repo2docker! + build_image: quay.io/jupyterhub/repo2docker:2023.06.0-8.gd414e99 + node_selector: + # Schedule builder pods to run on user nodes only + hub.jupyter.org/node-purpose: user ingressBasicAuth: enabled: false diff --git a/terraform/aws/projects/opensci.tfvars b/terraform/aws/projects/opensci.tfvars new file mode 100644 index 0000000000..7472d20bcb --- /dev/null +++ b/terraform/aws/projects/opensci.tfvars @@ -0,0 +1,28 @@ +region = "us-west-2" + +cluster_name = "opensci" + +cluster_nodes_location = "us-west-2a" + +user_buckets = { + "scratch-staging" : { + "delete_after" : 7 + }, + "scratch" : { + "delete_after" : 7 + }, +} + + +hub_cloud_permissions = { + "staging" : { + requestor_pays : true, + bucket_admin_access : ["scratch-staging"], + extra_iam_policy : "" + }, + "prod" : { + requestor_pays : true, + bucket_admin_access : ["scratch"], + extra_iam_policy : "" + }, +} \ No newline at end of file