From 2de5410ada6c14f9752b9fbfd331f0e79dab2c5e Mon Sep 17 00:00:00 2001 From: lcaggio Date: Thu, 14 Jul 2022 17:47:05 +0200 Subject: [PATCH 1/5] First commit --- .../data-solutions/data-playground/README.md | 46 ++++----- .../data-playground/diagram.png | Bin 27555 -> 18824 bytes .../data-solutions/data-playground/main.tf | 91 +++++++++++++++--- .../data-solutions/data-playground/outputs.tf | 11 ++- .../data-playground/variables.tf | 13 +-- .../data_playground/fixture/main.tf | 1 + .../data_playground/test_plan.py | 4 +- 7 files changed, 114 insertions(+), 52 deletions(-) diff --git a/examples/data-solutions/data-playground/README.md b/examples/data-solutions/data-playground/README.md index fb75969505..df663199d7 100644 --- a/examples/data-solutions/data-playground/README.md +++ b/examples/data-solutions/data-playground/README.md @@ -13,31 +13,31 @@ This sample creates several distinct groups of resources: - projects - Service Project configured for GCE instances and GCS buckets - networking - - VPC network - - One default subnet + - VPC network with a default subnet and CloudNat - Firewall rules for [SSH access via IAP](https://cloud.google.com/iap/docs/using-tcp-forwarding) and open communication within the VPC -- Vertex AI notebook - - One Jupyter lab notebook instance with public access -- GCS - - One bucket initial bucket - - +- Vertex AI Workbench notebook with a specialized Service Account +- One bucket bucket +- One BigQuery dataset + ## Variables -| name | description | type | required | default | -| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -------- | ------------ | -| project\_id | Project id, references existing project if \`project\_create\` is null. | string | ✓ | | -| location | The location where resources will be deployed | string | | europe | -| region | The region where resources will be deployed. | string | | europe-west1 | -| project\_create | Provide values if project creation is needed, uses existing project if null. Parent format: folders/folder\_id or organizations/org\_id | object({…}) | | null | -| prefix | Unique prefix used for resource names. Not used for project if 'project\_create' is null. | string | | dp | -| service\_encryption\_keys | Cloud KMS to use to encrypt different services. Key location should match service region. | object({…}) | | null | -| vpc\_config | Parameters to create a simple VPC for the Data Playground | object({…}) | | {...} | + +| name | description | type | required | default | +|---|---|:---:|:---:|:---:| +| [prefix](variables.tf#L36) | Unique prefix used for resource names. Not used for project if 'project_create' is null. | string | ✓ | | +| [project_id](variables.tf#L22) | Project id, references existing project if `project_create` is null. | string | ✓ | | +| [location](variables.tf#L16) | The location where resources will be deployed. | string | | "EU" | +| [project_create](variables.tf#L27) | Provide values if project creation is needed, uses existing project if null. Parent format: folders/folder_id or organizations/org_id | object({…}) | | null | +| [region](variables.tf#L41) | The region where resources will be deployed. | string | | "europe-west1" | +| [vpc_config](variables.tf#L55) | Parameters to create a simple VPC for the Data Playground | object({…}) | | {…} | ## Outputs -| Name | Description | -| ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | -| bucket | GCS Bucket URL. | -| project | Project id | -| vpc | VPC Network name | -| notebook | Vertex AI notebook name | + +| name | description | sensitive | +|---|---|:---:| +| [bucket](outputs.tf#L15) | GCS Bucket URL. | | +| [notebook](outputs.tf#L20) | Vertex AI notebook | | +| [project](outputs.tf#L25) | Project id | | +| [vpc](outputs.tf#L30) | VPC Network | | + + diff --git a/examples/data-solutions/data-playground/diagram.png b/examples/data-solutions/data-playground/diagram.png index 9da71fd09edc9e7aa171658766a8e0224bf04bbb..b2d2d8ebafba06e2e09c3080413ecb4ab0204c26 100644 GIT binary patch literal 18824 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 CKt(|S literal 27555 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 Date: Thu, 14 Jul 2022 17:57:51 +0200 Subject: [PATCH 2/5] Fix README --- examples/data-solutions/data-playground/README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/examples/data-solutions/data-playground/README.md b/examples/data-solutions/data-playground/README.md index df663199d7..3af52718ee 100644 --- a/examples/data-solutions/data-playground/README.md +++ b/examples/data-solutions/data-playground/README.md @@ -1,6 +1,6 @@ # Data Playground -This example creates a minimum viable template for a data experimentation project with the needed APIs enabled, basic VPC and Firewall set in place, GCS bucket and an AI notebook to get started. +This example creates a minimum viable template for a data experimentation project with the needed APIs enabled, basic VPC and Firewall set in place, BigQuesy dataset, GCS bucket and an AI notebook to get started. This is the high level diagram: @@ -10,8 +10,7 @@ This is the high level diagram: This sample creates several distinct groups of resources: -- projects - - Service Project configured for GCE instances and GCS buckets +- project - networking - VPC network with a default subnet and CloudNat - Firewall rules for [SSH access via IAP](https://cloud.google.com/iap/docs/using-tcp-forwarding) and open communication within the VPC @@ -29,15 +28,15 @@ This sample creates several distinct groups of resources: | [location](variables.tf#L16) | The location where resources will be deployed. | string | | "EU" | | [project_create](variables.tf#L27) | Provide values if project creation is needed, uses existing project if null. Parent format: folders/folder_id or organizations/org_id | object({…}) | | null | | [region](variables.tf#L41) | The region where resources will be deployed. | string | | "europe-west1" | -| [vpc_config](variables.tf#L55) | Parameters to create a simple VPC for the Data Playground | object({…}) | | {…} | +| [vpc_config](variables.tf#L57) | Parameters to create a VPC. | object({…}) | | {…} | ## Outputs | name | description | sensitive | |---|---|:---:| | [bucket](outputs.tf#L15) | GCS Bucket URL. | | -| [notebook](outputs.tf#L20) | Vertex AI notebook | | -| [project](outputs.tf#L25) | Project id | | -| [vpc](outputs.tf#L30) | VPC Network | | +| [notebook](outputs.tf#L20) | Vertex AI notebook details. | | +| [project](outputs.tf#L28) | Project id | | +| [vpc](outputs.tf#L33) | VPC Network | | From f22af2e27f72b606c6ff95c42cb34cd0effbc9ae Mon Sep 17 00:00:00 2001 From: lcaggio Date: Fri, 15 Jul 2022 10:04:07 +0200 Subject: [PATCH 3/5] Improve READMEs --- examples/data-solutions/README.md | 4 +-- .../data-solutions/data-playground/README.md | 31 +++++++++++++++++-- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/examples/data-solutions/README.md b/examples/data-solutions/README.md index 23fabdcc27..e91e4873d5 100644 --- a/examples/data-solutions/README.md +++ b/examples/data-solutions/README.md @@ -36,6 +36,6 @@ This [example](./cloudsql-multiregion/) creates a [Cloud SQL instance](https://c ### Data Playground starter with Cloud Vertex AI Notebook and GCS - -This [example](./data-playground/) creates a [Vertex AI Notebook](https://cloud.google.com/vertex-ai/docs/workbench/introduction) running under a VPC network and a starter GCS bucket to store inputs and outputs of data experiments. + +This [example](./data-playground/) creates a [Vertex AI Notebook](https://cloud.google.com/vertex-ai/docs/workbench/introduction) running on a VPC with a private IP and a dedicated Service Account. A GCS bucket and a BigQuery dataset are created to store inputs and outputs of data experiments.
\ No newline at end of file diff --git a/examples/data-solutions/data-playground/README.md b/examples/data-solutions/data-playground/README.md index 3af52718ee..c88aba06f5 100644 --- a/examples/data-solutions/data-playground/README.md +++ b/examples/data-solutions/data-playground/README.md @@ -1,6 +1,6 @@ # Data Playground -This example creates a minimum viable template for a data experimentation project with the needed APIs enabled, basic VPC and Firewall set in place, BigQuesy dataset, GCS bucket and an AI notebook to get started. +This example creates a minimum viable architecture for a data experimentation project with the needed APIs enabled, VPC and Firewall set in place, BigQuesy dataset, GCS bucket and an AI notebook to get started. This is the high level diagram: @@ -14,9 +14,34 @@ This sample creates several distinct groups of resources: - networking - VPC network with a default subnet and CloudNat - Firewall rules for [SSH access via IAP](https://cloud.google.com/iap/docs/using-tcp-forwarding) and open communication within the VPC -- Vertex AI Workbench notebook with a specialized Service Account -- One bucket bucket +- Vertex AI Workbench notebook configured with a private IP and using a dedicated Service Account +- One GCS bucket - One BigQuery dataset + +## Deploy your enviroment +We assume the identiy running the following steps has the following role: + +- resourcemanager.projectCreator in case a new project will be created. +- owner on the project in case you use an existing project. + +Run Terraform init: +``` +$ terraform init +``` + +Configure the Terraform variable in your terraform.tfvars file. You need to spefify at least the following variables: +``` +prefix = "prefix" +project_id = "data-001" +``` + +You can run now: +``` +$ terraform apply +``` + +You can now connect to the Vertex AI notbook to perform your data analysy. + ## Variables From fff141d8e0307f68db899945ceaa07a78f2a8905 Mon Sep 17 00:00:00 2001 From: lcaggio Date: Fri, 15 Jul 2022 10:43:56 +0200 Subject: [PATCH 4/5] Implement PR comments. --- examples/data-solutions/data-playground/main.tf | 6 +++--- examples/data-solutions/data-playground/outputs.tf | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/examples/data-solutions/data-playground/main.tf b/examples/data-solutions/data-playground/main.tf index a01b7bf151..b6b23d97ed 100644 --- a/examples/data-solutions/data-playground/main.tf +++ b/examples/data-solutions/data-playground/main.tf @@ -80,9 +80,9 @@ module "vpc-firewall" { network = module.vpc.name admin_ranges = [var.vpc_config.ip_cidr_range] custom_rules = { - #TODO Remove and rely on 'ssh' tag once issues/9273 is fixed + #TODO Remove and rely on 'ssh' tag once terraform-provider-google/issues/9273 is fixed ("${var.prefix}-iap") = { - description = "Enable SSH from IAP on Notboks." + description = "Enable SSH from IAP on Notebooks." direction = "INGRESS" action = "allow" sources = [] @@ -169,6 +169,6 @@ resource "google_notebooks_instance" "playground" { service_account = module.service-account-notebook.email - #TODO Uncomment once issues/9273 is fixed + #TODO Uncomment once terraform-provider-google/issues/9273 is fixed # tags = ["ssh"] } diff --git a/examples/data-solutions/data-playground/outputs.tf b/examples/data-solutions/data-playground/outputs.tf index 9ab608cf89..03db250609 100644 --- a/examples/data-solutions/data-playground/outputs.tf +++ b/examples/data-solutions/data-playground/outputs.tf @@ -17,6 +17,11 @@ output "bucket" { value = module.bucket.url } +output "dataset" { + description = "GCS Bucket URL." + value = module.dataset.id +} + output "notebook" { description = "Vertex AI notebook details." value = { From 6fdeeabf96e357420bfbb6b9bfc147d587e3a3f3 Mon Sep 17 00:00:00 2001 From: lcaggio Date: Fri, 15 Jul 2022 11:04:46 +0200 Subject: [PATCH 5/5] Fix --- examples/data-solutions/data-playground/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/data-solutions/data-playground/README.md b/examples/data-solutions/data-playground/README.md index c88aba06f5..91a06145c0 100644 --- a/examples/data-solutions/data-playground/README.md +++ b/examples/data-solutions/data-playground/README.md @@ -41,7 +41,6 @@ $ terraform apply ``` You can now connect to the Vertex AI notbook to perform your data analysy. - ## Variables @@ -60,8 +59,9 @@ You can now connect to the Vertex AI notbook to perform your data analysy. | name | description | sensitive | |---|---|:---:| | [bucket](outputs.tf#L15) | GCS Bucket URL. | | -| [notebook](outputs.tf#L20) | Vertex AI notebook details. | | -| [project](outputs.tf#L28) | Project id | | -| [vpc](outputs.tf#L33) | VPC Network | | +| [dataset](outputs.tf#L20) | GCS Bucket URL. | | +| [notebook](outputs.tf#L25) | Vertex AI notebook details. | | +| [project](outputs.tf#L33) | Project id | | +| [vpc](outputs.tf#L38) | VPC Network | |