diff --git a/modules/looker-core/README.md b/modules/looker-core/README.md new file mode 100644 index 000000000..55c34dc37 --- /dev/null +++ b/modules/looker-core/README.md @@ -0,0 +1,195 @@ +# Looker Core module + +This module manages the creation of a [Looker Core instance](https://cloud.google.com/looker/docs/looker-core). + +This module accepts Oauth client ID and secret in the input variable `oauth_config` in case you have +already [set up an oauth client and credentials](https://cloud.google.com/looker/docs/looker-core-create-oauth). +If that is not the case it is possible to specify support_email in the same variable `oauth_config` for a default oauth +client id and secret setup within the terraform script, be aware that **such an oauth client id is not suitable for +authenticating end users**, and it is only used to provision the looker core instance. +You'll still be forced to create a new oauth and update the looker core instance from the console (or gcloud) as there +is no terraform support for these resources. + + +> [!WARNING] +> Please be aware that, at the time of this writing, deleting the looker core instance via terraform is not possible due +> to https://github.com/hashicorp/terraform-provider-google/issues/19467. The work-around is to delete the instance from the +> console (or gcloud with force option) and remove the corresponding resource from the terraform state. + + + +* [Looker Core module](#looker-core-module) + * [Examples](#examples) + * [Simple example](#simple-example) + * [Looker Core private instance with PSA](#looker-core-private-instance-with-psa) + * [Looker Core full example](#looker-core-full-example) + * [Variables](#variables) + * [Outputs](#outputs) + + + +## Examples + +### Simple example + +This example shows how to set up a public Looker Core instance. + +```hcl +module "looker" { + source = "./fabric/modules/looker-core" + project_id = var.project_id + region = var.region + name = "looker" + network_config = { + public = true + } + oauth_config = { + support_email = "support@google.com" + } +} +# tftest modules=1 resources=3 inventory=simple.yaml +``` + +### Looker Core private instance with PSA + +```hcl +module "project" { + source = "./fabric/modules/project" + billing_account = var.billing_account_id + parent = var.folder_id + name = "looker" + prefix = var.prefix + services = [ + "servicenetworking.googleapis.com", + "looker.googleapis.com", + ] +} + +module "vpc" { + source = "./fabric/modules/net-vpc" + project_id = module.project.project_id + name = "my-network" + psa_configs = [ + { + ranges = { looker = "10.60.0.0/16" } + } + ] +} + +module "looker" { + source = "./fabric/modules/looker-core" + project_id = module.project.project_id + region = var.region + name = "looker" + network_config = { + psa_config = { + network = module.vpc.id + } + } + oauth_config = { + support_email = "support@google.com" + } + platform_edition = "LOOKER_CORE_ENTERPRISE_ANNUAL" +} +# tftest modules=3 resources=16 inventory=psa.yaml +``` + +### Looker Core full example + +```hcl +module "project" { + source = "./fabric/modules/project" + billing_account = var.billing_account_id + parent = var.folder_id + name = "looker" + prefix = var.prefix + services = [ + "cloudkms.googleapis.com", + "iap.googleapis.com", + "looker.googleapis.com", + "servicenetworking.googleapis.com" + ] +} + +module "vpc" { + source = "./fabric/modules/net-vpc" + project_id = module.project.project_id + name = "my-network" + psa_configs = [ + { + ranges = { looker = "10.60.0.0/16" } + } + ] +} + +module "kms" { + source = "./fabric/modules/kms" + project_id = module.project.project_id + keyring = { + location = var.region + name = "keyring" + } + keys = { + "key-regional" = { + } + } + iam = { + "roles/cloudkms.cryptoKeyEncrypterDecrypter" = [ + module.project.service_agents.looker.iam_email + ] + } +} + +module "looker" { + source = "./fabric/modules/looker-core" + project_id = module.project.project_id + region = var.region + name = "looker" + admin_settings = { + allowed_email_domains = ["google.com"] + } + encryption_config = { + kms_key_name = module.kms.keys.key-regional.id + } + network_config = { + psa_config = { + network = module.vpc.id + } + } + oauth_config = { + client_id = "xxxxxxxxx" + client_secret = "xxxxxxxx" + } + platform_edition = "LOOKER_CORE_ENTERPRISE_ANNUAL" +} +# tftest modules=4 resources=22 inventory=full.yaml +``` + +## Variables + +| name | description | type | required | default | +|---|---|:---:|:---:|:---:| +| [name](variables.tf#L85) | Name of the looker core instance. | string | ✓ | | +| [network_config](variables.tf#L90) | Network configuration for cluster and instance. Only one between psa_config and psc_config can be used. | object({…}) | ✓ | | +| [oauth_config](variables.tf#L108) | Looker Core Oauth config. Either client ID and secret (existing oauth client) or support email (temporary internal oauth client setup) must be specified. | object({…}) | ✓ | | +| [project_id](variables.tf#L141) | The ID of the project where this instances will be created. | string | ✓ | | +| [region](variables.tf#L146) | Region for the Looker core instance. | string | ✓ | | +| [admin_settings](variables.tf#L17) | Looker Core admins settings. | object({…}) | | null | +| [encryption_config](variables.tf#L26) | Set encryption configuration. KMS name format: 'projects/[PROJECT]/locations/[REGION]/keyRings/[RING]/cryptoKeys/[KEY_NAME]'. | object({…}) | | null | +| [maintenance_config](variables.tf#L35) | Set maintenance window configuration and maintenance deny period (up to 90 days). Date format: 'yyyy-mm-dd'. | object({…}) | | {} | +| [platform_edition](variables.tf#L121) | Platform editions for a Looker instance. Each edition maps to a set of instance features, like its size. | string | | "LOOKER_CORE_TRIAL" | +| [prefix](variables.tf#L131) | Optional prefix used to generate instance names. | string | | null | + +## Outputs + +| name | description | sensitive | +|---|---|:---:| +| [egress_public_ip](outputs.tf#L17) | Public IP address of Looker instance for egress. | | +| [id](outputs.tf#L22) | Fully qualified primary instance id. | | +| [ingress_private_ip](outputs.tf#L27) | Private IP address of Looker instance for ingress. | | +| [ingress_public_ip](outputs.tf#L32) | Public IP address of Looker instance for ingress. | | +| [instance](outputs.tf#L37) | Looker Core instance resource. | ✓ | +| [instance_name](outputs.tf#L43) | Name of the looker instance. | | +| [looker_uri](outputs.tf#L48) | Looker core URI. | | +| [looker_version](outputs.tf#L53) | Looker core version. | | + diff --git a/modules/looker-core/main.tf b/modules/looker-core/main.tf new file mode 100644 index 000000000..389faf4fc --- /dev/null +++ b/modules/looker-core/main.tf @@ -0,0 +1,108 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + bootstrap_oauth_client = var.oauth_config.client_secret == null || var.oauth_config.client_id == null + looker_instance_name = "${local.prefix}${var.name}" + oauth_client_id = local.bootstrap_oauth_client ? google_iap_client.looker_client[0].client_id : var.oauth_config.client_id + oauth_client_secret = local.bootstrap_oauth_client ? google_iap_client.looker_client[0].secret : var.oauth_config.client_secret + prefix = var.prefix == null ? "" : "${var.prefix}-" +} + +resource "google_looker_instance" "looker" { + project = var.project_id + name = local.looker_instance_name + consumer_network = try(var.network_config.psa_config.network, null) + platform_edition = var.platform_edition + private_ip_enabled = try(var.network_config.psa_config.enable_private_ip, null) + public_ip_enabled = coalesce(var.network_config.public, false) || try(var.network_config.psa_config.enable_public_ip, false) + region = var.region + reserved_range = try(var.network_config.psa_config.allocated_ip_range, null) + + oauth_config { + client_id = local.oauth_client_id + client_secret = local.oauth_client_secret + } + + dynamic "admin_settings" { + for_each = var.admin_settings != null ? [""] : [] + content { + allowed_email_domains = var.admin_settings.allowed_email_domains + } + } + dynamic "deny_maintenance_period" { + for_each = var.maintenance_config.deny_maintenance_period != null ? [1] : [] + content { + start_date { + year = var.maintenance_config.deny_maintenance_period.start_date.year + month = var.maintenance_config.deny_maintenance_period.start_date.month + day = var.maintenance_config.deny_maintenance_period.start_date.day + } + end_date { + year = var.maintenance_config.deny_maintenance_period.start_date.year + month = var.maintenance_config.deny_maintenance_period.start_date.month + day = var.maintenance_config.deny_maintenance_period.start_date.day + } + time { + hours = var.maintenance_config.deny_maintenance_period.start_times.hours + minutes = var.maintenance_config.deny_maintenance_period.start_times.minutes + seconds = var.maintenance_config.deny_maintenance_period.start_times.seconds + nanos = var.maintenance_config.deny_maintenance_period.start_times.nanos + } + } + } + dynamic "encryption_config" { + for_each = var.encryption_config != null ? [""] : [] + content { + kms_key_name = var.encryption_config.kms_key_name + } + } + dynamic "maintenance_window" { + for_each = var.maintenance_config.maintenance_window != null ? [""] : [] + content { + day_of_week = var.maintenance_config.maintenance_window.day + start_time { + hours = var.maintenance_config.maintenance_window.start_times.hours + minutes = var.maintenance_config.maintenance_window.start_times.minutes + seconds = var.maintenance_config.maintenance_window.start_times.seconds + nanos = var.maintenance_config.maintenance_window.start_times.nanos + } + } + } + lifecycle { + ignore_changes = [ + oauth_config # do not replace target oauth client updated on the console with default one + ] + } +} + + +# Only "Organization Internal" brands can be created programmatically via API. To convert it into an external brands please use the GCP Console. +resource "google_iap_brand" "looker_brand" { + count = local.bootstrap_oauth_client ? 1 : 0 + support_email = var.oauth_config.support_email + # application_title = "Looker Core Application" + application_title = "Cloud IAP protected Application" + project = var.project_id +} + +# Only internal org clients can be created via declarative tools. External clients must be manually created via the GCP console. +# This is a temporary IAP oauth client to be replaced after Looker Core is provisioned. +resource "google_iap_client" "looker_client" { + count = local.bootstrap_oauth_client ? 1 : 0 + display_name = "Looker Core default oauth client." + brand = google_iap_brand.looker_brand[0].name +} diff --git a/modules/looker-core/outputs.tf b/modules/looker-core/outputs.tf new file mode 100644 index 000000000..9c2af964f --- /dev/null +++ b/modules/looker-core/outputs.tf @@ -0,0 +1,56 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +output "egress_public_ip" { + description = "Public IP address of Looker instance for egress." + value = google_looker_instance.looker.egress_public_ip +} + +output "id" { + description = "Fully qualified primary instance id." + value = google_looker_instance.looker.id +} + +output "ingress_private_ip" { + description = "Private IP address of Looker instance for ingress." + value = google_looker_instance.looker.ingress_private_ip +} + +output "ingress_public_ip" { + description = "Public IP address of Looker instance for ingress." + value = google_looker_instance.looker.ingress_public_ip +} + +output "instance" { + description = "Looker Core instance resource." + value = google_looker_instance.looker.id + sensitive = true +} + +output "instance_name" { + description = "Name of the looker instance." + value = google_looker_instance.looker.name +} + +output "looker_uri" { + description = "Looker core URI." + value = google_looker_instance.looker.looker_uri +} + +output "looker_version" { + description = "Looker core version." + value = google_looker_instance.looker.looker_version +} diff --git a/modules/looker-core/variables.tf b/modules/looker-core/variables.tf new file mode 100644 index 000000000..ab54d1f0a --- /dev/null +++ b/modules/looker-core/variables.tf @@ -0,0 +1,149 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +variable "admin_settings" { + description = "Looker Core admins settings." + type = object({ + allowed_email_domains = list(string) + }) + default = null + nullable = true +} + +variable "encryption_config" { + description = "Set encryption configuration. KMS name format: 'projects/[PROJECT]/locations/[REGION]/keyRings/[RING]/cryptoKeys/[KEY_NAME]'." + type = object({ + kms_key_name = string + }) + default = null + nullable = true +} + +variable "maintenance_config" { + description = "Set maintenance window configuration and maintenance deny period (up to 90 days). Date format: 'yyyy-mm-dd'." + type = object({ + maintenance_window = optional(object({ + day = optional(string, "SUNDAY") + start_time = optional(object({ + hours = optional(number, 23) + minutes = optional(number, 0) + seconds = optional(number, 0) + nanos = optional(number, 0) + }), {}) + }), null) + deny_maintenance_period = optional(object({ + start_date = object({ + year = number + month = number + day = number + }) + end_date = object({ + year = number + month = number + day = number + }) + start_time = optional(object({ + hours = optional(number, 23) + minutes = optional(number, 0) + seconds = optional(number, 0) + nanos = optional(number, 0) + }), {}) + }), null) + }) + default = {} + validation { + condition = ( + try(var.maintenance_config.maintenance_window, null) == null ? true : ( + var.maintenance_config.start_time.hours >= 0 && + var.maintenance_config.start_time.hours <= 23 && + var.maintenance_config.start_time.minutes == 0 && + var.maintenance_config.start_time.seconds == 0 && + var.maintenance_config.start_time.nanos == 0 && + # Maintenance window day validation + contains([ + "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY" + ], var.maintenance_config.day) + ) + ) + error_message = "Maintenance window day must be between 1 and 7, maintenance window hour must be between 0 and 23 and maintenance window update_track must be 'stable' or 'canary'." + } +} + +variable "name" { + description = "Name of the looker core instance." + type = string +} + +variable "network_config" { + description = "Network configuration for cluster and instance. Only one between psa_config and psc_config can be used." + type = object({ + psa_config = optional(object({ + network = string + allocated_ip_range = optional(string) + enable_public_ip = optional(bool, false) + enable_private_ip = optional(bool, true) + })) + public = optional(bool, false) + }) + nullable = false + validation { + condition = (coalesce(var.network_config.public, false)) == (var.network_config.psa_config == null) + error_message = "Please specify either psa_config or public to true." + } +} + +variable "oauth_config" { + description = "Looker Core Oauth config. Either client ID and secret (existing oauth client) or support email (temporary internal oauth client setup) must be specified." + type = object({ + client_id = optional(string, null) + client_secret = optional(string, null) + support_email = optional(string, null) + }) + validation { + condition = (var.oauth_config.client_id == null && var.oauth_config.client_secret == null) != (var.oauth_config.support_email == null) + error_message = "Please specify either client_id and client_secret or support email." + } +} + +variable "platform_edition" { + description = "Platform editions for a Looker instance. Each edition maps to a set of instance features, like its size." + type = string + default = "LOOKER_CORE_TRIAL" + validation { + condition = contains(["LOOKER_CORE_TRIAL", "LOOKER_CORE_STANDARD", "LOOKER_CORE_STANDARD_ANNUAL", "LOOKER_CORE_ENTERPRISE_ANNUAL", "LOOKER_CORE_EMBED_ANNUAL"], var.platform_edition) + error_message = "Platform Edition type must one of 'LOOKER_CORE_TRIAL', 'LOOKER_CORE_STANDARD', 'LOOKER_CORE_STANDARD_ANNUAL', 'LOOKER_CORE_ENTERPRISE_ANNUAL', 'LOOKER_CORE_EMBED_ANNUAL'." + } +} + +variable "prefix" { + description = "Optional prefix used to generate instance names." + type = string + default = null + validation { + condition = var.prefix != "" + error_message = "Prefix cannot be empty, please use null instead." + } +} + +variable "project_id" { + description = "The ID of the project where this instances will be created." + type = string +} + +variable "region" { + description = "Region for the Looker core instance." + type = string +} diff --git a/modules/looker-core/versions.tf b/modules/looker-core/versions.tf new file mode 100644 index 000000000..f569ce5af --- /dev/null +++ b/modules/looker-core/versions.tf @@ -0,0 +1,29 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Fabric release: v35.0.0 + +terraform { + required_version = ">= 1.7.4" + required_providers { + google = { + source = "hashicorp/google" + version = ">= 6.1.0, < 7.0.0" # tftest + } + google-beta = { + source = "hashicorp/google-beta" + version = ">= 6.1.0, < 7.0.0" # tftest + } + } +} diff --git a/tests/examples_e2e/setup_module/main.tf b/tests/examples_e2e/setup_module/main.tf index accf880fd..82b59b840 100644 --- a/tests/examples_e2e/setup_module/main.tf +++ b/tests/examples_e2e/setup_module/main.tf @@ -41,7 +41,9 @@ locals { "dns.googleapis.com", "eventarc.googleapis.com", "iam.googleapis.com", + "iap.googleapis.com", "logging.googleapis.com", + "looker.googleapis.com", "monitoring.googleapis.com", "networkconnectivity.googleapis.com", "pubsub.googleapis.com", diff --git a/tests/modules/looker_core/examples/full.yaml b/tests/modules/looker_core/examples/full.yaml new file mode 100644 index 000000000..0a84020c7 --- /dev/null +++ b/tests/modules/looker_core/examples/full.yaml @@ -0,0 +1,204 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +values: + module.kms.google_kms_crypto_key.default["key-regional"]: + effective_labels: + goog-terraform-provisioned: 'true' + labels: null + name: key-regional + purpose: ENCRYPT_DECRYPT + rotation_period: null + skip_initial_version_creation: false + terraform_labels: + goog-terraform-provisioned: 'true' + timeouts: null + module.kms.google_kms_key_ring.default[0]: + location: europe-west8 + name: keyring + project: test-looker + timeouts: null + module.kms.google_kms_key_ring_iam_binding.authoritative["roles/cloudkms.cryptoKeyEncrypterDecrypter"]: + condition: [] + role: roles/cloudkms.cryptoKeyEncrypterDecrypter + module.looker.google_looker_instance.looker: + admin_settings: + - allowed_email_domains: + - google.com + custom_domain: [] + deny_maintenance_period: [] + encryption_config: + - {} + maintenance_window: [] + name: looker + oauth_config: + - client_id: xxxxxxxxx + client_secret: xxxxxxxx + platform_edition: LOOKER_CORE_ENTERPRISE_ANNUAL + private_ip_enabled: true + project: test-looker + public_ip_enabled: false + region: europe-west8 + reserved_range: null + timeouts: null + user_metadata: [] + module.project.google_project.project[0]: + auto_create_network: false + billing_account: 123456-123456-123456 + deletion_policy: DELETE + effective_labels: + goog-terraform-provisioned: 'true' + folder_id: '1122334455' + labels: null + name: test-looker + org_id: null + project_id: test-looker + terraform_labels: + goog-terraform-provisioned: 'true' + timeouts: null + module.project.google_project_iam_member.service_agents["cloudkms"]: + condition: [] + project: test-looker + role: roles/cloudkms.serviceAgent + module.project.google_project_iam_member.service_agents["looker"]: + condition: [] + project: test-looker + role: roles/looker.serviceAgent + module.project.google_project_iam_member.service_agents["service-networking"]: + condition: [] + project: test-looker + role: roles/servicenetworking.serviceAgent + module.project.google_project_service.project_services["cloudkms.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-looker + service: cloudkms.googleapis.com + timeouts: null + module.project.google_project_service.project_services["iap.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-looker + service: iap.googleapis.com + timeouts: null + module.project.google_project_service.project_services["looker.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-looker + service: looker.googleapis.com + timeouts: null + module.project.google_project_service.project_services["servicenetworking.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-looker + service: servicenetworking.googleapis.com + timeouts: null + module.project.google_project_service_identity.default["cloudkms.googleapis.com"]: + project: test-looker + service: cloudkms.googleapis.com + timeouts: null + module.project.google_project_service_identity.default["iap.googleapis.com"]: + project: test-looker + service: iap.googleapis.com + timeouts: null + module.project.google_project_service_identity.default["looker.googleapis.com"]: + project: test-looker + service: looker.googleapis.com + timeouts: null + module.project.google_project_service_identity.default["servicenetworking.googleapis.com"]: + project: test-looker + service: servicenetworking.googleapis.com + timeouts: null + module.vpc.google_compute_global_address.psa_ranges["servicenetworking-googleapis-com-looker"]: + address: 10.60.0.0 + address_type: INTERNAL + description: null + effective_labels: + goog-terraform-provisioned: 'true' + ip_version: null + labels: null + name: servicenetworking-googleapis-com-looker + prefix_length: 16 + project: test-looker + purpose: VPC_PEERING + terraform_labels: + goog-terraform-provisioned: 'true' + timeouts: null + module.vpc.google_compute_network.network[0]: + auto_create_subnetworks: false + delete_default_routes_on_create: false + description: Terraform-managed. + enable_ula_internal_ipv6: null + name: my-network + network_firewall_policy_enforcement_order: AFTER_CLASSIC_FIREWALL + project: test-looker + routing_mode: GLOBAL + timeouts: null + module.vpc.google_compute_network_peering_routes_config.psa_routes["servicenetworking.googleapis.com"]: + export_custom_routes: false + import_custom_routes: false + network: my-network + project: test-looker + timeouts: null + module.vpc.google_compute_route.gateway["private-googleapis"]: + description: Terraform-managed. + dest_range: 199.36.153.8/30 + name: my-network-private-googleapis + network: my-network + next_hop_gateway: default-internet-gateway + next_hop_ilb: null + next_hop_instance: null + next_hop_vpn_tunnel: null + priority: 1000 + project: test-looker + tags: null + timeouts: null + module.vpc.google_compute_route.gateway["restricted-googleapis"]: + description: Terraform-managed. + dest_range: 199.36.153.4/30 + name: my-network-restricted-googleapis + network: my-network + next_hop_gateway: default-internet-gateway + next_hop_ilb: null + next_hop_instance: null + next_hop_vpn_tunnel: null + priority: 1000 + project: test-looker + tags: null + timeouts: null + module.vpc.google_service_networking_connection.psa_connection["servicenetworking.googleapis.com"]: + deletion_policy: null + reserved_peering_ranges: + - servicenetworking-googleapis-com-looker + service: servicenetworking.googleapis.com + timeouts: null + update_on_creation_fail: null + +counts: + google_compute_global_address: 1 + google_compute_network: 1 + google_compute_network_peering_routes_config: 1 + google_compute_route: 2 + google_kms_crypto_key: 1 + google_kms_key_ring: 1 + google_kms_key_ring_iam_binding: 1 + google_looker_instance: 1 + google_project: 1 + google_project_iam_member: 3 + google_project_service: 4 + google_project_service_identity: 4 + google_service_networking_connection: 1 + modules: 4 + resources: 22 + +outputs: {} diff --git a/tests/modules/looker_core/examples/psa.yaml b/tests/modules/looker_core/examples/psa.yaml new file mode 100644 index 000000000..af56f18de --- /dev/null +++ b/tests/modules/looker_core/examples/psa.yaml @@ -0,0 +1,164 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +values: + module.looker.google_iap_brand.looker_brand[0]: + application_title: Cloud IAP protected Application + project: test-looker + support_email: support@google.com + timeouts: null + module.looker.google_iap_client.looker_client[0]: + display_name: Looker Core default oauth client. + timeouts: null + module.looker.google_looker_instance.looker: + admin_settings: [] + custom_domain: [] + deny_maintenance_period: [] + maintenance_window: [] + name: looker + oauth_config: + - {} + platform_edition: LOOKER_CORE_ENTERPRISE_ANNUAL + private_ip_enabled: true + project: test-looker + public_ip_enabled: false + region: europe-west8 + reserved_range: null + timeouts: null + user_metadata: [] + module.project.google_project.project[0]: + auto_create_network: false + billing_account: 123456-123456-123456 + deletion_policy: DELETE + effective_labels: + goog-terraform-provisioned: 'true' + folder_id: '1122334455' + labels: null + name: test-looker + org_id: null + project_id: test-looker + terraform_labels: + goog-terraform-provisioned: 'true' + timeouts: null + module.project.google_project_iam_member.service_agents["looker"]: + condition: [] + project: test-looker + role: roles/looker.serviceAgent + module.project.google_project_iam_member.service_agents["service-networking"]: + condition: [] + project: test-looker + role: roles/servicenetworking.serviceAgent + module.project.google_project_service.project_services["looker.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-looker + service: looker.googleapis.com + timeouts: null + module.project.google_project_service.project_services["servicenetworking.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-looker + service: servicenetworking.googleapis.com + timeouts: null + module.project.google_project_service_identity.default["looker.googleapis.com"]: + project: test-looker + service: looker.googleapis.com + timeouts: null + module.project.google_project_service_identity.default["servicenetworking.googleapis.com"]: + project: test-looker + service: servicenetworking.googleapis.com + timeouts: null + module.vpc.google_compute_global_address.psa_ranges["servicenetworking-googleapis-com-looker"]: + address: 10.60.0.0 + address_type: INTERNAL + description: null + effective_labels: + goog-terraform-provisioned: 'true' + ip_version: null + labels: null + name: servicenetworking-googleapis-com-looker + prefix_length: 16 + project: test-looker + purpose: VPC_PEERING + terraform_labels: + goog-terraform-provisioned: 'true' + timeouts: null + module.vpc.google_compute_network.network[0]: + auto_create_subnetworks: false + delete_default_routes_on_create: false + description: Terraform-managed. + enable_ula_internal_ipv6: null + name: my-network + network_firewall_policy_enforcement_order: AFTER_CLASSIC_FIREWALL + project: test-looker + routing_mode: GLOBAL + timeouts: null + module.vpc.google_compute_network_peering_routes_config.psa_routes["servicenetworking.googleapis.com"]: + export_custom_routes: false + import_custom_routes: false + network: my-network + project: test-looker + timeouts: null + module.vpc.google_compute_route.gateway["private-googleapis"]: + description: Terraform-managed. + dest_range: 199.36.153.8/30 + name: my-network-private-googleapis + network: my-network + next_hop_gateway: default-internet-gateway + next_hop_ilb: null + next_hop_instance: null + next_hop_vpn_tunnel: null + priority: 1000 + project: test-looker + tags: null + timeouts: null + module.vpc.google_compute_route.gateway["restricted-googleapis"]: + description: Terraform-managed. + dest_range: 199.36.153.4/30 + name: my-network-restricted-googleapis + network: my-network + next_hop_gateway: default-internet-gateway + next_hop_ilb: null + next_hop_instance: null + next_hop_vpn_tunnel: null + priority: 1000 + project: test-looker + tags: null + timeouts: null + module.vpc.google_service_networking_connection.psa_connection["servicenetworking.googleapis.com"]: + deletion_policy: null + reserved_peering_ranges: + - servicenetworking-googleapis-com-looker + service: servicenetworking.googleapis.com + timeouts: null + update_on_creation_fail: null + +counts: + google_compute_global_address: 1 + google_compute_network: 1 + google_compute_network_peering_routes_config: 1 + google_compute_route: 2 + google_iap_brand: 1 + google_iap_client: 1 + google_looker_instance: 1 + google_project: 1 + google_project_iam_member: 2 + google_project_service: 2 + google_project_service_identity: 2 + google_service_networking_connection: 1 + modules: 3 + resources: 16 + +outputs: {} + diff --git a/tests/modules/looker_core/examples/simple.yaml b/tests/modules/looker_core/examples/simple.yaml new file mode 100644 index 000000000..a14d02cef --- /dev/null +++ b/tests/modules/looker_core/examples/simple.yaml @@ -0,0 +1,49 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +values: + module.looker.google_iap_brand.looker_brand[0]: + application_title: Cloud IAP protected Application + project: project-id + support_email: support@google.com + timeouts: null + module.looker.google_iap_client.looker_client[0]: + display_name: Looker Core default oauth client. + timeouts: null + module.looker.google_looker_instance.looker: + admin_settings: [] + consumer_network: null + custom_domain: [] + deny_maintenance_period: [] + maintenance_window: [] + name: looker + oauth_config: + - {} + platform_edition: LOOKER_CORE_TRIAL + private_ip_enabled: false + project: project-id + public_ip_enabled: true + region: europe-west8 + reserved_range: null + timeouts: null + user_metadata: [] + +counts: + google_iap_brand: 1 + google_iap_client: 1 + google_looker_instance: 1 + modules: 1 + resources: 3 + +outputs: {}