From b5f1ec4e33b4752e4dc781dafe2d9c7f800f1a65 Mon Sep 17 00:00:00 2001 From: ionel_panaitescu Date: Tue, 26 Oct 2021 17:38:14 +0300 Subject: [PATCH 1/5] Added Oracle Cloud Foundation Terraform Solution - Departmental data warehousing - business domain analytics Solutions --- .../database/adw/main.tf | 30 + .../database/adw/outputs.tf | 6 + .../database/adw/variables.tf | 27 + .../datacatalog/main.tf | 12 + .../datacatalog/outputs.tf | 10 + .../datacatalog/variables.tf | 10 + .../cloud-foundation-library/oac/main.tf | 37 ++ .../cloud-foundation-library/oac/outputs.tf | 7 + .../cloud-foundation-library/oac/variables.tf | 22 + .../object-storage/main.tf | 19 + .../object-storage/outputs.tf | 9 + .../object-storage/variables.tf | 18 + .../cloud-foundation-library/odi/main.tf | 26 + .../cloud-foundation-library/odi/outputs.tf | 9 + .../cloud-foundation-library/odi/variables.tf | 15 + .../network/vcn-basic/main.tf | 2 +- .../Departmental DWH - Full Solution.zip | Bin 0 -> 54466 bytes ...tmental DWH - Small Footprint Solution.zip | Bin 0 -> 41260 bytes .../solutions-for-oracle-res-mgr/README.md | 6 + .../Departmental-DWH-Full-Solution/.gitignore | 3 + .../CONTRIBUTING.md | 33 ++ .../Departmental-DWH-Full-Solution/LICENSE | 27 + .../Departmental-DWH-Full-Solution/README.md | 530 ++++++++++++++++++ .../Departmental-DWH-Full-Solution/local.tf | 379 +++++++++++++ .../Departmental-DWH-Full-Solution/main.tf | 275 +++++++++ .../modules/adw_subsystem/main.tf | 28 + .../modules/adw_subsystem/outputs.tf | 6 + .../modules/adw_subsystem/variables.tf | 26 + .../modules/datacatalog_subsystem/main.tf | 14 + .../modules/datacatalog_subsystem/outputs.tf | 6 + .../datacatalog_subsystem/variables.tf | 18 + .../modules/oac_subsystem/main.tf | 24 + .../modules/oac_subsystem/outputs.tf | 11 + .../modules/oac_subsystem/variables.tf | 55 ++ .../modules/object-storage_subsystem/main.tf | 18 + .../object-storage_subsystem/outputs.tf | 6 + .../object-storage_subsystem/variables.tf | 35 ++ .../modules/odi_subsystem/main.tf | 17 + .../modules/odi_subsystem/outputs.tf | 6 + .../modules/odi_subsystem/variables.tf | 27 + .../Departmental-DWH-Full-Solution/outputs.tf | 26 + .../provider.tf | 11 + .../schema.yaml | 464 +++++++++++++++ .../variables.tf | 285 ++++++++++ .../.gitignore | 3 + .../CONTRIBUTING.md | 33 ++ .../LICENSE | 27 + .../README.md | 447 +++++++++++++++ .../local.tf | 379 +++++++++++++ .../main.tf | 235 ++++++++ .../modules/adw_subsystem/main.tf | 28 + .../modules/adw_subsystem/outputs.tf | 6 + .../modules/adw_subsystem/variables.tf | 26 + .../modules/oac_subsystem/main.tf | 24 + .../modules/oac_subsystem/outputs.tf | 11 + .../modules/oac_subsystem/variables.tf | 55 ++ .../outputs.tf | 15 + .../provider.tf | 11 + .../schema.yaml | 373 ++++++++++++ .../variables.tf | 244 ++++++++ cloud-foundation/solutions/README.md | 8 + 61 files changed, 4519 insertions(+), 1 deletion(-) create mode 100644 cloud-foundation/modules/cloud-foundation-library/database/adw/main.tf create mode 100644 cloud-foundation/modules/cloud-foundation-library/database/adw/outputs.tf create mode 100644 cloud-foundation/modules/cloud-foundation-library/database/adw/variables.tf create mode 100644 cloud-foundation/modules/cloud-foundation-library/datacatalog/main.tf create mode 100644 cloud-foundation/modules/cloud-foundation-library/datacatalog/outputs.tf create mode 100644 cloud-foundation/modules/cloud-foundation-library/datacatalog/variables.tf create mode 100644 cloud-foundation/modules/cloud-foundation-library/oac/main.tf create mode 100644 cloud-foundation/modules/cloud-foundation-library/oac/outputs.tf create mode 100644 cloud-foundation/modules/cloud-foundation-library/oac/variables.tf create mode 100644 cloud-foundation/modules/cloud-foundation-library/object-storage/main.tf create mode 100644 cloud-foundation/modules/cloud-foundation-library/object-storage/outputs.tf create mode 100644 cloud-foundation/modules/cloud-foundation-library/object-storage/variables.tf create mode 100644 cloud-foundation/modules/cloud-foundation-library/odi/main.tf create mode 100644 cloud-foundation/modules/cloud-foundation-library/odi/outputs.tf create mode 100644 cloud-foundation/modules/cloud-foundation-library/odi/variables.tf create mode 100644 cloud-foundation/solutions-for-oracle-res-mgr/Departmental DWH - Full Solution.zip create mode 100644 cloud-foundation/solutions-for-oracle-res-mgr/Departmental DWH - Small Footprint Solution.zip create mode 100644 cloud-foundation/solutions-for-oracle-res-mgr/README.md create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/.gitignore create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/CONTRIBUTING.md create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/LICENSE create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/README.md create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/local.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/main.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/adw_subsystem/main.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/adw_subsystem/outputs.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/adw_subsystem/variables.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/datacatalog_subsystem/main.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/datacatalog_subsystem/outputs.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/datacatalog_subsystem/variables.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/oac_subsystem/main.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/oac_subsystem/outputs.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/oac_subsystem/variables.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/object-storage_subsystem/main.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/object-storage_subsystem/outputs.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/object-storage_subsystem/variables.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/odi_subsystem/main.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/odi_subsystem/outputs.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/odi_subsystem/variables.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/outputs.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/provider.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/schema.yaml create mode 100644 cloud-foundation/solutions/Departmental-DWH-Full-Solution/variables.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/.gitignore create mode 100644 cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/CONTRIBUTING.md create mode 100644 cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/LICENSE create mode 100644 cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/README.md create mode 100644 cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/local.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/main.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/adw_subsystem/main.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/adw_subsystem/outputs.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/adw_subsystem/variables.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/oac_subsystem/main.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/oac_subsystem/outputs.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/oac_subsystem/variables.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/outputs.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/provider.tf create mode 100644 cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/schema.yaml create mode 100644 cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/variables.tf create mode 100644 cloud-foundation/solutions/README.md diff --git a/cloud-foundation/modules/cloud-foundation-library/database/adw/main.tf b/cloud-foundation/modules/cloud-foundation-library/database/adw/main.tf new file mode 100644 index 0000000..f2fe9a0 --- /dev/null +++ b/cloud-foundation/modules/cloud-foundation-library/database/adw/main.tf @@ -0,0 +1,30 @@ +# # Copyright © 2021, Oracle and/or its affiliates. +# # All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +resource "oci_database_autonomous_database" "adw" { + for_each = { + for k,v in var.adw_params : k => v if v.compartment_id != "" + } + admin_password = each.value.database_admin_password + compartment_id = each.value.compartment_id + cpu_core_count = each.value.adw_cpu_core_count + data_storage_size_in_tbs = each.value.adw_size_in_tbs + db_name = each.value.adw_db_name + display_name = each.value.adw_db_name + db_workload = each.value.adw_db_workload + db_version = each.value.adw_db_version + is_auto_scaling_enabled = each.value.adw_enable_auto_scaling + is_free_tier = each.value.adw_is_free_tier + license_model = each.value.adw_license_model + # subnet_id = each.value.subnet_id + # nsg_ids = each.value.nsg_ids + defined_tags = each.value.defined_tags +} + +resource "oci_database_autonomous_database_wallet" "autonomous_data_warehouse_wallet" { + for_each = var.adw_params + autonomous_database_id = oci_database_autonomous_database.adw[each.key].id + password = each.value.database_wallet_password + base64_encode_content = true +} + diff --git a/cloud-foundation/modules/cloud-foundation-library/database/adw/outputs.tf b/cloud-foundation/modules/cloud-foundation-library/database/adw/outputs.tf new file mode 100644 index 0000000..98ffdff --- /dev/null +++ b/cloud-foundation/modules/cloud-foundation-library/database/adw/outputs.tf @@ -0,0 +1,6 @@ +# # Copyright © 2021, Oracle and/or its affiliates. +# # All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +output "ADW_Service_Console_URL" { + value = join(", ", [for x in oci_database_autonomous_database.adw : x.service_console_url]) +} diff --git a/cloud-foundation/modules/cloud-foundation-library/database/adw/variables.tf b/cloud-foundation/modules/cloud-foundation-library/database/adw/variables.tf new file mode 100644 index 0000000..ac1848f --- /dev/null +++ b/cloud-foundation/modules/cloud-foundation-library/database/adw/variables.tf @@ -0,0 +1,27 @@ +# # Copyright © 2021, Oracle and/or its affiliates. +# # All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +variable "adw_params" { + type = map(object({ + compartment_id = string + adw_cpu_core_count = number + adw_size_in_tbs = number + adw_db_name = string + adw_db_workload = string + adw_db_version = string + adw_enable_auto_scaling = bool + adw_is_free_tier = bool + adw_license_model = string + database_admin_password = string + database_wallet_password = string + # subnet_id = string + # nsg_ids = list(string) + defined_tags = map(string) + })) +} + + + + + + \ No newline at end of file diff --git a/cloud-foundation/modules/cloud-foundation-library/datacatalog/main.tf b/cloud-foundation/modules/cloud-foundation-library/datacatalog/main.tf new file mode 100644 index 0000000..fcad9ff --- /dev/null +++ b/cloud-foundation/modules/cloud-foundation-library/datacatalog/main.tf @@ -0,0 +1,12 @@ +// Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +resource "oci_datacatalog_catalog" "this" { + for_each = { + for k,v in var.datacatalog_params : k => v if v.compartment_id != "" + } + compartment_id = each.value.compartment_id + display_name = each.value.catalog_display_name + defined_tags = each.value.defined_tags +} + diff --git a/cloud-foundation/modules/cloud-foundation-library/datacatalog/outputs.tf b/cloud-foundation/modules/cloud-foundation-library/datacatalog/outputs.tf new file mode 100644 index 0000000..4dea57e --- /dev/null +++ b/cloud-foundation/modules/cloud-foundation-library/datacatalog/outputs.tf @@ -0,0 +1,10 @@ +// Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +output "datacatalog" { + value = { + for datacatalog in oci_datacatalog_catalog.this: + datacatalog.display_name => datacatalog.display_name + } +} + diff --git a/cloud-foundation/modules/cloud-foundation-library/datacatalog/variables.tf b/cloud-foundation/modules/cloud-foundation-library/datacatalog/variables.tf new file mode 100644 index 0000000..b4d39fb --- /dev/null +++ b/cloud-foundation/modules/cloud-foundation-library/datacatalog/variables.tf @@ -0,0 +1,10 @@ +// Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +variable "datacatalog_params" { + type = map(object({ + compartment_id = string + catalog_display_name = string + defined_tags = map(string) + })) +} diff --git a/cloud-foundation/modules/cloud-foundation-library/oac/main.tf b/cloud-foundation/modules/cloud-foundation-library/oac/main.tf new file mode 100644 index 0000000..f52cdae --- /dev/null +++ b/cloud-foundation/modules/cloud-foundation-library/oac/main.tf @@ -0,0 +1,37 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +resource "oci_analytics_analytics_instance" "oac" { + for_each = { + for k,v in var.oac_params : k => v if v.compartment_id != "" + } + compartment_id = each.value.compartment_id + feature_set = each.value.analytics_instance_feature_set + license_type = each.value.analytics_instance_license_type + name = each.value.analytics_instance_hostname + description = "Oracle Analytics Cloud" + idcs_access_token = each.value.analytics_instance_idcs_access_token + #Optional + defined_tags = each.value.defined_tags + network_endpoint_details { + #Required + network_endpoint_type = each.value.analytics_instance_network_endpoint_details_network_endpoint_type + + #Optional + subnet_id = each.value.subnet_id + vcn_id = each.value.vcn_id + whitelisted_ips = each.value.analytics_instance_network_endpoint_details_whitelisted_ips + + whitelisted_vcns { + #Optional + id = each.value.analytics_instance_network_endpoint_details_whitelisted_vcns_id + whitelisted_ips = each.value.whitelisted_ips + } + } + capacity { + capacity_type = each.value.analytics_instance_capacity_capacity_type + capacity_value = each.value.analytics_instance_capacity_value + } +} + + diff --git a/cloud-foundation/modules/cloud-foundation-library/oac/outputs.tf b/cloud-foundation/modules/cloud-foundation-library/oac/outputs.tf new file mode 100644 index 0000000..ce235d9 --- /dev/null +++ b/cloud-foundation/modules/cloud-foundation-library/oac/outputs.tf @@ -0,0 +1,7 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +output "Analytics_URL" { + value = join(", ", [for x in oci_analytics_analytics_instance.oac : x.service_url]) +} + diff --git a/cloud-foundation/modules/cloud-foundation-library/oac/variables.tf b/cloud-foundation/modules/cloud-foundation-library/oac/variables.tf new file mode 100644 index 0000000..52f14f2 --- /dev/null +++ b/cloud-foundation/modules/cloud-foundation-library/oac/variables.tf @@ -0,0 +1,22 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +variable "oac_params" { + type = map(object({ + compartment_id = string + analytics_instance_feature_set = string + analytics_instance_license_type = string + analytics_instance_hostname = string + analytics_instance_idcs_access_token = string + analytics_instance_capacity_capacity_type = string + analytics_instance_capacity_value = number + defined_tags = map(string) + analytics_instance_network_endpoint_details_network_endpoint_type = string + subnet_id = string + vcn_id = string + analytics_instance_network_endpoint_details_whitelisted_ips = list(string) + analytics_instance_network_endpoint_details_whitelisted_vcns_id = string + whitelisted_ips = list(string) + })) +} + diff --git a/cloud-foundation/modules/cloud-foundation-library/object-storage/main.tf b/cloud-foundation/modules/cloud-foundation-library/object-storage/main.tf new file mode 100644 index 0000000..5da8e9e --- /dev/null +++ b/cloud-foundation/modules/cloud-foundation-library/object-storage/main.tf @@ -0,0 +1,19 @@ +// Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +data "oci_objectstorage_namespace" "os" { + compartment_id = var.tenancy_ocid +} + +resource "oci_objectstorage_bucket" "os" { + for_each = { + for k,v in var.bucket_params : k => v if v.compartment_id != "" + } + compartment_id = each.value.compartment_id + name = each.value.name + namespace = data.oci_objectstorage_namespace.os.namespace + access_type = each.value.access_type + storage_tier = each.value.storage_tier + object_events_enabled = each.value.events_enabled + defined_tags = each.value.defined_tags +} diff --git a/cloud-foundation/modules/cloud-foundation-library/object-storage/outputs.tf b/cloud-foundation/modules/cloud-foundation-library/object-storage/outputs.tf new file mode 100644 index 0000000..2c08bbf --- /dev/null +++ b/cloud-foundation/modules/cloud-foundation-library/object-storage/outputs.tf @@ -0,0 +1,9 @@ +// Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +output "buckets" { + value = { + for bucket in oci_objectstorage_bucket.os: + bucket.name => bucket.access_type + } +} diff --git a/cloud-foundation/modules/cloud-foundation-library/object-storage/variables.tf b/cloud-foundation/modules/cloud-foundation-library/object-storage/variables.tf new file mode 100644 index 0000000..ec0afbf --- /dev/null +++ b/cloud-foundation/modules/cloud-foundation-library/object-storage/variables.tf @@ -0,0 +1,18 @@ +// Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +variable "tenancy_ocid" { + type = string +} + +variable "bucket_params" { + type = map(object({ + compartment_id = string + name = string + access_type = string + storage_tier = string + events_enabled = bool + defined_tags = map(string) + })) +} + diff --git a/cloud-foundation/modules/cloud-foundation-library/odi/main.tf b/cloud-foundation/modules/cloud-foundation-library/odi/main.tf new file mode 100644 index 0000000..2ceb5b2 --- /dev/null +++ b/cloud-foundation/modules/cloud-foundation-library/odi/main.tf @@ -0,0 +1,26 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + + resource "oci_dataintegration_workspace" "this" { + for_each = { + for k,v in var.odi_params : k => v if v.compartment_id != "" + } + #Required + compartment_id = each.value.compartment_id + display_name = each.value.display_name + + #Optional + defined_tags = each.value.defined_tags + description = each.value.description + # dns_server_ip = var.workspace_dns_server_ip + # dns_server_zone = var.workspace_dns_server_zone + # freeform_tags = each.value.freeform_tags + # is_private_network_enabled = each.value.is_private_network_enabled + is_private_network_enabled = false + # subnet_id = each.value.subnet_id + # vcn_id = each.value.vcn_id +} + + + + diff --git a/cloud-foundation/modules/cloud-foundation-library/odi/outputs.tf b/cloud-foundation/modules/cloud-foundation-library/odi/outputs.tf new file mode 100644 index 0000000..efc44d5 --- /dev/null +++ b/cloud-foundation/modules/cloud-foundation-library/odi/outputs.tf @@ -0,0 +1,9 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +output "odi" { + value = { + for odi in oci_dataintegration_workspace.this: + odi.display_name => odi.display_name + } +} \ No newline at end of file diff --git a/cloud-foundation/modules/cloud-foundation-library/odi/variables.tf b/cloud-foundation/modules/cloud-foundation-library/odi/variables.tf new file mode 100644 index 0000000..9b3abb1 --- /dev/null +++ b/cloud-foundation/modules/cloud-foundation-library/odi/variables.tf @@ -0,0 +1,15 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +variable "odi_params" { + type = map(object({ + compartment_id = string + display_name = string + description = string + # is_private_network_enabled = bool + # subnet_id = string + # vcn_id = string + defined_tags = map(string) + })) +} + diff --git a/cloud-foundation/modules/oci-cis-landingzone-quickstart/network/vcn-basic/main.tf b/cloud-foundation/modules/oci-cis-landingzone-quickstart/network/vcn-basic/main.tf index 902ebce..35c64ce 100644 --- a/cloud-foundation/modules/oci-cis-landingzone-quickstart/network/vcn-basic/main.tf +++ b/cloud-foundation/modules/oci-cis-landingzone-quickstart/network/vcn-basic/main.tf @@ -79,7 +79,7 @@ resource "oci_core_drg_attachment" "these" { ### Subnets resource "oci_core_subnet" "these" { - for_each = {for subnet in local.subnets : "${subnet.display_name}" => subnet if subnet.cidr != ""} + for_each = {for subnet in local.subnets : subnet.display_name => subnet if subnet.cidr != ""} display_name = each.value.display_name vcn_id = each.value.vcn_name != "" ? oci_core_vcn.these[each.value.vcn_name].id : each.value.vcn_id availability_domain = each.value.availability_domain diff --git a/cloud-foundation/solutions-for-oracle-res-mgr/Departmental DWH - Full Solution.zip b/cloud-foundation/solutions-for-oracle-res-mgr/Departmental DWH - Full Solution.zip new file mode 100644 index 0000000000000000000000000000000000000000..45728a3f83d272cf83155933f31def497c958fc7 GIT binary patch literal 54466 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 literal 0 HcmV?d00001 diff --git a/cloud-foundation/solutions-for-oracle-res-mgr/Departmental DWH - Small Footprint Solution.zip b/cloud-foundation/solutions-for-oracle-res-mgr/Departmental DWH - Small Footprint Solution.zip new file mode 100644 index 0000000000000000000000000000000000000000..f817c5987ddb37d480d60697d31e3804a675ad7b GIT binary patch literal 41260 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 +This is the folder for the Oracle OCI Console Resource Manager files. +They will be automatically generated when something in the modules and/or solutions folders changes. \ No newline at end of file diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/.gitignore b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/.gitignore new file mode 100644 index 0000000..bb8c378 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/.gitignore @@ -0,0 +1,3 @@ +.terraform +*tfstate* +*.pem \ No newline at end of file diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/CONTRIBUTING.md b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/CONTRIBUTING.md new file mode 100644 index 0000000..7fd10e9 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/CONTRIBUTING.md @@ -0,0 +1,33 @@ + +# Contributing to Oracle Cloud Foundation Terraform Framework + +## Contributing to Oracle Cloud Foundation Terraform Framework + +Oracle welcomes contributions to this repository from anyone. + +If you want to submit a pull request to fix a bug or enhance an existing +feature, please first open an issue and link to that issue when you +submit your pull request. + +If you have any questions about a possible submission, feel free to open +an issue too. + +## Pull request process + +1. Fork this repository +1. Create a branch in your fork to implement the changes. We recommend using +the issue number as part of your branch name, e.g. `1234-fixes` +1. Ensure that there is at least one test that would fail without the fix and +passes post fix +1. Submit the pull request. *Do not leave the pull request blank*. Explain exactly +what your changes are meant to do and provide simple steps on how to validate +your changes, ideally referencing the test. Ensure that you reference the issue +you created as well. We will assign the pull request to 1-2 people for review +before it is submitted internally and the PR is closed. \ No newline at end of file diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/LICENSE b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/LICENSE new file mode 100644 index 0000000..74bc471 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/LICENSE @@ -0,0 +1,27 @@ +Copyright © 2021 Oracle and/or its affiliates. All rights reserved. + +The Universal Permissive License (UPL), Version 1.0 + +Subject to the condition set forth below, permission is hereby granted to any person obtaining a copy of this +software, associated documentation and/or data (collectively the "Software"), free of charge and under any and +all copyright rights in the Software, and any and all patent rights owned or freely licensable by each licensor +hereunder covering either (i) the unmodified Software as contributed to or provided by such licensor, or +(ii) the Larger Works (as defined below), to deal in both + +(a) the Software, and +(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if one is included with the Software +(each a “Larger Work” to which the Software is contributed by such licensors), + +without restriction, including without limitation the rights to copy, create derivative works of, display, +perform, and distribute the Software and make, use, sell, offer for sale, import, export, have made, and have +sold the Software and the Larger Work(s), and to sublicense the foregoing rights on either these or other terms. + +This license is subject to the following condition: +The above copyright notice and either this complete permission notice or at a minimum a reference to the UPL must +be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. \ No newline at end of file diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/README.md b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/README.md new file mode 100644 index 0000000..b128ac9 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/README.md @@ -0,0 +1,530 @@ +# Oracle Cloud Foundation Terraform Solution - Departmental data warehousing - business domain analytics + +## Table of Contents +1. [Overview](#overview) +1. [Deliverables](#deliverables) +1. [Architecture](#Architecture-Diagram) +1. [Executing Instructions](#instructions) + 1. [Deploy Using Oracle Resource Manager](#Deploy-Using-Oracle-Resource-Manager) + 1. [Deploy Using the Terraform CLI](#Deploy-Using-the-Terraform-CLI) +1. [Documentation](#documentation) +1. [The Team](#team) +1. [Feedback](#feedback) +1. [Known Issues](#known-issues) +1. [Contribute](#CONTRIBUTING.md) + + +## Overview +This architecture uses Oracle Autonomous Data Warehouse to load and optimize data from multiple flat-file sources into a centralized data warehouse and then uses Oracle Analytics Cloud to analyze the data to provide actionable insights. + +For details of the architecture, see [_Departmental data warehousing - business domain analytics_](https://docs.oracle.com/en/solutions/oci-spreadsheet-analysis/index.html) + +## Deliverables + This repository encloses one deliverable: + +- A reference implementation written in Terraform HCL (Hashicorp Language) that provisions fully functional resources in an OCI tenancy. + +## Architecture-Diagram +The diagram below shows services that are deployed: + +![](https://docs.oracle.com/en/solutions/oci-spreadsheet-analysis/img/analysis-spreadsheets-architecture.png) + + +## Executing Instructions + +## Prerequisites + +- Permission to `manage` the following types of resources in your Oracle Cloud Infrastructure tenancy: `autonomous-database-family`. +- Quota to create the following resources: 1 ADW database instance and 1 Oracle Analytics Cloud (OAC) instance. +If you don't have the required permissions and quota, contact your tenancy administrator. See [Policy Reference](https://docs.cloud.oracle.com/en-us/iaas/Content/Identity/Reference/policyreference.htm), [Service Limits](https://docs.cloud.oracle.com/en-us/iaas/Content/General/Concepts/servicelimits.htm), [Compartment Quotas](https://docs.cloud.oracle.com/iaas/Content/General/Concepts/resourcequotas.htm). + +# Deploy Using Oracle Resource Manager + +1. Click [![Deploy to Oracle Cloud](https://oci-resourcemanager-plugin.plugins.oci.oraclecloud.com/latest/deploy-to-oracle-cloud.svg)](https://cloud.oracle.com/resourcemanager/stacks/create?region=home&zipUrl=https://github.com/oracle-devrel/terraform-oci-oracle-cloud-foundation/tree/main/releases/latest/download/oci-arch-adw-oac-stack-latest.zip) + + If you aren't already signed in, when prompted, enter the tenancy and user credentials. + +2. Review and accept the terms and conditions. +3. Select the region where you want to deploy the stack. +4. Follow the on-screen prompts and instructions to create the stack. +5. After creating the stack, click **Terraform Actions**, and select **Plan**. +6. Wait for the job to be completed, and review the plan. + To make any changes, return to the Stack Details page, click **Edit Stack**, and make the required changes. Then, run the **Plan** action again. +7. If no further changes are necessary, return to the Stack Details page, click **Terraform Actions**, and select **Apply**. + + +# Deploy Using the Terraform CLI + +## Clone the Module +Now, you'll want a local copy of this repo. You can make that with the commands: + + git clone https://github.com/oracle-devrel/terraform-oci-oracle-cloud-foundation.git + cd terraform-oci-oracle-cloud-foundation/cloud-foundation/solutions/Departmental-DWH-Full-Solution + ls + +## Deployment + +- Follow the instructions from Prerequisites links in order to install terraform. +- Download the terraform version suitable for your operating system. +- Unzip the archive. +- Add the executable to the PATH. +- You will have to generate an API signing key (public/private keys) and the public key should be uploaded in the OCI console, for the iam user that will be used to create the resources. Also, you should make sure that this user has enough permissions to create resources in OCI. In order to generate the API Signing key, follow the steps from: https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm#How + The API signing key will generate a fingerprint in the OCI console, and that fingerprint will be used in a terraform file described below. +- You will also need to generate an OpenSSH public key pair. Please store those keys in a place accessible like your user home .ssh directory. + +## Prerequisites + +- Install Terraform v0.13 or greater: https://www.terraform.io/downloads.html +- Install Python 3.6: https://www.digitalocean.com/community/tutorials/how-to-install-python-3-and-set-up-a-local-programming-environment-on-centos-7 +- Generate an OCI API Key +- Create your config under \$home*directory/.oci/config (run \_oci setup config* and follow the steps) +- Gather Tenancy related variables (tenancy_id, user_id, local path to the oci_api_key private key, fingerprint of the oci_api_key_public key, and region) + +### Installing Terraform + +Go to [terraform.io](https://www.terraform.io/downloads.html) and download the proper package for your operating system and architecture. Terraform is distributed as a single binary. +Install Terraform by unzipping it and moving it to a directory included in your system's PATH. You will need the latest version available. + +### Prepare Terraform Provider Values + +**variables.tf** is located in the root directory. This file is used in order to be able to make API calls in OCI, hence it will be needed by all terraform automations. + +In order to populate the **variables.tf** file, you will need the following: + +- Tenancy OCID +- User OCID +- Local Path to your private oci api key +- Fingerprint of your public oci api key +- Region + +#### **Getting the Tenancy and User OCIDs** + +You will have to login to the [console](https://console.us-ashburn-1.oraclecloud.com) using your credentials (tenancy name, user name and password). If you do not know those, you will have to contact a tenancy administrator. + +In order to obtain the tenancy ocid, after logging in, from the menu, select Administration -> Tenancy Details. The tenancy OCID, will be found under Tenancy information and it will be similar to **ocid1.tenancy.oc1..aaa…** + +In order to get the user ocid, after logging in, from the menu, select Identity -> Users. Find your user and click on it (you will need to have this page open for uploading the oci_api_public_key). From this page, you can get the user OCID which will be similar to **ocid1.user.oc1..aaaa…** + +#### **Creating the OCI API Key Pair and Upload it to your user page** + +Create an oci_api_key pair in order to authenticate to oci as specified in the [documentation](https://docs.cloud.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm#How): + +Create the .oci directory in the home of the current user + +`$ mkdir ~/.oci` + +Generate the oci api private key + +`$ openssl genrsa -out ~/.oci/oci_api_key.pem 2048` + +Make sure only the current user can access this key + +`$ chmod go-rwx ~/.oci/oci_api_key.pem` + +Generate the oci api public key from the private key + +`$ openssl rsa -pubout -in ~/.oci/oci_api_key.pem -out ~/.oci/oci_api_key_public.pem` + +You will have to upload the public key to the oci console for your user (go to your user page -> API Keys -> Add Public Key and paste the contents in there) in order to be able to do make API calls. + +After uploading the public key, you can see its fingerprint into the console. You will need that fingerprint for your variables.tf file. +You can also get the fingerprint from running the following command on your local workstation by using your newly generated oci api private key. + +`$ openssl rsa -pubout -outform DER -in ~/.oci/oci_api_key.pem | openssl md5 -c` + +#### **Generating an SSH Key Pair on UNIX or UNIX-Like Systems Using ssh-keygen** + +- Run the ssh-keygen command. + +`ssh-keygen -b 2048 -t rsa` + +- The command prompts you to enter the path to the file in which you want to save the key. A default path and file name are suggested in parentheses. For example: /home/user_name/.ssh/id_rsa. To accept the default path and file name, press Enter. Otherwise, enter the required path and file name, and then press Enter. +- The command prompts you for a passphrase. Enter a passphrase, or press ENTER if you don't want to havea passphrase. + Note that the passphrase isn't displayed when you type it in. Remember the passphrase. If you forget the passphrase, you can't recover it. When prompted, enter the passphrase again to confirm it. +- The command generates an SSH key pair consisting of a public key and a private key, and saves them in the specified path. The file name of the public key is created automatically by appending .pub to the name of the private key file. For example, if the file name of the SSH private key is id_rsa, then the file name of the public key would be id_rsa.pub. + Make a note of the path where you've saved the SSH key pair. + When you create instances, you must provide the SSH public key. When you log in to an instance, you must specify the corresponding SSH private key and enter the passphrase when prompted. + +#### **Getting the Region** + +Even though, you may know your region name, you will needs its identifier for the variables.tf file (for example, US East Ashburn has us-ashburn-1 as its identifier). +In order to obtain your region identifier, you will need to Navigate in the OCI Console to Administration -> Region Management +Select the region you are interested in, and save the region identifier. + +#### **Prepare the variables.tf file** + +You will have to modify the **variables.tf** file to reflect the values that you’ve captured. + +``` +variable "tenancy_ocid" { + type = string + default = "" (tenancy ocid, obtained from OCI console - Profile -> Tenancy) +} + +variable "region" { + type = string + default = "" (the region used for deploying the infrastructure - ex: eu-frankfurt-1) +} + +variable "compartment_id" { + type = string + default = "" (the compartment used for deploying the solution - ex: compartment1) +} + +variable "user_ocid" { + type = string + default = "" (user ocid, obtained from OCI console - Profile -> User Settings) +} + +variable "fingerprint" { + type = string + default = "" (fingerprint obtained after setting up the API public key in OCI console - Profile -> User Settings -> API Keys -> Add Public Key) +} + +variable "private_key_path" { + type = string + default = "" (the path of your local oci api key - ex: /root/.ssh/oci_api_key.pem) +} +``` + +## Repository files + + +* **modules(folder)** - Contains folders with subsystems and modules for each section of the project: networking, autonomous database, analytics cloud, etc. +* **main.tf** - Main Terraform script used for instantiating the Oracle Cloud Infrastructure provider and all subsystems modules +* **README.md** - This file +* **outputs.tf** - Defines project's outputs that you will see after the code runs successfuly +* **provider.tf** - The terraform provider that will be used (OCI) +* **LICENSE** - The Universal Permissive License (UPL), Version 1.0 +* **local.tf** - Local values can be helpful to avoid repeating the same values or expressions multiple times in a configuration, but if overused they can also make a configuration hard to read by future maintainers by hiding the actual values used. +* **schema.yaml** - Schema documents are recommended for Terraform configurations when using Resource Manager. Including a schema document allows you to extend pages in the Oracle Cloud Infrastructure Console. Facilitate variable entry in the Create Stack page by surfacing SSH key controls and by naming, grouping, dynamically prepopulating values, and more. Define text in the Application Information tab of the stack detail page displayed for a created stack. +* **variables.tf** - Project's global variables + + +Secondly, populate the `terraform.tf` file with the disared configuration following the information: + + +# Autonomous Data Warehouse + +The ADW subsystem / module is able to create ADW/ATP databases. + +* Parameters: + * __adw_cpu_core_count__ - The number of OCPU cores to be made available to the database. For Autonomous Databases on dedicated Exadata infrastructure, the maximum number of cores is determined by the infrastructure shape. See Characteristics of Infrastructure Shapes for shape details. + * __adw_size_in_tbss__ - The size, in gigabytes, of the data volume that will be created and attached to the database. This storage can later be scaled up if needed. The maximum storage value is determined by the infrastructure shape. See Characteristics of Infrastructure Shapes for shape details. + * __adw_db_name__ - The database name. The name must begin with an alphabetic character and can contain a maximum of 14 alphanumeric characters. Special characters are not permitted. The database name must be unique in the tenancy. + * __adw_db_workload__ - The Autonomous Database workload type. The following values are valid: + - OLTP - indicates an Autonomous Transaction Processing database + - DW - indicates an Autonomous Data Warehouse database + - AJD - indicates an Autonomous JSON Database + - APEX - indicates an Autonomous Database with the Oracle APEX Application Development workload type. *Note: db_workload can only be updated from AJD to OLTP or from a free OLTP to AJD. + * __adw_db_version__ - A valid Oracle Database version for Autonomous Database.db_workload AJD and APEX are only supported for db_version 19c and above. + * __adw_enable_auto_scaling__ - Indicates if auto scaling is enabled for the Autonomous Database OCPU core count. The default value is FALSE. + * __adw_is_free_tier__ - Indicates if this is an Always Free resource. The default value is false. Note that Always Free Autonomous Databases have 1 CPU and 20GB of memory. For Always Free databases, memory and CPU cannot be scaled. When db_workload is AJD or APEX it cannot be true. + * __adw_license_model__ - The Oracle license model that applies to the Oracle Autonomous Database. Bring your own license (BYOL) allows you to apply your current on-premises Oracle software licenses to equivalent, highly automated Oracle PaaS and IaaS services in the cloud. License Included allows you to subscribe to new Oracle Database software licenses and the Database service. Note that when provisioning an Autonomous Database on dedicated Exadata infrastructure, this attribute must be null because the attribute is already set at the Autonomous Exadata Infrastructure level. When using shared Exadata infrastructure, if a value is not specified, the system will supply the value of BRING_YOUR_OWN_LICENSE. It is a required field when db_workload is AJD and needs to be set to LICENSE_INCLUDED as AJD does not support default license_model value BRING_YOUR_OWN_LICENSE. + * __database_admin_password__ - The password must be between 12 and 30 characters long, and must contain at least 1 uppercase, 1 lowercase, and 1 numeric character. It cannot contain the double quote symbol (") or the username "admin", regardless of casing. The password is mandatory if source value is "BACKUP_FROM_ID", "BACKUP_FROM_TIMESTAMP", "DATABASE" or "NONE". + * __database_wallet_password__ - (Required) The password to encrypt the keys inside the wallet. The password must be at least 8 characters long and must include at least 1 letter and either 1 numeric character or 1 special character. + +Below is an example: + +``` +variable "adw_cpu_core_count" { + type = number + default = 1 +} + +variable "adw_size_in_tbs" { + type = number + default = 1 +} + +variable "adw_db_name" { + type = string + default = "ADWipan" +} + +variable "adw_db_workload" { + type = string + default = "DW" +} + +variable "adw_db_version" { + type = string + default = "19c" +} + +variable "adw_enable_auto_scaling" { + type = bool + default = true +} + +variable "adw_is_free_tier" { + type = bool + default = false +} + +variable "adw_license_model" { + type = string + default = "LICENSE_INCLUDED" +} + +variable "database_admin_password" { + type = string + default = "" +} + +variable "database_wallet_password" { + type = string + default = "" +} + +``` + +# Oracle Analytics Cloud +This resource provides the Analytics Instance resource in Oracle Cloud Infrastructure Analytics service. +Create a new AnalyticsInstance in the specified compartment. The operation is long-running and creates a new WorkRequest. + +* Parameters + * __analytics_instance_feature_set__ - Analytics feature set: ENTERPRISE_ANALYTICS or SELF_SERVICE_ANALYTICS set + * __analytics_instance_license_type__ - The license used for the service: LICENSE_INCLUDED or BRING_YOUR_OWN_LICENSE + * __analytics_instance_hostname__ - The name of the Analytics instance. This name must be unique in the tenancy and cannot be changed. + * __analytics_instance_idcs_access_token__ - IDCS access token identifying a stripe and service administrator user. THe IDCS access token can be obtained from OCI console - Menu -> Identity & Security -> Federation -> OracleIdentityCloudService - and now click on the Oracle Identity Cloud Service Console) + Access Oracle Identity Cloud Service console, click the avatar icon on the top-right corner, and then click My Access Tokens. + You can download an access token in the following ways: + Select Invokes Identity Cloud Service APIs to specify the available administrator roles that are assigned to you. The APIs from the specified administrator roles will be included in the token. + Select Invokes other APIs to select confidential applications that are assigned to the user account. + Click Select an Application to add a configured confidential resource application. On the Select an Application window, the list of assigned confidential applications displays. + Click applications to select them, and then click Add. The My Access Tokens page lists the added applications. + In the Token Expires in (Mins) field, select or enter how long (in minutes) the access token you're generating can be used before it expires. You can choose to keep the default number or specify between 1 and 527,040. + Click Download Token. The access token is generated and downloaded to your local machine as a tokens.tok file. + * __analytics_instance_capacity_capacity_type__ - The capacity model to use. Accepted values are: OLPU_COUNT, USER_COUNT . Values are case-insensitive. + * __analytics_instance_capacity_value__ - The capacity value selected (OLPU count, number of users, …etc…). This parameter affects the number of CPUs, amount of memory or other resources allocated to the instance. + * __analytics_instance_network_endpoint_details_network_endpoint_type__ - The type of network endpoint public or private + * __whitelisted_ips__ and __analytics_instance_network_endpoint_details_whitelisted_ips__ - If the network_endpoint_type is public you need to put the Source IP addresses or IP address ranges igress rules. + + +Below is an example: +``` +variable "analytics_instance_feature_set" { + type = string + default = "ENTERPRISE_ANALYTICS" +} + +variable "analytics_instance_license_type" { + type = string + default = "LICENSE_INCLUDED" +} + +variable "analytics_instance_hostname" { + type = string + default = "AnalyicSD" +} + +variable "analytics_instance_idcs_access_token" { + type = string + default = "copy-paste your token instead" +} + +variable "analytics_instance_capacity_capacity_type" { + type = string + default = "OLPU_COUNT" +} + +variable "analytics_instance_capacity_value" { + type = number + default = 1 +} + +variable "analytics_instance_network_endpoint_details_network_endpoint_type" { + type = string + default = "public" +} + +variable "whitelisted_ips" { + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "analytics_instance_network_endpoint_details_whitelisted_ips" { + type = list(string) + default = ["0.0.0.0/0"] +} +``` + +# Network +This resource provides the Vcn resource in Oracle Cloud Infrastructure Core service anso This resource provides the Subnet resource in Oracle Cloud Infrastructure Core service. +The solution will create 1 VCN in your compartment, 2 subnets ( one public and one private so the analytics cloud instance can be public or private ), 2 route tables for incomming and outoing traffic, 2 Network Security Groups for ingress and egress traffic, 1 internet gateway, 2 route tables for each subnet, dhcp service, NAT Gateway and a Service Gateway. + +* Parameters + * __service_name__ - The names of all compute and network resources will begin with this prefix. It can only contain letters or numbers and must begin with a letter. + * __vcn_cidr__ - The list of one or more IPv4 CIDR blocks for the VCN that meet the following criteria: + The CIDR blocks must be valid. + They must not overlap with each other or with the on-premises network CIDR block. + The number of CIDR blocks must not exceed the limit of CIDR blocks allowed per VCN. It is an error to set both cidrBlock and cidrBlocks. Note: cidr_blocks update must be restricted to one operation at a time (either add/remove or modify one single cidr_block) or the operation will be declined. + * __vcn_name__ - A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information. + * __public_subnet_cidr__ - The CIDR IP address range of the subnet. The CIDR must maintain the following rules - a. The CIDR block is valid and correctly formatted. b. The new range is within one of the parent VCN ranges. This is the cidr for the public subnet. + * __public_subnet_name__ - A user-friendly name for the public subnet. Does not have to be unique, and it's changeable. Avoid entering confidential information. + * __private_subnet_cidr__ - The CIDR IP address range of the subnet. The CIDR must maintain the following rules - a. The CIDR block is valid and correctly formatted. b. The new range is within one of the parent VCN ranges. This is the cidr for the private subnet. + * __private_subnet_name__ - A user-friendly name for the private subnet. Does not have to be unique, and it's changeable. Avoid entering confidential information. + + +Below is an example: +``` +variable "service_name" { + type = string + default = "servicename" + description = "prefix for stack resources" +} + +variable "vcn_cidr" { + default = "172.0.0.0/16" + description = "CIDR for new virtual cloud network" +} + +variable "vcn_name" { + default = "vcn" + description = "Name of new virtual cloud network" +} + +variable "public_subnet_cidr" { + default = "172.0.0.128/27" + description = "CIDR for bastion subnet" +} + +variable "public_subnet_name" { + default = "pub" +} + +variable "private_subnet_cidr" { + default = "172.0.0.32/27" +} + +variable "private_subnet_name" { + default = "priv" +} +``` + +# Object Storage +This resource provides the Bucket resource in Oracle Cloud Infrastructure Object Storage service. +Creates a bucket in the given namespace with a bucket name and optional user-defined metadata. Avoid entering confidential information in bucket names. + +* Parameters: + * __bucket_name__ - The name of the bucket. Valid characters are uppercase or lowercase letters, numbers, hyphens, underscores, and periods. Bucket names must be unique within an Object Storage namespace. Avoid entering confidential information. example: Example: my-new-bucket1 + * __bucket_access_type__ - The type of public access enabled on this bucket. A bucket is set to NoPublicAccess by default, which only allows an authenticated caller to access the bucket and its contents. When ObjectRead is enabled on the bucket, public access is allowed for the GetObject, HeadObject, and ListObjects operations. When ObjectReadWithoutList is enabled on the bucket, public access is allowed for the GetObject and HeadObject operations. + * __bucket_storage_tier__ - The type of storage tier of this bucket. A bucket is set to 'Standard' tier by default, which means the bucket will be put in the standard storage tier. When 'Archive' tier type is set explicitly, the bucket is put in the Archive Storage tier. The 'storageTier' property is immutable after bucket is created. + * __bucket_events_enabled__ - Whether or not events are emitted for object state changes in this bucket. By default, objectEventsEnabled is set to false. Set objectEventsEnabled to true to emit events for object state changes. For more information about events, see Overview of Events. + + +Below is an example: +``` +variable "bucket_name" { + type = string + default = "BucketOnee" +} + +variable "bucket_access_type" { + type = string + default = "NoPublicAccess" +} + +variable "bucket_storage_tier" { + type = string + default = "Standard" +} + +variable "bucket_events_enabled" { + type = bool + default = false +} +``` + +# Data Catalog +This resource provides the Catalog resource in Oracle Cloud Infrastructure Data Catalog service. +Creates a new data catalog instance that includes a console and an API URL for managing metadata operations. For more information, please see the documentation. + +* Parameters: + * __datacatalog_display_name__ - Data catalog identifier. + + +Below is an example: +``` +variable "datacatalog_display_name" { + type = string + default = "DataCatalogIP" +} +``` + +# Oracle Cloud Infrastructure Data Integration service +This resource provides the Workspace resource in Oracle Cloud Infrastructure Data Integration service. +Creates a new Data Integration workspace ready for performing data integration tasks. + +* Parameters: + * __odi_display_name__ - A user-friendly display name for the workspace. Does not have to be unique, and can be modified. Avoid entering confidential information. + * __odi_description__ - A user defined description for the workspace. + + +Below is an example: +``` +variable "odi_display_name" { + type = string + default = "odi_workspace" +} + +variable "odi_description" { + type = string + default = "odi_workspace" +} +``` + +Don't modify any other variables in the variable.tf file - it may cause that the solution will not work propertly. + +## Running the code + +``` +# Run init to get terraform modules +$ terraform init + +# Create the infrastructure +$ terraform apply --auto-approve + +# If you are done with this infrastructure, take it down +$ terraform destroy --auto-approve +``` + + +## Documentation + +[Autonomous Databases Overview](https://docs.oracle.com/en-us/iaas/Content/Database/Concepts/adboverview.htm) + +[Analytics Cloud Overview](https://docs.oracle.com/en-us/iaas/analytics-cloud/index.html) + +[Network Overview](https://docs.cloud.oracle.com/iaas/Content/Network/Concepts/overview.htm) + +[Object Storage Overview](https://docs.oracle.com/en-us/iaas/Content/Object/Concepts/objectstorageoverview.htm) + +[Data Catalog Overview](https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/data-catalog/using/overview.htm) + +[Data Integration Overview](https://docs.oracle.com/en-us/iaas/data-integration/using/overview.htm) + +[Terraform Autonomous Databases Resource](https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/database_autonomous_database) + +[Terraform Analytics Cloud Resource](https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/analytics_analytics_instance) + +[Terraform Vcn resource in Oracle Cloud Infrastructure Core service](https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/core_vcn) + +[Terraform Subnet resource in Oracle Cloud Infrastructure Core service](https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/core_subnet) + +[Terraform Object Storage Service Resource](https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/objectstorage_bucket) + +[Terraform Data Catalog Service Resource](https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/datacatalog_catalog) + +[Terraform Data Integration Service Resource](https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/dataintegration_workspace) + +## The Team +- **Owners**: [Panaitescu Ionel](https://github.com/ionelpanaitescu), [Corina Todea](https://github.com/ctodearo) +- **Contributors**: Name Name, [Name Name](https://github.com/somebody), [Name Name](https://github.com/somebody) + +## Feedback +We welcome your feedback. To post feedback, submit feature ideas or report bugs, please use the Issues section on this repository. + +## Known Issues +**At the moment, there are no known issues** \ No newline at end of file diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/local.tf b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/local.tf new file mode 100644 index 0000000..f69ecb1 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/local.tf @@ -0,0 +1,379 @@ +data "oci_identity_availability_domains" "ADs" { + compartment_id = var.tenancy_ocid +} + +data "oci_identity_tenancy" "tenancy" { + tenancy_id = var.tenancy_ocid +} + +data "template_file" "ad_names" { + count = length(data.oci_identity_availability_domains.ADs.availability_domains) + template = lookup(data.oci_identity_availability_domains.ADs.availability_domains[count.index], "name") +} + +data "oci_core_services" "tf_services" { + filter { + name = "cidr_block" + values = ["all-.*-services-in-oracle-services-network"] + regex = true + } +} + +# resource "oci_identity_tag_namespace" "namespace" { +# provider = oci +# compartment_id = var.compartment_id +# description = "cloudfoundationorcl" +# name = "cloudfoundationorcl-deploy-adw-oac" + +# provisioner "local-exec" { +# command = "sleep 60" +# } +# } + +# resource "oci_identity_tag" "release" { +# provider = oci +# description = "release" +# name = "release" +# tag_namespace_id = oci_identity_tag_namespace.namespace.id + +# provisioner "local-exec" { +# command = "sleep 60" +# } +# } + +# resource "oci_identity_tag" "solution" { +# provider = oci +# description = "solution" +# name = "solution" +# tag_namespace_id = oci_identity_tag_namespace.namespace.id + +# provisioner "local-exec" { +# command = "sleep 60" +# } +# } + +# resource "oci_identity_tag" "subsystem" { +# provider = oci +# description = "subsystem" +# name = "subsystem" +# tag_namespace_id = oci_identity_tag_namespace.namespace.id + +# provisioner "local-exec" { +# command = "sleep 60" +# } +# } + +# resource "oci_identity_tag" "module" { +# provider = oci +# description = "module" +# name = "module" +# tag_namespace_id = oci_identity_tag_namespace.namespace.id + +# provisioner "local-exec" { +# command = "sleep 60" +# } +# } + +locals { + +# # # Remove all characters from the service_name that dont satisfy the criteria: +# # # must start with letter, must only contain letters and numbers and length between 1,8 +# # # See https://github.com/google/re2/wiki/Syntax - regex syntax supported by replace() + service_name_prefix = replace(var.service_name, "/[^a-zA-Z0-9]/", "") + # # #Availability Domains + ad_names = compact(data.template_file.ad_names.*.rendered) + public_subnet_availability_domain = local.ad_names[0] + + num_ads = length( + data.oci_identity_availability_domains.ADs.availability_domains, + ) + + is_single_ad_region = local.num_ads == 1 ? true : false + use_existing_subnets = false + is_vcn_peering = false + vcnsCount = var.vcn_name !="" && local.use_existing_subnets==false ? 1:0 + assign_public_ip = var.assign_public_ip || var.subnet_type == "Use Public Subnet" ? true : false + + public_subnet_cidr = var.public_subnet_cidr == "" && var.vcn_name != "" && ! local.assign_public_ip ? local.is_vcn_peering ? "11.0.6.0/24" : "10.0.6.0/24" : var.public_subnet_cidr + private_subnet_cidr = var.private_subnet_cidr == "" && var.vcn_name != "" ? local.is_vcn_peering ? "11.0.3.0/24" : "10.0.3.0/24" : var.private_subnet_cidr + + public_subnet = { + exists = {compartment_id=var.compartment_id, + availability_domain=var.use_regional_subnet? "" : local.public_subnet_availability_domain, + cidr = local.public_subnet_cidr, + dns_label=replace("${var.public_subnet_name}-${substr(uuid(), -7, -1)}", "-",""), + private=false, + dhcp_options_id=module.network-dhcp-options.dhcp_options["${var.service_name}-${var.dhcp_options_name}"].id, + security_list_ids=local.public_security_list_id, + defined_tags=local.defined_tags, + # defined_tags=var.network_defined_tags, + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "vcn-basic" + # } + freeform_tags=local.freeform_tags} + not_exists = {compartment_id="", availability_domain="", cidr="", dns_label="",private=false,dhcp_options_id="",security_list_ids=[""], defined_tags={}, freeform_tags={}} + } + + private_subnet = { + exists = {compartment_id=var.compartment_id, + availability_domain=var.use_regional_subnet? "" : var.private_subnet_availability_domain_name, + cidr = local.private_subnet_cidr, + dns_label=replace(format("%s-%s", var.private_subnet_name, substr(strrev(var.service_name), 0, 7)), "-",""), + private=true, + dhcp_options_id=module.network-dhcp-options.dhcp_options["${var.service_name}-${var.dhcp_options_name}"].id, + security_list_ids=local.private_security_list_id, + defined_tags=local.defined_tags, + # defined_tags=var.network_defined_tags, + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "vcn-basic" + # } + freeform_tags=local.freeform_tags} + not_exists={compartment_id="", availability_domain="", cidr="", dns_label="",private=false,dhcp_options_id="",security_list_ids=[""], defined_tags={}, freeform_tags={}} + } + + exists_public_subnet = ! local.assign_public_ip && var.public_subnet_id == "" ? true : false + exists_private_subnet = ! local.assign_public_ip && var.private_subnet_id == "" ? true : false + + existing_public_subnet = local.public_subnet[local.exists_public_subnet ? "exists" : "not_exists"] + existing_private_subnet = local.private_subnet[local.exists_private_subnet ? "exists" : "not_exists"] + +create_subnets = {"${local.service_name_prefix}-${var.public_subnet_name}"=local.existing_public_subnet,"${local.service_name_prefix}-${var.private_subnet_name}"=local.existing_private_subnet} + +# Security Lists + + public-security-list-def = { + exists = { + vcn_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id, + compartment_id = var.compartment_id, + defined_tags=local.defined_tags, + # defined_tags = var.security_defined_tags, + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "security" + # } + ingress_rules = concat([ + { + stateless = false, + protocol = "6", + src = var.anywhere_cidr, + src_type = "CIDR_BLOCK", + src_port = null, + dst_port = {min = 22, max = 22}, + icmp_type = null, + icmp_code = null + }], + [ + { + stateless = false, + protocol = "6", + src = var.anywhere_cidr, + src_type = "CIDR_BLOCK", + src_port = null, + dst_port = {min = 80, max = 80}, + icmp_type = null, + icmp_code = null + }]), + egress_rules = [ + { + stateless = false, + protocol = "all", + dst = var.anywhere_cidr, + dst_type = "CIDR_BLOCK", + src_port = null, + dst_port = null, + icmp_type = null, + icmp_code = null + }] + } + not_exists = {vcn_id="", compartment_id="", defined_tags = {}, ingress_rules=[], egress_rules=[]} + } + + private-security-list-def = { + exists = { + vcn_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id, + compartment_id = var.compartment_id, + defined_tags=local.defined_tags, + # defined_tags = var.security_defined_tags, + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "security" + # } + ingress_rules = [ + { + stateless = false, + protocol = "6", + src = var.public_subnet_cidr, + src_type = "CIDR_BLOCK", + src_port = null, + dst_port = null, + icmp_type = null, + icmp_code = null + }], + egress_rules = [ + { + stateless = false, + protocol = "all", + dst = var.anywhere_cidr, + dst_type = "CIDR_BLOCK", + src_port = null, + dst_port = null, + icmp_type = null, + icmp_code = null + }] + } + not_exists = {vcn_id="", compartment_id="", defined_tags = {}, ingress_rules=[], egress_rules=[]} + } + + public_security_list_id = compact( + concat( + [module.network-security-lists.security_lists["${var.service_name}-public-security-list"].id], + ), + ) + + private_security_list_id = compact( + concat( + [module.network-security-lists.security_lists["${var.service_name}-private-security-list"].id], + ), + ) + + public-security-list = local.public-security-list-def[local.use_existing_subnets ? "not_exists" : "exists"] + private-security-list = local.private-security-list-def[local.use_existing_subnets ? "not_exists" : "exists"] + + security-lists = { + !local.assign_public_ip ? "${var.service_name}-public-security-list" : "${var.service_name}-public-security-list" = local.public-security-list, + "${var.service_name}-private-security-list" = local.private-security-list, + } + + +# NSG: + public-nsgs-list-def = { + exists = { + vcn_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id, + compartment_id = var.compartment_id, + defined_tags=local.defined_tags, + # defined_tags = var.security_defined_tags, + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "security" + # } + ingress_rules = { ingress1 = { + is_create = true, + description = "Parameters for customizing Network Security Group(s).", + protocol = "all", + stateless = false, + src = var.public_subnet_cidr, + src_type = "CIDR_BLOCK", + dst_port_min = null, + dst_port_max = null, + src_port_min = null, + src_port_max = null, + icmp_type = null, + icmp_code = null + }}, + egress_rules = { egress1 = { + is_create = true, + description = "Parameters for customizing Network Security Group(s).", + protocol = "all", + stateless = false, + dst = var.anywhere_cidr, + dst_type = "CIDR_BLOCK", + dst_port_min = null, + dst_port_max = null, + src_port_min = null, + src_port_max = null, + icmp_type = null, + icmp_code = null + }}, + } + not_exists = {vcn_id="", ingress_rules=[], egress_rules=[]} + } + +### + private-nsgs-list-def = { + exists = { + vcn_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id, + compartment_id = var.compartment_id, + defined_tags=local.defined_tags, + # defined_tags = var.security_defined_tags, + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "security" + # } + ingress_rules = { ingress2 = { + is_create = true, + description = "Parameters for customizing Network Security Group(s).", + protocol = "all", + stateless = false, + src = var.private_subnet_cidr, + src_type = "CIDR_BLOCK", + dst_port_min = null, + dst_port_max = null, + src_port_min = null, + src_port_max = null, + icmp_type = null, + icmp_code = null + }}, + egress_rules = { egress2 = { + is_create = true, + description = "Parameters for customizing Network Security Group(s).", + protocol = "all", + stateless = false, + dst = var.anywhere_cidr, + dst_type = "CIDR_BLOCK", + dst_port_min = null, + dst_port_max = null, + src_port_min = null, + src_port_max = null, + icmp_type = null, + icmp_code = null + }} + } + not_exists = {vcn_id="", ingress_rules=[], egress_rules=[]} + } + + + public_nsg_list_id = compact( + concat( + [module.network-security-groups.nsgs["${var.service_name}-public-nsg-list"].id], + ), + ) + + private_nsg_list_id = compact( + concat( + [module.network-security-groups.nsgs["${var.service_name}-private-nsg-list"].id], + ), + ) + + public-nsg-list = local.public-nsgs-list-def[local.use_existing_subnets ? "not_exists" : "exists"] + private-nsg-list = local.private-nsgs-list-def[local.use_existing_subnets ? "not_exists" : "exists"] + nsgs-lists = {!local.assign_public_ip ? "${var.service_name}-public-nsg-list" : "${var.service_name}-public-nsg-list" = local.public-nsg-list, + "${var.service_name}-private-nsg-list" = local.private-nsg-list, + } + +# Tags + + #map of Tag key and value + #special chars string denotes empty values for tags for validation purposes + #otherwise zipmap function below fails first for empty strings before validators executed + use_defined_tags = var.defined_tag == "~!@#$%^&*()" && var.defined_tag_value == "~!@#$%^&*()" ? false : true + use_freeform_tags = var.free_form_tag == "~!@#$%^&*()" && var.free_form_tag_value == "~!@#$%^&*()" ? false : true + + #ignore defaults of special chars if tags are not provided + defined_tag = false == local.use_defined_tags ? "" : var.defined_tag + defined_tag_value = false == local.use_defined_tags ? "" : var.defined_tag_value + free_form_tag = false == local.use_freeform_tags ? "" : var.free_form_tag + free_form_tag_value = false == local.use_freeform_tags ? "" : var.free_form_tag_value + + defined_tags = zipmap( + compact([trimspace(local.defined_tag)]), + compact([trimspace(local.defined_tag_value)]), + ) + freeform_tags = zipmap( + compact([trimspace(local.free_form_tag)]), + compact([trimspace(local.free_form_tag_value)]), + ) + +} + diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/main.tf b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/main.tf new file mode 100644 index 0000000..7b77469 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/main.tf @@ -0,0 +1,275 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +module "adw" { + source = "./modules/adw_subsystem" + compartment_id = var.compartment_id + adw_cpu_core_count = var.adw_cpu_core_count + adw_size_in_tbs = var.adw_size_in_tbs + adw_db_name = var.adw_db_name + adw_db_workload = var.adw_db_workload + adw_db_version = var.adw_db_version + adw_enable_auto_scaling = var.adw_enable_auto_scaling + adw_is_free_tier = var.adw_is_free_tier + adw_license_model = var.adw_license_model + database_admin_password = var.database_admin_password + database_wallet_password = var.database_wallet_password + # subnet_ocid = lookup(module.network-subnets.subnets,"${local.service_name_prefix}-${var.private_subnet_name}").id + # nsg_ids = module.network-security-groups.nsgid + defined_tags = local.defined_tags + # defined_tags = var.adw_defined_tags + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "adw_subsystem", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "adw" + # } +} + +module "oac" { + source = "./modules/oac_subsystem" + compartment_id = var.compartment_id + analytics_instance_feature_set = var.analytics_instance_feature_set + analytics_instance_license_type = var.analytics_instance_license_type + analytics_instance_hostname = var.analytics_instance_hostname + analytics_instance_idcs_access_token = var.analytics_instance_idcs_access_token + analytics_instance_capacity_capacity_type = var.analytics_instance_capacity_capacity_type + analytics_instance_capacity_value = var.analytics_instance_capacity_value + analytics_instance_network_endpoint_details_network_endpoint_type = var.analytics_instance_network_endpoint_details_network_endpoint_type + subnet_id = lookup(module.network-subnets.subnets,"${local.service_name_prefix}-${var.private_subnet_name}").id + vcn_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id + analytics_instance_network_endpoint_details_whitelisted_ips = var.analytics_instance_network_endpoint_details_whitelisted_ips + analytics_instance_network_endpoint_details_whitelisted_vcns_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id + whitelisted_ips = var.whitelisted_ips + defined_tags = local.defined_tags + # defined_tags = var.oac_defined_tags + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "oac_subsystem", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "oac" + # } +} + +module "os" { + source = "./modules/object-storage_subsystem" + tenancy_ocid = var.tenancy_ocid + compartment_id = var.compartment_id + bucket_name = var.bucket_name + bucket_access_type = var.bucket_access_type + bucket_storage_tier = var.bucket_storage_tier + bucket_events_enabled = var.bucket_events_enabled + defined_tags = local.defined_tags + # defined_tags = var.os_defined_tags + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "objectstorage", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "objectstorage" + # } +} + +module "datacatalog" { + source = "./modules/datacatalog_subsystem" + compartment_id = var.compartment_id + datacatalog_display_name = var.datacatalog_display_name + defined_tags = local.defined_tags + # defined_tags = var.datacatalog_defined_tags + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "datacatalog_subsystem", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "datacatalog" + # } +} + +module "odi" { + source = "./modules/odi_subsystem" + compartment_id = var.compartment_id + display_name = var.odi_display_name + description = var.odi_description + defined_tags = local.defined_tags + # defined_tags = var.os_defined_tags + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "objectstorage", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "objectstorage" + # } +} + +module "network-vcn" { + + source = "../../../cloud-foundation/modules/oci-cis-landingzone-quickstart/network/vcn-basic" + + compartment_id = var.compartment_id + service_label = var.service_name + service_gateway_cidr = lookup(data.oci_core_services.tf_services.services[0], "cidr_block") + + vcns = {for x in range(local.vcnsCount) : "${var.service_name}-${var.vcn_name}" => { + + compartment_id = var.compartment_id + cidr = var.vcn_cidr + dns_label = format("%svcn",substr((var.service_name), 0, 10)) + is_create_igw = (var.vcn_name=="" || local.use_existing_subnets) ? false : true + is_attach_drg = false + block_nat_traffic = local.assign_public_ip && var.vcn_name!="" ? true : false + + subnets = {subnet={compartment_id="", vcn_id="", availability_domain="", cidr="", dns_label="",private=false,dhcp_options_id="",security_list_ids=[""], defined_tags={}, freeform_tags={}}} + + defined_tags = local.defined_tags + # defined_tags = var.network_defined_tags + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "vcn-basic" + # } + freeform_tags = local.freeform_tags + } + } +} + +module "network-subnets" { + + source = "../../../cloud-foundation/modules/oci-cis-landingzone-quickstart/network/vcn-basic" + + compartment_id = var.compartment_id + service_label = var.service_name + service_gateway_cidr = "all-.*-services-in-oracle-services-network" + + vcns = {for x in range(local.vcnsCount) : "" => { + + compartment_id = var.compartment_id + cidr = var.vcn_cidr + dns_label = format("%svcn",substr((var.service_name), 0, 10)) + is_create_igw = false + is_attach_drg = false + block_nat_traffic = local.assign_public_ip && var.vcn_name!="" ? true : false + + subnets = {for k, v in local.create_subnets: k => { + compartment_id = v.compartment_id, + vcn_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id + availability_domain = v.availability_domain, + cidr = v.cidr, + dns_label = v.dns_label, + private = v.private, + dhcp_options_id = v.dhcp_options_id, + security_list_ids = v.security_list_ids, + defined_tags = v.defined_tags, + freeform_tags = v.freeform_tags + } if v.compartment_id != "" + } + + defined_tags = local.defined_tags + # defined_tags = var.network_defined_tags + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "vcn-basic" + # } + freeform_tags = local.freeform_tags + } + } +} + +module "network-routing" { + + source = "../../../cloud-foundation/modules/oci-cis-landingzone-quickstart/network/vcn-routing" + + compartment_id = var.compartment_id + + subnets_route_tables = { + "${local.service_name_prefix}-routetable-out" = { + compartment_id = var.compartment_id, + vcn_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id, + subnet_id = lookup(module.network-subnets.subnets,"${local.service_name_prefix}-${var.public_subnet_name}").id, + route_table_id = "", + route_rules = [{ + is_create = true, + destination = "0.0.0.0/0", + destination_type = "CIDR_BLOCK", + network_entity_id = lookup(module.network-vcn.internet_gateways, lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id).id, + description = "" + }], + defined_tags = local.defined_tags + # defined_tags = var.routing_defined_tags + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "vcn-routing" + # } + }, + "${local.service_name_prefix}-routetable" = { + compartment_id = var.compartment_id, + vcn_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id, + subnet_id = lookup(module.network-subnets.subnets,"${local.service_name_prefix}-${var.private_subnet_name}").id, + route_table_id = "", + route_rules = concat( [], + [ + { + is_create = true + destination = lookup(data.oci_core_services.tf_services.services[0], "cidr_block"), + destination_type = "SERVICE_CIDR_BLOCK", + network_entity_id = lookup(module.network-vcn.service_gateways, lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id).id, + description = "" + } + ]), + defined_tags = local.defined_tags + # defined_tags = var.routing_defined_tags + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "vcn-routing" + # } + } + } +} + +module "network-routing-attachment" { + source = "../../../cloud-foundation/modules/oci-cis-landingzone-quickstart/network/vcn-routing" + compartment_id = var.compartment_id + + subnets_route_tables = { + "" = { + compartment_id = var.compartment_id, + vcn_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id, + subnet_id = lookup(module.network-subnets.subnets,"${local.service_name_prefix}-${var.public_subnet_name}").id, + route_table_id = lookup(module.network-routing.subnets_route_tables,"${local.service_name_prefix}-routetable-out").id, + route_rules = ([]), + defined_tags = local.defined_tags + # defined_tags = var.routing_defined_tags + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "vcn-routing" + # } + } + } +} + +module "network-security-lists" { + source = "../../../cloud-foundation/modules/oci-cis-landingzone-quickstart/network/security" + compartment_id = var.compartment_id + ports_not_allowed_from_anywhere_cidr = [3390,4500] + + security_lists = { + for k,v in local.security-lists : k => v if v.compartment_id != "" + } +} + +module "network-dhcp-options" { + source = "../../../cloud-foundation/modules/oci-cis-landingzone-quickstart/network/security" + compartment_id = var.compartment_id + + dhcp_options = {for x in range(local.is_vcn_peering ? 0 : (local.use_existing_subnets ? 0 : 1 ) ) : "${var.service_name}-${var.dhcp_options_name}" => { + vcn_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id, + compartment_id = var.compartment_id, + options = { + type = "DomainNameServer" + server_type = "VcnLocalPlusInternet" + }, + defined_tags = local.defined_tags + # defined_tags = var.security_defined_tags, + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "security" + # } + freeform_tags = local.freeform_tags + } + } +} + +module "network-security-groups" { + source = "../../../cloud-foundation/modules/oci-cis-landingzone-quickstart/network/security" + compartment_id = var.compartment_id + + nsgs = { + for k,v in local.nsgs-lists : k => v if v.compartment_id != "" + } +} + diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/adw_subsystem/main.tf b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/adw_subsystem/main.tf new file mode 100644 index 0000000..50963df --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/adw_subsystem/main.tf @@ -0,0 +1,28 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +module "adw" { + source = "../../../../../cloud-foundation/modules/cloud-foundation-library/database/adw" + adw_params = { + adw = { + compartment_id = var.compartment_id, + adw_cpu_core_count = var.adw_cpu_core_count, + adw_size_in_tbs = var.adw_size_in_tbs, + adw_db_name = var.adw_db_name, + adw_db_workload = var.adw_db_workload, + adw_db_version = var.adw_db_version, + adw_enable_auto_scaling = var.adw_enable_auto_scaling, + adw_is_free_tier = var.adw_is_free_tier, + adw_license_model = var.adw_license_model, + database_admin_password = var.database_admin_password, + database_wallet_password = var.database_wallet_password, + # subnet_id = var.subnet_ocid, + # nsg_ids = var.nsg_ids, + defined_tags = var.defined_tags + }, + } +} + + + + \ No newline at end of file diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/adw_subsystem/outputs.tf b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/adw_subsystem/outputs.tf new file mode 100644 index 0000000..0976316 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/adw_subsystem/outputs.tf @@ -0,0 +1,6 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +output "ADW_Service_Console_URL" { + value = module.adw.ADW_Service_Console_URL +} diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/adw_subsystem/variables.tf b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/adw_subsystem/variables.tf new file mode 100644 index 0000000..df44792 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/adw_subsystem/variables.tf @@ -0,0 +1,26 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +variable "compartment_id" {} +variable "adw_cpu_core_count" {} +variable "adw_size_in_tbs" {} +variable "adw_db_name" {} +variable "adw_db_workload" {} +variable "adw_db_version" {} +variable "adw_enable_auto_scaling" {} +variable "adw_is_free_tier" {} +variable "adw_license_model" {} +variable "database_admin_password" {} +variable "database_wallet_password" {} + +# variable "subnet_ocid" {} + +# variable "nsg_ids" { +# type = list(string) +# default = [] +# } + +variable "defined_tags" { + type = map + default = {} +} diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/datacatalog_subsystem/main.tf b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/datacatalog_subsystem/main.tf new file mode 100644 index 0000000..b5ba36e --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/datacatalog_subsystem/main.tf @@ -0,0 +1,14 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +module "datacatalog" { + source = "../../../../../cloud-foundation/modules/cloud-foundation-library/datacatalog" + + datacatalog_params = { + datacatalog = { + compartment_id = var.compartment_id, + catalog_display_name = var.datacatalog_display_name, + defined_tags = var.defined_tags + } + } +} diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/datacatalog_subsystem/outputs.tf b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/datacatalog_subsystem/outputs.tf new file mode 100644 index 0000000..410f01e --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/datacatalog_subsystem/outputs.tf @@ -0,0 +1,6 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +output "datacatalog" { + value = module.datacatalog.datacatalog +} \ No newline at end of file diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/datacatalog_subsystem/variables.tf b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/datacatalog_subsystem/variables.tf new file mode 100644 index 0000000..9b21bd3 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/datacatalog_subsystem/variables.tf @@ -0,0 +1,18 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +variable "compartment_id" { + type = string +} + +variable "datacatalog_display_name" { + type = string +} + +variable "defined_tags" { + type = map + default = {} +} + + + diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/oac_subsystem/main.tf b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/oac_subsystem/main.tf new file mode 100644 index 0000000..ae21690 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/oac_subsystem/main.tf @@ -0,0 +1,24 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +module "oac" { + source = "../../../../../cloud-foundation/modules/cloud-foundation-library/oac" + oac_params = { + oac = { + compartment_id = var.compartment_id, + analytics_instance_feature_set = var.analytics_instance_feature_set, + analytics_instance_license_type = var.analytics_instance_license_type, + analytics_instance_hostname = var.analytics_instance_hostname, + analytics_instance_idcs_access_token = var.analytics_instance_idcs_access_token, + analytics_instance_capacity_capacity_type = var.analytics_instance_capacity_capacity_type, + analytics_instance_capacity_value = var.analytics_instance_capacity_value, + defined_tags = var.defined_tags + analytics_instance_network_endpoint_details_network_endpoint_type = var.analytics_instance_network_endpoint_details_network_endpoint_type + subnet_id = var.subnet_id + vcn_id = var.vcn_id + analytics_instance_network_endpoint_details_whitelisted_ips = var.analytics_instance_network_endpoint_details_whitelisted_ips + analytics_instance_network_endpoint_details_whitelisted_vcns_id = var.analytics_instance_network_endpoint_details_whitelisted_vcns_id + whitelisted_ips = var.whitelisted_ips + } + } +} diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/oac_subsystem/outputs.tf b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/oac_subsystem/outputs.tf new file mode 100644 index 0000000..896ba46 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/oac_subsystem/outputs.tf @@ -0,0 +1,11 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +output "Analytics_URL" { + value = module.oac.Analytics_URL +} + + + + + diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/oac_subsystem/variables.tf b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/oac_subsystem/variables.tf new file mode 100644 index 0000000..4fd45c6 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/oac_subsystem/variables.tf @@ -0,0 +1,55 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +variable "compartment_id" { + type = string +} + +variable "analytics_instance_feature_set" { + type = string +} + +variable "analytics_instance_license_type" { + type = string +} + +variable "analytics_instance_hostname" { + type = string +} + +variable "analytics_instance_idcs_access_token" { + type = string +} + +variable "analytics_instance_capacity_capacity_type" { + type = string +} + +variable "analytics_instance_capacity_value" { + type = number +} + +variable "defined_tags" { + type = map + default = {} +} + +variable "subnet_id" {} +variable "vcn_id" {} +variable "analytics_instance_network_endpoint_details_network_endpoint_type" {} +variable "analytics_instance_network_endpoint_details_whitelisted_vcns_id" {} + +variable "whitelisted_ips" { + type = list(string) + default = [] +} + +variable "analytics_instance_network_endpoint_details_whitelisted_ips" { + type = list(string) + default = [] +} + + + + + diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/object-storage_subsystem/main.tf b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/object-storage_subsystem/main.tf new file mode 100644 index 0000000..5a6f33e --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/object-storage_subsystem/main.tf @@ -0,0 +1,18 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +module "os" { + source = "../../../../../cloud-foundation/modules/cloud-foundation-library/object-storage" + tenancy_ocid = var.tenancy_ocid + + bucket_params = { + bucket = { + compartment_id = var.compartment_id, + name = var.bucket_name, + access_type = var.bucket_access_type, + storage_tier = var.bucket_storage_tier, + events_enabled = var.bucket_events_enabled, + defined_tags = var.defined_tags + } + } +} diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/object-storage_subsystem/outputs.tf b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/object-storage_subsystem/outputs.tf new file mode 100644 index 0000000..2576639 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/object-storage_subsystem/outputs.tf @@ -0,0 +1,6 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +output "buckets" { + value = module.os.buckets +} \ No newline at end of file diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/object-storage_subsystem/variables.tf b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/object-storage_subsystem/variables.tf new file mode 100644 index 0000000..e6428ce --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/object-storage_subsystem/variables.tf @@ -0,0 +1,35 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +variable "tenancy_ocid" { + type = string +} + +variable "compartment_id" { + type = string +} + +variable "bucket_name" { + type = string +} + +variable "bucket_access_type" { + type = string +} + +variable "bucket_storage_tier" { + type = string +} + +variable "bucket_events_enabled" { + type = bool +} + +variable "defined_tags" { + type = map + default = {} +} + + + + diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/odi_subsystem/main.tf b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/odi_subsystem/main.tf new file mode 100644 index 0000000..dd24316 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/odi_subsystem/main.tf @@ -0,0 +1,17 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +module "odi" { + source = "../../../../../cloud-foundation/modules/cloud-foundation-library/odi" + odi_params = { + odi = { + compartment_id = var.compartment_id, + display_name = var.display_name, + description = var.description, + # is_private_network_enabled = var.is_private_network_enabled + # subnet_id = var.subnet_id + # vcn_id = var.vcn_id + defined_tags = var.defined_tags + } + } +} diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/odi_subsystem/outputs.tf b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/odi_subsystem/outputs.tf new file mode 100644 index 0000000..86d8d60 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/odi_subsystem/outputs.tf @@ -0,0 +1,6 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +output "odi" { + value = module.odi.odi +} \ No newline at end of file diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/odi_subsystem/variables.tf b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/odi_subsystem/variables.tf new file mode 100644 index 0000000..674e3f6 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/modules/odi_subsystem/variables.tf @@ -0,0 +1,27 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +variable "compartment_id" { + type = string +} + +variable "display_name" { + type = string +} + +variable "description" { + type = string +} + +# variable "is_private_network_enabled" { +# type = bool +# } + +# variable "subnet_id" {} +# variable "vcn_id" {} + +variable "defined_tags" { + type = map + default = {} +} + diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/outputs.tf b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/outputs.tf new file mode 100644 index 0000000..5fc0c27 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/outputs.tf @@ -0,0 +1,26 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +output "ADW_Service_Console_URL" { + value = module.adw.ADW_Service_Console_URL +} + +output "Analytics_URL" { + value = module.oac.Analytics_URL +} + +output "Instructions" { + value = "Please use the ADW URL to login by using the user admin and the password that it's provided in the output.Also change the password with one that you desire." +} + +output "Buckets" { + value = module.os.buckets +} + +output "DataCatalog" { + value = module.datacatalog.datacatalog +} + +output "Odi" { + value = module.odi.odi +} \ No newline at end of file diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/provider.tf b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/provider.tf new file mode 100644 index 0000000..6019931 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/provider.tf @@ -0,0 +1,11 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +terraform { + required_providers { + oci = { + version = ">= 4.37.0" + source = "hashicorp/oci" + } + } +} diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/schema.yaml b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/schema.yaml new file mode 100644 index 0000000..aba25b5 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/schema.yaml @@ -0,0 +1,464 @@ +title: "Create ADW and OAC in Oracle Cloud Infrastructure" +stackDescription: "Deploy Autonomous Data Warehouse (ADW) and Oracle Analytics Cloud (OAC) in Oracle Cloud Infrastructure." +schemaVersion: 1.1.0 +version: "20210902" +locale: "en" +groupings: + - title: "General Settings" + visible: true + variables: + - tenancy_ocid + - compartment_id + - region + - display_name_prefix + - title: "Autonomous Database Configuration" + variables: + - adw_db_name + - adw_is_free_tier + - adw_license_model + - database_admin_password + - database_wallet_password + - adw_db_version + - adw_size_in_tbs + - adw_enable_auto_scaling + - adw_cpu_core_count + - adw_db_workload + - title: "Oracle Analytics Cloud Configuration" + variables: + - analytics_instance_hostname + - analytics_instance_license_type + - analytics_instance_feature_set + - analytics_instance_capacity_value + - analytics_instance_capacity_capacity_type + - analytics_instance_network_endpoint_details_network_endpoint_type + - analytics_instance_idcs_access_token + - title: "Object Storage" + variables: + - bucket_name + - bucket_access_type + - bucket_storage_tier + - bucket_events_enabled + - title: "Data Catalog" + variables: + - datacatalog_display_name + - title: "Oracle Cloud Infrastructure Data Integration Service" + variables: + - odi_display_name + - odi_description + - title: "Network Configuration" + variables: + - service_name + - vcn_cidr + - vcn_name + - public_subnet_name + - public_subnet_cidr + - private_subnet_name + - private_subnet_cidr + - show_advanced_options + - title: "Hidden Variables" + visible: false + variables: + - user_ocid + - fingerprint + - private_key_path + - defined_tag + - defined_tag_value + - free_form_tag + - free_form_tag_value + - dhcp_options_name + - anywhere_cidr + - assign_public_ip + - use_regional_subnet + - subnet_type + - private_subnet_availability_domain_name + - private_subnet_id + - public_subnet_id + - whitelisted_ips + - analytics_instance_network_endpoint_details_whitelisted_ips +# General Configuration Variables +variables: + tenancy_ocid: + title: Tenancy ID + description: The Oracle Cloud Identifier (OCID) for your tenancy. + type: string + required: true + visible: false + compartment_id: + title: Stack Compartment + description: Choose the compartment where all resources will be provisioned. + type: oci:identity:compartment:id + required: true + visible: true + region: + title: Region + description: Select Region where all resources will be created. + type: oci:identity:region:name + required: true + visible: true + display_name_prefix: + title: Display Name Prefix + type: string + default: "Autonomous Data Warehouse (ADW) and Oracle Analytics Cloud (OAC)" + description: Enter the Display name for the solution. + required: true + visible: true +# Autonomous Database Configuration Variables + adw_db_name: + title: Database Name + description: "Provide Database name. Constraints: 12 alphanumeric characters only. No Spaces." + required: true + type: string + maxLength: 14 + adw_is_free_tier: + title: Do do want a always Free Oracle Autonomous Database instance? + description: "Provision Always Free Oracle Autonomous Database instance (1 OCPU 20 GB Storage)?" + type: enum + enum: + - "true" + - "false" + default: "false" + required: true + visible: true + adw_license_model: + title: "Provision Paid Oracle Autonomous Database instance (2 OCPU 1 TB Storage) - License Included or BYOL?" + description: "Note: This configuration can be changed later from the OCI console." + type: enum + enum: + - LICENSE_INCLUDED + - BRING_YOUR_OWN_LICENSE + default: LICENSE_INCLUDED + required: true + visible: + eq: + - adw_is_free_tier + - "false" + database_admin_password: + title: Database Admin Password + description: "Provide admin password. Constraints: 12 - 30 characters. At least one uppercase letter, one lowercase letter, and one number. No special characters." + type: password + required: true + confirmation: true + pattern: ((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*[%!@^&)(]).{12,20}) + database_wallet_password: + title: Database Wallet Password + description: Provide database wallet password. Must be a minimum 12 characters, contain at least one uppercase letter, one lowercase letter, one number. Do not include special characters. + type: password + required: true + confirmation: true + pattern: ((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*[%!@^&)(]).{12,20}) + adw_db_version: + title: "A valid Oracle Database version for Autonomous Database" + description: "A valid Oracle Database version for Autonomous Database" + type: enum + enum: + - "19c" + default: "19c" + required: true + visible: true + adw_size_in_tbs: + title: "The quantity of data in the database, in terabytes." + description: "The quantity of data in the database, in terabytes." + type: enum + enum: + - 1 + - 2 + - 4 + - 6 + - 8 + - 10 + - 12 + - 16 + - 24 + - 36 + - 52 + - 128 + default: 1 + visible: true + required: true + adw_enable_auto_scaling: + title: Indicates if auto scaling is enabled for the Autonomous Database CPU core count. + description: "Indicates if auto scaling is enabled for the Autonomous Database CPU core count. " + type: enum + enum: + - "true" + - "false" + default: "true" + required: true + visible: true + adw_cpu_core_count: + title: The number of OCPU cores to be made available to the database + description: "The number of OCPU cores to enable. Available cores are subject to your tenancy's service limits." + type: enum + enum: + - 1 + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + - 8 + - 9 + - 10 + - 11 + - 12 + default: 1 + required: true + visible: true + adw_db_workload: + title: Autonomous Database Type of workload. + description: "Autonomous Database Type of workload." + type: enum + enum: + - "DW" + default: "DW" + required: true + visible: false + # Oracle Analytics Cloud Configuration + analytics_instance_hostname: + title: Analytics Instance Name + description: "Enter a unique name for this instance. The name provided must start with a letter, contain only alphanumeric characters, no spaces and span up to 30 characters in total." + type: string + maxLength: 30 + default: "AnalyticsX" + required: true + visible: true + analytics_instance_license_type: + title: Analytics License + description: Choose your Oracle Analytics Cloud License Type. + type: enum + enum: + - LICENSE_INCLUDED + - BRING_YOUR_OWN_LICENSE + default: LICENSE_INCLUDED + visible: true + required: true + analytics_instance_feature_set: + title: Analytics Instance Type + description: Choose the Analytics Product Type. + type: enum + enum: + - SELF_SERVICE_ANALYTICS + - ENTERPRISE_ANALYTICS + default: "ENTERPRISE_ANALYTICS" + visible: create_analytics_instance + required: true + analytics_instance_capacity_value: + title: Analytics Instance Capacity + description: Provide the number of OCPUs for the Oracle Analytics Instance. + type: enum + enum: + - 1 + - 2 + - 4 + - 6 + - 8 + - 10 + - 12 + - 16 + - 24 + - 36 + - 52 + default: 1 + visible: true + required: true + analytics_instance_capacity_capacity_type: + title: Analytics Instance Capacity Type + description: The capacity value selected (OLPU count, number of users, …etc…). This parameter affects the number of CPUs, amount of memory or other resources allocated to the instance. + type: enum + enum: + - "OLPU_COUNT" + - "USERS_COUNT" + default: "OLPU_COUNT" + visible: true + required: true + analytics_instance_network_endpoint_details_network_endpoint_type: + title: Analytics Instance Base representation of a network endpoint + description: "The type of network endpoint: Public or Private Network endpoint" + type: enum + enum: + - "public" + - "private" + default: "public" + visible: true + required: true + analytics_instance_idcs_access_token: + title: IDCS Access Token + description: Provide IDCS Access token. See Pre-req section in the Installation Document. + type: string + default: "copy-paste your token instead" + visible: true + required: true +# Object Storage Configuration + bucket_name: + title: Object Storage Bucket Name + description: "Enter a unique name for this object storage bucket. The name provided must start with a letter, contain only alphanumeric characters, no spaces and span up to 30 characters in total." + type: string + maxLength: 30 + default: "BucketOne" + required: true + visible: true + bucket_access_type: + title: Object Storage Access Type + description: "Select the Access Type of the bucket." + type: enum + enum: + - NoPublicAccess + - ObjectReadWithoutList + - ObjectRead + default: "NoPublicAccess" + required: true + visible: true + bucket_storage_tier: + title: Object Storage Bucket Name + description: "Select the storage Tier of the bucket." + type: enum + enum: + - Standard + - Archive + default: "Standard" + required: true + visible: true + bucket_events_enabled: + title: Indicates if bucket events are enabled or not. + description: "Indicates if bucket events are enabled or not " + type: enum + enum: + - "true" + - "false" + default: "false" + required: true + visible: true +# Data Catalog Configuration + datacatalog_display_name: + title: Data Catalog Name + description: "Enter a unique name for this data catalog. The name provided must start with a letter, contain only alphanumeric characters, no spaces and span up to 30 characters in total." + type: string + maxLength: 30 + default: "DataCatalogIP" + required: true + visible: true +# ODI - Oracle Cloud Infrastructure Data Integration service + odi_display_name: + title: Oracle Data Integration Service + description: "Enter a unique name for the Oracle Data Integration Service. The name provided must start with a letter, contain only alphanumeric characters, no spaces and span up to 30 characters in total." + type: string + maxLength: 30 + default: "odi_workspace" + required: true + visible: true + odi_description: + title: Oracle Data Integration Service + description: "Enter a descriptionfor the Oracle Data Integration Service." + type: string + maxLength: 30 + default: "odi_workspace" + required: true + visible: true +# Network Configuration + service_name: + visible: + and: + - show_advanced_options + type: string + default: "servicename" + minLength: 1 + maxLength: 255 + pattern: "^[a-zA-Z_]\\w{0,254}$" + required: true + title: Resource Name Prefix + description: The names of all compute and network resources will begin with this prefix. It can only contain letters or numbers and must begin with a letter. + vcn_cidr: + visible: + and: + - show_advanced_options + type: string + default: "172.0.0.0/16" + pattern: "^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\/(3[0-2]|[1-2]?[0-9])$" + title: VCN Network CIDR + required: true + description: The CIDR to assign to the new Virtual Cloud Network (VCN) to create for this service. This field is not required if you want to use an existing VCN. When using VCN peering ensure that the VCNs being peered have non-overlapping CIDR blocks. + vcn_name: + visible: + and: + - show_advanced_options + type: string + default: "vcn" + minLength: 1 + maxLength: 255 + pattern: "^[a-zA-Z_]\\w{0,254}$" + required: true + title: VCN Name + description: The name of the new Virtual Cloud Network (VCN) to create for this service + public_subnet_cidr: + visible: + and: + - show_advanced_options + type: string + default: "172.0.0.128/27" + pattern: "^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\/(3[0-2]|[1-2]?[0-9])$" + required: true + title: Public Subnet CIDR + description: "The CIDR of the new public subnet." + public_subnet_name: + visible: + and: + - show_advanced_options + type: string + default: "pub" + required: true + title: Public Subnet Name + description: "The name of the new public subnet." + private_subnet_cidr: + visible: + and: + - show_advanced_options + type: string + default: "172.0.0.32/27" + pattern: "^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\/(3[0-2]|[1-2]?[0-9])$" + required: true + title: Private Subnet CIDR + description: "The CIDR of the new private subnet." + private_subnet_name: + visible: + and: + - show_advanced_options + type: string + default: "priv" + required: true + title: Private Subnet Name + description: "The name of the new private subnet." + show_advanced_options: + title: Show Advanced Options + description: Enable advanced options for network. + type: boolean + default: false + visible: true +outputs: + Instructions: + type: string + title: Instructions + Analytics_URL: + type: link + title: Analytics URL + ADW_Service_Console_URL: + type: link + title: ADB Service Console URL + Buckets: + type: string + title: Buckets + DataCatalog: + type: string + title: DataCatalog + Odi: + type: string + title: Odi workspace +outputGroups: + - title: Application + outputs: + - Instructions + - ADW_Service_Console_URL + - Analytics_URL + - Buckets + - DataCatalog + - Odi diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/variables.tf b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/variables.tf new file mode 100644 index 0000000..878591f --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/variables.tf @@ -0,0 +1,285 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + + +terraform { + required_version = ">= 0.14.0" +} + +variable "tenancy_ocid" { + type = string + default = "" +} +variable "region" { + type = string + default = "" +} + +variable "compartment_id" { + type = string + default = "" +} + +variable "user_ocid" { + type = string + default = "" +} + +variable "fingerprint" { + type = string + default = "" +} + +variable "private_key_path" { + type = string + default = "" +} + +# Autonomous Database Configuration Variables + +variable "adw_cpu_core_count" { + type = number + default = 1 +} + +variable "adw_size_in_tbs" { + type = number + default = 1 +} + +variable "adw_db_name" { + type = string + default = "ADWipa" +} + +variable "adw_db_workload" { + type = string + default = "DW" +} + +variable "adw_db_version" { + type = string + default = "19c" +} + +variable "adw_enable_auto_scaling" { + type = bool + default = true +} + +variable "adw_is_free_tier" { + type = bool + default = false +} + +variable "adw_license_model" { + type = string + default = "LICENSE_INCLUDED" +} + +variable "database_admin_password" { + type = string + default = "" +} + +variable "database_wallet_password" { + type = string + default = "" +} + +# Oracle Analytics Cloud Configuration + +variable "analytics_instance_feature_set" { + type = string + default = "ENTERPRISE_ANALYTICS" +} + +variable "analytics_instance_license_type" { + type = string + default = "LICENSE_INCLUDED" +} + +variable "analytics_instance_hostname" { + type = string + default = "AnalyicsO" +} + +variable "analytics_instance_idcs_access_token" { + type = string + default = "copy-paste your token instead" +} + +variable "analytics_instance_capacity_capacity_type" { + type = string + default = "OLPU_COUNT" +} + +variable "analytics_instance_capacity_value" { + type = number + default = 1 +} + +variable "analytics_instance_network_endpoint_details_network_endpoint_type" { + type = string + default = "public" +} + +variable "whitelisted_ips" { + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "analytics_instance_network_endpoint_details_whitelisted_ips" { + type = list(string) + default = ["0.0.0.0/0"] +} + +# Object Storage Bucket + +variable "bucket_name" { + type = string + default = "BucketOnee" +} + +variable "bucket_access_type" { + type = string + default = "NoPublicAccess" +} + +variable "bucket_storage_tier" { + type = string + default = "Standard" +} + +variable "bucket_events_enabled" { + type = bool + default = false +} + +# Data Catalog + +variable "datacatalog_display_name" { + type = string + default = "DataCatalogIP" +} + +# ODI - Oracle Cloud Infrastructure Data Integration service + +variable "odi_display_name" { + type = string + default = "odi_workspace" +} + +variable "odi_description" { + type = string + default = "odi_workspace" +} + +# Network + +variable "service_name" { + type = string + default = "servicename" + description = "prefix for stack resources" +} + +variable "vcn_cidr" { + default = "172.0.0.0/16" + description = "CIDR for new virtual cloud network" +} + +variable "vcn_name" { + default = "vcn" + description = "Name of new virtual cloud network" +} + +variable "public_subnet_cidr" { + default = "172.0.0.128/27" + description = "CIDR for bastion subnet" +} + +variable "public_subnet_name" { + default = "pub" +} + +variable "private_subnet_cidr" { + default = "172.0.0.32/27" +} + +variable "private_subnet_name" { + default = "priv" +} + +# don't modify any other variables (below) - it may cause that the solution will not work propertly. + +variable "use_regional_subnet" { + type = bool + default = true + description = "Indicates use of regional subnets (preferred) instead of AD specific subnets" +} + +variable "subnet_type" { + default = "Use Private Subnet" +} + +variable "public_subnet_id" { + default = "" + description = "OCID for existing subnet for bastion instance" +} + +variable "private_subnet_id" { + default = "" + description = "OCID for existing subnet for weblogic instances" +} + +variable "assign_public_ip" { + type = bool + default = false + description = "Indicates use of private subnets" +} + +variable "private_subnet_availability_domain_name" { + type = string + default = "" + description = "availablility domain for weblogic vm instances" +} + +variable "dhcp_options_name" { + default = "dhcpOptions" +} + +variable anywhere_cidr { + default = "0.0.0.0/0" +} + +# Define Tags + + +#Note: special chars string denotes empty values for tags for validation purposes +#otherwise zipmap function in main.tf fails first for empty strings before validators executed. + +variable "defined_tag" { + type = string + default = "~!@#$%^&*()" + description = "defined resource tag name" +} + +variable "defined_tag_value" { + type = string + default = "~!@#$%^&*()" + description = "defined resource tag value" +} + +variable "free_form_tag" { + type = string + default = "~!@#$%^&*()" + description = "free form resource tag name" +} + +variable "free_form_tag_value" { + type = string + default = "~!@#$%^&*()" + description = "free form resource tag value" +} + +# End diff --git a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/.gitignore b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/.gitignore new file mode 100644 index 0000000..bb8c378 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/.gitignore @@ -0,0 +1,3 @@ +.terraform +*tfstate* +*.pem \ No newline at end of file diff --git a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/CONTRIBUTING.md b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/CONTRIBUTING.md new file mode 100644 index 0000000..7fd10e9 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/CONTRIBUTING.md @@ -0,0 +1,33 @@ + +# Contributing to Oracle Cloud Foundation Terraform Framework + +## Contributing to Oracle Cloud Foundation Terraform Framework + +Oracle welcomes contributions to this repository from anyone. + +If you want to submit a pull request to fix a bug or enhance an existing +feature, please first open an issue and link to that issue when you +submit your pull request. + +If you have any questions about a possible submission, feel free to open +an issue too. + +## Pull request process + +1. Fork this repository +1. Create a branch in your fork to implement the changes. We recommend using +the issue number as part of your branch name, e.g. `1234-fixes` +1. Ensure that there is at least one test that would fail without the fix and +passes post fix +1. Submit the pull request. *Do not leave the pull request blank*. Explain exactly +what your changes are meant to do and provide simple steps on how to validate +your changes, ideally referencing the test. Ensure that you reference the issue +you created as well. We will assign the pull request to 1-2 people for review +before it is submitted internally and the PR is closed. \ No newline at end of file diff --git a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/LICENSE b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/LICENSE new file mode 100644 index 0000000..74bc471 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/LICENSE @@ -0,0 +1,27 @@ +Copyright © 2021 Oracle and/or its affiliates. All rights reserved. + +The Universal Permissive License (UPL), Version 1.0 + +Subject to the condition set forth below, permission is hereby granted to any person obtaining a copy of this +software, associated documentation and/or data (collectively the "Software"), free of charge and under any and +all copyright rights in the Software, and any and all patent rights owned or freely licensable by each licensor +hereunder covering either (i) the unmodified Software as contributed to or provided by such licensor, or +(ii) the Larger Works (as defined below), to deal in both + +(a) the Software, and +(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if one is included with the Software +(each a “Larger Work” to which the Software is contributed by such licensors), + +without restriction, including without limitation the rights to copy, create derivative works of, display, +perform, and distribute the Software and make, use, sell, offer for sale, import, export, have made, and have +sold the Software and the Larger Work(s), and to sublicense the foregoing rights on either these or other terms. + +This license is subject to the following condition: +The above copyright notice and either this complete permission notice or at a minimum a reference to the UPL must +be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. \ No newline at end of file diff --git a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/README.md b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/README.md new file mode 100644 index 0000000..3660e75 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/README.md @@ -0,0 +1,447 @@ +# Oracle Cloud Foundation Terraform Solution - Departmental data warehousing - business domain analytics + +## Table of Contents +1. [Overview](#overview) +1. [Deliverables](#deliverables) +1. [Architecture](#Architecture-Diagram) +1. [Executing Instructions](#instructions) + 1. [Deploy Using Oracle Resource Manager](#Deploy-Using-Oracle-Resource-Manager) + 1. [Deploy Using the Terraform CLI](#Deploy-Using-the-Terraform-CLI) +1. [Documentation](#documentation) +1. [The Team](#team) +1. [Feedback](#feedback) +1. [Known Issues](#known-issues) +1. [Contribute](#CONTRIBUTING.md) + + +## Overview +This architecture uses Oracle Autonomous Data Warehouse to load and optimize data from multiple flat-file sources into a centralized data warehouse and then uses Oracle Analytics Cloud to analyze the data to provide actionable insights. + +For details of the architecture, see [_Departmental data warehousing - business domain analytics_](https://docs.oracle.com/en/solutions/oci-spreadsheet-analysis/index.html) + +## Deliverables + This repository encloses one deliverable: + +- A reference implementation written in Terraform HCL (Hashicorp Language) that provisions fully functional resources in an OCI tenancy. + +## Architecture-Diagram +The diagram below shows services that are deployed: + +![](https://docs.oracle.com/en/solutions/oci-spreadsheet-analysis/img/analysis-spreadsheets-architecture.png) + + +## Executing Instructions + +## Prerequisites + +- Permission to `manage` the following types of resources in your Oracle Cloud Infrastructure tenancy: `autonomous-database-family`. +- Quota to create the following resources: 1 ADW database instance and 1 Oracle Analytics Cloud (OAC) instance. +If you don't have the required permissions and quota, contact your tenancy administrator. See [Policy Reference](https://docs.cloud.oracle.com/en-us/iaas/Content/Identity/Reference/policyreference.htm), [Service Limits](https://docs.cloud.oracle.com/en-us/iaas/Content/General/Concepts/servicelimits.htm), [Compartment Quotas](https://docs.cloud.oracle.com/iaas/Content/General/Concepts/resourcequotas.htm). + +# Deploy Using Oracle Resource Manager + +1. Click [![Deploy to Oracle Cloud](https://oci-resourcemanager-plugin.plugins.oci.oraclecloud.com/latest/deploy-to-oracle-cloud.svg)](https://cloud.oracle.com/resourcemanager/stacks/create?region=home&zipUrl=https://github.com/oracle-devrel/terraform-oci-oracle-cloud-foundation/tree/main/releases/latest/download/oci-arch-adw-oac-stack-latest.zip) + + If you aren't already signed in, when prompted, enter the tenancy and user credentials. + +2. Review and accept the terms and conditions. +3. Select the region where you want to deploy the stack. +4. Follow the on-screen prompts and instructions to create the stack. +5. After creating the stack, click **Terraform Actions**, and select **Plan**. +6. Wait for the job to be completed, and review the plan. + To make any changes, return to the Stack Details page, click **Edit Stack**, and make the required changes. Then, run the **Plan** action again. +7. If no further changes are necessary, return to the Stack Details page, click **Terraform Actions**, and select **Apply**. + + +# Deploy Using the Terraform CLI + +## Clone the Module +Now, you'll want a local copy of this repo. You can make that with the commands: + + git clone https://github.com/oracle-devrel/terraform-oci-oracle-cloud-foundation.git + cd terraform-oci-oracle-cloud-foundation/cloud-foundation/solutions/Departmental-DWH-Full-Solution + ls + +## Deployment + +- Follow the instructions from Prerequisites links in order to install terraform. +- Download the terraform version suitable for your operating system. +- Unzip the archive. +- Add the executable to the PATH. +- You will have to generate an API signing key (public/private keys) and the public key should be uploaded in the OCI console, for the iam user that will be used to create the resources. Also, you should make sure that this user has enough permissions to create resources in OCI. In order to generate the API Signing key, follow the steps from: https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm#How + The API signing key will generate a fingerprint in the OCI console, and that fingerprint will be used in a terraform file described below. +- You will also need to generate an OpenSSH public key pair. Please store those keys in a place accessible like your user home .ssh directory. + +## Prerequisites + +- Install Terraform v0.13 or greater: https://www.terraform.io/downloads.html +- Install Python 3.6: https://www.digitalocean.com/community/tutorials/how-to-install-python-3-and-set-up-a-local-programming-environment-on-centos-7 +- Generate an OCI API Key +- Create your config under \$home*directory/.oci/config (run \_oci setup config* and follow the steps) +- Gather Tenancy related variables (tenancy_id, user_id, local path to the oci_api_key private key, fingerprint of the oci_api_key_public key, and region) + +### Installing Terraform + +Go to [terraform.io](https://www.terraform.io/downloads.html) and download the proper package for your operating system and architecture. Terraform is distributed as a single binary. +Install Terraform by unzipping it and moving it to a directory included in your system's PATH. You will need the latest version available. + +### Prepare Terraform Provider Values + +**variables.tf** is located in the root directory. This file is used in order to be able to make API calls in OCI, hence it will be needed by all terraform automations. + +In order to populate the **variables.tf** file, you will need the following: + +- Tenancy OCID +- User OCID +- Local Path to your private oci api key +- Fingerprint of your public oci api key +- Region + +#### **Getting the Tenancy and User OCIDs** + +You will have to login to the [console](https://console.us-ashburn-1.oraclecloud.com) using your credentials (tenancy name, user name and password). If you do not know those, you will have to contact a tenancy administrator. + +In order to obtain the tenancy ocid, after logging in, from the menu, select Administration -> Tenancy Details. The tenancy OCID, will be found under Tenancy information and it will be similar to **ocid1.tenancy.oc1..aaa…** + +In order to get the user ocid, after logging in, from the menu, select Identity -> Users. Find your user and click on it (you will need to have this page open for uploading the oci_api_public_key). From this page, you can get the user OCID which will be similar to **ocid1.user.oc1..aaaa…** + +#### **Creating the OCI API Key Pair and Upload it to your user page** + +Create an oci_api_key pair in order to authenticate to oci as specified in the [documentation](https://docs.cloud.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm#How): + +Create the .oci directory in the home of the current user + +`$ mkdir ~/.oci` + +Generate the oci api private key + +`$ openssl genrsa -out ~/.oci/oci_api_key.pem 2048` + +Make sure only the current user can access this key + +`$ chmod go-rwx ~/.oci/oci_api_key.pem` + +Generate the oci api public key from the private key + +`$ openssl rsa -pubout -in ~/.oci/oci_api_key.pem -out ~/.oci/oci_api_key_public.pem` + +You will have to upload the public key to the oci console for your user (go to your user page -> API Keys -> Add Public Key and paste the contents in there) in order to be able to do make API calls. + +After uploading the public key, you can see its fingerprint into the console. You will need that fingerprint for your variables.tf file. +You can also get the fingerprint from running the following command on your local workstation by using your newly generated oci api private key. + +`$ openssl rsa -pubout -outform DER -in ~/.oci/oci_api_key.pem | openssl md5 -c` + +#### **Generating an SSH Key Pair on UNIX or UNIX-Like Systems Using ssh-keygen** + +- Run the ssh-keygen command. + +`ssh-keygen -b 2048 -t rsa` + +- The command prompts you to enter the path to the file in which you want to save the key. A default path and file name are suggested in parentheses. For example: /home/user_name/.ssh/id_rsa. To accept the default path and file name, press Enter. Otherwise, enter the required path and file name, and then press Enter. +- The command prompts you for a passphrase. Enter a passphrase, or press ENTER if you don't want to havea passphrase. + Note that the passphrase isn't displayed when you type it in. Remember the passphrase. If you forget the passphrase, you can't recover it. When prompted, enter the passphrase again to confirm it. +- The command generates an SSH key pair consisting of a public key and a private key, and saves them in the specified path. The file name of the public key is created automatically by appending .pub to the name of the private key file. For example, if the file name of the SSH private key is id_rsa, then the file name of the public key would be id_rsa.pub. + Make a note of the path where you've saved the SSH key pair. + When you create instances, you must provide the SSH public key. When you log in to an instance, you must specify the corresponding SSH private key and enter the passphrase when prompted. + +#### **Getting the Region** + +Even though, you may know your region name, you will needs its identifier for the variables.tf file (for example, US East Ashburn has us-ashburn-1 as its identifier). +In order to obtain your region identifier, you will need to Navigate in the OCI Console to Administration -> Region Management +Select the region you are interested in, and save the region identifier. + +#### **Prepare the variables.tf file** + +You will have to modify the **variables.tf** file to reflect the values that you’ve captured. + +``` +variable "tenancy_ocid" { + type = string + default = "" (tenancy ocid, obtained from OCI console - Profile -> Tenancy) +} + +variable "region" { + type = string + default = "" (the region used for deploying the infrastructure - ex: eu-frankfurt-1) +} + +variable "compartment_id" { + type = string + default = "" (the compartment used for deploying the solution - ex: compartment1) +} + +variable "user_ocid" { + type = string + default = "" (user ocid, obtained from OCI console - Profile -> User Settings) +} + +variable "fingerprint" { + type = string + default = "" (fingerprint obtained after setting up the API public key in OCI console - Profile -> User Settings -> API Keys -> Add Public Key) +} + +variable "private_key_path" { + type = string + default = "" (the path of your local oci api key - ex: /root/.ssh/oci_api_key.pem) +} +``` + +## Repository files + + +* **modules(folder)** - Contains folders with subsystems and modules for each section of the project: networking, autonomous database, analytics cloud, etc. +* **main.tf** - Main Terraform script used for instantiating the Oracle Cloud Infrastructure provider and all subsystems modules +* **README.md** - This file +* **outputs.tf** - Defines project's outputs that you will see after the code runs successfuly +* **provider.tf** - The terraform provider that will be used (OCI) +* **LICENSE** - The Universal Permissive License (UPL), Version 1.0 +* **local.tf** - Local values can be helpful to avoid repeating the same values or expressions multiple times in a configuration, but if overused they can also make a configuration hard to read by future maintainers by hiding the actual values used. +* **schema.yaml** - Schema documents are recommended for Terraform configurations when using Resource Manager. Including a schema document allows you to extend pages in the Oracle Cloud Infrastructure Console. Facilitate variable entry in the Create Stack page by surfacing SSH key controls and by naming, grouping, dynamically prepopulating values, and more. Define text in the Application Information tab of the stack detail page displayed for a created stack. +* **variables.tf** - Project's global variables + + +Secondly, populate the `terraform.tf` file with the disared configuration following the information: + + +# Autonomous Data Warehouse + +The ADW subsystem / module is able to create ADW/ATP databases. + +* Parameters: + * __adw_cpu_core_count__ - The number of OCPU cores to be made available to the database. For Autonomous Databases on dedicated Exadata infrastructure, the maximum number of cores is determined by the infrastructure shape. See Characteristics of Infrastructure Shapes for shape details. + * __adw_size_in_tbss__ - The size, in gigabytes, of the data volume that will be created and attached to the database. This storage can later be scaled up if needed. The maximum storage value is determined by the infrastructure shape. See Characteristics of Infrastructure Shapes for shape details. + * __adw_db_name__ - The database name. The name must begin with an alphabetic character and can contain a maximum of 14 alphanumeric characters. Special characters are not permitted. The database name must be unique in the tenancy. + * __adw_db_workload__ - The Autonomous Database workload type. The following values are valid: + - OLTP - indicates an Autonomous Transaction Processing database + - DW - indicates an Autonomous Data Warehouse database + - AJD - indicates an Autonomous JSON Database + - APEX - indicates an Autonomous Database with the Oracle APEX Application Development workload type. *Note: db_workload can only be updated from AJD to OLTP or from a free OLTP to AJD. + * __adw_db_version__ - A valid Oracle Database version for Autonomous Database.db_workload AJD and APEX are only supported for db_version 19c and above. + * __adw_enable_auto_scaling__ - Indicates if auto scaling is enabled for the Autonomous Database OCPU core count. The default value is FALSE. + * __adw_is_free_tier__ - Indicates if this is an Always Free resource. The default value is false. Note that Always Free Autonomous Databases have 1 CPU and 20GB of memory. For Always Free databases, memory and CPU cannot be scaled. When db_workload is AJD or APEX it cannot be true. + * __adw_license_model__ - The Oracle license model that applies to the Oracle Autonomous Database. Bring your own license (BYOL) allows you to apply your current on-premises Oracle software licenses to equivalent, highly automated Oracle PaaS and IaaS services in the cloud. License Included allows you to subscribe to new Oracle Database software licenses and the Database service. Note that when provisioning an Autonomous Database on dedicated Exadata infrastructure, this attribute must be null because the attribute is already set at the Autonomous Exadata Infrastructure level. When using shared Exadata infrastructure, if a value is not specified, the system will supply the value of BRING_YOUR_OWN_LICENSE. It is a required field when db_workload is AJD and needs to be set to LICENSE_INCLUDED as AJD does not support default license_model value BRING_YOUR_OWN_LICENSE. + * __database_admin_password__ - The password must be between 12 and 30 characters long, and must contain at least 1 uppercase, 1 lowercase, and 1 numeric character. It cannot contain the double quote symbol (") or the username "admin", regardless of casing. The password is mandatory if source value is "BACKUP_FROM_ID", "BACKUP_FROM_TIMESTAMP", "DATABASE" or "NONE". + * __database_wallet_password__ - (Required) The password to encrypt the keys inside the wallet. The password must be at least 8 characters long and must include at least 1 letter and either 1 numeric character or 1 special character. + +Below is an example: + +``` +variable "adw_cpu_core_count" { + type = number + default = 1 +} + +variable "adw_size_in_tbs" { + type = number + default = 1 +} + +variable "adw_db_name" { + type = string + default = "ADWipan" +} + +variable "adw_db_workload" { + type = string + default = "DW" +} + +variable "adw_db_version" { + type = string + default = "19c" +} + +variable "adw_enable_auto_scaling" { + type = bool + default = true +} + +variable "adw_is_free_tier" { + type = bool + default = false +} + +variable "adw_license_model" { + type = string + default = "LICENSE_INCLUDED" +} + +variable "database_admin_password" { + type = string + default = "" +} + +variable "database_wallet_password" { + type = string + default = "" +} + +``` + +# Oracle Analytics Cloud +This resource provides the Analytics Instance resource in Oracle Cloud Infrastructure Analytics service. +Create a new AnalyticsInstance in the specified compartment. The operation is long-running and creates a new WorkRequest. + +* Parameters + * __analytics_instance_feature_set__ - Analytics feature set: ENTERPRISE_ANALYTICS or SELF_SERVICE_ANALYTICS set + * __analytics_instance_license_type__ - The license used for the service: LICENSE_INCLUDED or BRING_YOUR_OWN_LICENSE + * __analytics_instance_hostname__ - The name of the Analytics instance. This name must be unique in the tenancy and cannot be changed. + * __analytics_instance_idcs_access_token__ - IDCS access token identifying a stripe and service administrator user. THe IDCS access token can be obtained from OCI console - Menu -> Identity & Security -> Federation -> OracleIdentityCloudService - and now click on the Oracle Identity Cloud Service Console) + Access Oracle Identity Cloud Service console, click the avatar icon on the top-right corner, and then click My Access Tokens. + You can download an access token in the following ways: + Select Invokes Identity Cloud Service APIs to specify the available administrator roles that are assigned to you. The APIs from the specified administrator roles will be included in the token. + Select Invokes other APIs to select confidential applications that are assigned to the user account. + Click Select an Application to add a configured confidential resource application. On the Select an Application window, the list of assigned confidential applications displays. + Click applications to select them, and then click Add. The My Access Tokens page lists the added applications. + In the Token Expires in (Mins) field, select or enter how long (in minutes) the access token you're generating can be used before it expires. You can choose to keep the default number or specify between 1 and 527,040. + Click Download Token. The access token is generated and downloaded to your local machine as a tokens.tok file. + * __analytics_instance_capacity_capacity_type__ - The capacity model to use. Accepted values are: OLPU_COUNT, USER_COUNT . Values are case-insensitive. + * __analytics_instance_capacity_value__ - The capacity value selected (OLPU count, number of users, …etc…). This parameter affects the number of CPUs, amount of memory or other resources allocated to the instance. + * __analytics_instance_network_endpoint_details_network_endpoint_type__ - The type of network endpoint public or private + * __whitelisted_ips__ and __analytics_instance_network_endpoint_details_whitelisted_ips__ - If the network_endpoint_type is public you need to put the Source IP addresses or IP address ranges igress rules. + + +Below is an example: +``` +variable "analytics_instance_feature_set" { + type = string + default = "ENTERPRISE_ANALYTICS" +} + +variable "analytics_instance_license_type" { + type = string + default = "LICENSE_INCLUDED" +} + +variable "analytics_instance_hostname" { + type = string + default = "AnalyicSD" +} + +variable "analytics_instance_idcs_access_token" { + type = string + default = "copy-paste your token instead" +} + +variable "analytics_instance_capacity_capacity_type" { + type = string + default = "OLPU_COUNT" +} + +variable "analytics_instance_capacity_value" { + type = number + default = 1 +} + +variable "analytics_instance_network_endpoint_details_network_endpoint_type" { + type = string + default = "public" +} + +variable "whitelisted_ips" { + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "analytics_instance_network_endpoint_details_whitelisted_ips" { + type = list(string) + default = ["0.0.0.0/0"] +} +``` + +# Network +This resource provides the Vcn resource in Oracle Cloud Infrastructure Core service anso This resource provides the Subnet resource in Oracle Cloud Infrastructure Core service. +The solution will create 1 VCN in your compartment, 2 subnets ( one public and one private so the analytics cloud instance can be public or private ), 2 route tables for incomming and outoing traffic, 2 Network Security Groups for ingress and egress traffic, 1 internet gateway, 2 route tables for each subnet, dhcp service, NAT Gateway and a Service Gateway. + +* Parameters + * __service_name__ - The names of all compute and network resources will begin with this prefix. It can only contain letters or numbers and must begin with a letter. + * __vcn_cidr__ - The list of one or more IPv4 CIDR blocks for the VCN that meet the following criteria: + The CIDR blocks must be valid. + They must not overlap with each other or with the on-premises network CIDR block. + The number of CIDR blocks must not exceed the limit of CIDR blocks allowed per VCN. It is an error to set both cidrBlock and cidrBlocks. Note: cidr_blocks update must be restricted to one operation at a time (either add/remove or modify one single cidr_block) or the operation will be declined. + * __vcn_name__ - A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information. + * __public_subnet_cidr__ - The CIDR IP address range of the subnet. The CIDR must maintain the following rules - a. The CIDR block is valid and correctly formatted. b. The new range is within one of the parent VCN ranges. This is the cidr for the public subnet. + * __public_subnet_name__ - A user-friendly name for the public subnet. Does not have to be unique, and it's changeable. Avoid entering confidential information. + * __private_subnet_cidr__ - The CIDR IP address range of the subnet. The CIDR must maintain the following rules - a. The CIDR block is valid and correctly formatted. b. The new range is within one of the parent VCN ranges. This is the cidr for the private subnet. + * __private_subnet_name__ - A user-friendly name for the private subnet. Does not have to be unique, and it's changeable. Avoid entering confidential information. + + +Below is an example: +``` +variable "service_name" { + type = string + default = "servicename" + description = "prefix for stack resources" +} + +variable "vcn_cidr" { + default = "172.0.0.0/16" + description = "CIDR for new virtual cloud network" +} + +variable "vcn_name" { + default = "vcn" + description = "Name of new virtual cloud network" +} + +variable "public_subnet_cidr" { + default = "172.0.0.128/27" + description = "CIDR for bastion subnet" +} + +variable "public_subnet_name" { + default = "pub" +} + +variable "private_subnet_cidr" { + default = "172.0.0.32/27" +} + +variable "private_subnet_name" { + default = "priv" +} +``` + +Don't modify any other variables in the variable.tf file - it may cause that the solution will not work propertly. + +## Running the code + +``` +# Run init to get terraform modules +$ terraform init + +# Create the infrastructure +$ terraform apply --auto-approve + +# If you are done with this infrastructure, take it down +$ terraform destroy --auto-approve +``` + + +## Documentation + +[Autonomous Databases Overview](https://docs.oracle.com/en-us/iaas/Content/Database/Concepts/adboverview.htm) + +[Analytics Cloud Overview](https://docs.oracle.com/en-us/iaas/analytics-cloud/index.html) + +[Network Overview](https://docs.cloud.oracle.com/iaas/Content/Network/Concepts/overview.htm) + +[Terraform Autonomous Databases Resource](https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/database_autonomous_database) + +[Terraform Analytics Cloud Resource](https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/analytics_analytics_instance) + +[Terraform Vcn resource in Oracle Cloud Infrastructure Core service](https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/core_vcn) + +[Terraform Subnet resource in Oracle Cloud Infrastructure Core service](https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/core_subnet) + + +## The Team +- **Owners**: [Panaitescu Ionel](https://github.com/ionelpanaitescu), [Corina Todea](https://github.com/ctodearo) +- **Contributors**: Name Name, [Name Name](https://github.com/somebody), [Name Name](https://github.com/somebody) + +## Feedback +We welcome your feedback. To post feedback, submit feature ideas or report bugs, please use the Issues section on this repository. + +## Known Issues +**At the moment, there are no known issues** \ No newline at end of file diff --git a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/local.tf b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/local.tf new file mode 100644 index 0000000..f69ecb1 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/local.tf @@ -0,0 +1,379 @@ +data "oci_identity_availability_domains" "ADs" { + compartment_id = var.tenancy_ocid +} + +data "oci_identity_tenancy" "tenancy" { + tenancy_id = var.tenancy_ocid +} + +data "template_file" "ad_names" { + count = length(data.oci_identity_availability_domains.ADs.availability_domains) + template = lookup(data.oci_identity_availability_domains.ADs.availability_domains[count.index], "name") +} + +data "oci_core_services" "tf_services" { + filter { + name = "cidr_block" + values = ["all-.*-services-in-oracle-services-network"] + regex = true + } +} + +# resource "oci_identity_tag_namespace" "namespace" { +# provider = oci +# compartment_id = var.compartment_id +# description = "cloudfoundationorcl" +# name = "cloudfoundationorcl-deploy-adw-oac" + +# provisioner "local-exec" { +# command = "sleep 60" +# } +# } + +# resource "oci_identity_tag" "release" { +# provider = oci +# description = "release" +# name = "release" +# tag_namespace_id = oci_identity_tag_namespace.namespace.id + +# provisioner "local-exec" { +# command = "sleep 60" +# } +# } + +# resource "oci_identity_tag" "solution" { +# provider = oci +# description = "solution" +# name = "solution" +# tag_namespace_id = oci_identity_tag_namespace.namespace.id + +# provisioner "local-exec" { +# command = "sleep 60" +# } +# } + +# resource "oci_identity_tag" "subsystem" { +# provider = oci +# description = "subsystem" +# name = "subsystem" +# tag_namespace_id = oci_identity_tag_namespace.namespace.id + +# provisioner "local-exec" { +# command = "sleep 60" +# } +# } + +# resource "oci_identity_tag" "module" { +# provider = oci +# description = "module" +# name = "module" +# tag_namespace_id = oci_identity_tag_namespace.namespace.id + +# provisioner "local-exec" { +# command = "sleep 60" +# } +# } + +locals { + +# # # Remove all characters from the service_name that dont satisfy the criteria: +# # # must start with letter, must only contain letters and numbers and length between 1,8 +# # # See https://github.com/google/re2/wiki/Syntax - regex syntax supported by replace() + service_name_prefix = replace(var.service_name, "/[^a-zA-Z0-9]/", "") + # # #Availability Domains + ad_names = compact(data.template_file.ad_names.*.rendered) + public_subnet_availability_domain = local.ad_names[0] + + num_ads = length( + data.oci_identity_availability_domains.ADs.availability_domains, + ) + + is_single_ad_region = local.num_ads == 1 ? true : false + use_existing_subnets = false + is_vcn_peering = false + vcnsCount = var.vcn_name !="" && local.use_existing_subnets==false ? 1:0 + assign_public_ip = var.assign_public_ip || var.subnet_type == "Use Public Subnet" ? true : false + + public_subnet_cidr = var.public_subnet_cidr == "" && var.vcn_name != "" && ! local.assign_public_ip ? local.is_vcn_peering ? "11.0.6.0/24" : "10.0.6.0/24" : var.public_subnet_cidr + private_subnet_cidr = var.private_subnet_cidr == "" && var.vcn_name != "" ? local.is_vcn_peering ? "11.0.3.0/24" : "10.0.3.0/24" : var.private_subnet_cidr + + public_subnet = { + exists = {compartment_id=var.compartment_id, + availability_domain=var.use_regional_subnet? "" : local.public_subnet_availability_domain, + cidr = local.public_subnet_cidr, + dns_label=replace("${var.public_subnet_name}-${substr(uuid(), -7, -1)}", "-",""), + private=false, + dhcp_options_id=module.network-dhcp-options.dhcp_options["${var.service_name}-${var.dhcp_options_name}"].id, + security_list_ids=local.public_security_list_id, + defined_tags=local.defined_tags, + # defined_tags=var.network_defined_tags, + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "vcn-basic" + # } + freeform_tags=local.freeform_tags} + not_exists = {compartment_id="", availability_domain="", cidr="", dns_label="",private=false,dhcp_options_id="",security_list_ids=[""], defined_tags={}, freeform_tags={}} + } + + private_subnet = { + exists = {compartment_id=var.compartment_id, + availability_domain=var.use_regional_subnet? "" : var.private_subnet_availability_domain_name, + cidr = local.private_subnet_cidr, + dns_label=replace(format("%s-%s", var.private_subnet_name, substr(strrev(var.service_name), 0, 7)), "-",""), + private=true, + dhcp_options_id=module.network-dhcp-options.dhcp_options["${var.service_name}-${var.dhcp_options_name}"].id, + security_list_ids=local.private_security_list_id, + defined_tags=local.defined_tags, + # defined_tags=var.network_defined_tags, + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "vcn-basic" + # } + freeform_tags=local.freeform_tags} + not_exists={compartment_id="", availability_domain="", cidr="", dns_label="",private=false,dhcp_options_id="",security_list_ids=[""], defined_tags={}, freeform_tags={}} + } + + exists_public_subnet = ! local.assign_public_ip && var.public_subnet_id == "" ? true : false + exists_private_subnet = ! local.assign_public_ip && var.private_subnet_id == "" ? true : false + + existing_public_subnet = local.public_subnet[local.exists_public_subnet ? "exists" : "not_exists"] + existing_private_subnet = local.private_subnet[local.exists_private_subnet ? "exists" : "not_exists"] + +create_subnets = {"${local.service_name_prefix}-${var.public_subnet_name}"=local.existing_public_subnet,"${local.service_name_prefix}-${var.private_subnet_name}"=local.existing_private_subnet} + +# Security Lists + + public-security-list-def = { + exists = { + vcn_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id, + compartment_id = var.compartment_id, + defined_tags=local.defined_tags, + # defined_tags = var.security_defined_tags, + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "security" + # } + ingress_rules = concat([ + { + stateless = false, + protocol = "6", + src = var.anywhere_cidr, + src_type = "CIDR_BLOCK", + src_port = null, + dst_port = {min = 22, max = 22}, + icmp_type = null, + icmp_code = null + }], + [ + { + stateless = false, + protocol = "6", + src = var.anywhere_cidr, + src_type = "CIDR_BLOCK", + src_port = null, + dst_port = {min = 80, max = 80}, + icmp_type = null, + icmp_code = null + }]), + egress_rules = [ + { + stateless = false, + protocol = "all", + dst = var.anywhere_cidr, + dst_type = "CIDR_BLOCK", + src_port = null, + dst_port = null, + icmp_type = null, + icmp_code = null + }] + } + not_exists = {vcn_id="", compartment_id="", defined_tags = {}, ingress_rules=[], egress_rules=[]} + } + + private-security-list-def = { + exists = { + vcn_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id, + compartment_id = var.compartment_id, + defined_tags=local.defined_tags, + # defined_tags = var.security_defined_tags, + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "security" + # } + ingress_rules = [ + { + stateless = false, + protocol = "6", + src = var.public_subnet_cidr, + src_type = "CIDR_BLOCK", + src_port = null, + dst_port = null, + icmp_type = null, + icmp_code = null + }], + egress_rules = [ + { + stateless = false, + protocol = "all", + dst = var.anywhere_cidr, + dst_type = "CIDR_BLOCK", + src_port = null, + dst_port = null, + icmp_type = null, + icmp_code = null + }] + } + not_exists = {vcn_id="", compartment_id="", defined_tags = {}, ingress_rules=[], egress_rules=[]} + } + + public_security_list_id = compact( + concat( + [module.network-security-lists.security_lists["${var.service_name}-public-security-list"].id], + ), + ) + + private_security_list_id = compact( + concat( + [module.network-security-lists.security_lists["${var.service_name}-private-security-list"].id], + ), + ) + + public-security-list = local.public-security-list-def[local.use_existing_subnets ? "not_exists" : "exists"] + private-security-list = local.private-security-list-def[local.use_existing_subnets ? "not_exists" : "exists"] + + security-lists = { + !local.assign_public_ip ? "${var.service_name}-public-security-list" : "${var.service_name}-public-security-list" = local.public-security-list, + "${var.service_name}-private-security-list" = local.private-security-list, + } + + +# NSG: + public-nsgs-list-def = { + exists = { + vcn_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id, + compartment_id = var.compartment_id, + defined_tags=local.defined_tags, + # defined_tags = var.security_defined_tags, + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "security" + # } + ingress_rules = { ingress1 = { + is_create = true, + description = "Parameters for customizing Network Security Group(s).", + protocol = "all", + stateless = false, + src = var.public_subnet_cidr, + src_type = "CIDR_BLOCK", + dst_port_min = null, + dst_port_max = null, + src_port_min = null, + src_port_max = null, + icmp_type = null, + icmp_code = null + }}, + egress_rules = { egress1 = { + is_create = true, + description = "Parameters for customizing Network Security Group(s).", + protocol = "all", + stateless = false, + dst = var.anywhere_cidr, + dst_type = "CIDR_BLOCK", + dst_port_min = null, + dst_port_max = null, + src_port_min = null, + src_port_max = null, + icmp_type = null, + icmp_code = null + }}, + } + not_exists = {vcn_id="", ingress_rules=[], egress_rules=[]} + } + +### + private-nsgs-list-def = { + exists = { + vcn_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id, + compartment_id = var.compartment_id, + defined_tags=local.defined_tags, + # defined_tags = var.security_defined_tags, + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "security" + # } + ingress_rules = { ingress2 = { + is_create = true, + description = "Parameters for customizing Network Security Group(s).", + protocol = "all", + stateless = false, + src = var.private_subnet_cidr, + src_type = "CIDR_BLOCK", + dst_port_min = null, + dst_port_max = null, + src_port_min = null, + src_port_max = null, + icmp_type = null, + icmp_code = null + }}, + egress_rules = { egress2 = { + is_create = true, + description = "Parameters for customizing Network Security Group(s).", + protocol = "all", + stateless = false, + dst = var.anywhere_cidr, + dst_type = "CIDR_BLOCK", + dst_port_min = null, + dst_port_max = null, + src_port_min = null, + src_port_max = null, + icmp_type = null, + icmp_code = null + }} + } + not_exists = {vcn_id="", ingress_rules=[], egress_rules=[]} + } + + + public_nsg_list_id = compact( + concat( + [module.network-security-groups.nsgs["${var.service_name}-public-nsg-list"].id], + ), + ) + + private_nsg_list_id = compact( + concat( + [module.network-security-groups.nsgs["${var.service_name}-private-nsg-list"].id], + ), + ) + + public-nsg-list = local.public-nsgs-list-def[local.use_existing_subnets ? "not_exists" : "exists"] + private-nsg-list = local.private-nsgs-list-def[local.use_existing_subnets ? "not_exists" : "exists"] + nsgs-lists = {!local.assign_public_ip ? "${var.service_name}-public-nsg-list" : "${var.service_name}-public-nsg-list" = local.public-nsg-list, + "${var.service_name}-private-nsg-list" = local.private-nsg-list, + } + +# Tags + + #map of Tag key and value + #special chars string denotes empty values for tags for validation purposes + #otherwise zipmap function below fails first for empty strings before validators executed + use_defined_tags = var.defined_tag == "~!@#$%^&*()" && var.defined_tag_value == "~!@#$%^&*()" ? false : true + use_freeform_tags = var.free_form_tag == "~!@#$%^&*()" && var.free_form_tag_value == "~!@#$%^&*()" ? false : true + + #ignore defaults of special chars if tags are not provided + defined_tag = false == local.use_defined_tags ? "" : var.defined_tag + defined_tag_value = false == local.use_defined_tags ? "" : var.defined_tag_value + free_form_tag = false == local.use_freeform_tags ? "" : var.free_form_tag + free_form_tag_value = false == local.use_freeform_tags ? "" : var.free_form_tag_value + + defined_tags = zipmap( + compact([trimspace(local.defined_tag)]), + compact([trimspace(local.defined_tag_value)]), + ) + freeform_tags = zipmap( + compact([trimspace(local.free_form_tag)]), + compact([trimspace(local.free_form_tag_value)]), + ) + +} + diff --git a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/main.tf b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/main.tf new file mode 100644 index 0000000..916dbfe --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/main.tf @@ -0,0 +1,235 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +module "adw" { + source = "./modules/adw_subsystem" + compartment_id = var.compartment_id + adw_cpu_core_count = var.adw_cpu_core_count + adw_size_in_tbs = var.adw_size_in_tbs + adw_db_name = var.adw_db_name + adw_db_workload = var.adw_db_workload + adw_db_version = var.adw_db_version + adw_enable_auto_scaling = var.adw_enable_auto_scaling + adw_is_free_tier = var.adw_is_free_tier + adw_license_model = var.adw_license_model + database_admin_password = var.database_admin_password + database_wallet_password = var.database_wallet_password + # subnet_ocid = lookup(module.network-subnets.subnets,"${local.service_name_prefix}-${var.private_subnet_name}").id + # nsg_ids = module.network-security-groups.nsgid + defined_tags = local.defined_tags + # defined_tags = var.adw_defined_tags + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "adw_subsystem", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "adw" + # } +} + + +module "oac" { + source = "./modules/oac_subsystem" + compartment_id = var.compartment_id + analytics_instance_feature_set = var.analytics_instance_feature_set + analytics_instance_license_type = var.analytics_instance_license_type + analytics_instance_hostname = var.analytics_instance_hostname + analytics_instance_idcs_access_token = var.analytics_instance_idcs_access_token + analytics_instance_capacity_capacity_type = var.analytics_instance_capacity_capacity_type + analytics_instance_capacity_value = var.analytics_instance_capacity_value + analytics_instance_network_endpoint_details_network_endpoint_type = var.analytics_instance_network_endpoint_details_network_endpoint_type + subnet_id = lookup(module.network-subnets.subnets,"${local.service_name_prefix}-${var.private_subnet_name}").id + vcn_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id + analytics_instance_network_endpoint_details_whitelisted_ips = var.analytics_instance_network_endpoint_details_whitelisted_ips + analytics_instance_network_endpoint_details_whitelisted_vcns_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id + whitelisted_ips = var.whitelisted_ips + defined_tags = local.defined_tags + # defined_tags = var.oac_defined_tags + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "oac_subsystem", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "oac" + # } +} + +module "network-vcn" { + + source = "../../../cloud-foundation/modules/oci-cis-landingzone-quickstart/network/vcn-basic" + + compartment_id = var.compartment_id + service_label = var.service_name + service_gateway_cidr = lookup(data.oci_core_services.tf_services.services[0], "cidr_block") + + vcns = {for x in range(local.vcnsCount) : "${var.service_name}-${var.vcn_name}" => { + + compartment_id = var.compartment_id + cidr = var.vcn_cidr + dns_label = format("%svcn",substr((var.service_name), 0, 10)) + is_create_igw = (var.vcn_name=="" || local.use_existing_subnets) ? false : true + is_attach_drg = false + block_nat_traffic = local.assign_public_ip && var.vcn_name!="" ? true : false + + subnets = {subnet={compartment_id="", vcn_id="", availability_domain="", cidr="", dns_label="",private=false,dhcp_options_id="",security_list_ids=[""], defined_tags={}, freeform_tags={}}} + + defined_tags = local.defined_tags + # defined_tags = var.network_defined_tags + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "vcn-basic" + # } + freeform_tags = local.freeform_tags + } + } +} + +module "network-subnets" { + + source = "../../../cloud-foundation/modules/oci-cis-landingzone-quickstart/network/vcn-basic" + + compartment_id = var.compartment_id + service_label = var.service_name + service_gateway_cidr = "all-.*-services-in-oracle-services-network" + + vcns = {for x in range(local.vcnsCount) : "" => { + + compartment_id = var.compartment_id + cidr = var.vcn_cidr + dns_label = format("%svcn",substr((var.service_name), 0, 10)) + is_create_igw = false + is_attach_drg = false + block_nat_traffic = local.assign_public_ip && var.vcn_name!="" ? true : false + + subnets = {for k, v in local.create_subnets: k => { + compartment_id = v.compartment_id, + vcn_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id + availability_domain = v.availability_domain, + cidr = v.cidr, + dns_label = v.dns_label, + private = v.private, + dhcp_options_id = v.dhcp_options_id, + security_list_ids = v.security_list_ids, + defined_tags = v.defined_tags, + freeform_tags = v.freeform_tags + } if v.compartment_id != "" + } + + defined_tags = local.defined_tags + # defined_tags = var.network_defined_tags + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "vcn-basic" + # } + freeform_tags = local.freeform_tags + } + } +} + +module "network-routing" { + + source = "../../../cloud-foundation/modules/oci-cis-landingzone-quickstart/network/vcn-routing" + + compartment_id = var.compartment_id + + subnets_route_tables = { + "${local.service_name_prefix}-routetable-out" = { + compartment_id = var.compartment_id, + vcn_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id, + subnet_id = lookup(module.network-subnets.subnets,"${local.service_name_prefix}-${var.public_subnet_name}").id, + route_table_id = "", + route_rules = [{ + is_create = true, + destination = "0.0.0.0/0", + destination_type = "CIDR_BLOCK", + network_entity_id = lookup(module.network-vcn.internet_gateways, lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id).id, + description = "" + }], + defined_tags = local.defined_tags + # defined_tags = var.routing_defined_tags + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "vcn-routing" + # } + }, + "${local.service_name_prefix}-routetable" = { + compartment_id = var.compartment_id, + vcn_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id, + subnet_id = lookup(module.network-subnets.subnets,"${local.service_name_prefix}-${var.private_subnet_name}").id, + route_table_id = "", + route_rules = concat( [], + [ + { + is_create = true + destination = lookup(data.oci_core_services.tf_services.services[0], "cidr_block"), + destination_type = "SERVICE_CIDR_BLOCK", + network_entity_id = lookup(module.network-vcn.service_gateways, lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id).id, + description = "" + } + ]), + defined_tags = local.defined_tags + # defined_tags = var.routing_defined_tags + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "vcn-routing" + # } + } + } +} + +module "network-routing-attachment" { + source = "../../../cloud-foundation/modules/oci-cis-landingzone-quickstart/network/vcn-routing" + compartment_id = var.compartment_id + + subnets_route_tables = { + "" = { + compartment_id = var.compartment_id, + vcn_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id, + subnet_id = lookup(module.network-subnets.subnets,"${local.service_name_prefix}-${var.public_subnet_name}").id, + route_table_id = lookup(module.network-routing.subnets_route_tables,"${local.service_name_prefix}-routetable-out").id, + route_rules = ([]), + defined_tags = local.defined_tags + # defined_tags = var.routing_defined_tags + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "vcn-routing" + # } + } + } +} + +module "network-security-lists" { + source = "../../../cloud-foundation/modules/oci-cis-landingzone-quickstart/network/security" + compartment_id = var.compartment_id + ports_not_allowed_from_anywhere_cidr = [3390,4500] + + security_lists = { + for k,v in local.security-lists : k => v if v.compartment_id != "" + } +} + +module "network-dhcp-options" { + source = "../../../cloud-foundation/modules/oci-cis-landingzone-quickstart/network/security" + compartment_id = var.compartment_id + + dhcp_options = {for x in range(local.is_vcn_peering ? 0 : (local.use_existing_subnets ? 0 : 1 ) ) : "${var.service_name}-${var.dhcp_options_name}" => { + vcn_id = lookup(module.network-vcn.vcns,"${var.service_name}-${var.vcn_name}").id, + compartment_id = var.compartment_id, + options = { + type = "DomainNameServer" + server_type = "VcnLocalPlusInternet" + }, + defined_tags = local.defined_tags + # defined_tags = var.security_defined_tags, + # defined_tags = { "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.release.name}" = "1.0", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.subsystem.name}" = "network", + # "${oci_identity_tag_namespace.namespace.name}.${oci_identity_tag.module.name}" = "security" + # } + freeform_tags = local.freeform_tags + } + } +} + +module "network-security-groups" { + source = "../../../cloud-foundation/modules/oci-cis-landingzone-quickstart/network/security" + compartment_id = var.compartment_id + + nsgs = { + for k,v in local.nsgs-lists : k => v if v.compartment_id != "" + } +} + diff --git a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/adw_subsystem/main.tf b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/adw_subsystem/main.tf new file mode 100644 index 0000000..50963df --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/adw_subsystem/main.tf @@ -0,0 +1,28 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +module "adw" { + source = "../../../../../cloud-foundation/modules/cloud-foundation-library/database/adw" + adw_params = { + adw = { + compartment_id = var.compartment_id, + adw_cpu_core_count = var.adw_cpu_core_count, + adw_size_in_tbs = var.adw_size_in_tbs, + adw_db_name = var.adw_db_name, + adw_db_workload = var.adw_db_workload, + adw_db_version = var.adw_db_version, + adw_enable_auto_scaling = var.adw_enable_auto_scaling, + adw_is_free_tier = var.adw_is_free_tier, + adw_license_model = var.adw_license_model, + database_admin_password = var.database_admin_password, + database_wallet_password = var.database_wallet_password, + # subnet_id = var.subnet_ocid, + # nsg_ids = var.nsg_ids, + defined_tags = var.defined_tags + }, + } +} + + + + \ No newline at end of file diff --git a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/adw_subsystem/outputs.tf b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/adw_subsystem/outputs.tf new file mode 100644 index 0000000..0976316 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/adw_subsystem/outputs.tf @@ -0,0 +1,6 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +output "ADW_Service_Console_URL" { + value = module.adw.ADW_Service_Console_URL +} diff --git a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/adw_subsystem/variables.tf b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/adw_subsystem/variables.tf new file mode 100644 index 0000000..df44792 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/adw_subsystem/variables.tf @@ -0,0 +1,26 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +variable "compartment_id" {} +variable "adw_cpu_core_count" {} +variable "adw_size_in_tbs" {} +variable "adw_db_name" {} +variable "adw_db_workload" {} +variable "adw_db_version" {} +variable "adw_enable_auto_scaling" {} +variable "adw_is_free_tier" {} +variable "adw_license_model" {} +variable "database_admin_password" {} +variable "database_wallet_password" {} + +# variable "subnet_ocid" {} + +# variable "nsg_ids" { +# type = list(string) +# default = [] +# } + +variable "defined_tags" { + type = map + default = {} +} diff --git a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/oac_subsystem/main.tf b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/oac_subsystem/main.tf new file mode 100644 index 0000000..ae21690 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/oac_subsystem/main.tf @@ -0,0 +1,24 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +module "oac" { + source = "../../../../../cloud-foundation/modules/cloud-foundation-library/oac" + oac_params = { + oac = { + compartment_id = var.compartment_id, + analytics_instance_feature_set = var.analytics_instance_feature_set, + analytics_instance_license_type = var.analytics_instance_license_type, + analytics_instance_hostname = var.analytics_instance_hostname, + analytics_instance_idcs_access_token = var.analytics_instance_idcs_access_token, + analytics_instance_capacity_capacity_type = var.analytics_instance_capacity_capacity_type, + analytics_instance_capacity_value = var.analytics_instance_capacity_value, + defined_tags = var.defined_tags + analytics_instance_network_endpoint_details_network_endpoint_type = var.analytics_instance_network_endpoint_details_network_endpoint_type + subnet_id = var.subnet_id + vcn_id = var.vcn_id + analytics_instance_network_endpoint_details_whitelisted_ips = var.analytics_instance_network_endpoint_details_whitelisted_ips + analytics_instance_network_endpoint_details_whitelisted_vcns_id = var.analytics_instance_network_endpoint_details_whitelisted_vcns_id + whitelisted_ips = var.whitelisted_ips + } + } +} diff --git a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/oac_subsystem/outputs.tf b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/oac_subsystem/outputs.tf new file mode 100644 index 0000000..896ba46 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/oac_subsystem/outputs.tf @@ -0,0 +1,11 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +output "Analytics_URL" { + value = module.oac.Analytics_URL +} + + + + + diff --git a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/oac_subsystem/variables.tf b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/oac_subsystem/variables.tf new file mode 100644 index 0000000..4fd45c6 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/modules/oac_subsystem/variables.tf @@ -0,0 +1,55 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +variable "compartment_id" { + type = string +} + +variable "analytics_instance_feature_set" { + type = string +} + +variable "analytics_instance_license_type" { + type = string +} + +variable "analytics_instance_hostname" { + type = string +} + +variable "analytics_instance_idcs_access_token" { + type = string +} + +variable "analytics_instance_capacity_capacity_type" { + type = string +} + +variable "analytics_instance_capacity_value" { + type = number +} + +variable "defined_tags" { + type = map + default = {} +} + +variable "subnet_id" {} +variable "vcn_id" {} +variable "analytics_instance_network_endpoint_details_network_endpoint_type" {} +variable "analytics_instance_network_endpoint_details_whitelisted_vcns_id" {} + +variable "whitelisted_ips" { + type = list(string) + default = [] +} + +variable "analytics_instance_network_endpoint_details_whitelisted_ips" { + type = list(string) + default = [] +} + + + + + diff --git a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/outputs.tf b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/outputs.tf new file mode 100644 index 0000000..3f82620 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/outputs.tf @@ -0,0 +1,15 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +output "ADW_Service_Console_URL" { + value = module.adw.ADW_Service_Console_URL +} + +output "Analytics_URL" { + value = module.oac.Analytics_URL +} + +output "Instructions" { + value = "Please use the ADW URL to login by using the user admin and the password that it's provided in the output.Also change the password with one that you desire." +} + diff --git a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/provider.tf b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/provider.tf new file mode 100644 index 0000000..6019931 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/provider.tf @@ -0,0 +1,11 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + +terraform { + required_providers { + oci = { + version = ">= 4.37.0" + source = "hashicorp/oci" + } + } +} diff --git a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/schema.yaml b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/schema.yaml new file mode 100644 index 0000000..1196415 --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/schema.yaml @@ -0,0 +1,373 @@ +title: "Create ADW and OAC in Oracle Cloud Infrastructure" +stackDescription: "Deploy Autonomous Data Warehouse (ADW) and Oracle Analytics Cloud (OAC) in Oracle Cloud Infrastructure." +schemaVersion: 1.1.0 +version: "20210902" +locale: "en" +groupings: + - title: "General Settings" + visible: true + variables: + - region + - tenancy_ocid + - compartment_id + - display_name_prefix + - title: "Autonomous Database Configuration" + variables: + - adw_db_name + - adw_is_free_tier + - adw_license_model + - database_admin_password + - database_wallet_password + - adw_db_version + - adw_size_in_tbs + - adw_enable_auto_scaling + - adw_cpu_core_count + - adw_db_workload + - title: "Oracle Analytics Cloud Configuration" + variables: + - analytics_instance_hostname + - analytics_instance_license_type + - analytics_instance_feature_set + - analytics_instance_capacity_value + - analytics_instance_capacity_capacity_type + - analytics_instance_network_endpoint_details_network_endpoint_type + - analytics_instance_idcs_access_token + - title: "Network Configuration" + variables: + - service_name + - vcn_cidr + - vcn_name + - public_subnet_name + - public_subnet_cidr + - private_subnet_name + - private_subnet_cidr + - show_advanced_options + - title: "Hidden Variables" + visible: false + variables: + - user_ocid + - fingerprint + - private_key_path + - defined_tag + - defined_tag_value + - free_form_tag + - free_form_tag_value + - dhcp_options_name + - anywhere_cidr + - assign_public_ip + - use_regional_subnet + - subnet_type + - private_subnet_availability_domain_name + - private_subnet_id + - public_subnet_id + - whitelisted_ips + - analytics_instance_network_endpoint_details_whitelisted_ips +# General Configuration Variables +variables: + tenancy_ocid: + title: Tenancy ID + description: The Oracle Cloud Identifier (OCID) for your tenancy. + type: string + required: true + visible: false + region: + title: Region + description: Select Region where all resources will be created. + type: oci:identity:region:name + required: true + visible: true + compartment_id: + title: Stack Compartment + description: Choose the compartment where all resources will be provisioned. + type: oci:identity:compartment:id + required: true + visible: true + display_name_prefix: + title: Display Name Prefix + type: string + default: "Autonomous Data Warehouse (ADW) and Oracle Analytics Cloud (OAC)" + description: Enter the Display name for the solution. + required: true + visible: true +# Autonomous Database Configuration Variables + adw_db_name: + title: Database Name + description: "Provide Database name. Constraints: 12 alphanumeric characters only. No Spaces." + required: true + type: string + maxLength: 14 + adw_is_free_tier: + title: Do do want a always Free Oracle Autonomous Database instance? + description: "Provision Always Free Oracle Autonomous Database instance (1 OCPU 20 GB Storage)?" + type: enum + enum: + - "true" + - "false" + default: "false" + required: true + visible: true + adw_license_model: + title: "Provision Paid Oracle Autonomous Database instance (2 OCPU 1 TB Storage) - License Included or BYOL?" + description: "Note: This configuration can be changed later from the OCI console." + type: enum + enum: + - LICENSE_INCLUDED + - BRING_YOUR_OWN_LICENSE + default: LICENSE_INCLUDED + required: true + visible: + eq: + - adw_is_free_tier + - "false" + database_admin_password: + title: Database Admin Password + description: "Provide admin password. Constraints: 12 - 30 characters. At least one uppercase letter, one lowercase letter, and one number. No special characters." + type: password + required: true + confirmation: true + pattern: ((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*[%!@^&)(]).{12,20}) + database_wallet_password: + title: Database Wallet Password + description: Provide database wallet password. Must be a minimum 12 characters, contain at least one uppercase letter, one lowercase letter, one number. Do not include special characters. + type: password + required: true + confirmation: true + pattern: ((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*[%!@^&)(]).{12,20}) + adw_db_version: + title: "A valid Oracle Database version for Autonomous Database" + description: "A valid Oracle Database version for Autonomous Database" + type: enum + enum: + - "19c" + default: "19c" + required: true + visible: true + adw_size_in_tbs: + title: "The quantity of data in the database, in terabytes." + description: "The quantity of data in the database, in terabytes." + type: enum + enum: + - 1 + - 2 + - 4 + - 6 + - 8 + - 10 + - 12 + - 16 + - 24 + - 36 + - 52 + - 128 + default: 1 + visible: true + required: true + adw_enable_auto_scaling: + title: Indicates if auto scaling is enabled for the Autonomous Database CPU core count. + description: "Indicates if auto scaling is enabled for the Autonomous Database CPU core count. " + type: enum + enum: + - "true" + - "false" + default: "true" + required: true + visible: true + adw_cpu_core_count: + title: The number of OCPU cores to be made available to the database + description: "The number of OCPU cores to enable. Available cores are subject to your tenancy's service limits." + type: enum + enum: + - 1 + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + - 8 + - 9 + - 10 + - 11 + - 12 + default: 1 + required: true + visible: true + adw_db_workload: + title: Autonomous Database Type of workload. + description: "Autonomous Database Type of workload." + type: enum + enum: + - "DW" + default: "DW" + required: true + visible: false + # Oracle Analytics Cloud Configuration + analytics_instance_hostname: + title: Analytics Instance Name + description: "Enter a unique name for this instance. The name provided must start with a letter, contain only alphanumeric characters, no spaces and span up to 30 characters in total." + type: string + maxLength: 30 + default: "AnalyticsG" + required: true + visible: true + analytics_instance_license_type: + title: Analytics License + description: Choose your Oracle Analytics Cloud License Type. + type: enum + enum: + - LICENSE_INCLUDED + - BRING_YOUR_OWN_LICENSE + default: LICENSE_INCLUDED + visible: true + required: true + analytics_instance_feature_set: + title: Analytics Instance Type + description: Choose the Analytics Product Type. + type: enum + enum: + - SELF_SERVICE_ANALYTICS + - ENTERPRISE_ANALYTICS + default: "ENTERPRISE_ANALYTICS" + visible: create_analytics_instance + required: true + analytics_instance_capacity_value: + title: Analytics Instance Capacity + description: Provide the number of OCPUs for the Oracle Analytics Instance. + type: enum + enum: + - 1 + - 2 + - 4 + - 6 + - 8 + - 10 + - 12 + - 16 + - 24 + - 36 + - 52 + default: 1 + visible: true + required: true + analytics_instance_capacity_capacity_type: + title: Analytics Instance Capacity Type + description: The capacity value selected (OLPU count, number of users, …etc…). This parameter affects the number of CPUs, amount of memory or other resources allocated to the instance. + type: enum + enum: + - "OLPU_COUNT" + - "USERS_COUNT" + default: "OLPU_COUNT" + visible: true + required: true + analytics_instance_network_endpoint_details_network_endpoint_type: + title: Analytics Instance Base representation of a network endpoint + description: "The type of network endpoint: Public or Private Network endpoint" + type: enum + enum: + - "public" + - "private" + default: "public" + visible: true + required: true + analytics_instance_idcs_access_token: + title: IDCS Access Token + description: Provide IDCS Access token. See Pre-req section in the Installation Document. + type: string + default: "copy-paste your token instead" + visible: true + required: true +# Network Configuration + service_name: + visible: + and: + - show_advanced_options + type: string + default: "servicename" + minLength: 1 + maxLength: 255 + pattern: "^[a-zA-Z_]\\w{0,254}$" + required: true + title: Resource Name Prefix + description: The names of all compute and network resources will begin with this prefix. It can only contain letters or numbers and must begin with a letter. + vcn_cidr: + visible: + and: + - show_advanced_options + type: string + default: "172.0.0.0/16" + pattern: "^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\/(3[0-2]|[1-2]?[0-9])$" + title: VCN Network CIDR + required: true + description: The CIDR to assign to the new Virtual Cloud Network (VCN) to create for this service. This field is not required if you want to use an existing VCN. When using VCN peering ensure that the VCNs being peered have non-overlapping CIDR blocks. + vcn_name: + visible: + and: + - show_advanced_options + type: string + default: "vcn" + minLength: 1 + maxLength: 255 + pattern: "^[a-zA-Z_]\\w{0,254}$" + required: true + title: VCN Name + description: The name of the new Virtual Cloud Network (VCN) to create for this service + public_subnet_cidr: + visible: + and: + - show_advanced_options + type: string + default: "172.0.0.128/27" + pattern: "^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\/(3[0-2]|[1-2]?[0-9])$" + required: true + title: Public Subnet CIDR + description: "The CIDR of the new public subnet." + public_subnet_name: + visible: + and: + - show_advanced_options + type: string + default: "pub" + required: true + title: Public Subnet Name + description: "The name of the new public subnet." + private_subnet_cidr: + visible: + and: + - show_advanced_options + type: string + default: "172.0.0.32/27" + pattern: "^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\/(3[0-2]|[1-2]?[0-9])$" + required: true + title: Private Subnet CIDR + description: "The CIDR of the new private subnet." + private_subnet_name: + visible: + and: + - show_advanced_options + type: string + default: "priv" + required: true + title: Private Subnet Name + description: "The name of the new private subnet." + show_advanced_options: + title: Show Advanced Options + description: Enable advanced options for network. + type: boolean + default: false + visible: true +outputs: + Instructions: + type: string + title: Instructions + Analytics_URL: + type: link + title: Analytics URL + ADW_Service_Console_URL: + type: link + title: ADB Service Console URL +outputGroups: + - title: Application + outputs: + - Instructions + - ADW_Service_Console_URL + - Analytics_URL diff --git a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/variables.tf b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/variables.tf new file mode 100644 index 0000000..4428a1d --- /dev/null +++ b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/variables.tf @@ -0,0 +1,244 @@ +# Copyright © 2021, Oracle and/or its affiliates. +# All rights reserved. Licensed under the Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl. + + +terraform { + required_version = ">= 0.14.0" +} + +variable "tenancy_ocid" { + type = string + default = "" +} +variable "region" { + type = string + default = "" +} + +variable "compartment_id" { + type = string + default = "" +} + +variable "user_ocid" { + type = string + default = "" +} + +variable "fingerprint" { + type = string + default = "" +} + +variable "private_key_path" { + type = string + default = "" +} + +# Autonomous Database Configuration Variables + +variable "adw_cpu_core_count" { + type = number + default = 1 +} + +variable "adw_size_in_tbs" { + type = number + default = 1 +} + +variable "adw_db_name" { + type = string + default = "ADWiopa" +} + +variable "adw_db_workload" { + type = string + default = "DW" +} + +variable "adw_db_version" { + type = string + default = "19c" +} + +variable "adw_enable_auto_scaling" { + type = bool + default = true +} + +variable "adw_is_free_tier" { + type = bool + default = false +} + +variable "adw_license_model" { + type = string + default = "LICENSE_INCLUDED" +} + +variable "database_admin_password" { + type = string + default = "" +} + +variable "database_wallet_password" { + type = string + default = "" +} + +# Oracle Analytics Cloud Configuration + +variable "analytics_instance_feature_set" { + type = string + default = "ENTERPRISE_ANALYTICS" +} + +variable "analytics_instance_license_type" { + type = string + default = "LICENSE_INCLUDED" +} + +variable "analytics_instance_hostname" { + type = string + default = "AnalyicSD" +} + +variable "analytics_instance_idcs_access_token" { + type = string + default = "copy-paste your token instead" +} + +variable "analytics_instance_capacity_capacity_type" { + type = string + default = "OLPU_COUNT" +} + +variable "analytics_instance_capacity_value" { + type = number + default = 1 +} + +variable "analytics_instance_network_endpoint_details_network_endpoint_type" { + type = string + default = "public" +} + +variable "whitelisted_ips" { + type = list(string) + default = ["0.0.0.0/0"] +} + +variable "analytics_instance_network_endpoint_details_whitelisted_ips" { + type = list(string) + default = ["0.0.0.0/0"] +} + +# Network + +variable "service_name" { + type = string + default = "servicename" + description = "prefix for stack resources" +} + +variable "vcn_cidr" { + default = "172.0.0.0/16" + description = "CIDR for new virtual cloud network" +} + +variable "vcn_name" { + default = "vcn" + description = "Name of new virtual cloud network" +} + +variable "public_subnet_cidr" { + default = "172.0.0.128/27" + description = "CIDR for bastion subnet" +} + +variable "public_subnet_name" { + default = "pub" +} + +variable "private_subnet_cidr" { + default = "172.0.0.32/27" +} + +variable "private_subnet_name" { + default = "priv" +} + +# don't modify any other variables (below) - it may cause that the solution will not work propertly. + +variable "use_regional_subnet" { + type = bool + default = true + description = "Indicates use of regional subnets (preferred) instead of AD specific subnets" +} + +variable "subnet_type" { + default = "Use Private Subnet" +} + +variable "public_subnet_id" { + default = "" + description = "OCID for existing subnet for bastion instance" +} + +variable "private_subnet_id" { + default = "" + description = "OCID for existing subnet for weblogic instances" +} + +variable "assign_public_ip" { + type = bool + default = false + description = "Indicates use of private subnets" +} + +variable "private_subnet_availability_domain_name" { + type = string + default = "" + description = "availablility domain for weblogic vm instances" +} + +variable "dhcp_options_name" { + default = "dhcpOptions" +} + +variable anywhere_cidr { + default = "0.0.0.0/0" +} + +# Define Tags + + +#Note: special chars string denotes empty values for tags for validation purposes +#otherwise zipmap function in main.tf fails first for empty strings before validators executed. + +variable "defined_tag" { + type = string + default = "~!@#$%^&*()" + description = "defined resource tag name" +} + +variable "defined_tag_value" { + type = string + default = "~!@#$%^&*()" + description = "defined resource tag value" +} + +variable "free_form_tag" { + type = string + default = "~!@#$%^&*()" + description = "free form resource tag name" +} + +variable "free_form_tag_value" { + type = string + default = "~!@#$%^&*()" + description = "free form resource tag value" +} + +# End diff --git a/cloud-foundation/solutions/README.md b/cloud-foundation/solutions/README.md new file mode 100644 index 0000000..5bfc83e --- /dev/null +++ b/cloud-foundation/solutions/README.md @@ -0,0 +1,8 @@ +# Oracle Cloud Foundation Terraform Solution Available today + + +## Overview +For the moment we have implemented the following solutions: +- Departmental DWH Full Solution +- Departmental DWH Small Footprint Solution +- Weblogic Clustered Deployment Solution \ No newline at end of file From 096e60f89447d194fb4846c26414e286b65b2335 Mon Sep 17 00:00:00 2001 From: ionel_panaitescu Date: Tue, 26 Oct 2021 17:40:35 +0300 Subject: [PATCH 2/5] Added URLS in the readme.md for the resource manager solutions --- .../solutions/Departmental-DWH-Full-Solution/README.md | 2 +- .../Departmental-DWH-Small-Footprint-Solution/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/README.md b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/README.md index b128ac9..9420e30 100644 --- a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/README.md +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/README.md @@ -40,7 +40,7 @@ If you don't have the required permissions and quota, contact your tenancy admin # Deploy Using Oracle Resource Manager -1. Click [![Deploy to Oracle Cloud](https://oci-resourcemanager-plugin.plugins.oci.oraclecloud.com/latest/deploy-to-oracle-cloud.svg)](https://cloud.oracle.com/resourcemanager/stacks/create?region=home&zipUrl=https://github.com/oracle-devrel/terraform-oci-oracle-cloud-foundation/tree/main/releases/latest/download/oci-arch-adw-oac-stack-latest.zip) +1. Click [![Deploy to Oracle Cloud](https://oci-resourcemanager-plugin.plugins.oci.oraclecloud.com/latest/deploy-to-oracle-cloud.svg)](https://cloud.oracle.com/resourcemanager/stacks/create?region=home&zipUrl=https://github.com/oracle-devrel/terraform-oci-oracle-cloud-foundation/blob/develop/cloud-foundation/solutions-for-oracle-res-mgr/Departmental%20DWH%20-%20Full%20Solution.zip) If you aren't already signed in, when prompted, enter the tenancy and user credentials. diff --git a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/README.md b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/README.md index 3660e75..8654323 100644 --- a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/README.md +++ b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/README.md @@ -40,7 +40,7 @@ If you don't have the required permissions and quota, contact your tenancy admin # Deploy Using Oracle Resource Manager -1. Click [![Deploy to Oracle Cloud](https://oci-resourcemanager-plugin.plugins.oci.oraclecloud.com/latest/deploy-to-oracle-cloud.svg)](https://cloud.oracle.com/resourcemanager/stacks/create?region=home&zipUrl=https://github.com/oracle-devrel/terraform-oci-oracle-cloud-foundation/tree/main/releases/latest/download/oci-arch-adw-oac-stack-latest.zip) +1. Click [![Deploy to Oracle Cloud](https://oci-resourcemanager-plugin.plugins.oci.oraclecloud.com/latest/deploy-to-oracle-cloud.svg)](https://cloud.oracle.com/resourcemanager/stacks/create?region=home&zipUrl=https://github.com/oracle-devrel/terraform-oci-oracle-cloud-foundation/blob/develop/cloud-foundation/solutions-for-oracle-res-mgr/Departmental%20DWH%20-%20Small%20Footprint%20Solution.zip) If you aren't already signed in, when prompted, enter the tenancy and user credentials. From 0095703b3101202e32d1d8ebad505ed4e1655d64 Mon Sep 17 00:00:00 2001 From: ionel_panaitescu Date: Tue, 26 Oct 2021 17:46:04 +0300 Subject: [PATCH 3/5] all --- ...ution.zip => Departmental-DWH-Full-Solution.zip} | Bin ...> Departmental-DWH-Small-Footprint-Solution.zip} | Bin 2 files changed, 0 insertions(+), 0 deletions(-) rename cloud-foundation/solutions-for-oracle-res-mgr/{Departmental DWH - Full Solution.zip => Departmental-DWH-Full-Solution.zip} (100%) rename cloud-foundation/solutions-for-oracle-res-mgr/{Departmental DWH - Small Footprint Solution.zip => Departmental-DWH-Small-Footprint-Solution.zip} (100%) diff --git a/cloud-foundation/solutions-for-oracle-res-mgr/Departmental DWH - Full Solution.zip b/cloud-foundation/solutions-for-oracle-res-mgr/Departmental-DWH-Full-Solution.zip similarity index 100% rename from cloud-foundation/solutions-for-oracle-res-mgr/Departmental DWH - Full Solution.zip rename to cloud-foundation/solutions-for-oracle-res-mgr/Departmental-DWH-Full-Solution.zip diff --git a/cloud-foundation/solutions-for-oracle-res-mgr/Departmental DWH - Small Footprint Solution.zip b/cloud-foundation/solutions-for-oracle-res-mgr/Departmental-DWH-Small-Footprint-Solution.zip similarity index 100% rename from cloud-foundation/solutions-for-oracle-res-mgr/Departmental DWH - Small Footprint Solution.zip rename to cloud-foundation/solutions-for-oracle-res-mgr/Departmental-DWH-Small-Footprint-Solution.zip From 86bc3dc00de4ebe955ee3fd9f2e4d29cdbd29e0b Mon Sep 17 00:00:00 2001 From: ionel_panaitescu Date: Tue, 26 Oct 2021 17:48:04 +0300 Subject: [PATCH 4/5] Added URLS in the readme.md for the resource manager solutions --- .../solutions/Departmental-DWH-Full-Solution/README.md | 2 +- .../Departmental-DWH-Small-Footprint-Solution/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/README.md b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/README.md index 9420e30..22da517 100644 --- a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/README.md +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/README.md @@ -40,7 +40,7 @@ If you don't have the required permissions and quota, contact your tenancy admin # Deploy Using Oracle Resource Manager -1. Click [![Deploy to Oracle Cloud](https://oci-resourcemanager-plugin.plugins.oci.oraclecloud.com/latest/deploy-to-oracle-cloud.svg)](https://cloud.oracle.com/resourcemanager/stacks/create?region=home&zipUrl=https://github.com/oracle-devrel/terraform-oci-oracle-cloud-foundation/blob/develop/cloud-foundation/solutions-for-oracle-res-mgr/Departmental%20DWH%20-%20Full%20Solution.zip) +1. Click [![Deploy to Oracle Cloud](https://oci-resourcemanager-plugin.plugins.oci.oraclecloud.com/latest/deploy-to-oracle-cloud.svg)](https://cloud.oracle.com/resourcemanager/stacks/create?region=home&zipUrl=https://github.com/oracle-devrel/terraform-oci-oracle-cloud-foundation/blob/develop/cloud-foundation/solutions-for-oracle-res-mgr/Departmental-DWH-Full-Solution.zip) If you aren't already signed in, when prompted, enter the tenancy and user credentials. diff --git a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/README.md b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/README.md index 8654323..9cb2ca1 100644 --- a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/README.md +++ b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/README.md @@ -40,7 +40,7 @@ If you don't have the required permissions and quota, contact your tenancy admin # Deploy Using Oracle Resource Manager -1. Click [![Deploy to Oracle Cloud](https://oci-resourcemanager-plugin.plugins.oci.oraclecloud.com/latest/deploy-to-oracle-cloud.svg)](https://cloud.oracle.com/resourcemanager/stacks/create?region=home&zipUrl=https://github.com/oracle-devrel/terraform-oci-oracle-cloud-foundation/blob/develop/cloud-foundation/solutions-for-oracle-res-mgr/Departmental%20DWH%20-%20Small%20Footprint%20Solution.zip) +1. Click [![Deploy to Oracle Cloud](https://oci-resourcemanager-plugin.plugins.oci.oraclecloud.com/latest/deploy-to-oracle-cloud.svg)](https://cloud.oracle.com/resourcemanager/stacks/create?region=home&zipUrl=https://github.com/oracle-devrel/terraform-oci-oracle-cloud-foundation/blob/develop/cloud-foundation/solutions-for-oracle-res-mgr/Departmental-DWH-Small-Footprint-Solution.zip) If you aren't already signed in, when prompted, enter the tenancy and user credentials. From fd5da928561f233b975b6bf09bb5beb3c20bc869 Mon Sep 17 00:00:00 2001 From: ionel_panaitescu Date: Tue, 26 Oct 2021 18:19:55 +0300 Subject: [PATCH 5/5] Added new URL links --- .../solutions/Departmental-DWH-Full-Solution/README.md | 2 +- .../Departmental-DWH-Small-Footprint-Solution/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/README.md b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/README.md index 22da517..401cc71 100644 --- a/cloud-foundation/solutions/Departmental-DWH-Full-Solution/README.md +++ b/cloud-foundation/solutions/Departmental-DWH-Full-Solution/README.md @@ -40,7 +40,7 @@ If you don't have the required permissions and quota, contact your tenancy admin # Deploy Using Oracle Resource Manager -1. Click [![Deploy to Oracle Cloud](https://oci-resourcemanager-plugin.plugins.oci.oraclecloud.com/latest/deploy-to-oracle-cloud.svg)](https://cloud.oracle.com/resourcemanager/stacks/create?region=home&zipUrl=https://github.com/oracle-devrel/terraform-oci-oracle-cloud-foundation/blob/develop/cloud-foundation/solutions-for-oracle-res-mgr/Departmental-DWH-Full-Solution.zip) +1. Click [![Deploy to Oracle Cloud](https://oci-resourcemanager-plugin.plugins.oci.oraclecloud.com/latest/deploy-to-oracle-cloud.svg)](https://cloud.oracle.com/resourcemanager/stacks/create?region=home&zipUrl=https://raw.githubusercontent.com/oracle-devrel/terraform-oci-oracle-cloud-foundation/develop/cloud-foundation/solutions-for-oracle-res-mgr/Departmental-DWH-Full-Solution.zip) If you aren't already signed in, when prompted, enter the tenancy and user credentials. diff --git a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/README.md b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/README.md index 9cb2ca1..cf46870 100644 --- a/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/README.md +++ b/cloud-foundation/solutions/Departmental-DWH-Small-Footprint-Solution/README.md @@ -40,7 +40,7 @@ If you don't have the required permissions and quota, contact your tenancy admin # Deploy Using Oracle Resource Manager -1. Click [![Deploy to Oracle Cloud](https://oci-resourcemanager-plugin.plugins.oci.oraclecloud.com/latest/deploy-to-oracle-cloud.svg)](https://cloud.oracle.com/resourcemanager/stacks/create?region=home&zipUrl=https://github.com/oracle-devrel/terraform-oci-oracle-cloud-foundation/blob/develop/cloud-foundation/solutions-for-oracle-res-mgr/Departmental-DWH-Small-Footprint-Solution.zip) +1. Click [![Deploy to Oracle Cloud](https://oci-resourcemanager-plugin.plugins.oci.oraclecloud.com/latest/deploy-to-oracle-cloud.svg)](https://cloud.oracle.com/resourcemanager/stacks/create?region=home&zipUrl=https://raw.githubusercontent.com/oracle-devrel/terraform-oci-oracle-cloud-foundation/develop/cloud-foundation/solutions-for-oracle-res-mgr/Departmental-DWH-Small-Footprint-Solution.zip) If you aren't already signed in, when prompted, enter the tenancy and user credentials.