| no |
+| [region](#input\_region) | The OCI region | `string` | n/a | yes |
+| [route\_table\_display\_name](#input\_route\_table\_display\_name) | Workload Expansion Spoke Route Table Name Disply Name. | `string` | n/a | yes |
+| [security\_list\_display\_name](#input\_security\_list\_display\_name) | Workload Expansion Spoke Security List Name Disly Name. | `string` | n/a | yes |
+| [service\_gateway\_display\_name](#input\_service\_gateway\_display\_name) | (Updatable) Name of Service Gateway. Does not have to be unique. | `string` | n/a | yes |
+| [service\_gw\_spoke\_check](#input\_service\_gw\_spoke\_check) | n/a | `list(string)` |
[ "" ]
| no |
+| [tenancy\_ocid](#input\_tenancy\_ocid) | The OCID of tenancy | `string` | n/a | yes |
+| [vcn\_display\_name](#input\_vcn\_display\_name) | Workload Expansion Spoke VCN Display Name | `string` | n/a | yes |
+| [vcn\_dns\_label](#input\_vcn\_dns\_label) | A DNS label for the VCN, used in conjunction with the VNIC's hostname and subnet's DNS label to form a fully qualified domain name (FQDN) for each VNIC within this subnet | `string` | n/a | yes |
+| [workload\_compartment\_id](#input\_workload\_compartment\_id) | n/a | `string` | n/a | yes |
+| [workload\_compartment\_name](#input\_workload\_compartment\_name) | The name of the workload compartment by default OCI-ELZ--. | `string` | `"OCI-ELZ-Workload1"` | no |
+| [workload\_expansion\_flag](#input\_workload\_expansion\_flag) | Set to true if you want to use this as independent Workload Expansion Deployment Stack. | `bool` | n/a | yes |
+| [workload\_private\_spoke\_subnet\_app\_cidr\_block](#input\_workload\_private\_spoke\_subnet\_app\_cidr\_block) | Workload Enivornment Spoke VCN CIDR Block. | `string` | n/a | yes |
+| [workload\_private\_spoke\_subnet\_app\_display\_name](#input\_workload\_private\_spoke\_subnet\_app\_display\_name) | Workload Expansion Spoke App Subnet Display Name. | `string` | n/a | yes |
+| [workload\_private\_spoke\_subnet\_app\_dns\_label](#input\_workload\_private\_spoke\_subnet\_app\_dns\_label) | A DNS label for the VCN Subnet, used in conjunction with the VNIC's hostname and subnet's DNS label to form a fully qualified domain name (FQDN) for each VNIC within this subnet | `string` | n/a | yes |
+| [workload\_private\_spoke\_subnet\_db\_cidr\_block](#input\_workload\_private\_spoke\_subnet\_db\_cidr\_block) | Workload Enivornment Spoke VCN CIDR Block. | `string` | n/a | yes |
+| [workload\_private\_spoke\_subnet\_db\_display\_name](#input\_workload\_private\_spoke\_subnet\_db\_display\_name) | Workload Expansion Spoke Db Subnet Display Name. | `string` | n/a | yes |
+| [workload\_private\_spoke\_subnet\_db\_dns\_label](#input\_workload\_private\_spoke\_subnet\_db\_dns\_label) | A DNS label for the VCN Subnet, used in conjunction with the VNIC's hostname and subnet's DNS label to form a fully qualified domain name (FQDN) for each VNIC within this subnet | `string` | n/a | yes |
+| [workload\_private\_spoke\_subnet\_web\_cidr\_block](#input\_workload\_private\_spoke\_subnet\_web\_cidr\_block) | Workload Enivornment Spoke VCN CIDR Block. | `string` | n/a | yes |
+| [workload\_private\_spoke\_subnet\_web\_display\_name](#input\_workload\_private\_spoke\_subnet\_web\_display\_name) | Workload Expansion Spoke Web Subnet Display Name. | `string` | n/a | yes |
+| [workload\_private\_spoke\_subnet\_web\_dns\_label](#input\_workload\_private\_spoke\_subnet\_web\_dns\_label) | A DNS label for the VCN Subnet, used in conjunction with the VNIC's hostname and subnet's DNS label to form a fully qualified domain name (FQDN) for each VNIC within this subnet | `string` | n/a | yes |
+| [workload\_spoke\_vcn\_cidr](#input\_workload\_spoke\_vcn\_cidr) | The list of IPv4 CIDR blocks the VCN will use. | `list(string)` | n/a | yes |
+
+## Outputs
+
+No outputs.
+
\ No newline at end of file
diff --git a/templates/elz-spoke/datasources.tf b/templates/elz-spoke/datasources.tf
new file mode 100644
index 00000000..3e483838
--- /dev/null
+++ b/templates/elz-spoke/datasources.tf
@@ -0,0 +1,12 @@
+# -----------------------------------------------------------------------------
+# Support for multi-region deployments
+# -----------------------------------------------------------------------------
+locals {
+ region_subscriptions = data.oci_identity_region_subscriptions.regions.region_subscriptions
+ home_region = [for region in local.region_subscriptions : region.region_name if region.is_home_region == true]
+ region_key = [for region in local.region_subscriptions : region.region_key if region.region_name == var.region]
+}
+
+data "oci_identity_region_subscriptions" "regions" {
+ tenancy_id = var.tenancy_ocid
+}
diff --git a/templates/elz-spoke/main.tf b/templates/elz-spoke/main.tf
new file mode 100644
index 00000000..7847dcb6
--- /dev/null
+++ b/templates/elz-spoke/main.tf
@@ -0,0 +1,206 @@
+######################################################################
+# Workload | Workload Expansion Spoke Network Configuration #
+######################################################################
+locals {
+ workload_nat_gw_spoke_check = var.enable_nat_gateway_spoke == true ? var.nat_gw_spoke_check : []
+ workload_service_gw_spoke_check = var.enable_service_gateway_spoke == true ? var.service_gw_spoke_check : []
+
+ ipsec_connection_static_routes = var.enable_vpn_or_fastconnect == "VPN" && var.enable_vpn_on_environment ? var.ipsec_connection_static_routes : []
+ customer_onprem_ip_cidr = var.enable_vpn_or_fastconnect == "FASTCONNECT" ? var.customer_onprem_ip_cidr : []
+
+
+ spoke_route_rules_options = {
+ route_rules_default = {
+ "spoke-public-subnet" = {
+ network_entity_id = var.drg_id
+ destination = var.hub_public_subnet_cidr_block
+ destination_type = "CIDR_BLOCK"
+ }
+ "spoke-private-subnet" = {
+ network_entity_id = var.drg_id
+ destination = var.hub_private_subnet_cidr_block
+ destination_type = "CIDR_BLOCK"
+ }
+ "spoke-route-target" = {
+ network_entity_id = var.drg_id
+ destination = var.workload_spoke_vcn_cidr
+ destination_type = "CIDR_BLOCK"
+ }
+ }
+ route_rules_nat_spoke = {
+ for index, route in local.workload_nat_gw_spoke_check : "nat-gw-rule-${index}" => {
+ network_entity_id = module.workload-spoke-nat-gateway[0].nat_gw_id
+ destination = "0.0.0.0/0"
+ destination_type = "CIDR_BLOCK"
+ }
+ }
+ route_rules_srvc_gw_spoke = {
+ for index, route in local.workload_service_gw_spoke_check : "service-gw-rule-${index}" => {
+ network_entity_id = module.workload-spoke-service-gateway[0].service_gw_id
+ destination = data.oci_core_services.service_gateway.services[0]["cidr_block"]
+ destination_type = "SERVICE_CIDR_BLOCK"
+
+ }
+ }
+ route_rules_vpn = {
+ for index, route in local.ipsec_connection_static_routes : "cpe-rule-${index}" => {
+ network_entity_id = var.drg_id
+ destination = route
+ destination_type = "CIDR_BLOCK"
+ }
+ }
+ route_rules_fastconnect = {
+ for index, route in local.customer_onprem_ip_cidr : "fc-rule-${index}" => {
+ network_entity_id = var.drg_id
+ destination = route
+ destination_type = "CIDR_BLOCK"
+ }
+ }
+ }
+ spoke_route_rules = {
+ route_rules = merge(local.spoke_route_rules_options.route_rules_default, local.spoke_route_rules_options.route_rules_nat_spoke, local.spoke_route_rules_options.route_rules_srvc_gw_spoke, local.spoke_route_rules_options.route_rules_fastconnect, local.spoke_route_rules_options.route_rules_vpn)
+ }
+ workload_expansion_subnet_map = {
+ Workload-Spoke-Web-Subnet = {
+ name = var.workload_private_spoke_subnet_web_display_name
+ description = "Web Subnet"
+ dns_label = var.workload_private_spoke_subnet_web_dns_label
+ cidr_block = var.workload_private_spoke_subnet_web_cidr_block
+ prohibit_public_ip_on_vnic = true
+ }
+ Workload-Spoke-App-Subnet = {
+ name = var.workload_private_spoke_subnet_app_display_name
+ description = "App Subnet"
+ dns_label = var.workload_private_spoke_subnet_app_dns_label
+ cidr_block = var.workload_private_spoke_subnet_app_cidr_block
+ prohibit_public_ip_on_vnic = true
+ }
+ Workload-Spoke-Db-Subnet = {
+ name = var.workload_private_spoke_subnet_db_display_name
+ description = "DB Subnet"
+ dns_label = var.workload_private_spoke_subnet_db_dns_label
+ cidr_block = var.workload_private_spoke_subnet_db_cidr_block
+ prohibit_public_ip_on_vnic = true
+ }
+ }
+ ip_protocols = {
+ ICMP = "1"
+ TCP = "6"
+ UDP = "17"
+ ICMPv6 = "58"
+ }
+ security_list_ingress = {
+ protocol = local.ip_protocols.ICMP
+ source = "0.0.0.0/0"
+ description = "All ICMP Taffic"
+ source_type = "CIDR_BLOCK"
+ }
+ security_list_ingress_ssh = {
+ protocol = local.ip_protocols.TCP
+ source = "0.0.0.0/0"
+ description = "SSH Traffic"
+ source_type = "CIDR_BLOCK"
+ tcp_port = 22
+ }
+ security_list_egress = {
+ destination = "0.0.0.0/0"
+ protocol = "all"
+ description = "All Traffic For All Port"
+ destination_type = "CIDR_BLOCK"
+ }
+}
+#Get Service Gateway For Region .
+data "oci_core_services" "service_gateway" {
+ filter {
+ name = "name"
+ values = [".*Object.*Storage"]
+ regex = true
+ }
+}
+
+######################################################################
+# Create Workload VCN Spoke #
+######################################################################
+module "workload_spoke_vcn" {
+ source = "../../modules/vcn"
+
+ vcn_cidrs = [var.workload_spoke_vcn_cidr]
+ compartment_ocid_id = var.workload_compartment_id
+ vcn_display_name = var.vcn_display_name
+ vcn_dns_label = var.vcn_dns_label
+ enable_ipv6 = false
+
+ providers = {
+ oci = oci.home_region
+ }
+}
+######################################################################
+# Create Workload VCN Spoke Security List #
+######################################################################
+module "workload_spoke_security_list" {
+ source = "../../modules/security-list"
+
+ compartment_id = var.workload_compartment_id
+ vcn_id = module.workload_spoke_vcn.vcn_id
+ spoke_security_list_display_name = var.security_list_display_name
+ security_list_egress_destination = local.security_list_egress.destination
+ security_list_egress_protocol = local.security_list_egress.protocol
+ security_list_egress_description = local.security_list_egress.description
+ security_list_egress_destination_type = local.security_list_egress.destination_type
+
+ security_list_ingress_protocol = local.security_list_ingress.protocol
+ security_list_ingress_source = local.security_list_ingress.source
+ security_list_ingress_description = local.security_list_ingress.description
+ security_list_ingress_source_type = local.security_list_ingress.source_type
+
+}
+######################################################################
+# Create Workload VCN Spoke Subnet #
+######################################################################
+module "workload_spoke_subnet" {
+ source = "../../modules/subnet"
+
+ subnet_map = local.workload_expansion_subnet_map
+ compartment_id = var.workload_compartment_id
+ vcn_id = module.workload_spoke_vcn.vcn_id
+ subnet_route_table_id = module.workload_spoke_route_table.route_table_id
+ subnet_security_list_id = toset([module.workload_spoke_security_list.security_list_id])
+}
+######################################################################
+# Create Workload VCN Spoke Gateway #
+######################################################################
+module "workload-spoke-nat-gateway" {
+ source = "../../modules/nat-gateway"
+ count = var.enable_nat_gateway_spoke ? 1 : 0
+ nat_gateway_display_name = var.nat_gateway_display_name
+ network_compartment_id = var.workload_compartment_id
+ vcn_id = module.workload_spoke_vcn.vcn_id
+}
+
+module "workload-spoke-service-gateway" {
+ source = "../../modules/service-gateway"
+ count = var.enable_service_gateway_spoke ? 1 : 0
+ network_compartment_id = var.workload_compartment_id
+ service_gateway_display_name = var.service_gateway_display_name
+ vcn_id = module.workload_spoke_vcn.vcn_id
+}
+######################################################################
+# Create Workload VCN Spoke Route Table #
+######################################################################
+module "workload_spoke_route_table" {
+ source = "../../modules/route-table"
+ compartment_id = var.workload_compartment_id
+ vcn_id = module.workload_spoke_vcn.vcn_id
+ route_table_display_name = var.route_table_display_name
+ route_rules = local.spoke_route_rules.route_rules
+}
+######################################################################
+# Attach Workload Spoke VCN to DRG #
+######################################################################
+module "workload_spoke_vcn_drg_attachment" {
+ source = "../../modules/drg-attachment"
+ drg_id = var.drg_id
+ vcn_id = module.workload_spoke_vcn.vcn_id
+ drg_attachment_type = "VCN"
+ drg_attachment_vcn_route_type = "VCN_CIDRS"
+}
\ No newline at end of file
diff --git a/templates/elz-spoke/outputs.tf b/templates/elz-spoke/outputs.tf
new file mode 100644
index 00000000..7e99d0b6
--- /dev/null
+++ b/templates/elz-spoke/outputs.tf
@@ -0,0 +1,20 @@
+output "spoke_web_subnet_ocid" {
+ value = module.workload_spoke_subnet.subnets[var.workload_private_spoke_subnet_web_display_name]
+}
+
+output "spoke_app_subnet_ocid" {
+ value = module.workload_spoke_subnet.subnets[var.workload_private_spoke_subnet_app_display_name]
+}
+
+output "spoke_db_subnet_ocid" {
+ value = module.workload_spoke_subnet.subnets[var.workload_private_spoke_subnet_db_display_name]
+}
+
+output "subnets" {
+ value = {
+ (var.workload_private_spoke_subnet_db_display_name) = module.workload_spoke_subnet.subnets[var.workload_private_spoke_subnet_db_display_name]
+ (var.workload_private_spoke_subnet_app_display_name) = module.workload_spoke_subnet.subnets[var.workload_private_spoke_subnet_app_display_name]
+ (var.workload_private_spoke_subnet_web_display_name) = module.workload_spoke_subnet.subnets[var.workload_private_spoke_subnet_web_display_name]
+ }
+ description = "The subnet OCID"
+}
\ No newline at end of file
diff --git a/templates/elz-spoke/provider.tf b/templates/elz-spoke/provider.tf
new file mode 100644
index 00000000..2bbda84d
--- /dev/null
+++ b/templates/elz-spoke/provider.tf
@@ -0,0 +1,72 @@
+# -----------------------------------------------------------------------------
+# Provider Requirements if using stack as a module
+# -----------------------------------------------------------------------------
+terraform {
+ required_version = ">= 1.0.0"
+
+ required_providers {
+ oci = {
+ source = "oracle/oci"
+ version = "4.96.0" # October 05, 2022 Release
+ configuration_aliases = [oci, oci.home_region]
+ }
+ }
+}
+
+# # -----------------------------------------------------------------------------
+# # WARNING!
+# # UNCOMMENT EVERYTHING BELOW AND COMMENT EVERYTHING ABOVE IF YOU WISH TO USE THIS
+# # STACK AS A STANDALONE - DO NOT TOUCH IF USING THIS STACK IN A MODULE CALL
+# # Provider Requirements if using stack as standalone
+# # -----------------------------------------------------------------------------
+# terraform {
+# required_version = ">= 1.0.0"
+
+# required_providers {
+# oci = {
+# source = "oracle/oci"
+# version = "4.96.0" # October 05, 2022 Release
+# }
+# }
+# }
+
+# # -----------------------------------------------------------------------------
+# # Provider blocks for home region and alternate region(s)
+# # -----------------------------------------------------------------------------
+# provider "oci" {
+# tenancy_ocid = var.tenancy_ocid
+# user_ocid = var.current_user_ocid
+# fingerprint = var.api_fingerprint
+# private_key_path = var.api_private_key_path
+# region = var.region
+# }
+
+# provider "oci" {
+# alias = "home_region"
+# tenancy_ocid = var.tenancy_ocid
+# user_ocid = var.current_user_ocid
+# fingerprint = var.api_fingerprint
+# private_key_path = var.api_private_key_path
+# region = local.home_region[0]
+# }
+
+# # -----------------------------------------------------------------------------
+# # Provider Variables
+# # -----------------------------------------------------------------------------
+# variable "current_user_ocid" {
+# type = string
+# description = "The OCID of the current user"
+# default = ""
+# }
+
+# variable "api_fingerprint" {
+# type = string
+# description = "The fingerprint of API"
+# default = ""
+# }
+
+# variable "api_private_key_path" {
+# type = string
+# description = "The local path to the API private key"
+# default = ""
+# }
diff --git a/templates/elz-spoke/variables.tf b/templates/elz-spoke/variables.tf
new file mode 100644
index 00000000..2624bfb0
--- /dev/null
+++ b/templates/elz-spoke/variables.tf
@@ -0,0 +1,119 @@
+
+variable "environment_prefix" {
+ type = string
+ description = "the 1 character string representing the environment eg. P (prod), N (non-prod), D, T, U"
+}
+variable "tenancy_ocid" {
+ type = string
+ description = "The OCID of tenancy"
+}
+
+variable "region" {
+ type = string
+ description = "The OCI region"
+}
+
+variable "workload_spoke_vcn_cidr" {
+ description = "The list of IPv4 CIDR blocks the VCN will use."
+ type = string
+}
+variable "vcn_dns_label" {
+ description = "A DNS label for the VCN, used in conjunction with the VNIC's hostname and subnet's DNS label to form a fully qualified domain name (FQDN) for each VNIC within this subnet"
+ type = string
+}
+variable "workload_private_spoke_subnet_web_cidr_block" {
+ type = string
+ description = "Workload Enivornment Spoke VCN CIDR Block."
+}
+variable "workload_private_spoke_subnet_app_cidr_block" {
+ type = string
+ description = "Workload Enivornment Spoke VCN CIDR Block."
+}
+variable "workload_private_spoke_subnet_db_cidr_block" {
+ type = string
+ description = "Workload Enivornment Spoke VCN CIDR Block."
+}
+
+variable "workload_private_spoke_subnet_web_dns_label" {
+ description = "A DNS label for the VCN Subnet, used in conjunction with the VNIC's hostname and subnet's DNS label to form a fully qualified domain name (FQDN) for each VNIC within this subnet"
+ type = string
+}
+variable "workload_private_spoke_subnet_app_dns_label" {
+ description = "A DNS label for the VCN Subnet, used in conjunction with the VNIC's hostname and subnet's DNS label to form a fully qualified domain name (FQDN) for each VNIC within this subnet"
+ type = string
+}
+variable "workload_private_spoke_subnet_db_dns_label" {
+ description = "A DNS label for the VCN Subnet, used in conjunction with the VNIC's hostname and subnet's DNS label to form a fully qualified domain name (FQDN) for each VNIC within this subnet"
+ type = string
+}
+
+variable "nat_gateway_display_name" {
+ description = "(Updatable) Name of NAT Gateway. Does not have to be unique."
+ type = string
+}
+
+variable "service_gateway_display_name" {
+ description = "(Updatable) Name of Service Gateway. Does not have to be unique."
+ type = string
+}
+variable "workload_compartment_name" {
+ type = string
+ description = "The name of the workload compartment by default OCI-ELZ--."
+ default = "OCI-ELZ-Workload1"
+}
+variable "enable_nat_gateway_spoke" {
+ type = bool
+}
+variable "enable_service_gateway_spoke" {
+ type = bool
+}
+
+variable "nat_gw_spoke_check" {
+ type = list(string)
+ default = [""]
+}
+
+variable "service_gw_spoke_check" {
+ type = list(string)
+ default = [""]
+}
+variable "drg_id" {
+ type = string
+}
+variable "hub_public_subnet_cidr_block" {
+ type = string
+}
+variable "hub_private_subnet_cidr_block" {
+ type = string
+}
+variable "workload_compartment_id" {
+ type = string
+}
+variable "vcn_display_name" {
+ type = string
+ description = "Workload Expansion Spoke VCN Display Name"
+}
+variable "workload_private_spoke_subnet_web_display_name" {
+ type = string
+ description = "Workload Expansion Spoke Web Subnet Display Name."
+}
+variable "workload_private_spoke_subnet_app_display_name" {
+ type = string
+ description = "Workload Expansion Spoke App Subnet Display Name."
+}
+variable "workload_private_spoke_subnet_db_display_name" {
+ type = string
+ description = "Workload Expansion Spoke Db Subnet Display Name."
+}
+variable "route_table_display_name" {
+ type = string
+ description = "Workload Expansion Spoke Route Table Name Disply Name."
+}
+variable "security_list_display_name" {
+ type = string
+ description = "Workload Expansion Spoke Security List Name Disly Name."
+}
+variable "enable_vpn_or_fastconnect" {}
+variable "enable_vpn_on_environment" {}
+variable "ipsec_connection_static_routes" {}
+variable "customer_onprem_ip_cidr" {}
\ No newline at end of file
diff --git a/templates/elz-workload/Architecture_Guide.md b/templates/elz-workload/Architecture_Guide.md
new file mode 100644
index 00000000..5ac21cd3
--- /dev/null
+++ b/templates/elz-workload/Architecture_Guide.md
@@ -0,0 +1,3 @@
+# Architectural Guide
+
+# **Intro**
diff --git a/templates/elz-workload/BackEnd.sh b/templates/elz-workload/BackEnd.sh
new file mode 100755
index 00000000..d7609ece
--- /dev/null
+++ b/templates/elz-workload/BackEnd.sh
@@ -0,0 +1,7 @@
+#! /bin/bash
+
+cat <> backend.tf
+terraform {
+ backend "http" {}
+}
+EOT
\ No newline at end of file
diff --git a/templates/elz-workload/CONFIGURATION.md b/templates/elz-workload/CONFIGURATION.md
index 055342f9..d1168f85 100644
--- a/templates/elz-workload/CONFIGURATION.md
+++ b/templates/elz-workload/CONFIGURATION.md
@@ -1,12 +1,119 @@
-## Configuration Guide (DO NOT UPDATE)
+## Enterprise Scale Baseline Landing Zone Workload Extension Configuration Guide
-### Compartment
-For the Workload stack, we have the below compartment architecture:
-* Workload
+This configuration guide will detail the required and available configurations needed to deploy an Enterprise Scale Baseline Landing Zone(ESBLZ) 2.0 Workload Expansion on Oracle Cloud Infrastructure.
-To configure the compartment the required user inputs are:
-* **enviroment_compartment_id**: the OCID of the higher level environment compartment
-* **workload_compartment_name**: the name of workload compartment, by default OCI-ELZ--
-* **workload_name**: the name of the workload
-* **home_compartment_id**: the OCID of the compartment that the environment compartment build on.
+## Prerequisites
+Enterprise Scale Baseline Landing Zone(ESBLZ) stack will be fully deployed on the OCI Tenanacy.
+
+
+## Minimum Required Configuration
+
+Deployment of the ESBLZ is controlled by several Terraform [input variables](README.md#inputs), however most of these have sensible default values. Here are the minimum required configurations to deploy a ESBLZ Workload Expansion:
+
+### Basic Terraform Connection Information
+The required provider variables for the ESBLZ:
+
+| Name | Description | Type | Default | Required |
+| ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | -------- | ------- | :------: |
+| [current\_user\_ocid](#input\_current\_user\_ocid) | The ID of user to deploy the ESBLZ. | `string` | `""` | no |
+| [api\_fingerprint](#input\_api\_fingerprint) | The API fingerprint which can be retrieved from the console. | `string` | `""` | no |
+| [api\_private\_key](#input\_api\_private\_key) | The API private key | `string` | `""` | yes |
+| [api\_private\_key\_path](#input\_api\_private\_key\_path) | The local path to the API private key | `string` | `""` | no |
+| [tenancy\_ocid](#input\_tenancy\_ocid) | The ID of tenancy | `string` | n/a | yes |
+| [region](#input\_region) | The OCI region to deploy the ESBLZ resources to. | `string` | n/a | yes |
+
+
+## Compartment Module
+
+This architecture diagram illustrates the compartments for Enterprise LZ deploys Workload Expansion.
+
+![Architecture](<../images/LZ-v2.0.png> "Architecture")
+
+The ESBLZ Workload Expansion will create L3 workload compartment on the user defined Parent Compartment OCID .
+
+The required arguments for ESBLZ Workload Compartment:
+* **compartment_parent_id**: the OCID of compartment/tenancy that you create the ESBLZ Workload Compartment
+* **compartment_name**: the name of ESBLZ Workload Compartment
+* **compartment_description**: the description of ESBLZ Workload Compartment
+* **enable_compartment_delete**: unless enable_delete is explicitly set to true, Terraform will not delete compartments on destroy
+
+| Name | Description | Type | Default | Required |
+| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | -------- | -------------------- | :------: |
+| [enable\_compartment\_delete](#input\_enable\_compartment\_delete) | Set to true to allow the compartments to delete on terraform destroy. | `bool` | `true` | yes |
+| [workload\_compartment\_name](#input\_home\_compartment\_name) | The name of the workload compartment under which all Workload resources will be deployed. | `string` | `"OCI-ELZ-Workload1-[Region]-01"` | yes |
+| [environment\_compartment\_id](#input\_home\_compartment\_name) | The name of parent compartment where workload compartment will be created | `string` | `"OCID Value"` | yes |
+
+## Network Module
+
+The required arguments for ESBLZ Workload Network:
+* **ESBLZ Workload Spoke VCN Related Variables**
+
+| Name | Description | Type | Default | Required |
+| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | -------- | -------------------- | :------: |
+| [workload\_prefix](#workload\_prefix) | Workload Prefix. | `string` | `"WRK1"` | yes |
+| [vcn\_display\_name](#vcn\_display\_name) | Workload Spoke VCN Display Name. | `string` | `"OCI-ELZ-${var.workload_prefix}-EXP-SPK-VCN-${local.region_key[0]}"`| no |
+| [workload\_spoke\_vcn\_cidr](#workload\_spoke\_vcn\_cidr) | Workload Spoke VCN IPv4 CIDR Block. | `list(string)` | `[" "]` | yes |
+| [vcn\_dns\_label](#vcn\_dns\_label) | Workload Spoke VCN DNS Label. | `string` | `"wrkspokevcn"` | yes |
+
+* **ESBLZ Workload Spoke VCN Subnet Related Variables**
+
+| Name | Description | Type | Default | Required |
+| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | -------- | -------------------- | :------: |
+| [workload\_private\_spoke\_subnet\_web\_display\_name](#workload\_private\_spoke\_subnet\_web\_display\_name) | Workload Spoke VCN Web Subnet Display Name | `string` | `"OCI-ELZ-${var.workload_prefix}-EXP-SPK-VCN-SUB-${local.region_key[0]}-001"` | no |
+| [workload\_private\_spoke\_subnet\_app\_display\_name](#workload\_private\_spoke\_subnet\_app\_display\_name) | Workload Spoke VCN App Subnet Display Name | `string` | `"OCI-ELZ-${var.workload_prefix}-EXP-SPK-VCN-SUB-${local.region_key[0]}-002"` | no |
+| [workload\_private\_spoke\_subnet\_db\_display\_name](#workload\_private\_spoke\_subnet\_db\_display\_name) | Workload Spoke VCN DB Subnet Display Name | `string` | `"OCI-ELZ-${var.workload_prefix}-EXP-SPK-VCN-SUB-${local.region_key[0]}-003"` | no |
+| [workload\_private\_spoke\_subnet\_web\_cidr\_block](#workload\_private\_spoke\_subnet\_web\cidr\_block) | Workload Spoke VCN Web Subnet CIDR BLOCK | `string` | `""(Valid IPv4 Address)` | yes |
+| [workload\_private\_spoke\_subnet\_app\_cidr\_block](#workload\_private\_spoke\_subnet\_app\cidr\_block) | Workload Spoke VCN App Subnet CIDR BLOCK | `string` | `""(Valid IPv4 Address)` | yes |
+| [workload\_private\_spoke\_subnet\_db\_cidr\_block](#workload\_private\_spoke\_subnet\_db\cidr\_block) | Workload Spoke VCN Db Subnet CIDR BLOCK | `string` | `""(Valid IPv4 Address)` | yes |
+| [workload\_private\_spoke\_subnet\_web\_dns\_label](#workload\_private\_spoke\_subnet\_web\_dns\_label) | Workload Spoke VCN Web Subnet DNS Label | `string` | `"wrkweblabel"` | yes |
+| [workload\_private\_spoke\_subnet\_app\_dns\_label](#workload\_private\_spoke\_subnet\_app\_dns\_label) | Workload Spoke VCN App Subnet DNS Label | `string` | `"wrkapplabel"` | yes |
+| [workload\_private\_spoke\_subnet\_db\_dns\_label](#workload\_private\_spoke\_subnet\_db\_dns\_label) | Workload Spoke VCN Db Subnet DNS Label | `string` | `"wrkdblabel"` | yes |
+
+* **ESBLZ Workload Spoke VCN Gateway Related Variables**
+
+| Name | Description | Type | Default | Required |
+| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | -------- | -------------------- | :------: |
+| [enable\_nat\_gateway\_spoke](#enable\_nat\_gateway\_spoke) | Workload Spoke VCN Enable Nat-Gateway | `bool` | `false` | yes |
+| [nat\_gateway\_display\_name](#nat\_gateway\_display\_name) | Workload Spoke VCN Nat-Gateway Display Name | `string` | `"OCI-ELZ-${var.workload_prefix}-EXP-SPK-NAT-${local.region_key[0]}"` | no |
+| [enable\_service\_gateway\_spoke](#enable\_service\_gateway\_spoke) | Workload Spoke VCN Enable Service Gateway | `bool` | `false` | yes |
+| [service\_gateway\_display\_name](#service\_gateway\_display\_name) | Workload Spoke VCN Service Gateway Display Name | `string` | `"OCI-ELZ-${var.workload_prefix}-EXP-SPK-SGW-${local.region_key[0]}"` | no |
+
+* **ESBLZ Workload Spoke VCN Route Table and Security List Related Variables**
+
+| Name | Description | Type | Default | Required |
+| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | -------- | -------------------- | :------: |
+| [hub\_public\_subnet\_cidr\_block](#hub\_public\_subnet\_cidr\_block) | Provide Hub Public Subnet IPv4 CIDR Block. | `string` | `""(Valid IPv4 CIDR Block)` | yes |
+| [hub\_private\_subnet\_cidr\_block](#hub\_private\_subnet\_cidr\_block) | Provide Hub Private Subnet IPv4 CIDR Block. | `string` | `""(Valid IPv4 CIDR Block)` | yes |
+| [hub\_vcn\_parent\_compartment\_id](#hub\_vcn\_parent\_compartment\_id) | Provide Hub VCN Parent Compartment OCID. | `string` | `""(Valid Compartment OCID)` | yes |
+| [hub\_vcn\_id](#hub\_vcn\_id]) | Provide Hub VCN OCID. | `string` | `""(Valid VCN OCID)` | yes |
+
+
+## IAM
+
+The required arguments Workload Expansion IAM:
+
+| Name | Description | Type | Default | Required |
+| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | -------- | -------------------- | :------: |
+| [workload\_admin\_group\_name](#workload\_admin\_group\_name) | Provide Workload Admin Group Name. | `string` | `"OCI-ELZ-UGP-[workload_prefix]-WRK-ADMIN"` | yes |
+| [application\_admin\_group\_name](#application\_admin\_group\_name) | Provide Workload Application Admin Group Name. | `string` | `"OCI-ELZ-UGP-[workload_prefix]-APP-ADMIN"` | yes |
+| [database\_admin\_group\_name](#database\_admin\_group\_name) | Provide Workload DB Admin Group Name. | `string` | `"OCI-ELZ-UGP-[workload_prefix]-DB-ADMIN"` | yes |
+
+## Policy
+
+The required arguments Workload Expansion Policy:
+
+| Name | Description | Type | Default | Required |
+| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | -------- | -------------------- | :------: |
+| [security\_compartment\_name](#security\_compartment\_name) | Provide Security Compartment Name. | `string` | `""` | yes |
+| [security\_compartment\_ocid](#security\_compartment\_ocid) | Provide Security Compartment OCID. | `string` | `""` | yes |
+| [security\_admin\_group\_name](#security\_admin\_group\_name) | Provide Security Admin Group Name. | `string` | `""` | yes |
+| [network\_admin\_group\_name](#network\_admin\_group\_name) | Provide Network Admin Group Name. | `string` | `""` | yes |
+
+## Monitoring
+
+These are the configuration options for Workload Monitoring:
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [workload\_topic\_endpoints](#input\_workload\_topic\_endpoints) | List of email addresses for Workload notifications. | `list(string)` | `[]` | no |
diff --git a/templates/elz-workload/IMPLEMENTATION.md b/templates/elz-workload/IMPLEMENTATION.md
new file mode 100644
index 00000000..f4372c48
--- /dev/null
+++ b/templates/elz-workload/IMPLEMENTATION.md
@@ -0,0 +1,71 @@
+# Enterprise Scale Baseline Landing Zone Workload Extension
+
+## Prerequisites
+
+1) To deploy the Enterprise Scale Baseline Landing Zone Workload Expansion from the terraform cli you will need the following prerequisites.
+- [Latest Version of Terrafom](https://developer.hashicorp.com/terraform/downloads)
+- [OCI Terraform provider](https://registry.terraform.io/providers/oracle/oci/latest/docs) v4.109.0 or later
+- [oci - cli](https://github.com/oracle/oci-cli)
+
+2) Enterprise Scale Baseline Landing Zone is deployed.
+
+## User
+
+The Enterprise Scale Baseline Landing Zone Workload Expansion should be deployed by a user who is a member of the Administrators group for the tenancy. This user need to have an api key entry defined as decribed [here](https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/terraformproviderconfiguration.htm). Once the user and API Key are defined your oci-cli config should resemble.
+
+```text
+[DEFAULT]
+user=ocid1.xxxxxx.xxxxxx.xxxxxx..... #ocid of the user
+fingerprint=xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx #user api key fingerprint
+tenancy=ocid1.xxxxxx.xxxxxx.xxxxxx..... #tenancy ocid
+region=us-phoenix-1 #or desired region
+key_file= # TODO
+```
+
+## Region
+
+The Enterprise Scale Baseline Landing Zone Workload will be deployed as L3 on user defined Parent Compartment OCID.
+
+### Resource Limits
+TBD
+
+### Compartment Structure
+
+For the Enterprise Scale Baseline Landing Zone, we have the below compartment architecture:
+
+* Enterprise Scale Baseline Landing Zone Workload Compartment will be deployed on user defined Parent Compartment OCID. So there are two deployment scenario.
+
+1) First Case : Workload Expansion will be deployed On Prod Environment.
+ * Prod
+ * Shared Infrastructure
+ * Network
+ * Security
+ * Workload
+ * Logging
+ * Backup
+ * Workload Expansion
+
+2) Second Case : Workload Expansion will be deployed On Non-Prod Environment.
+ * Non Prod
+ * Shared Infrastructure
+ * Network
+ * Security
+ * Workload
+ * Logging
+ * Backup
+ * Workload Expansion
+
+### Workload Expansion : Network
+
+ESBLZ Workload Expansion Stack will deploy one Spoke VCN on user defined Compartment. It will deploy VCN Gateway like Nat Gateway and Service Gateway, Security Rules and Route Tables as per the User prefence and will attach the VCN to configured DRG. There will be three Subnets for Web ,App and DB Application Resources.
+
+
+Logging for the Enterprise Scale Baseline Landing Zone is configured at the Environment level, with logs for all Workloads within a given Environment being sent to object storage buckets set up per-environment, as well as an archive bucket for all Environments, with a long term retention policy. No logging configuration per Workload is necessary.
+
+### Workload Expansion : Policy
+
+As part of Workload Expansion three user groups will be created Workload Admin, Application Admin and Database Admin. We are adding default policy so that newly created user groups have fine-grained access to workload resources.
+
+### Workload Expansion : Monitoring
+
+The Workload Expansion will create a series of monitoring alarms (11 Critical alarms, and 6 Warning alarms) for each Workload it creates. Notifications created by these alarms being triggered will be delivered by email to a list of email addresses (The workload_topic_endpoints) specified for that Workload.
\ No newline at end of file
diff --git a/templates/elz-workload/README.md b/templates/elz-workload/README.md
index fe3c9146..a7a7f896 100644
--- a/templates/elz-workload/README.md
+++ b/templates/elz-workload/README.md
@@ -16,8 +16,12 @@
| Name | Source | Version |
|------|--------|---------|
+| [groups](#module\_groups) | ../../modules/identity-domain-group | n/a |
+| [spoke\_workload\_compartment](#module\_spoke\_workload\_compartment) | ../elz-spoke | n/a |
| [workload\_compartment](#module\_workload\_compartment) | ../../modules/compartment | n/a |
| [workload\_critical\_topic](#module\_workload\_critical\_topic) | ../../modules/notification-topic | n/a |
+| [workload\_expansion\_policy](#module\_workload\_expansion\_policy) | ../../modules/policies | n/a |
+| [workload\_expansion\_sec\_policy](#module\_workload\_expansion\_sec\_policy) | ../../modules/policies | n/a |
| [workload\_warning\_topic](#module\_workload\_warning\_topic) | ../../modules/notification-topic | n/a |
## Resources
@@ -30,21 +34,60 @@
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
+| [application\_admin\_group\_name](#input\_application\_admin\_group\_name) | the name of workload application admin group | `string` | `""` | no |
+| [database\_admin\_group\_name](#input\_database\_admin\_group\_name) | the name of workload database admin group | `string` | `""` | no |
+| [drg\_id](#input\_drg\_id) | n/a | `string` | `"ocid1.drg."` | no |
| [enable\_compartment\_delete](#input\_enable\_compartment\_delete) | Set to true to allow the compartments to delete on terraform destroy. | `bool` | `true` | no |
-| [enable\_network\_monitoring\_alarms](#input\_enable\_network\_monitoring\_alarms) | Enable Network Monitoring Alarms in Network Compartment | `bool` | n/a | yes |
-| [enable\_security\_monitoring\_alarms](#input\_enable\_security\_monitoring\_alarms) | Enable Security Monitoring Alarms in Security Compartment | `bool` | n/a | yes |
-| [enable\_workload\_monitoring\_alarms](#input\_enable\_workload\_monitoring\_alarms) | Enable Workload Monitoring Alarms in Workload Compartment | `bool` | n/a | yes |
+| [enable\_internet\_gateway\_spoke](#input\_enable\_internet\_gateway\_spoke) | n/a | `bool` | `false` | no |
+| [enable\_nat\_gateway\_spoke](#input\_enable\_nat\_gateway\_spoke) | n/a | `bool` | `false` | no |
+| [enable\_network\_monitoring\_alarms](#input\_enable\_network\_monitoring\_alarms) | Enable Network Monitoring Alarms in Network Compartment | `bool` | `false` | no |
+| [enable\_security\_monitoring\_alarms](#input\_enable\_security\_monitoring\_alarms) | Enable Security Monitoring Alarms in Security Compartment | `bool` | `false` | no |
+| [enable\_service\_gateway\_spoke](#input\_enable\_service\_gateway\_spoke) | n/a | `bool` | `false` | no |
+| [enable\_workload\_monitoring\_alarms](#input\_enable\_workload\_monitoring\_alarms) | Enable Workload Monitoring Alarms in Workload Compartment | `bool` | `false` | no |
| [environment\_compartment\_id](#input\_environment\_compartment\_id) | n/a | `string` | n/a | yes |
| [environment\_prefix](#input\_environment\_prefix) | the 1 character string representing the environment eg. P (prod), N (non-prod), D, T, U | `string` | n/a | yes |
-| [network\_compartment\_id](#input\_network\_compartment\_id) | the OCID of the compartment where the environment will be created. In general, this should be the Landing zone parent compartment. | `string` | n/a | yes |
+| [hub\_private\_subnet\_cidr\_block](#input\_hub\_private\_subnet\_cidr\_block) | n/a | `string` | `"10.1.2.0/24"` | no |
+| [hub\_public\_subnet\_cidr\_block](#input\_hub\_public\_subnet\_cidr\_block) | n/a | `string` | `"10.1.1.0/24"` | no |
+| [hub\_route\_table\_name](#input\_hub\_route\_table\_name) | n/a | `string` | `""` | no |
+| [hub\_security\_list\_id](#input\_hub\_security\_list\_id) | n/a | `string` | `"ocid1.securitylist."` | no |
+| [hub\_vcn\_id](#input\_hub\_vcn\_id) | n/a | `string` | `"ocid1.vcn."` | no |
+| [hub\_vcn\_parent\_compartment\_id](#input\_hub\_vcn\_parent\_compartment\_id) | n/a | `string` | `"ocid1.compartment."` | no |
+| [identity\_domain\_id](#input\_identity\_domain\_id) | the ocid of identity domain | `string` | `"ocid1.domain."` | no |
+| [identity\_domain\_name](#input\_identity\_domain\_name) | identity domain name | `string` | `""` | no |
+| [internet\_gateway\_display\_name](#input\_internet\_gateway\_display\_name) | (Updatable) Name of Internet Gateway. Does not have to be unique. | `string` | `"igw"` | no |
+| [nat\_gateway\_display\_name](#input\_nat\_gateway\_display\_name) | (Updatable) Name of NAT Gateway. Does not have to be unique. | `string` | `"ngw"` | no |
+| [nat\_gw\_spoke\_check](#input\_nat\_gw\_spoke\_check) | n/a | `list(string)` |
[ "" ]
| no |
+| [network\_admin\_group\_name](#input\_network\_admin\_group\_name) | Network Admin Group Name. | `string` | `""` | no |
+| [network\_compartment\_id](#input\_network\_compartment\_id) | the OCID of the compartment where the environment will be created. In general, this should be the Landing zone parent compartment. | `string` | `""` | no |
| [network\_topic\_endpoints](#input\_network\_topic\_endpoints) | List of email addresses for Network Warning and Critical notifications. | `list(string)` | `[]` | no |
| [region](#input\_region) | The OCI region | `string` | n/a | yes |
+| [route\_table\_display\_name](#input\_route\_table\_display\_name) | Workload Expansion Spoke Route Table Name Disply Name. | `string` | `""` | no |
| [secops\_topic\_endpoints](#input\_secops\_topic\_endpoints) | List of email addresses for Secops Warning and Critical notifications. | `list(string)` | `[]` | no |
-| [security\_compartment\_id](#input\_security\_compartment\_id) | the OCID of the compartment where the environment will be created. In general, this should be the Landing zone parent compartment. | `string` | n/a | yes |
+| [security\_admin\_group\_name](#input\_security\_admin\_group\_name) | Security Admin Group Name. | `string` | `""` | no |
+| [security\_compartment\_id](#input\_security\_compartment\_id) | the OCID of the compartment where the environment will be created. In general, this should be the Landing zone parent compartment. | `string` | `""` | no |
+| [security\_compartment\_name](#input\_security\_compartment\_name) | Security Compartment Name. | `string` | `""` | no |
+| [security\_compartment\_ocid](#input\_security\_compartment\_ocid) | Security Compartment OCID. | `string` | `""` | no |
+| [security\_list\_display\_name](#input\_security\_list\_display\_name) | Workload Expansion Spoke Security List Name Disly Name. | `string` | `""` | no |
+| [service\_gateway\_display\_name](#input\_service\_gateway\_display\_name) | (Updatable) Name of Service Gateway. Does not have to be unique. | `string` | `"sgw"` | no |
+| [service\_gw\_spoke\_check](#input\_service\_gw\_spoke\_check) | n/a | `list(string)` |
[ "" ]
| no |
| [tenancy\_ocid](#input\_tenancy\_ocid) | The OCID of tenancy | `string` | n/a | yes |
-| [workload\_compartment\_id](#input\_workload\_compartment\_id) | the OCID of the compartment where the environment will be created. In general, this should be the Landing zone parent compartment. | `string` | `""` | no |
+| [vcn\_display\_name](#input\_vcn\_display\_name) | Workload Expansion Spoke VCN Display Name | `string` | `""` | no |
+| [vcn\_dns\_label](#input\_vcn\_dns\_label) | A DNS label for the VCN, used in conjunction with the VNIC's hostname and subnet's DNS label to form a fully qualified domain name (FQDN) for each VNIC within this subnet | `string` | `"wrkspokevcn"` | no |
+| [workload\_admin\_group\_name](#input\_workload\_admin\_group\_name) | the name of workload admin group | `string` | `""` | no |
| [workload\_compartment\_name](#input\_workload\_compartment\_name) | The name of the workload compartment by default OCI-ELZ--. | `string` | `""` | no |
-| [workload\_name](#input\_workload\_name) | The name of the workload. | `string` | n/a | yes |
+| [workload\_expansion\_flag](#input\_workload\_expansion\_flag) | Set to true if you want to use this as independent Workload Expansion Deployment Stack. | `bool` | `false` | no |
+| [workload\_name](#input\_workload\_name) | The name of the workload. | `string` | `""` | no |
+| [workload\_prefix](#input\_workload\_prefix) | Atleast 4 Alphanumeric Charater to Describe the Workload : WRK1 | `string` | `"WRK1"` | no |
+| [workload\_private\_spoke\_subnet\_app\_cidr\_block](#input\_workload\_private\_spoke\_subnet\_app\_cidr\_block) | Workload Enivornment Spoke VCN CIDR Block. | `string` | `"10.5.2.0/24"` | no |
+| [workload\_private\_spoke\_subnet\_app\_display\_name](#input\_workload\_private\_spoke\_subnet\_app\_display\_name) | Workload Expansion Spoke App Subnet Display Name. | `string` | `""` | no |
+| [workload\_private\_spoke\_subnet\_app\_dns\_label](#input\_workload\_private\_spoke\_subnet\_app\_dns\_label) | A DNS label for the VCN Subnet, used in conjunction with the VNIC's hostname and subnet's DNS label to form a fully qualified domain name (FQDN) for each VNIC within this subnet | `string` | `"wrkapplabel"` | no |
+| [workload\_private\_spoke\_subnet\_db\_cidr\_block](#input\_workload\_private\_spoke\_subnet\_db\_cidr\_block) | Workload Enivornment Spoke VCN CIDR Block. | `string` | `"10.5.3.0/24"` | no |
+| [workload\_private\_spoke\_subnet\_db\_display\_name](#input\_workload\_private\_spoke\_subnet\_db\_display\_name) | Workload Expansion Spoke Db Subnet Display Name. | `string` | `""` | no |
+| [workload\_private\_spoke\_subnet\_db\_dns\_label](#input\_workload\_private\_spoke\_subnet\_db\_dns\_label) | A DNS label for the VCN Subnet, used in conjunction with the VNIC's hostname and subnet's DNS label to form a fully qualified domain name (FQDN) for each VNIC within this subnet | `string` | `"wrkdblabel"` | no |
+| [workload\_private\_spoke\_subnet\_web\_cidr\_block](#input\_workload\_private\_spoke\_subnet\_web\_cidr\_block) | Workload Enivornment Spoke VCN CIDR Block. | `string` | `"10.5.1.0/24"` | no |
+| [workload\_private\_spoke\_subnet\_web\_display\_name](#input\_workload\_private\_spoke\_subnet\_web\_display\_name) | Workload Expansion Spoke Web Subnet Display Name. | `string` | `""` | no |
+| [workload\_private\_spoke\_subnet\_web\_dns\_label](#input\_workload\_private\_spoke\_subnet\_web\_dns\_label) | A DNS label for the VCN Subnet, used in conjunction with the VNIC's hostname and subnet's DNS label to form a fully qualified domain name (FQDN) for each VNIC within this subnet | `string` | `"wrkweblabel"` | no |
+| [workload\_spoke\_vcn\_cidr](#input\_workload\_spoke\_vcn\_cidr) | The list of IPv4 CIDR blocks the VCN will use. | `list(string)` |
[ "10.5.0.0/16" ]
| no |
| [workload\_topic\_endpoints](#input\_workload\_topic\_endpoints) | List of email addresses for Workload notifications. | `list(string)` | `[]` | no |
## Outputs
diff --git a/templates/elz-workload/add_workload.sh b/templates/elz-workload/add_workload.sh
new file mode 100755
index 00000000..a9398544
--- /dev/null
+++ b/templates/elz-workload/add_workload.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+if [ -z "$1" ]
+then
+ echo "Workload name must be supplied."
+ exit 1
+fi
+
+if [ -z "$2" ]
+then
+ echo "Environment (N or P) must be supplied."
+ exit 1
+fi
+
+WORKLOAD_STACK="elz-workload-$2-$1"
+
+echo "Creating $WORKLOAD_STACK"
+
+rm -rf $WORKLOAD_STACK
+cp -a "elz-workload" $WORKLOAD_STACK
+
+rm -f $WORKLOAD_STACK/providers.tf
+cp $WORKLOAD_STACK/providers.standalone $WORKLOAD_STACK/providers.tf
+
diff --git a/templates/elz-workload/backend.tf b/templates/elz-workload/backend.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/templates/elz-workload/iam.tf b/templates/elz-workload/iam.tf
index df2fdf97..8e52f279 100644
--- a/templates/elz-workload/iam.tf
+++ b/templates/elz-workload/iam.tf
@@ -6,6 +6,50 @@ locals {
name = var.workload_compartment_name != "" ? var.workload_compartment_name : "OCI-ELZ-${var.environment_prefix}-${var.workload_name}-${local.region_key[0]}"
description = "Workload Compartment"
}
+
+ group_names = {
+ workload_admin_group_name : var.workload_admin_group_name != "" ? var.workload_admin_group_name : "OCI-ELZ-UGP-${var.environment_prefix}-WRK-ADMIN",
+ application_admin_group_name : var.application_admin_group_name != "" ? var.application_admin_group_name : "OCI-ELZ-UGP-${var.environment_prefix}-APP-ADMIN",
+ database_admin_group_name : var.database_admin_group_name != "" ? var.database_admin_group_name : "OCI-ELZ-UGP-${var.environment_prefix}-DB-ADMIN",
+ }
+
+ workload_expansion_policy = {
+ name = "OCI-ELZ-WRK-EXP-${var.workload_prefix}-POLICY"
+ description = "OCI Workload Expansion Policy"
+ statements = [
+ "Allow group ${var.identity_domain_name}/${local.group_names["workload_admin_group_name"]} to manage virtual-network-family in compartment ${module.workload_compartment.compartment_name}",
+ "Allow group ${var.identity_domain_name}/${local.group_names["workload_admin_group_name"]} to manage alarms in compartment ${module.workload_compartment.compartment_name}",
+ "Allow group ${var.identity_domain_name}/${local.group_names["workload_admin_group_name"]} to manage ons-topics in compartment ${module.workload_compartment.compartment_name}",
+ "Allow group ${var.identity_domain_name}/${local.group_names["workload_admin_group_name"]} to manage ons-subscriptions in compartment ${module.workload_compartment.compartment_name}",
+ "Allow group ${var.identity_domain_name}/${local.group_names["workload_admin_group_name"]} to manage logging-family in compartment ${module.workload_compartment.compartment_name}",
+ "Allow group ${var.identity_domain_name}/${local.group_names["workload_admin_group_name"]} to manage streams in compartment ${module.workload_compartment.compartment_name}",
+ "Allow group ${var.identity_domain_name}/${local.group_names["workload_admin_group_name"]} to read announcements in compartment ${module.workload_compartment.compartment_name}",
+ "Allow group ${var.identity_domain_name}/${local.group_names["workload_admin_group_name"]} to read metrics in compartment ${module.workload_compartment.compartment_name}",
+ "Allow group ${var.identity_domain_name}/${local.group_names["workload_admin_group_name"]} to read audit-events in compartment ${module.workload_compartment.compartment_name}",
+
+ "Allow group ${var.identity_domain_name}/${local.group_names["application_admin_group_name"]} to manage load-balancers in compartment ${module.workload_compartment.compartment_name}",
+ "Allow group ${var.identity_domain_name}/${local.group_names["application_admin_group_name"]} to manage volume-family in compartment ${module.workload_compartment.compartment_name}",
+ "Allow group ${var.identity_domain_name}/${local.group_names["application_admin_group_name"]} to manage object-family in compartment ${module.workload_compartment.compartment_name}",
+ "Allow group ${var.identity_domain_name}/${local.group_names["application_admin_group_name"]} to manage file-family in compartment ${module.workload_compartment.compartment_name}",
+ "Allow group ${var.identity_domain_name}/${local.group_names["application_admin_group_name"]} to manage instance-family in compartment ${module.workload_compartment.compartment_name}",
+
+ "Allow group ${var.identity_domain_name}/${local.group_names["database_admin_group_name"]} to read autonomous-database-family in compartment ${module.workload_compartment.compartment_name}",
+ "Allow group ${var.identity_domain_name}/${local.group_names["database_admin_group_name"]} to read database-family in compartment ${module.workload_compartment.compartment_name}",
+ ]
+ }
+
+ workload_expansion_policy_security = {
+ name = "OCI-ELZ-WRK-EXP-${var.workload_prefix}-SEC-POLICY"
+ description = "OCI Workload Expansion Security Policy"
+
+ statements = [
+ "Allow group ${var.identity_domain_name}/${local.group_names["workload_admin_group_name"]} to read vaults in compartment ${var.security_compartment_name}",
+ "Allow group ${var.identity_domain_name}/${local.group_names["workload_admin_group_name"]} to inspect keys in compartment ${var.security_compartment_name}",
+ "Allow group ${var.identity_domain_name}/${local.group_names["workload_admin_group_name"]} to read vss-family in compartment ${var.security_compartment_name}",
+ "Allow group ${var.identity_domain_name}/${local.group_names["workload_admin_group_name"]} to use bastion in compartment ${var.security_compartment_name}",
+ "Allow group ${var.identity_domain_name}/${local.group_names["workload_admin_group_name"]} to manage bastion-session in compartment ${var.security_compartment_name}",
+ ]
+ }
}
module "workload_compartment" {
@@ -20,3 +64,25 @@ module "workload_compartment" {
oci = oci.home_region
}
}
+
+module "groups" {
+ source = "../../modules/identity-domain-group"
+ identity_domain_id = var.identity_domain_id
+ group_names = values(local.group_names)
+}
+
+module "workload_expansion_policy" {
+ source = "../../modules/policies"
+ compartment_ocid = module.workload_compartment.compartment_id
+ policy_name = local.workload_expansion_policy.name
+ description = local.workload_expansion_policy.description
+ statements = local.workload_expansion_policy.statements
+}
+
+module "workload_expansion_sec_policy" {
+ source = "../../modules/policies"
+ compartment_ocid = var.security_compartment_id
+ policy_name = local.workload_expansion_policy_security.name
+ description = local.workload_expansion_policy_security.description
+ statements = local.workload_expansion_policy_security.statements
+}
diff --git a/templates/elz-workload/integration.tfvars b/templates/elz-workload/integration.tfvars
new file mode 100644
index 00000000..3a018621
--- /dev/null
+++ b/templates/elz-workload/integration.tfvars
@@ -0,0 +1,34 @@
+#####################################################
+# Workload Expansion Compartment Variable
+#####################################################
+enable_compartment_delete = false
+workload_compartment_name = "ELZ-Workload1-P"
+workload_expansion_flag = true
+environment_prefix = "P"
+workload_prefix = "TestWE"
+is_create_alarms = false
+enable_network_monitoring_alarms = true
+enable_security_monitoring_alarms = true
+enable_workload_monitoring_alarms = true
+#####################################################
+# Workload Expansion Network Variables
+#####################################################
+workload_spoke_vcn_cidr = "10.5.0.0/16"
+workload_private_spoke_subnet_web_cidr_block = "10.5.1.0/24"
+workload_private_spoke_subnet_app_cidr_block = "10.5.2.0/24"
+workload_private_spoke_subnet_db_cidr_block = "10.5.3.0/24"
+enable_internet_gateway_spoke = false
+enable_nat_gateway_spoke = true
+enable_service_gateway_spoke = true
+
+#####################################################
+# Workload Expansion: IAM Policy Variable
+#####################################################
+workload_admin_group_name = "TestWE-ADMIN"
+application_admin_group_name = "TestWE-APP"
+database_admin_group_name = "TestWE-DB"
+security_admin_group_name = "OCI-ELZ-UGP-P-SEC-ADMIN"
+network_admin_group_name = "OCI-ELZ-UGP-P-NET-ADMIN"
+
+#####################################################
+
diff --git a/templates/elz-workload/monitoring.tf b/templates/elz-workload/monitoring.tf
index 8848c642..ecbd0c43 100644
--- a/templates/elz-workload/monitoring.tf
+++ b/templates/elz-workload/monitoring.tf
@@ -4,12 +4,12 @@
locals {
workload_critical_topic = {
- topic_name = "${var.environment_prefix}-Workload-Critical"
+ topic_name = "${var.environment_prefix}-${var.workload_name}-Critical"
topic_description = "OCI Landing Zone Critical Workload Topic"
subscription_protocol = "EMAIL"
}
workload_warning_topic = {
- topic_name = "${var.environment_prefix}-Workload-Warning"
+ topic_name = "${var.environment_prefix}-${var.workload_name}-Warning"
topic_description = "OCI Landing Zone Warning Workload Topic"
subscription_protocol = "EMAIL"
}
@@ -42,77 +42,77 @@ locals {
workload_alarms_critical_map = {
compute_instance_status_alarm = {
display_name = "compute_instance_status_alarm"
- metric_compartment_id = var.workload_compartment_id
+ metric_compartment_id = module.workload_compartment.compartment_id
namespace = "oci_compute_infrastructure_health"
query = "instance_status[1m].sum() > 0"
severity = "CRITICAL"
}
compute_vm_instance_status_alarm = {
display_name = "compute_vm_instance_status_alarm"
- metric_compartment_id = var.workload_compartment_id
+ metric_compartment_id = module.workload_compartment.compartment_id
namespace = "oci_compute_infrastructure_health"
query = "maintenance_status[1m].sum() > 0"
severity = "CRITICAL"
}
compute_bare_metal_unhealthy_alarm = {
display_name = "compute_bare_metal_unhealthy_alarm"
- metric_compartment_id = var.workload_compartment_id
+ metric_compartment_id = module.workload_compartment.compartment_id
namespace = "oci_compute_infrastructure_health"
query = "health_status[1m].count() > 0"
severity = "CRITICAL"
}
compute_high_compute_alarm = {
display_name = "compute_high_compute_alarm"
- metric_compartment_id = var.workload_compartment_id
+ metric_compartment_id = module.workload_compartment.compartment_id
namespace = "oci_computeagent"
query = "CpuUtilization[1m].mean() > 80"
severity = "CRITICAL"
}
compute_high_memory_alarm = {
display_name = "compute_high_memory_alarm"
- metric_compartment_id = var.workload_compartment_id
+ metric_compartment_id = module.workload_compartment.compartment_id
namespace = "oci_computeagent"
query = "MemoryUtilization[1m].mean() > 80"
severity = "CRITICAL"
}
database_adb_cpu_alarm = {
display_name = "database_adb_cpu_alarm"
- metric_compartment_id = var.workload_compartment_id
+ metric_compartment_id = module.workload_compartment.compartment_id
namespace = "oci_autonomous_database"
query = "CpuUtilization[1m].mean() > 80"
severity = "CRITICAL"
}
database_adb_storage_alarm = {
display_name = "database_adb_storage_alarm"
- metric_compartment_id = var.workload_compartment_id
+ metric_compartment_id = module.workload_compartment.compartment_id
namespace = "oci_autonomous_database"
query = "StorageUtilization[1m].mean() > 80"
severity = "CRITICAL"
}
network_lbUnHealthyBackendServers_alarm = {
display_name = "network_lbUnHealthyBackendServers_alarm"
- metric_compartment_id = var.workload_compartment_id
+ metric_compartment_id = module.workload_compartment.compartment_id
namespace = "oci_lbaas"
query = "UnHealthyBackendServers[1m].mean() > 0"
severity = "CRITICAL"
}
network_lbFailedSSLClientCertVerify_alarm = {
display_name = "network_lbFailedSSLClientCertVerify_alarm"
- metric_compartment_id = var.workload_compartment_id
+ metric_compartment_id = module.workload_compartment.compartment_id
namespace = "oci_lbaas"
query = "FailedSSLClientCertVerify[1m].mean() > 0"
severity = "CRITICAL"
}
network_lbFailedSSLHandshake_alarm = {
display_name = "network_lbFailedSSLHandshake_alarm"
- metric_compartment_id = var.workload_compartment_id
+ metric_compartment_id = module.workload_compartment.compartment_id
namespace = "oci_lbaas"
query = "FailedSSLHandshake[1m].mean() > 0"
severity = "CRITICAL"
}
network_vcnVnicConntrackIsFull_alarm = {
display_name = "network_vcnVnicConntrackIsFull_alarm"
- metric_compartment_id = var.workload_compartment_id
+ metric_compartment_id = module.workload_compartment.compartment_id
namespace = "oci_vcn"
query = "VnicConntrackIsFull[1m].mean() > 0"
severity = "CRITICAL"
@@ -121,42 +121,42 @@ locals {
workload_alarms_warning_map = {
objectstorage_UncommittedParts_alarm = {
display_name = "objectstorage_UncommittedParts_alarm"
- metric_compartment_id = var.workload_compartment_id
+ metric_compartment_id = module.workload_compartment.compartment_id
namespace = "oci_objectstorage"
query = "UncommittedParts[1m].count() > 0"
severity = "WARNING"
}
objectstorage_ClientErrors_alarm = {
display_name = "objectstorage_ClientErrors_alarm"
- metric_compartment_id = var.workload_compartment_id
+ metric_compartment_id = module.workload_compartment.compartment_id
namespace = "oci_objectstorage"
query = "ClientErrors[1m].sum() > 0"
severity = "WARNING"
}
network_lbPeakBandwidth_alarm = {
display_name = "network_lbPeakBandwidth_alarm"
- metric_compartment_id = var.workload_compartment_id
+ metric_compartment_id = module.workload_compartment.compartment_id
namespace = "oci_lbaas"
query = "PeakBandwidth[1m].mean() < 8"
severity = "WARNING"
}
network_vcnVnicConntrackUtilPercent_alarm = {
display_name = "network_vcnVnicConntrackUtilPercent_alarm"
- metric_compartment_id = var.workload_compartment_id
+ metric_compartment_id = module.workload_compartment.compartment_id
namespace = "oci_vcn"
query = "VnicConntrackUtilPercent[1m].mean() > 80"
severity = "WARNING"
}
network_vcnVnicEgressDropThrottle_alarm = {
display_name = "network_vcnVnicEgressDropThrottle_alarm"
- metric_compartment_id = var.workload_compartment_id
+ metric_compartment_id = module.workload_compartment.compartment_id
namespace = "oci_vcn"
query = "VnicEgressDropThrottle[1m].mean() > 0"
severity = "WARNING"
}
network_vcnVnicIngressDropThrottle_alarm = {
display_name = "network_vcnVnicIngressDropThrottle_alarm"
- metric_compartment_id = var.workload_compartment_id
+ metric_compartment_id = module.workload_compartment.compartment_id
namespace = "oci_vcn"
query = "VnicIngressDropThrottle[1m].mean() > 0"
severity = "WARNING"
@@ -167,31 +167,30 @@ locals {
module "workload_critical_topic" {
source = "../../modules/notification-topic"
+ count = var.is_create_alarms ? 1 : 0
- compartment_id = var.workload_compartment_id
+ compartment_id = module.workload_compartment.compartment_id
topic_name = local.workload_critical_topic.topic_name
topic_description = local.workload_critical_topic.topic_description
subscription_endpoint = var.workload_topic_endpoints
subscription_protocol = local.workload_critical_topic.subscription_protocol
-
- depends_on = [ module.workload_compartment ]
}
module "workload_warning_topic" {
source = "../../modules/notification-topic"
- compartment_id = var.workload_compartment_id
+ count = var.is_create_alarms ? 1 : 0
+
+ compartment_id = module.workload_compartment.compartment_id
topic_name = local.workload_warning_topic.topic_name
topic_description = local.workload_warning_topic.topic_description
subscription_endpoint = var.workload_topic_endpoints
subscription_protocol = local.workload_warning_topic.subscription_protocol
-
- depends_on = [ module.workload_compartment ]
}
#module "workload_alarms_warning" {
-# source = "../../modules/alarms"
-#
-# compartment_id = var.workload_compartment_id
+# source = "../../modules/alarms"
+
+# compartment_id = module.workload_compartment.compartment_id
# notification_topic_id = module.workload_warning_topic.topic_id
# is_enabled = local.workload_alarms.is_enabled
# message_format = local.workload_alarms.message_format
@@ -199,13 +198,12 @@ module "workload_warning_topic" {
# metric_compartment_id_in_subtree = local.workload_alarms.metric_compartment_id_in_subtree
# alarm_map = local.workload_alarms.workload_alarms_warning_map
#
-# depends_on = [ module.workload_compartment ]
#}
#module "workload_alarms_critical" {
-# source = "../../modules/alarms"
-#
-# compartment_id = var.workload_compartment_id
+# source = "../../modules/alarms"
+# count = var.workload_expansion_flag == true ? 1 : 0
+# compartment_id = module.workload_compartment.compartment_id
# notification_topic_id = module.workload_critical_topic.topic_id
# is_enabled = local.workload_alarms.is_enabled
# message_format = local.workload_alarms.message_format
@@ -213,5 +211,4 @@ module "workload_warning_topic" {
# metric_compartment_id_in_subtree = local.workload_alarms.metric_compartment_id_in_subtree
# alarm_map = local.workload_alarms.workload_alarms_critical_map
#
-# depends_on = [ module.workload_compartment ]
#}
diff --git a/templates/elz-workload/network.tf b/templates/elz-workload/network.tf
new file mode 100644
index 00000000..99f0a78b
--- /dev/null
+++ b/templates/elz-workload/network.tf
@@ -0,0 +1,46 @@
+################################################################
+# Workload Expansion Spoke NW Configuration #
+################################################################
+module "workload_expansion_spoke" {
+ source = "../elz-spoke"
+ count = var.workload_expansion_flag ? 1 : 0
+ environment_prefix = var.environment_prefix
+ tenancy_ocid = var.tenancy_ocid
+ region = var.region
+ #Spoke VCN Variables
+ workload_spoke_vcn_cidr = var.workload_spoke_vcn_cidr
+ vcn_dns_label = var.vcn_dns_label
+ vcn_display_name = var.vcn_display_name != "" ? var.vcn_display_name : "OCI-ELZ-${var.workload_prefix}-EXP-SPK-VCN-${local.region_key[0]}"
+ #Spoke VCN Subnet Variables
+ workload_private_spoke_subnet_web_display_name = var.workload_private_spoke_subnet_web_display_name != "" ? var.workload_private_spoke_subnet_web_display_name : "OCI-ELZ-${var.workload_prefix}-EXP-SPK-VCN-SUB-${local.region_key[0]}-001"
+ workload_private_spoke_subnet_app_display_name = var.workload_private_spoke_subnet_app_display_name != "" ? var.workload_private_spoke_subnet_app_display_name : "OCI-ELZ-${var.workload_prefix}-EXP-SPK-VCN-SUB-${local.region_key[0]}-002"
+ workload_private_spoke_subnet_db_display_name = var.workload_private_spoke_subnet_db_display_name != "" ? var.workload_private_spoke_subnet_db_display_name : "OCI-ELZ-${var.workload_prefix}-EXP-SPK-VCN-SUB-${local.region_key[0]}-003"
+ workload_private_spoke_subnet_web_cidr_block = var.workload_private_spoke_subnet_web_cidr_block
+ workload_private_spoke_subnet_app_cidr_block = var.workload_private_spoke_subnet_app_cidr_block
+ workload_private_spoke_subnet_db_cidr_block = var.workload_private_spoke_subnet_db_cidr_block
+ workload_private_spoke_subnet_web_dns_label = var.workload_private_spoke_subnet_web_dns_label
+ workload_private_spoke_subnet_app_dns_label = var.workload_private_spoke_subnet_app_dns_label
+ workload_private_spoke_subnet_db_dns_label = var.workload_private_spoke_subnet_db_dns_label
+
+ #VCN Gateway Variables
+ enable_nat_gateway_spoke = var.enable_nat_gateway_spoke
+ enable_service_gateway_spoke = var.enable_service_gateway_spoke
+ nat_gateway_display_name = var.nat_gateway_display_name != "" ? var.nat_gateway_display_name : "OCI-ELZ-${var.workload_prefix}-EXP-SPK-NAT-${local.region_key[0]}"
+ service_gateway_display_name = var.service_gateway_display_name != "" ? var.service_gateway_display_name : "OCI-ELZ-${var.workload_prefix}-EXP-SPK-SGW-${local.region_key[0]}"
+ route_table_display_name = var.route_table_display_name != "" ? var.route_table_display_name : "OCI-ELZ-${var.workload_prefix}-EXP-SPK-RTPRV-${local.region_key[0]}"
+ security_list_display_name = var.security_list_display_name != "" ? var.security_list_display_name : "OCI-ELZ-${var.workload_prefix}-EXP-SPK-Security-List"
+ drg_id = var.drg_id
+ hub_public_subnet_cidr_block = var.hub_public_subnet_cidr_block
+ hub_private_subnet_cidr_block = var.hub_private_subnet_cidr_block
+ workload_compartment_id = module.workload_compartment.compartment_id
+
+ customer_onprem_ip_cidr = var.customer_onprem_ip_cidr
+ enable_vpn_on_environment = var.enable_vpn_on_environment
+ enable_vpn_or_fastconnect = var.enable_vpn_or_fastconnect
+ ipsec_connection_static_routes = var.ipsec_connection_static_routes
+
+ providers = {
+ oci = oci
+ oci.home_region = oci.home_region
+ }
+}
diff --git a/templates/elz-workload/providers.standalone b/templates/elz-workload/providers.standalone
new file mode 100644
index 00000000..225d2964
--- /dev/null
+++ b/templates/elz-workload/providers.standalone
@@ -0,0 +1,49 @@
+# -----------------------------------------------------------------------------
+# providers.tf for using this template as a standalone stack.
+# Provider Requirements if using stack as standalone
+# -----------------------------------------------------------------------------
+terraform {
+ required_version = ">= 1.0.0"
+ required_providers {
+ oci = {
+ source = "oracle/oci"
+ version = "4.96.0" # October 05, 2022 Release
+ }
+ }
+}
+# -----------------------------------------------------------------------------
+# Provider blocks for home region and alternate region(s)
+# -----------------------------------------------------------------------------
+provider "oci" {
+ tenancy_ocid = var.tenancy_ocid
+ user_ocid = var.current_user_ocid
+ fingerprint = var.api_fingerprint
+ private_key_path = var.api_private_key_path
+ region = var.region
+}
+provider "oci" {
+ alias = "home_region"
+ tenancy_ocid = var.tenancy_ocid
+ user_ocid = var.current_user_ocid
+ fingerprint = var.api_fingerprint
+ private_key_path = var.api_private_key_path
+ region = local.home_region[0]
+}
+# -----------------------------------------------------------------------------
+# Provider Variables
+# -----------------------------------------------------------------------------
+variable "current_user_ocid" {
+ type = string
+ description = "The OCID of the current user"
+ default = ""
+}
+variable "api_fingerprint" {
+ type = string
+ description = "The fingerprint of API"
+ default = ""
+}
+variable "api_private_key_path" {
+ type = string
+ description = "The local path to the API private key"
+ default = ""
+}
\ No newline at end of file
diff --git a/templates/elz-workload/read_base_vars.py b/templates/elz-workload/read_base_vars.py
new file mode 100644
index 00000000..942d0cc9
--- /dev/null
+++ b/templates/elz-workload/read_base_vars.py
@@ -0,0 +1,54 @@
+import json
+import argparse
+
+def read_base_lz_vars(env, json_file):
+ with open(json_file, 'r') as f:
+ terr_out = json.load(f)
+
+ if env == "P":
+ key = "prod_environment"
+ else:
+ key = "nonprod_environment"
+
+ env_vars = terr_out[key]['value']
+ drg_id = env_vars['drg_id']
+ hub_vcn_id = env_vars['hub_vcn']
+ hub_public_subnet_cidr = env_vars["hub_public_subnet_cidr"]
+ hub_private_subnet_cidr = env_vars["hub_private_subnet_cidr"]
+
+ compartments = env_vars["compartments"]
+ net_comp_id = compartments["network"]["id"]
+ env_comp_id = compartments["environment"]["id"]
+ sec_comp_id = compartments["security"]["id"]
+ sec_comp_name = compartments["security"]["name"]
+
+ idomain = env_vars["identity_domain"]
+ id_id = idomain["id"]
+ id_name = idomain["display_name"]
+
+ print(f"hub_vcn_id = \"{hub_vcn_id}\"")
+ print(f"drg_id = \"{drg_id}\"")
+ print(f"hub_public_subnet_cidr_block = \"{hub_public_subnet_cidr}\"")
+ print(f"hub_private_subnet_cidr_block = \"{hub_private_subnet_cidr}\"")
+
+ print(f"security_compartment_id = \"{sec_comp_id}\"")
+ print(f"security_compartment_name = \"{sec_comp_name}\"")
+ print(f"environment_compartment_id = \"{env_comp_id}\"")
+
+ print(f"identity_domain_id = \"{id_id}\"")
+ print(f"identity_domain_name = \"{id_name}\"")
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(description="Script to read outputs from base Landing Zone for Workload")
+ parser.add_argument('-e','--environment',
+ choices=['N', 'P'],
+ default="P",
+ help="The environment (N or P) the workload will be deployed to")
+
+ parser.add_argument('-f', '--json-output-file',
+ required=True,
+ help="File containing output of `terraform output -json` in base landing zone")
+
+ args = parser.parse_args()
+ read_base_lz_vars(args.environment, args.json_output_file)
+
\ No newline at end of file
diff --git a/templates/elz-workload/schema.yaml b/templates/elz-workload/schema.yaml
new file mode 100644
index 00000000..15bb351e
--- /dev/null
+++ b/templates/elz-workload/schema.yaml
@@ -0,0 +1,319 @@
+title: Oracle Enterprise Landing Zone v2 - Workload Expansion
+description: Oracle Enterprise Landing Zone v2 - Workload Expansion developed by OCI
+schemaVersion: 1.0.0
+version: "1.0.0"
+locale: en
+variableGroups:
+ - title: Provider Variables
+ visible: false
+ variables:
+ - api_fingerprint
+ - api_private_key_path
+ - region
+ - tenancy_ocid
+ - current_user_ocid
+ - title: Compartment Variables
+ visible: true
+ variables:
+ - workload_expansion_flag
+ - workload_compartment_name
+ - environment_compartment_id
+ - environment_prefix
+ - workload_prefix
+ - enable_compartment_delete
+ - title: Monitoring Variables
+ visible: true
+ variables:
+ - enable_network_monitoring_alarms
+ - enable_security_monitoring_alarms
+ - enable_workload_monitoring_alarms
+ - workload_topic_endpoints
+ - workload_name
+ - title: Network Variables
+ visible: true
+ variables:
+ - workload_spoke_vcn_cidr
+ - vcn_display_name
+ - vcn_dns_label
+ - workload_private_spoke_subnet_web_cidr_block
+ - workload_private_spoke_subnet_db_cidr_block
+ - workload_private_spoke_subnet_app_cidr_block
+ - enable_nat_gateway_spoke
+ - enable_service_gateway_spoke
+ - hub_public_subnet_cidr_block
+ - hub_private_subnet_cidr_block
+ - workload_private_spoke_subnet_web_dns_label
+ - workload_private_spoke_subnet_app_dns_label
+ - workload_private_spoke_subnet_db_dns_label
+ - workload_private_spoke_subnet_web_display_name
+ - workload_private_spoke_subnet_app_display_name
+ - workload_private_spoke_subnet_db_display_name
+ - nat_gateway_display_name
+ - service_gateway_display_name
+ - route_table_display_name
+ - security_list_display_name
+ - drg_id
+ - title: IAM Policy Variables
+ visible: true
+ variables:
+ - identity_domain_id
+ - identity_domain_name
+ - workload_admin_group_name
+ - application_admin_group_name
+ - database_admin_group_name
+ - security_compartment_name
+ - security_compartment_id
+ - title: Invisible Variables
+ visible: false
+ variables:
+ - enable_internet_gateway_spoke
+ - nat_gw_spoke_check
+ - service_gw_spoke_check
+ - customer_onprem_ip_cidr
+ - enable_vpn_on_environment
+ - enable_vpn_or_fastconnect
+ - ipsec_connection_static_routes
+ - is_create_alarms
+ - network_compartment_id
+ - network_topic_endpoints
+ - secops_topic_endpoints
+
+variables:
+ #Provider Variables
+ api_fingerprint:
+ type: string
+ description: The fingerprint of API
+ default: "Value not required in Oracle Resource Manager."
+ title: Api Fingerprint
+ api_private_key_path:
+ type: string
+ description: The local path to the API private key
+ default: "Value not required in Oracle Resource Manager."
+ title: Api Private Key Path
+ region:
+ type: string
+ description: "the OCI region LZ is deployed to."
+ title: Region
+ required: true
+ tenancy_ocid:
+ type: string
+ description: "The OCID of tenancy"
+ title: Tenancy OCID
+ current_user_ocid:
+ type: string
+ description: "OCID of the current user"
+ title: Current User OCID
+ #Workload Variables
+ workload_expansion_flag:
+ type: boolean
+ description: "Set true to enable workload expansion"
+ default: true
+ title: Enable Workload Expansion
+ required: true
+ workload_compartment_name:
+ type: string
+ description: "The name of workload compartment is going to create."
+ title: Workload Compartment Name
+ required: true
+ environment_compartment_id:
+ type: string
+ description: "The OCID of the environment compartment that the workload is created in."
+ title: Environment Compartment OCID
+ required: true
+ environment_prefix:
+ type: string
+ description: "The unique prefix of environment compartment used in baseline stack."
+ title: Environment Prefix
+ required: true
+ workload_prefix:
+ type: string
+ description: "The unique prefix of the workload is going to create, using for avoid naming conflict."
+ title: Workload Prefix
+ required: true
+ enable_compartment_delete:
+ type: boolean
+ description: "Set to true to allow the compartments to delete on terraform destroy."
+ required: true
+ title: Enable Compartment Delete
+ enable_network_monitoring_alarms:
+ type: boolean
+ description: "Enable Network Monitoring Alarms in Workload Expansion."
+ default: false
+ required: true
+ title: Enable Network Monitoring Alarms in Workload Expansion
+ enable_security_monitoring_alarms:
+ type: boolean
+ description: "Enable Security Monitoring Alarms in Workload Expansion."
+ default: false
+ required: true
+ title: Enable Security Monitoring Alarms in Workload Expansion
+ enable_workload_monitoring_alarms:
+ type: boolean
+ description: "Enable Workload Monitoring Alarms in Workload Expansion."
+ default: false
+ required: true
+ title: Enable Workload Monitoring Alarms in Workload Expansion
+ workload_spoke_vcn_cidr:
+ type: string
+ description: "Vcn CIDR block in Workload Expansion Spoke"
+ required: true
+ pattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1][0-9]|[2][0-9]))$
+ title: VCN CIDR Block in Workload Expansion Spoke
+ vcn_display_name:
+ type: string
+ description: "Vcn display name in Workload Expansion Spoke"
+ required: true
+ title: VCN Display Name in Workload Expansion Spoke
+ vcn_dns_label:
+ type: string
+ description: "Vcn DNS label in Workload Expansion Spoke"
+ required: true
+ title: VCN DNS Label in Workload Expansion Spoke
+ workload_private_spoke_subnet_web_cidr_block:
+ type: string
+ description: "Web subnet CIDR block in Workload Expansion Spoke"
+ required: true
+ pattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1][0-9]|[2][0-9]))$
+ title: Web Subnet CIDR Block in Workload Expansion Spoke
+ workload_private_spoke_subnet_app_cidr_block:
+ type: string
+ description: "App subnet CIDR block in Workload Expansion Spoke"
+ required: true
+ pattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1][0-9]|[2][0-9]))$
+ title: App Subnet CIDR Block in Workload Expansion Spoke
+ workload_private_spoke_subnet_db_cidr_block:
+ type: string
+ description: "Database subnet CIDR block in Workload Expansion Spoke"
+ required: true
+ pattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1][0-9]|[2][0-9]))$
+ title: Database Subnet CIDR Block in Workload Expansion Spoke
+ enable_nat_gateway_spoke:
+ type: boolean
+ description: "Option to enable nat gateway in Workload Expansion spoke"
+ default: true
+ required: true
+ title: Enable NAT Gateway in Workload Expansion Spoke
+ enable_service_gateway_spoke:
+ type: boolean
+ description: "Option to enable service gateway in Workload Expansion spoke"
+ default: true
+ required: true
+ title: Enable Service Gateway in Workload Expansion Spoke
+ hub_public_subnet_cidr_block:
+ type: string
+ description: "the CIDR block of HUB public subnet in baseline stack"
+ required: true
+ title: HUB Public Subnet CIDR Block
+ hub_private_subnet_cidr_block:
+ type: string
+ description: "the CIDR block of HUB private subnet in baseline stack"
+ required: true
+ title: HUB Private Subnet CIDR Block
+ workload_private_spoke_subnet_web_dns_label:
+ type: string
+ description: "the DNS label for web subnet in workload expansion spoke."
+ required: true
+ title: Web Subnet DNS Label in Workload Expansion Spoke
+ workload_private_spoke_subnet_app_dns_label:
+ type: string
+ description: "the DNS label for App subnet in workload expansion spoke."
+ required: true
+ title: App Subnet DNS Label in Workload Expansion Spoke
+ workload_private_spoke_subnet_db_dns_label:
+ type: string
+ description: "the DNS label for Database subnet in workload expansion spoke."
+ required: true
+ title: Database Subnet DNS Label in Workload Expansion Spoke
+ workload_private_spoke_subnet_web_display_name:
+ type: string
+ description: "the display name for Web subnet in workload expansion spoke."
+ required: true
+ title: Web Subnet Display Name in Workload Expansion Spoke
+ workload_private_spoke_subnet_app_display_name:
+ type: string
+ description: "the display name for App subnet in workload expansion spoke."
+ required: true
+ title: App Subnet Display Name in Workload Expansion Spoke
+ workload_private_spoke_subnet_db_display_name:
+ type: string
+ description: "the display name for Database subnet in workload expansion spoke."
+ required: true
+ title: Database Subnet Display Name in Workload Expansion Spoke
+ nat_gateway_display_name:
+ type: string
+ description: "the display name of NAT Gateway"
+ title: NAT Gateway Display Name
+ default: "ngw"
+ required: true
+ service_gateway_display_name:
+ type: string
+ description: "the display name of Service Gateway"
+ title: Service Gateway Display Name
+ default: "sgw"
+ required: true
+ route_table_display_name:
+ type: string
+ description: "the display name of route table in workload expansion spoke"
+ title: Route Table Display Name
+ required: true
+ security_list_display_name:
+ type: string
+ description: "the display name of security list in workload expansion spoke"
+ title: Security List Display Name
+ required: true
+ drg_id:
+ type: string
+ description: "the OCID of DRG created in baseline stack"
+ title: DRG OCID
+ required: true
+ # IAM
+ identity_domain_id:
+ type: string
+ description: "the OCID of identity domain that the workload expansion is going to create in"
+ title: Identity Domain OCID
+ required: true
+ identity_domain_name:
+ type: string
+ description: "the name of identity domain that the workload expansion is going to create in"
+ title: Identity Domain Name
+ required: true
+ workload_admin_group_name:
+ type: string
+ description: "the name of workload admin"
+ title: Workload Admin Group Name
+ required: true
+ application_admin_group_name:
+ type: string
+ description: "the name of application admin"
+ title: Application Admin Group Name
+ required: true
+ database_admin_group_name:
+ type: string
+ description: "the name of database admin"
+ title: Databse Admin Group Name
+ required: true
+ security_compartment_name:
+ type: string
+ description: "the name of the security compartment that is in the same environment of workload expansion and created in baseline stack"
+ title: Security Compartment Name
+ required: true
+ security_compartment_id:
+ type: string
+ description: "the ocid of the security compartment that is in the same environment of workload expansion and created in baseline stack"
+ title: Security Compartment OCID
+ required: true
+ workload_topic_endpoints:
+ type: array
+ items:
+ type: string
+ pattern: ^[^\s@]+@([^\s@.,]+\.)+[^\s@.,]{2,}$
+ description: "List of email addresses for Workload Warning and Critical notifications."
+ required: false
+ default: [ ]
+ title: Workload Warning and Critical Notification Recipient Email List in Workload Expansion
+ workload_name:
+ type: string
+ required: true
+ default: "W"
+ description: Prefix Name of Workload Expansion Topics to avoid name conflicts
+ title: Prefix Name of Workload Expansion Topics
diff --git a/templates/elz-workload/variables.tf b/templates/elz-workload/variables.tf
index 158442f8..d69706b4 100644
--- a/templates/elz-workload/variables.tf
+++ b/templates/elz-workload/variables.tf
@@ -25,30 +25,27 @@ variable "enable_compartment_delete" {
default = true
}
-#variable "enviroment_compartment_id" {
-# type = string
-# description = "the OCID of the compartment where the environment will be created. In general, this should be the Landing zone parent compartment."
-#}
-
-variable "security_compartment_id" {
+variable "environment_compartment_id" {
type = string
description = "the OCID of the compartment where the environment will be created. In general, this should be the Landing zone parent compartment."
}
-variable "network_compartment_id" {
+variable "security_compartment_id" {
type = string
description = "the OCID of the compartment where the environment will be created. In general, this should be the Landing zone parent compartment."
+ default = ""
}
-variable "workload_compartment_id" {
+variable "network_compartment_id" {
type = string
- default = ""
description = "the OCID of the compartment where the environment will be created. In general, this should be the Landing zone parent compartment."
+ default = ""
}
variable "workload_name" {
type = string
description = "The name of the workload."
+ default = "W"
}
variable "workload_compartment_name" {
@@ -57,7 +54,9 @@ variable "workload_compartment_name" {
default = ""
}
-
+# -----------------------------------------------------------------------------
+# Monitoring Variables
+# -----------------------------------------------------------------------------
variable "workload_topic_endpoints" {
type = list(string)
default = []
@@ -70,6 +69,7 @@ variable "workload_topic_endpoints" {
error_message = "Validation failed: invalid email address."
}
}
+
variable "network_topic_endpoints" {
type = list(string)
default = []
@@ -95,19 +95,100 @@ variable "secops_topic_endpoints" {
error_message = "Validation failed: invalid email address."
}
}
+variable "is_create_alarms" {
+ type = bool
+ description = "Enable Alarms Creation in all Compartment"
+ default = true
+}
+# -----------------------------------------------------------------------------
+# Workload Expansion Variables
+# -----------------------------------------------------------------------------
+variable "customer_onprem_ip_cidr" {
+ type = list(string)
+ default = []
+}
+variable "enable_vpn_on_environment" {
+ type = bool
+ default = false
+}
+variable "enable_vpn_or_fastconnect" {
+ type = string
+ default = "NONE"
+}
+variable "ipsec_connection_static_routes" {
+ type = list(string)
+ default = [""]
+}
variable "enable_security_monitoring_alarms" {
type = bool
description = "Enable Security Monitoring Alarms in Security Compartment"
+ default = false
+ validation {
+ condition = can(regex("^([t][r][u][e]|[f][a][l][s][e])$", var.enable_security_monitoring_alarms))
+ error_message = "The workload_expansion_flag variable must be either true or false."
+ }
}
+
variable "enable_network_monitoring_alarms" {
type = bool
description = "Enable Network Monitoring Alarms in Network Compartment"
+ default = false
+ validation {
+ condition = can(regex("^([t][r][u][e]|[f][a][l][s][e])$", var.enable_network_monitoring_alarms))
+ error_message = "The workload_expansion_flag variable must be either true or false."
+ }
}
+
variable "enable_workload_monitoring_alarms" {
type = bool
description = "Enable Workload Monitoring Alarms in Workload Compartment"
+ default = false
+ validation {
+ condition = can(regex("^([t][r][u][e]|[f][a][l][s][e])$", var.enable_workload_monitoring_alarms))
+ error_message = "The workload_expansion_flag variable must be either true or false."
+ }
}
-variable "environment_compartment_id" {
+
+# -----------------------------------------------------------------------------
+# Identity Variables
+# -----------------------------------------------------------------------------
+variable "security_compartment_name" {
+ type = string
+ description = "Security Compartment Name."
+ default = ""
+}
+
+variable "identity_domain_id" {
+ type = string
+ description = "the ocid of identity domain"
+ default = "ocid1.domain."
+ validation {
+ condition = can(regex("^domain$", split(".", var.identity_domain_id)[1]))
+ error_message = "Only Domain are OCID is allowed."
+ }
+}
+
+variable "identity_domain_name" {
type = string
-}
\ No newline at end of file
+ description = "identity domain name"
+ default = ""
+}
+
+variable "workload_admin_group_name" {
+ type = string
+ description = "the name of workload admin group"
+ default = ""
+}
+
+variable "application_admin_group_name" {
+ type = string
+ description = "the name of workload application admin group"
+ default = ""
+}
+
+variable "database_admin_group_name" {
+ type = string
+ description = "the name of workload database admin group"
+ default = ""
+}
diff --git a/templates/elz-workload/workload_extension-variables.tf b/templates/elz-workload/workload_extension-variables.tf
new file mode 100644
index 00000000..79828aaa
--- /dev/null
+++ b/templates/elz-workload/workload_extension-variables.tf
@@ -0,0 +1,206 @@
+# -----------------------------------------------------------------------------
+# Network Variables
+# -----------------------------------------------------------------------------
+variable "workload_expansion_flag" {
+ type = bool
+ description = "Set to true if you want to use this as independent Workload Expansion Deployment Stack."
+ default = false
+ validation {
+ condition = can(regex("^([t][r][u][e]|[f][a][l][s][e])$", var.workload_expansion_flag))
+ error_message = "The workload_expansion_flag variable must be either true or false."
+ }
+}
+
+variable "workload_private_spoke_subnet_web_cidr_block" {
+ type = string
+ description = "Workload Enivornment Spoke VCN CIDR Block."
+ validation {
+ condition = can(cidrhost(var.workload_private_spoke_subnet_web_cidr_block, 0))
+ error_message = "Must be valid IPv4 CIDR."
+ }
+}
+
+variable "workload_private_spoke_subnet_app_cidr_block" {
+ type = string
+ description = "Workload Enivornment Spoke VCN CIDR Block."
+ validation {
+ condition = can(cidrhost(var.workload_private_spoke_subnet_app_cidr_block, 0))
+ error_message = "Must be valid IPv4 CIDR."
+ }
+}
+
+variable "workload_private_spoke_subnet_db_cidr_block" {
+ type = string
+ description = "Workload Enivornment Spoke VCN CIDR Block."
+ validation {
+ condition = can(cidrhost(var.workload_private_spoke_subnet_db_cidr_block, 0))
+ error_message = "Must be valid IPv4 CIDR."
+ }
+}
+
+variable "workload_spoke_vcn_cidr" {
+ description = "IPv4 CIDR blocks the VCN will use."
+ type = string
+}
+
+
+
+
+variable "enable_nat_gateway_spoke" {
+ type = bool
+ default = false
+ validation {
+ condition = can(regex("^([t][r][u][e]|[f][a][l][s][e])$", var.enable_nat_gateway_spoke))
+ error_message = "The variable must be either true or false."
+ }
+}
+
+variable "enable_service_gateway_spoke" {
+ type = bool
+ default = false
+ validation {
+ condition = can(regex("^([t][r][u][e]|[f][a][l][s][e])$", var.enable_service_gateway_spoke))
+ error_message = "The variable must be either true or false."
+ }
+}
+
+
+variable "vcn_dns_label" {
+ description = "A DNS label for the VCN, used in conjunction with the VNIC's hostname and subnet's DNS label to form a fully qualified domain name (FQDN) for each VNIC within this subnet"
+ type = string
+ default = "spokelabel"
+ validation {
+ condition = length(var.vcn_dns_label) < 16
+ error_message = "DNS Label : Max 15 alphanumeric characters allowed."
+ }
+}
+
+variable "enable_internet_gateway_spoke" {
+ type = bool
+ default = false
+ validation {
+ condition = can(regex("^([t][r][u][e]|[f][a][l][s][e])$", var.enable_internet_gateway_spoke))
+ error_message = "The workload_expansion_flag variable must be either true or false."
+ }
+}
+
+
+variable "workload_private_spoke_subnet_web_dns_label" {
+ description = "A DNS label for the VCN Subnet, used in conjunction with the VNIC's hostname and subnet's DNS label to form a fully qualified domain name (FQDN) for each VNIC within this subnet"
+ type = string
+ default = "webdnslabel"
+ validation {
+ condition = length(var.workload_private_spoke_subnet_web_dns_label) < 16
+ error_message = "DNS Label : Max 15 alphanumeric characters allowed."
+ }
+}
+
+variable "workload_private_spoke_subnet_app_dns_label" {
+ description = "A DNS label for the VCN Subnet, used in conjunction with the VNIC's hostname and subnet's DNS label to form a fully qualified domain name (FQDN) for each VNIC within this subnet"
+ type = string
+ default = "appdnslabel"
+ validation {
+ condition = length(var.workload_private_spoke_subnet_app_dns_label) < 16
+ error_message = "DNS Label : Max 15 alphanumeric characters allowed."
+ }
+}
+
+variable "workload_private_spoke_subnet_db_dns_label" {
+ description = "A DNS label for the VCN Subnet, used in conjunction with the VNIC's hostname and subnet's DNS label to form a fully qualified domain name (FQDN) for each VNIC within this subnet"
+ type = string
+ default = "dbdnslabel"
+ validation {
+ condition = length(var.workload_private_spoke_subnet_db_dns_label) < 16
+ error_message = "DNS Label : Max 15 alphanumeric characters allowed."
+ }
+}
+
+variable "nat_gateway_display_name" {
+ description = "(Updatable) Name of NAT Gateway. Does not have to be unique."
+ type = string
+ default = "ngw"
+}
+
+variable "service_gateway_display_name" {
+ description = "(Updatable) Name of Service Gateway. Does not have to be unique."
+ type = string
+ default = "sgw"
+}
+
+variable "nat_gw_spoke_check" {
+ type = list(string)
+ default = [""]
+}
+
+variable "service_gw_spoke_check" {
+ type = list(string)
+ default = [""]
+}
+
+variable "workload_prefix" {
+ type = string
+ description = "Atleast 4 Alphanumeric Charater to Describe the Workload : WRK1"
+ default = "WRK1"
+}
+
+variable "vcn_display_name" {
+ type = string
+ description = "Workload Expansion Spoke VCN Display Name"
+ default = ""
+}
+
+variable "workload_private_spoke_subnet_web_display_name" {
+ type = string
+ description = "Workload Expansion Spoke Web Subnet Display Name."
+ default = ""
+}
+
+variable "workload_private_spoke_subnet_app_display_name" {
+ type = string
+ description = "Workload Expansion Spoke App Subnet Display Name."
+ default = ""
+}
+
+variable "workload_private_spoke_subnet_db_display_name" {
+ type = string
+ description = "Workload Expansion Spoke Db Subnet Display Name."
+ default = ""
+}
+
+variable "route_table_display_name" {
+ type = string
+ description = "Workload Expansion Spoke Route Table Name Disply Name."
+ default = ""
+}
+
+variable "security_list_display_name" {
+ type = string
+ description = "Workload Expansion Spoke Security List Name Disly Name."
+ default = ""
+}
+
+variable "drg_id" {
+ type = string
+ validation {
+ condition = can(regex("^drg$", split(".", var.drg_id)[1]))
+ error_message = "Only Compartment OCID is allowed."
+ }
+}
+
+variable "hub_public_subnet_cidr_block" {
+ type = string
+ default = "10.1.1.0/24"
+ validation {
+ condition = can(cidrhost(var.hub_public_subnet_cidr_block, 0))
+ error_message = "Must be valid IPv4 CIDR."
+ }
+}
+
+variable "hub_private_subnet_cidr_block" {
+ type = string
+ default = "10.1.2.0/24"
+ validation {
+ condition = can(cidrhost(var.hub_private_subnet_cidr_block, 0))
+ error_message = "Must be valid IPv4 CIDR."
+ }
+}
diff --git a/templates/elz-workload/workload_extension.tfvars b/templates/elz-workload/workload_extension.tfvars
new file mode 100644
index 00000000..0c39fa61
--- /dev/null
+++ b/templates/elz-workload/workload_extension.tfvars
@@ -0,0 +1,63 @@
+# Provider
+current_user_ocid = ""
+region = ""
+tenancy_ocid = ""
+api_fingerprint = ""
+api_private_key_path = ""
+
+#####################################################
+# Workload Expansion Compartment Variable
+#####################################################
+enable_compartment_delete = false
+workload_compartment_name = ""
+environment_compartment_id = ""
+workload_expansion_flag = true
+environment_prefix = "N"
+workload_prefix = "WRK1"
+
+#####################################################
+# Workload Expansion IAM Group Variable
+#####################################################
+identity_domain_id = ""
+identity_domain_name = ""
+security_compartment_name = ""
+security_compartment_id = ""
+workload_admin_group_name = ""
+application_admin_group_name = ""
+database_admin_group_name = ""
+
+
+#####################################################
+# Workload Expansion Network Variables
+#####################################################
+vcn_display_name = ""
+vcn_dns_label = ""
+workload_spoke_vcn_cidr = "10.5.0.0/16"
+workload_private_spoke_subnet_web_cidr_block = "10.5.1.0/24"
+workload_private_spoke_subnet_app_cidr_block = "10.5.2.0/24"
+workload_private_spoke_subnet_db_cidr_block = "10.5.3.0/24"
+enable_nat_gateway_spoke = true
+enable_service_gateway_spoke = true
+drg_id = ""
+hub_public_subnet_cidr_block = "10.1.1.0/24"
+hub_private_subnet_cidr_block = "10.1.2.0/24"
+workload_private_spoke_subnet_web_dns_label = "workloadweblabel"
+workload_private_spoke_subnet_app_dns_label = "workloadapplabel"
+workload_private_spoke_subnet_db_dns_label = "workloaddblabel"
+nat_gateway_display_name = ""
+service_gateway_display_name = ""
+workload_private_spoke_subnet_web_display_name = ""
+workload_private_spoke_subnet_app_display_name = ""
+workload_private_spoke_subnet_db_display_name = ""
+route_table_display_name = ""
+security_list_display_name = ""
+drg_id = ""
+
+#####################################################
+# Workload Expansion Monitoring Variables
+#####################################################
+workload_topic_endpoints = [""]
+workload_name = "W"
+enable_network_monitoring_alarms = false
+enable_security_monitoring_alarms = false
+enable_workload_monitoring_alarms = false
diff --git a/templates/enterprise-landing-zone/IMPLEMENTATION.md b/templates/enterprise-landing-zone/IMPLEMENTATION.md
index f23d9d13..4ab06a03 100644
--- a/templates/enterprise-landing-zone/IMPLEMENTATION.md
+++ b/templates/enterprise-landing-zone/IMPLEMENTATION.md
@@ -284,6 +284,36 @@ The steps to clean up these resources is as follows:
Once these resources have been removed, you will be able to use Terraform to delete the rest of the Enterprise Scale Baseline Landing Zone. If using terraform CLI: run `terraform destroy` to remove other resources. If using ORM: navigate to the corresponding stack created and click `Destroy`.
+#### Cleanup Script
+A clean up script is provided to assist in cleaning up lingering resources that block terraform destroy.
+It can be found at `./destroy_lz.py`
+
+Once the script has been run, service connectors, buckets, and log analytics log groups will be deleted, identity domains deactivated, and vaults moved to the root compartment.
+Terraform destroy will need to be run after.
+
+1. To run the script ensure you have **python3** installed as well as an **oci api key**.
+ * install python [here](https://www.python.org/downloads/)
+ * set up api keys [here](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm)
+
+2. Verify the profile name(eg. DEFAULT) by checking the config file found at `~/.oci/config` (if the profile you want to use is not DEFAULT use the `--profile` flag to indicate).
+
+3. Install dependencies using the command:
+ ```
+ pip install oci tqdm
+ ```
+
+4. Run the command (from the templates/enterprise-landing-zone directory)
+ ```
+ python destroy_lz.py -r IAD -e P N -c OCI-ELZ-CMP-HOME
+ ```
+
+The `-r` flag indicates the 3 letter region key, the `-e` indicates the environment prefix, such as production and non-production, and the `-c` indicating the home compartment.
+
+For more information on flag usage for the script use the `--help` flag.
+```
+python destroy_lz.py --help
+```
+
## Known Issues
---
diff --git a/templates/enterprise-landing-zone/README.md b/templates/enterprise-landing-zone/README.md
index 957f1b08..0ef2f29a 100644
--- a/templates/enterprise-landing-zone/README.md
+++ b/templates/enterprise-landing-zone/README.md
@@ -110,7 +110,7 @@ Version 2 of Enterprise Scale Baseline Landing Zone
| [nonprod\_enable\_service\_gateway\_spoke](#input\_nonprod\_enable\_service\_gateway\_spoke) | Option to enable TRUE and Disable false. | `string` | `"false"` | no |
| [nonprod\_enable\_tagging](#input\_nonprod\_enable\_tagging) | Option to enable Tagging gateway in Non-Production environment | `bool` | `false` | no |
| [nonprod\_enable\_vault\_replication](#input\_nonprod\_enable\_vault\_replication) | Option to enable vault replication | `bool` | `false` | no |
-| [nonprod\_enable\_vpn](#input\_nonprod\_enable\_vpn) | Enable VPN in non prod environment | `bool` | n/a | yes |
+| [nonprod\_enable\_vpn](#input\_nonprod\_enable\_vpn) | Enable VPN in non prod environment | `bool` | `false` | no |
| [nonprod\_enable\_workload\_monitoring\_alarms](#input\_nonprod\_enable\_workload\_monitoring\_alarms) | Enable Workload Monitoring Alarms in Non-Production Workload Compartment | `bool` | `false` | no |
| [nonprod\_geo\_location\_tagging](#input\_nonprod\_geo\_location\_tagging) | Non-Production Geo Location. | `string` | n/a | yes |
| [nonprod\_hub\_private\_subnet\_cidr\_block](#input\_nonprod\_hub\_private\_subnet\_cidr\_block) | Non-Production Enivornment HUB Private Subnet CIDR Block. | `string` | n/a | yes |
@@ -172,7 +172,7 @@ Version 2 of Enterprise Scale Baseline Landing Zone
| [prod\_enable\_service\_gateway\_spoke](#input\_prod\_enable\_service\_gateway\_spoke) | Option to enable TRUE and Disable false. | `string` | `"false"` | no |
| [prod\_enable\_tagging](#input\_prod\_enable\_tagging) | Option to enable Tagging gateway in Production environment | `bool` | `false` | no |
| [prod\_enable\_vault\_replication](#input\_prod\_enable\_vault\_replication) | Option to enable vault replication | `bool` | `false` | no |
-| [prod\_enable\_vpn](#input\_prod\_enable\_vpn) | Enable VPN in prod environment | `bool` | n/a | yes |
+| [prod\_enable\_vpn](#input\_prod\_enable\_vpn) | Enable VPN in prod environment | `bool` | `false` | no |
| [prod\_enable\_workload\_monitoring\_alarms](#input\_prod\_enable\_workload\_monitoring\_alarms) | Enable Workload Monitoring Alarms in Production Workload Compartment | `bool` | `false` | no |
| [prod\_geo\_location\_tagging](#input\_prod\_geo\_location\_tagging) | Production Geo Center. | `string` | n/a | yes |
| [prod\_hub\_private\_subnet\_cidr\_block](#input\_prod\_hub\_private\_subnet\_cidr\_block) | Production Enivornment HUB Private Subnet CIDR Block. | `string` | n/a | yes |
diff --git a/templates/enterprise-landing-zone/destroy_lz.py b/templates/enterprise-landing-zone/destroy_lz.py
index d51a112e..e1013e80 100644
--- a/templates/enterprise-landing-zone/destroy_lz.py
+++ b/templates/enterprise-landing-zone/destroy_lz.py
@@ -1,24 +1,17 @@
import argparse
-import os
from concurrent.futures import ThreadPoolExecutor
from datetime import datetime
-from typing import List, Dict
-import subprocess
+from typing import Dict, List
import oci
from tqdm import tqdm
class DestroyLandingZone:
- def __init__(self, parent_cmp: str, region_key: str, env_prefixes: List[str], oci_config: str, profile_name: str):
- '''
- Inputs include parent compartment as its name can be overridden via tfvar.
- Region key and Environment prefix are variables used in compartment naming as well.
- '''
+ def __init__(self, parent_cmp: str, region_key: str, resource_label: str, oci_config: str = "~/.oci/config", profile_name: str = "DEFAULT"):
- self._conf_file = oci_config
self.config = oci.config.from_file(
- file_location=self.config_filename,
+ file_location=oci_config,
profile_name=profile_name
)
@@ -27,22 +20,22 @@ def __init__(self, parent_cmp: str, region_key: str, env_prefixes: List[str], o
self.log_analytics_client = oci.log_analytics.LogAnalyticsClient(
self.config)
self.identity_client = oci.identity.IdentityClient(self.config)
- self.key_management_client = oci.key_management.KmsVaultClient(
+ self.kms_vault_client = oci.key_management.KmsVaultClient(
self.config)
- print("finished initializing oci clients")
+ self.sch_client = oci.sch.ServiceConnectorClient(self.config)
self.tenancy_id = self.config["tenancy"]
- self.parent_cmp = parent_cmp
self.os_namespace = self.get_os_namespace()
+
+ self.parent_cmp = parent_cmp
self.region_key = region_key
- self.env_prefixes = env_prefixes
+ self.resource_label = resource_label
- @property
- def config_filename(self):
- fn = os.path.join(os.environ["HOME"], self._conf_file)
- return fn
+ def get_os_namespace(self) -> str:
+ os_namespace = self.os_client.get_namespace()
+ return os_namespace.data
- def get_cmps(self, env_prefix: str) -> Dict[str, str]:
+ def get_elz_cmps(self, env_prefix: str) -> Dict[str, str]:
parent_cmps_response = self.identity_client.list_compartments(
compartment_id=self.tenancy_id,
name=self.parent_cmp
@@ -87,9 +80,62 @@ def get_cmps(self, env_prefix: str) -> Dict[str, str]:
return cmp_map
- def get_os_namespace(self):
- os_namespace = self.os_client.get_namespace()
- return os_namespace.data
+ def get_scca_cmps(self) -> Dict[str, str]:
+ parent_cmps_response = self.identity_client.list_compartments(
+ compartment_id=self.tenancy_id,
+ name=self.parent_cmp
+ )
+ parent_cmp_id = parent_cmps_response.data[0].id
+
+ vdms_cmp_name = f"OCI-SCCA-LZ-VDMS-{self.region_key}-{self.resource_label}"
+ vdms_cmps_response = self.identity_client.list_compartments(
+ compartment_id=parent_cmp_id,
+ name=vdms_cmp_name
+ )
+ vdms_cmp_id = vdms_cmps_response.data[0].id
+
+ vdss_cmp_name = f"OCI-SCCA-LZ-VDSS-{self.region_key}-{self.resource_label}"
+ vdss_cmps_response = self.identity_client.list_compartments(
+ compartment_id=parent_cmp_id,
+ name=vdss_cmp_name
+ )
+ vdss_cmp_id = vdss_cmps_response.data[0].id
+
+ log_cmp_name = f"OCI-SCCA-LZ-Logging-{self.region_key}-{self.resource_label}"
+ log_cmps_response = self.identity_client.list_compartments(
+ compartment_id=parent_cmp_id,
+ name=log_cmp_name
+ )
+ log_cmp_id = log_cmps_response.data[0].id
+
+ iac_cmp_name = f"OCI-SCCA-LZ-IAC-TF-Configbackup-{self.resource_label}"
+ iac_cmps_response = self.identity_client.list_compartments(
+ compartment_id=parent_cmp_id,
+ name=iac_cmp_name
+ )
+ iac_cmp_id = iac_cmps_response.data[0].id
+
+ cmp_map = {
+ "parent": parent_cmp_id,
+ "vdms": vdms_cmp_id,
+ "vdss": vdss_cmp_id,
+ "log": log_cmp_id,
+ "iac": iac_cmp_id
+ }
+
+ return cmp_map
+
+ def get_sch_ids(self, cmp_id: str) -> List[str]:
+ list_service_connectors_response = self.sch_client.list_service_connectors(
+ compartment_id=cmp_id
+ )
+ sch_ids = [d.id for d in list_service_connectors_response.data.items]
+ return sch_ids
+
+ def delete_sch(self, sch_id: str):
+ delete_service_connector_response = self.sch_client.delete_service_connector(
+ service_connector_id=sch_id
+ )
def get_bucket_names(self, cmp_id: str) -> List[str]:
buckets_response = self.os_client.list_buckets(
@@ -152,20 +198,20 @@ def purge_log_analytics(self, cmp_id: str):
namespace_name=self.os_namespace,
purge_storage_data_details=oci.log_analytics.models.PurgeStorageDataDetails(
compartment_id=cmp_id,
- time_data_ended=datetime.now().strftime(
- "%Y-%m-%dT%H:%M:%S.%fZ"),
- compartment_id_in_subtree=True),
- # wait_for_states=["SUCCEEDED"]
+ time_data_ended=datetime.now().strftime("%Y-%m-%d") + "T23:59",
+ purge_query_string="*",
+ compartment_id_in_subtree=True
+ ),
+ )
+
+ wait_for_resource_id = purge_storage_data_response.headers['opc-work-request-id']
+ waiter_result = oci.wait_until(
+ self.log_analytics_client,
+ self.log_analytics_client.get_storage_work_request(
+ wait_for_resource_id, self.os_namespace),
+ "status",
+ "SUCCEEDED"
)
- # purge_storage_data_response = oci.log_analytics.LogAnalyticsClientCompositeOperations(self.log_analytics_client).purge_storage_data_and_wait_for_state(
- # namespace_name=self.os_namespace,
- # purge_storage_data_details=oci.log_analytics.models.PurgeStorageDataDetails(
- # compartment_id=cmp_id,
- # time_data_ended=datetime.now().strftime(
- # "%Y-%m-%dT%H:%M:%S.%fZ"),
- # compartment_id_in_subtree=True),
- # wait_for_states=["SUCCEEDED"]
- # )
def delete_log_analytics_group(self, cmp_id: str):
list_log_analytics_log_groups_response = self.log_analytics_client.list_log_analytics_log_groups(
@@ -181,36 +227,50 @@ def delete_log_analytics_group(self, cmp_id: str):
)
print(delete_log_analytics_log_group_response.data)
- def move_vaults(self, cmp_id):
- list_vaults_response = self.key_management_client.list_vaults(
+ def move_vaults(self, cmp_id: str):
+ list_vaults_response = self.kms_vault_client.list_vaults(
compartment_id=cmp_id
)
vaults = list_vaults_response.data
for vault in vaults:
- if vault.lifecycle_state != "CREATED":
+ if vault.lifecycle_state != "ACTIVE":
print(
f"ignoring vault {vault.display_name} not in created state")
continue
- change_vault_compartment_response = self.key_management_client.change_vault_compartment(
+ self.move_keys(cmp_id, vault.management_endpoint)
+
+ change_vault_compartment_response = self.kms_vault_client.change_vault_compartment(
vault_id=vault.id,
change_vault_compartment_details=oci.key_management.models.ChangeVaultCompartmentDetails(
compartment_id=self.tenancy_id
)
)
- def update_terraform_state(self):
- process = subprocess.run(["terraform state rm module.nonprod_environment.module.security.module.vault.oci_kms_vault.vault"],
- stdout=subprocess.PIPE,
- universal_newlines=True,
- shell=True)
- process = subprocess.run(["terraform state rm module.prod_environment.module.security.module.vault.oci_kms_vault.vault"],
- stdout=subprocess.PIPE,
- universal_newlines=True,
- shell=True)
-
- def deactivate_domains(self, cmp_id):
+ def move_keys(self, cmp_id, vault_endpoint):
+ kms_key_client = oci.key_management.KmsManagementClient(
+ self.config, vault_endpoint)
+
+ list_keys_response = kms_key_client.list_keys(
+ compartment_id=cmp_id
+ )
+ keys = list_keys_response.data
+
+ for key in keys:
+ if key.lifecycle_state != "ENABLED":
+ print(
+ f"ignoring key {key.display_name} not in created state")
+ continue
+
+ change_key_compartment_response = kms_key_client.change_key_compartment(
+ key_id=key.id,
+ change_key_compartment_details=oci.key_management.models.ChangeKeyCompartmentDetails(
+ compartment_id=self.tenancy_id
+ )
+ )
+
+ def deactivate_domains(self, cmp_id: str):
list_domains_response = self.identity_client.list_domains(
compartment_id=cmp_id
)
@@ -225,40 +285,82 @@ def delete_environment(self, env_prefix: str):
print(f"beginning env {env_prefix} destroy")
print("fetching compartment ids")
- compartments = self.get_cmps(env_prefix)
- bucket_cmps = [compartments["parent"], compartments["log"]]
+ compartments = self.get_elz_cmps(env_prefix)
+
+ # delete sc hubs to stop logs flowing into buckets and log groups
+ print("beginning service connector destroy")
+ sch_ids = self.get_sch_ids(compartments["security"])
+ for sch in sch_ids:
+ self.delete_sch(sch)
print("beginning bucket destroy")
+ bucket_cmps = [compartments["parent"], compartments["log"]]
bucket_names = []
for cmp in bucket_cmps:
bucket_names += self.get_bucket_names(cmp)
- print(bucket_names)
- with ThreadPoolExecutor(max_workers=4) as p:
+ with ThreadPoolExecutor(max_workers=3) as p:
p.map(self.delete_bucket_all, bucket_names)
+ # log analytics errors out in certain tenancies - fix unknown
print("beginning log analytics destroy")
self.purge_log_analytics(compartments["security"])
self.delete_log_analytics_group(compartments["security"])
+ print("deactivating domains")
+ self.deactivate_domains(compartments["security"])
+
+ # vault only needs to be moved out of the landing zone compartments
+ # - once you run destroy, terraform will destroy it where it is
+ # also note vault can only be moved in an ACTIVE state
print("beginning vault move")
self.move_vaults(compartments["security"])
- # self.update_terraform_state()
+
+ print("finished destroying ___\n\n")
+
+ def destroy_scca(self):
+ print("beginning elz destroy")
+
+ print("fetching compartment ids")
+ compartments = self.get_scca_cmps()
+
+ print("beginning service connector destroy")
+ sch_ids = self.get_sch_ids(compartments["vdms"])
+ for sch in sch_ids:
+ self.delete_sch(sch)
+
+ print("beginning bucket destroy")
+ bucket_cmps = [compartments["iac"], compartments["log"]]
+ bucket_names = []
+ for cmp in bucket_cmps:
+ bucket_names += self.get_bucket_names(cmp)
+
+ with ThreadPoolExecutor(max_workers=3) as p:
+ p.map(self.delete_bucket_all, bucket_names)
+
+ print("beginning log analytics destroy")
+ self.purge_log_analytics(compartments["vdms"])
+ self.delete_log_analytics_group(compartments["vdms"])
print("deactivating domains")
- self.deactivate_domains(compartments["security"])
+ self.deactivate_domains(compartments["vdms"])
- print("finished destroying ___\n\n")
+ print("beginning vault move")
+ self.move_vaults(compartments["vdms"])
- def run_all(self):
- for env in self.env_prefixes:
- self.delete_environment(env)
+ print("finished destroying ___\n\n")
if __name__ == "__main__":
+ '''
+ The script cleans up lingering resources that block terraform destroy. Once the
+ script has been run, service connectors, buckets, and log analytics log groups
+ will be deleted, identity domains deactivated, and vaults moved to the root
+ compartment. Terraform destroy will need to be run after.
+ '''
+
parser = argparse.ArgumentParser(
- description="Destroy Landing Zone Lingering Resources",
- epilog="python destroy_lz.py -r IAD -e P N")
+ description="Destroy Landing Zone Lingering Resources")
parser.add_argument("-c", "--cmp",
default="OCI-ELZ-CMP-HOME",
@@ -267,24 +369,40 @@ def run_all(self):
parser.add_argument("-r", "--region_key",
help="Region Key used in compartment naming eg. IAD, PHX")
- parser.add_argument("-e", "--env_prefixes", nargs="+",
+ parser.add_argument("-e", "--elz_envs", nargs="+",
default=["P", "N"],
- help="Environment prefix used in compartment naming")
+ help="Delete ELZ Landing Zone Environments by prefix eg. P, N")
+
+ parser.add_argument("-l", "--scca_label",
+ help="Delete SCCA Landing Zone with specified resource label")
+
+ parser.add_argument("--delete_buckets", nargs="+",
+ help="Delete buckets by bucket name")
parser.add_argument("--profile",
default="DEFAULT",
help="OCI profile you want to use in the specified region")
parser.add_argument("--oci_config",
- default=".oci/config",
+ default="~/.oci/config",
help="Path to the OCI Configuration file")
args = parser.parse_args()
- generate_schema = DestroyLandingZone(
+ destroy_lz = DestroyLandingZone(
parent_cmp=args.cmp,
region_key=args.region_key,
- env_prefixes=args.env_prefixes,
+ resource_label=args.scca_label,
oci_config=args.oci_config,
profile_name=args.profile
)
- generate_schema.run_all()
+
+ if args.delete_buckets:
+ for bucket in args.delete_buckets:
+ destroy_lz.delete_bucket_all(bucket)
+ elif args.scca_label:
+ destroy_lz.destroy_scca()
+ elif args.elz_envs:
+ for env in args.elz_envs:
+ destroy_lz.delete_environment(env)
+ else:
+ print("Select only one of the following flags: delete_buckets, scca_label, or elz_envs.")
diff --git a/templates/enterprise-landing-zone/environment.tf b/templates/enterprise-landing-zone/environment.tf
index 9d986585..c0afcd29 100644
--- a/templates/enterprise-landing-zone/environment.tf
+++ b/templates/enterprise-landing-zone/environment.tf
@@ -26,6 +26,7 @@ module "prod_environment" {
platform_admin_group_name = var.prod_platform_admin_group_name
ops_admin_group_name = var.prod_ops_admin_group_name
security_admin_group_name = var.prod_security_admin_group_name
+ workload_compartment_names = var.prod_workload_compartment_names
workload_admin_group_name = var.prod_workload_admin_group_name
application_admin_group_name = var.prod_application_admin_group_name
@@ -38,6 +39,9 @@ module "prod_environment" {
budget_alert_rule_recipients = var.prod_budget_alert_rule_recipients
enable_cloud_guard = var.enable_cloud_guard
cloud_guard_target_tenancy = var.cloud_guard_target_tenancy
+ is_create_alarms = var.is_create_alarms
+ domain_license_type = var.domain_license_type
+
home_compartment_name = var.home_compartment_name
enable_vpn_or_fastconnect = var.enable_vpn_or_fastconnect
cpe_ip_address = var.prod_cpe_ip_address
@@ -115,6 +119,7 @@ module "prod_environment" {
enable_network_monitoring_alarms = var.prod_enable_network_monitoring_alarms
enable_workload_monitoring_alarms = var.prod_enable_workload_monitoring_alarms
+ additional_workload_subnets_cidr_blocks = var.prod_additional_workload_subnets_cidr_blocks
providers = {
oci = oci
@@ -130,7 +135,7 @@ module "prod_environment" {
}
# -----------------------------------------------------------------------------
-# Prod Enviroment Resources
+# Non-Prod Enviroment Resources
# -----------------------------------------------------------------------------
locals {
nonprod_environment = {
@@ -157,6 +162,7 @@ module "nonprod_environment" {
platform_admin_group_name = var.nonprod_platform_admin_group_name
ops_admin_group_name = var.nonprod_ops_admin_group_name
security_admin_group_name = var.nonprod_security_admin_group_name
+ workload_compartment_names = var.nonprod_workload_compartment_names
workload_admin_group_name = var.nonprod_workload_admin_group_name
application_admin_group_name = var.nonprod_application_admin_group_name
@@ -167,6 +173,8 @@ module "nonprod_environment" {
budget_alert_rule_threshold = var.nonprod_budget_alert_rule_threshold
budget_alert_rule_message = var.nonprod_budget_alert_rule_message
budget_alert_rule_recipients = var.nonprod_budget_alert_rule_recipients
+ is_create_alarms = var.is_create_alarms
+ domain_license_type = var.domain_license_type
enable_cloud_guard = var.enable_cloud_guard
cloud_guard_target_tenancy = var.cloud_guard_target_tenancy
home_compartment_name = var.home_compartment_name
@@ -252,6 +260,8 @@ module "nonprod_environment" {
remote_peering_connection_peer_id = var.enable_vpn_or_fastconnect == "FASTCONNECT" ? module.prod_environment.rpc_id : null
remote_peering_connection_peer_region_name = var.region
+ additional_workload_subnets_cidr_blocks = var.nonprod_additional_workload_subnets_cidr_blocks
+
providers = {
oci = oci
oci.home_region = oci.home_region
diff --git a/templates/enterprise-landing-zone/example.tfvars b/templates/enterprise-landing-zone/example.tfvars
index 843d1ea4..af8a6599 100644
--- a/templates/enterprise-landing-zone/example.tfvars
+++ b/templates/enterprise-landing-zone/example.tfvars
@@ -92,3 +92,6 @@ nonprod_platform_topic_endpoints = []
nonprod_identity_topic_endpoints = []
nonprod_workload_topic_endpoints = []
+# Workload Expansion
+prod_additional_workload_subnets_cidr_blocks = []
+nonprod_additional_workload_subnets_cidr_blocks = []
\ No newline at end of file
diff --git a/templates/enterprise-landing-zone/integration.tfvars b/templates/enterprise-landing-zone/integration.tfvars
index 743715ee..28303ecb 100644
--- a/templates/enterprise-landing-zone/integration.tfvars
+++ b/templates/enterprise-landing-zone/integration.tfvars
@@ -71,4 +71,8 @@ prod_enable_tagging = true
nonprod_enable_tagging = true
# logging
-onboard_log_analytics = false
\ No newline at end of file
+onboard_log_analytics = false
+
+# Workload Expansion
+prod_additional_workload_subnets_cidr_blocks = []
+nonprod_additional_workload_subnets_cidr_blocks = []
\ No newline at end of file
diff --git a/templates/enterprise-landing-zone/outputs.tf b/templates/enterprise-landing-zone/outputs.tf
index 0d548592..9bc54a48 100644
--- a/templates/enterprise-landing-zone/outputs.tf
+++ b/templates/enterprise-landing-zone/outputs.tf
@@ -13,4 +13,30 @@ output "dynamic_group_detail" {
output "workload_compartment_id" {
value = module.prod_environment.workload_compartment_id
+}
+
+output "prod_environment" {
+ value = {
+ environment_prefix = local.prod_environment.environment_prefix
+ compartments = module.prod_environment.compartment
+ subnets = module.prod_environment.subnets
+ hub_vcn = module.prod_environment.vcn
+ hub_public_subnet_cidr = module.prod_environment.hub_public_subnet_cidr
+ hub_private_subnet_cidr = module.prod_environment.hub_private_subnet_cidr
+ drg_id = module.prod_environment.drg_id
+ identity_domain = module.prod_environment.identity_domain
+ }
+}
+
+output "nonprod_environment" {
+ value = {
+ environment_prefix = local.nonprod_environment.environment_prefix
+ compartments = module.nonprod_environment.compartment
+ subnets = module.nonprod_environment.subnets
+ hub_vcn = module.nonprod_environment.vcn
+ hub_public_subnet_cidr = module.nonprod_environment.hub_public_subnet_cidr
+ hub_private_subnet_cidr = module.nonprod_environment.hub_private_subnet_cidr
+ drg_id = module.nonprod_environment.drg_id
+ identity_domain = module.nonprod_environment.identity_domain
+ }
}
\ No newline at end of file
diff --git a/templates/enterprise-landing-zone/schema.yaml b/templates/enterprise-landing-zone/schema.yaml
index 0936d29e..d0d082a0 100644
--- a/templates/enterprise-landing-zone/schema.yaml
+++ b/templates/enterprise-landing-zone/schema.yaml
@@ -90,6 +90,8 @@ variableGroups:
- nonprod_spoke_subnet_web_cidr_block
- nonprod_spoke_subnet_app_cidr_block
- nonprod_spoke_subnet_db_cidr_block
+ - prod_additional_workload_subnets_cidr_blocks
+ - nonprod_additional_workload_subnets_cidr_blocks
- title: Tagging Variables
visible: true
variables:
@@ -872,6 +874,20 @@ variables:
required: true
pattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1][0-9]|[2][0-9]))$
title: Database Subnet CIDR Block in Non-Prod Spoke
+ prod_additional_workload_subnets_cidr_blocks:
+ type: array
+ items:
+ type: string
+ required: false
+ title: Additional Workload Subnets CIDR Blocks in Prod
+ description: "A list of subnets cidr blocks in additional workload expansion stack in Prod"
+ nonprod_additional_workload_subnets_cidr_blocks:
+ type: array
+ items:
+ type: string
+ required: false
+ title: Additional Workload Subnets CIDR Blocks in Non-Prod
+ description: "A list of subnets cidr blocks in additional workload expansion stack in Non-Prod"
# Network Extension Variables
enable_vpn_or_fastconnect:
diff --git a/templates/enterprise-landing-zone/security.tf b/templates/enterprise-landing-zone/security.tf
index 12d48fca..c3e190cf 100644
--- a/templates/enterprise-landing-zone/security.tf
+++ b/templates/enterprise-landing-zone/security.tf
@@ -109,6 +109,7 @@ locals {
}
module "cloud_guard_root_policy" {
+ count = var.enable_cloud_guard ? 1 : 0
source = "../../modules/policies"
compartment_ocid = var.tenancy_ocid
policy_name = local.cloud_guard_policy.name
@@ -117,6 +118,7 @@ module "cloud_guard_root_policy" {
}
module "cloud_guard_target_policy" {
+ count = var.enable_cloud_guard ? 1 : 0
source = "../../modules/policies"
compartment_ocid = var.cloud_guard_target_tenancy ? var.tenancy_ocid : module.home_compartment.compartment_id
policy_name = local.cloud_guard_target_policy.name
diff --git a/templates/enterprise-landing-zone/variables.tf b/templates/enterprise-landing-zone/variables.tf
index ed292c29..ba4485c1 100644
--- a/templates/enterprise-landing-zone/variables.tf
+++ b/templates/enterprise-landing-zone/variables.tf
@@ -50,6 +50,11 @@ variable "onboard_log_analytics" {
description = "Set to true to onboard the tenancy to logging analytics. "
default = true
}
+variable "domain_license_type" {
+ type = string
+ description = "Identity Domain License Type"
+ default = "premium"
+}
# -----------------------------------------------------------------------------
# Prod Enviroment Variables
@@ -106,6 +111,12 @@ variable "prod_database_admin_group_name" {
description = "The group name for the OCI Database Logging Administrators Group. Defaults to OCI-ELZ-UGP-P-DB-ADMIN if blank or not provided."
}
+variable "prod_workload_compartment_names" {
+ type = list(string)
+ default = []
+ description = "The names of the workload compartments to update policies for the Admin Groups"
+}
+
variable "prod_enable_budget" {
type = bool
}
@@ -188,6 +199,12 @@ variable "nonprod_database_admin_group_name" {
description = "The group name for the OCI Database Logging Administrators Group. Defaults to OCI-ELZ-UGP-N-DB-ADMIN if blank or not provided."
}
+variable "nonprod_workload_compartment_names" {
+ type = list(string)
+ default = []
+ description = "The names of the workload compartments to update policies for the Admin Groups"
+}
+
variable "nonprod_enable_budget" {
type = bool
}
@@ -621,7 +638,11 @@ variable "nonprod_workload_topic_endpoints" {
error_message = "Validation failed: invalid email address."
}
}
-
+variable "is_create_alarms" {
+ type = bool
+ default = true
+ description = "Enable Alarms Creation in all Compartment"
+}
variable "prod_enable_security_monitoring_alarms" {
type = bool
default = false
@@ -652,3 +673,18 @@ variable "nonprod_enable_workload_monitoring_alarms" {
default = false
description = "Enable Workload Monitoring Alarms in Non-Production Workload Compartment"
}
+
+# -----------------------------------------------------------------------------
+# Workload Network Variables
+# -----------------------------------------------------------------------------
+variable "prod_additional_workload_subnets_cidr_blocks" {
+ type = list(string)
+ default = []
+ description = "A list of subnets cidr blocks in additional workload stack in prod"
+}
+
+variable "nonprod_additional_workload_subnets_cidr_blocks" {
+ type = list(string)
+ default = []
+ description = "A list of subnets cidr blocks in additional workload stack in non-prod"
+}
\ No newline at end of file
diff --git a/templates/freetrial-landing-zone/.module-tf-docs.yml b/templates/freetrial-landing-zone/.module-tf-docs.yml
new file mode 100644
index 00000000..c8339416
--- /dev/null
+++ b/templates/freetrial-landing-zone/.module-tf-docs.yml
@@ -0,0 +1,13 @@
+formatter: "markdown table"
+
+recursive:
+ enabled: true
+ path: ../../modules
+
+output:
+ file: "README.md"
+ mode: insert
+ template: |-
+
+ {{ .Content }}
+
diff --git a/templates/freetrial-landing-zone/.terraform-docs.yml b/templates/freetrial-landing-zone/.terraform-docs.yml
new file mode 100644
index 00000000..904d9026
--- /dev/null
+++ b/templates/freetrial-landing-zone/.terraform-docs.yml
@@ -0,0 +1,13 @@
+formatter: "markdown table"
+
+recursive:
+ enabled: true
+ path: ../
+
+output:
+ file: "README.md"
+ mode: insert
+ template: |-
+
+ {{ .Content }}
+
diff --git a/templates/freetrial-landing-zone/Architecture_Guide.md b/templates/freetrial-landing-zone/Architecture_Guide.md
new file mode 100644
index 00000000..16524283
--- /dev/null
+++ b/templates/freetrial-landing-zone/Architecture_Guide.md
@@ -0,0 +1,195 @@
+# Oracle Enterprise Landing Zone Architectural Guide
+
+# **Introduction**
+
+The Oracle Enterprise Landing Zone "OELZ" provides the baseline architectural framework for your organization to deploy new projects and workloads on OCI. The landing zone consists of Terraform modules, the architectural documentation, and an implementation guide. The landing zone helps you quickly and securely create a foundation for your cloud deployment based on Oracle recommendations, customer experience, and industry-standard best practices.
+
+OELZ is a set of Terraform modules that are designed to make it easy to set up a secure and compliant multi-account infrastructure on OCI. Some common use cases for OCI Enterprise Scale Baseline Landing Zone include:
+
+- Governance and compliance: The OELZ provides a set of pre-built policies and guardrails that help ensure that your OCI environment is compliant with industry standards, such as ISO27001 and PCI DSS (these and other compliance standards will be part of ongoing releases).
+- Automation and scalability: The Landing Zone can be used to automate the creation of new accounts, users, and resources on OCI, making it easy to scale your infrastructure as your organization grows.
+
+# **Primary Objectives**
+
+The primary objectives of the OELZ zone include the following items:
+
+- Reduce time-to-start and deploy.
+- Provide an architecturally strong foundation.
+- Maintain the flexibility to customize and evolve the implementation to your organization's needs.
+
+# **Key Design Principles**
+
+Key design principles for resiliency and security ensure that the OELZ zone deploys a strong foundation for your cloud environment.
+
+## **_Resiliency_**
+
+A resilient cloud architecture helps you to avoid single points of failure for your cloud-based workloads.
+
+At the infrastructure level, OCI provides physical and logical resources to help you design for resiliency, such as [regions, availability domains, and fault domains](https://docs.oracle.com/iaas/Content/General/Concepts/regions.htm).
+
+Resiliency depends on the nature, architecture, and implementation of the workloads that you plan to deploy on OCI. For best practices, see [Resilience and Continuous Availability of Oracle Cloud Infrastructure Services and Platform FAQ](https://www.oracle.com/cloud/iaas/faq.html) and [Best practices for designing reliable and resilient cloud topologies](https://docs.oracle.com/en/solutions/oci-best-practices-resilience/reliable-and-resilient-cloud-topology-practices1.html).
+
+## **_Security_**
+
+The Enterprise Scale Baseline Landing Zone follows best practices for security design principles.
+
+- Design for attackers
+ - Limit permissions based on requirements
+ - Enforce network segmentation
+- Leverage native controls
+- Use identity as primary access control
+- Accountability
+- Embrace automation
+- Focus on information protection
+- Design for resilience
+ - Ongoing vigilance
+ - Defense in depth
+ - Defense at edge
+ - Least privilege
+- Assume zero trust
+
+For more information, see the security design principles in [Best practices framework for Oracle Cloud Infrastructure](https://docs.oracle.com/en/solutions/oci-best-practices/effective-strategies-security-and-compliance1.html#GUID-68F2BA09-96CE-48A4-B92E-8F928EE86F13).
+
+# **Architecture Overview**
+
+The OELZ creates an architectural framework that's ready for you to launch new projects and workloads on OCI.
+
+- [Compartments](https://docs.oracle.com/en-us/iaas/Content/cloud-adoption-framework/landing-zone.htm#compartments): Use compartments to organize and isolate your resources to make it easier to manage and secure access to them.
+- [Tags](https://docs.oracle.com/en-us/iaas/Content/cloud-adoption-framework/landing-zone.htm#tags): Use tags to organize and list resources based on your business needs.
+- [Budgets and alerts](https://docs.oracle.com/en-us/iaas/Content/cloud-adoption-framework/landing-zone.htm#budgets-alerts): Use [budgets](https://docs.oracle.com/iaas/Content/Billing/Concepts/budgetsoverview.htm) to set soft limits on your OCI spending.
+- [Oracle Cloud Infrastructure Identity and Access Management (IAM)](https://docs.oracle.com/en-us/iaas/Content/cloud-adoption-framework/landing-zone.htm#iam): Use IAM to control access to your cloud resources on OCI.
+- [Networking and connectivity](https://docs.oracle.com/en-us/iaas/Content/cloud-adoption-framework/landing-zone.htm#networking-connectivity): Create a virtual cloud network (VCN), subnets, and other networking and connectivity resources that are required to run your workloads and connect to the internet or your on-premises network via service gateway.
+- [Security](https://docs.oracle.com/en-us/iaas/Content/cloud-adoption-framework/landing-zone.htm#security): Enable a strong security posture by enabling OCI security services such as Oracle Cloud Infrastructure Bastion.
+
+The following diagram illustrates the OELZ.0 reference architecture.
+
+![](./images/enterprise-landing-zone-v2.svg)
+
+## **_Network and Connectivity_**
+
+One of the key components of the OELZ is the network architecture and its segmentation. With the adoption of the OELZ , you can have a highly segregated, functional environment to securely deploy your workloads. One of the key components of the network architecture is the use of the Hub & Spoke architecture the OELZ will provide two distinct Hub & Spoke architectures (one for the Production environment and one for non-Production environments) that are segregated from each other.
+
+In Oracle Cloud Infrastructure (OCI), the [Hub & Spoke architecture](https://docs.oracle.com/en/solutions/hub-spoke-network-drg/index.html#GUID-FB5990CB-A23B-482D-80F4-AE4A548DEC9C) is a network design pattern in which a central hub network is connected to multiple spoke networks. The hub network is typically used for shared resources, such as security appliances and core services, while the spoke networks are used for individual workloads or applications.
+
+The Hub & Spoke architecture deployed within the OELZ can provide several benefits, including:
+
+1. Isolation: Each spoke is its own compartment, which provides an additional layer of isolation and security for resources. This allows for better management and control over access to resources and limits the blast radius of any security incident.
+2. Scalability: Spokes can be added or removed as needed to support different use cases or teams. This allows for a flexible and scalable architecture that can adapt to changing business needs.
+3. Networking: A hub provides a central point for all network traffic to flow through, which simplifies the overall network architecture and improves security. Resources in different spokes can communicate with each other over the hub-spoke network without having to traverse the internet.
+4. Resource Management: Each spoke can be managed and administered independently, which allows for better resource allocation and more efficient use of resources. It also allows for different teams or business units to manage their own resources, with the ability to have different access to control and management.
+5. Cost Optimization: By centralizing certain resources, like VPN gateways and load balancers, in the hub, it can be more cost-effective to manage them.
+6. Governance: By having a central hub it becomes much more easier to apply governance rules and policies across the whole infrastructure and have a clear view of all the resources and activity going on in your enterprise.
+
+It's important to notice that this architecture is really flexible, so some of the components in the hub, like load balancer, could be moved to the Spoke, depending on the use case or need.
+
+In OELZ OCI, the hub network is created using a Virtual Cloud Network (VCN) in the Network Shared Infrastructure compartment in each environment, and the spoke networks are created in each Application compartment, using VCN Attachment through a [Dynamic Routing Gateway (DRG)](https://docs.oracle.com/en-us/iaas/Content/Network/Tasks/managingDRGs.htm). This allows the spoke networks to access the shared resources in the hub network while maintaining their isolation from each other.
+
+Overall, the Hub & Spoke architecture is a flexible and scalable design pattern that can be used to build complex network architectures in OCI and this is one of the main reasons why OELZ will allow you to have a pre-configured environment ready to use within minutes.
+
+For more information on the network architecture components, please refer to the sections of the modules that compose it.
+
+## **_Identity_**
+
+Use Oracle Cloud Infrastructure Identity and Access Management (IAM) to control access to your cloud resources on OCI.
+
+The Landing Zone creates IAM groups and policies that control access to the resources created by the Landing Zone. Optionally, you can federate with your organization's Microsoft Active Directory implementation.
+
+## _Compliance_
+
+OELZ includes a set of pre-built policies and guardrails that help ensure that your OCI environment has a strong security foundation to help your organization achieve your security compliance goals. The security controls that have been implemented in OELZ include recommendations that help our customers attain [CIS 1.2](https://www.cisecurity.org/benchmark/oracle_cloud) compliance Level 1.
+
+The Center for Internet Security, Inc. (CIS®) is a community-driven non-profit, responsible for the CIS Controls® and CIS Benchmarks™, globally recognized best practices for securing IT systems and data. The goal of CIS is to prevent and mitigate new cyber threats that are identified in the industry today. For many OCI customers, this has been a go-to benchmark that guides their architecture to help them secure their workloads in Oracle Cloud Infrastructure (OCI). Recognizing the importance of adhering to best practice guidance from both OCI teams and the industry, OCI Landing Zones continues to implement support for CIS Benchmarks today.
+
+For more information, please refer to ["CIS 1.2 Level 1"](./images/CIS1.2Level1.xlsx) for a list of security controls that are included in OELZ.
+
+## **_Compartments Module_**
+
+You use compartments to organize and isolate your resources to make it easier to manage and secure access to them.
+
+The OELZ creates a compartment structure for your organization. You control access to compartment by creating policies that specify what actions groups of users can take on the resources in those compartments. The following diagram shows the compartment structure that is created by the landing zone:
+
+![](./images/Compartment.png)
+
+The compartments module only creates the compartment structure for a single environment which include the following compartments:
+
+- **L2 - Environment:** The encapsulating compartment for an environment
+- **L3 - Shared infrastructure** : compartment containing the shared infrastructure:
+ - **L4: Network** : The compartment that will hold the Hub component of the network
+ - **L4 Security** : The compartment holding the security and identity components
+- **L3 - Workload** compartment that will hold a spoke connecting to the hub
+- **L3 Logging** : Compartment that will hold a bucket to store the log files from the environment
+- **L3 Backup** : A backup compartment that will contain the configuration and state file
+
+## **_Identity Module_**
+
+The identity module creates and configures an identity domain in an environment in the landing zone.
+
+In order to isolate access between resources, groups are created together with policies in order to restrict access to certain resources.
+
+- **Network Admin: ** User group that have access to the network resources inside your environment
+- **SecOps Admin: ** User group that have access to the security related resources inside your environment
+- **Identity Admin: ** User group that can manage the identity related resources
+- **Platform Admin: ** User group that have access to usage reports and can manage budgets
+- **Ops Admin: ** User group that have access to the metrics, events and alerts in your environment
+- **Log Admin: ** User group that have access to the logs of your environment
+
+
+**Streams & Events**
+
+OCI Streaming service is used for real-time ingestion of high-volume data streams. It can be used where data is continually produced and published sequentially such as with log events. The OELZ will utilize the OCI Streaming Service in conjunction with OCI events. OCI services generate _events_ that provide notifications when there are any resource changes in your environment.
+
+Please refer to [Services Event Types](https://docs.oracle.com/en-us/iaas/Content/Events/Reference/eventsproducers.htm#Services_that_Produce_Events) for a full list and refer to these links for more information regarding [Streaming](https://docs.oracle.com/en-us/iaas/Content/Streaming/home.htm) and [Events](https://docs.oracle.com/en-us/iaas/Content/Events/home.htm).
+
+
+## **_Network Module_**
+
+The network module includes two main Functional Modules, the first will deploy a type of network called "Hub & Spoke" (H&P) that will allow the various workloads to interconnect with each other. The second one called "Network Extension Module" will extend connectivity with the on-premises network as well using the H&P created previously.
+By default, the OELZ will deploy the H&P module within the " **L2 - OCI-ELZ-\**" compartment (for **PROD** and **NO-PROD** ). Also, the Network Extension Module will be an optional module and it will only be allowed to be deployed in the production environment. As a result, it will be shared between the two environments prod and non-prod.
+
+The main components that the Hub module will have been as follows:
+
+- A **VCN** which will host the different subnets of the HUB deployed in the **L4 - Network compartment**
+- A **public subnet** to host all internet-facing servers and resources, including load balancers, Web Servers...This subnet must be secured with the correct Cloud Guard recipes and other security features, as described in [Security paragraph](#ArchitecturalGuide-security)[.](#ArchitecturalGuide-securitymodule)
+- A **private subnet** to host all common or shared services that your environment uses such as Network Virtual Appliance, Internal Jump Box Server.
+- A **DRG** which will enable routing between the VNC Hub and other application VCNs (spokes), deployed in the **L4 - Network compartment**
+- A **Internet Gateways** [Optional] which allows traffic between the public subnets in a VCN and the public internet, deployed in the **L4 - Network compartment**
+- A **NAT Gateways** [Optional] which enables private resources in a VCN to access hosts on the internet, without exposing those resources to incoming internet connections, deployed in the **L4 - Network compartment**
+- A **Service gateway** [Optional] which provides access from a VCN to other services, such as Oracle Cloud Infrastructure Object Storage. The traffic from the VCN to the Oracle service travels over the Oracle network fabric and never traverses the internet, deployed in the **L4 - Network compartment.**
+
+The main components that the Spoke module will have are as follows:
+
+- A **VCN** which will host the different subnets of the Spoke deployed in the **L3 - Workload compartment**
+- Three **private subnets** to host all components of your application using different tier such as Web, App and DB.
+- A **VCN Attachments** which will be connected to the DRG of the HUB.
+- A **NAT Gateways** [Optional] which enables private resources in a VCN to access hosts on the internet, without exposing those resources to incoming internet connections, deployed in the **L3 - Workload compartment**
+- A **Service gateway** [Optional] which provides access from a VCN to other services, such as Oracle Cloud Infrastructure Object Storage. The traffic from the VCN to the Oracle service travels over the Oracle network fabric and never traverses the internet, deployed in the **L3 - Workload compartment.**
+
+**NOTE :** In a scenario in which the customer wishes to publish its Web Servers using the OELZ , an Public Load Balancer must be deployed within the public subnet in the HUB ( **L4 - Network Compartment** ), which will have as endpoints the Web Servers present in the subnet that will be part of the **L3 - Workload compartment.** Since connectivity is already configured via the Hub & Spoke architecture, all that needs to be done is to change the Security Lists associated with the subnets to enable traffic between the Load Balancer and the endpoints.
+
+
+## **_Security Module_**
+
+Oracle Cloud Infrastructure (OCI) is a Security-first Cloud Service that helps organizations reduce the risk of security threats for cloud workloads by putting our customers' Data Security and Privacy first. This is achieved via the automation of security operations with simple, prescriptive, and integrated cloud-native security capabilities built into the OCI platform. Oracle helps customers easily adopt OIC services and secure their cloud infrastructure, data, and applications.
+
+The OELZ further supports Oracle's Security-First Cloud strategy tenets:
+
+- Security should be simple—easy to use, deploy, and operate
+- Security tools should offer guidance to help customers achieve strong security more easily
+- Security should be integrated and automated, reducing manual security tasks and human errors
+- Cloud security should be economically attractive, improving the cost of securing cloud workloads
+
+
+# Mushop 3-tier Web Application
+
+After the baseline "OELZ" stack has been installed , we will install Mushop Web Application on L3 workload compartment.
+
+## **_Mushop Introduction_**
+
+MuShop Complete is a polyglot micro-services application built to showcase a cloud native approach to application development on [Oracle Cloud Infrastructure][oci] using Oracle's [cloud native](https://www.oracle.com/cloud/cloud-native/) services.
+- Mushop Topology
+![mushop_topo](<./images/mushop-topology.png> "mushop_topo")
+- Mushop Services Architecture
+![mushop_diagram](<./images/mushop-service.png> "mushop_diagram")
+MuShop is a showcase of several [Oracle Cloud Infrastructure][oci] services in a unified reference application. The sample application implements an e-commerce platform built as a set of micro-services. The accompanying content can be used to get started with cloud native application development on [Oracle Cloud Infrastructure][oci]. We will use Mushop 3-tier reference application is built to showcase the Oracle Cloud Infrastructure][oci] using OCI Free tier.
+
+
diff --git a/templates/freetrial-landing-zone/BackEnd.sh b/templates/freetrial-landing-zone/BackEnd.sh
new file mode 100755
index 00000000..d7609ece
--- /dev/null
+++ b/templates/freetrial-landing-zone/BackEnd.sh
@@ -0,0 +1,7 @@
+#! /bin/bash
+
+cat <> backend.tf
+terraform {
+ backend "http" {}
+}
+EOT
\ No newline at end of file
diff --git a/templates/freetrial-landing-zone/CONFIGURATION.md b/templates/freetrial-landing-zone/CONFIGURATION.md
new file mode 100644
index 00000000..c62cdd68
--- /dev/null
+++ b/templates/freetrial-landing-zone/CONFIGURATION.md
@@ -0,0 +1,61 @@
+## Oracle Enterprise Landing Zone Configuration Guide
+
+This configuration guide will detail the required and available configurations needed to deploy an Oracle Enterprise Landing Zone (OELZ) on Oracle Cloud Infrastructure.
+
+## Prerequisites
+
+The Oracle Enterprise Landing Zone is designed to be deployed to a tenancy owned by the individual Tenancy Administrator. The user deploying the OELZ must be a member of the Administrators group for the tenancy. The tenancy must have the required Resource Limits and have the Logging Analytics feature turned on. Detailed information on these prerequisites, and how to check that your tenancy meets them, and enable needed features can be found in the [Implementation Document](Implementation.md)
+
+
+## Minimum Required Configuration
+
+Deployment of the OELZ is controlled by several Terraform [input variables](README.md#inputs), however most of these have sensible default values. Here are the minimum required configurations to deploy a OELZ:
+
+### Basic Terraform Connection Information
+The required provider variables for the OELZ:
+
+| Name | Description | Type | Default | Required |
+| ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | -------- | ------- | :------: |
+| [current\_user\_ocid](#input\_current\_user\_ocid) | The ID of user to deploy the OELZ. | `string` | `""` | no |
+| [api\_fingerprint](#input\_api\_fingerprint) | The API fingerprint which can be retrieved from the console. | `string` | `""` | no |
+| [api\_private\_key](#input\_api\_private\_key) | The API private key | `string` | `""` | no |
+| [api\_private\_key\_path](#input\_api\_private\_key\_path) | The local path to the API private key | `string` | `""` | no |
+| [tenancy\_ocid](#input\_tenancy\_ocid) | The ID of tenancy | `string` | n/a | yes |
+| [region](#input\_region) | The OCI region to deploy the OELZ resources to. | `string` | n/a | yes |
+
+
+### OELZ Stack variables
+
+| Variable | Value |
+| :------------------------------------- | --------------------------------------- |
+| [resource\_label](#input\_resource\_label) | "LIVELAB" |
+| [enable\_compartment\_delete](#enable\_compartment\_delete) | false |
+| [prod\_domain\_admin\_email](#prod\_domain\_admin\_email) | Enter Email Address |
+| [home_compartment_name](#home_compartment_name) | "LIVELAB-OCI-CMP-HOME" |
+| [enable\_cloud\_guard](#enable\_cloud\_guard) | false |
+| [cloud\_guard\_target\_tenancy](#cloud\_guard\_target\_tenancy) | false |
+| [prod\_enable\_bastion](#prod\_enable\_bastion) | true |
+| [prod\_bastion\_client\_cidr\_block\_allow\_list](#prod\_bastion\_client\_cidr\_block\_allow\_list) | "10.0.0.0/16" "10.0.0.0/24" |
+| [prod\_budget\_alert\_rule\_message](#prod\_budget\_alert\_rule\_message) | "LIVELAB_ALEART" |
+| [prod\_budget\_alert\_rule\_threshold](#prod\_budget\_alert\_rule\_threshold) | "10000000" |
+| [prod\_budget\_amount](#prod\_budget\_amount) | "1000000" |
+| [prod\_enable\_budget](#prod\_enable\_budget) | true |
+| [is\_create\_alarms](#is\_create\_alarms) | false |
+| [domain\_license\_type](#domain\_license\_type) | "free" |
+| [onboard\_log\_analytics](#onboard\_log\_analytics) | false |
+| [prod\_enable\_vpn](#prod\_enable\_vpn) | false |
+| [prod\_cost\_center\_tagging](#prod\_cost\_center\_tagging) | "LIVELAB_COST_TAG" |
+| [prod\_geo\_location\_tagging](#prod\_geo\_location\_tagging) | "LIVELAB_GEO_TAG" |
+| [prod\_enable\_tagging](#prod\_enable\_tagging) | true |
+| [prod\_enable\_internet\_gateway\_hub](#prod\_enable\_internet\_gateway\_hub) | true |
+| [prod\_enable\_nat\_gateway\_hub](#prod\_enable\_nat\_gateway\_hub) | true |
+| [prod\_enable\_service\_gateway\_hub](#prod\_enable\_service\_gateway\_hub) | true |
+| [prod\_enable\_nat\_gateway\_spoke](#prod\_enable\_nat\_gateway\_spoke]) | true |
+| [prod\_enable\_service\_gateway\_spoke](#prod\_enable\_service\_gateway\_spoke) | true |
+| [prod\_hub\_vcn\_cidr\_block](#prod\_hub\_vcn\_cidr\_block) | "10.1.0.0/16" |
+| [prod\_hub\_public\_subnet\_cidr\_block](#prod\_hub\_public\_subnet\_cidr\_block) | "10.1.1.0/24" |
+| [prod\_hub\_private\_subnet\_cidr\_block](#prod\_hub\_private\_subnet\_cidr\_block) | "10.1.2.0/24" |
+| [prod\_spoke\_vcn\_cidr](#prod\_spoke\_vcn\_cidr) | "10.2.0.0/16" |
+| [prod\_spoke\_subnet\_web\_cidr\_block](#prod\_spoke\_subnet\_web\_cidr\_block) | "10.2.1.0/24" |
+| [prod\_spoke\_subnet\_app\_cidr\_block](#prod\_spoke\_subnet\_app\_cidr\_block) | "10.2.2.0/24" |
+| [prod\_spoke\_subnet\_db\_cidr\_block](#prod\_spoke\_subnet\_db\_cidr\_block) | "10.2.3.0/24" |
\ No newline at end of file
diff --git a/templates/freetrial-landing-zone/IMPLEMENTATION.md b/templates/freetrial-landing-zone/IMPLEMENTATION.md
new file mode 100644
index 00000000..41dc624a
--- /dev/null
+++ b/templates/freetrial-landing-zone/IMPLEMENTATION.md
@@ -0,0 +1,212 @@
+# Oracle Enterprise Landing Zone Infrastructure
+
+## Prerequisites
+
+To deploy the Oracle Enterprise Landing Zone Infrastructure OELZ from the terraform cli you will need the following prerequisites.
+- [Latest Version of Terrafom](https://developer.hashicorp.com/terraform/downloads)
+- [OCI Terraform provider](https://registry.terraform.io/providers/oracle/oci/latest/docs) v4.109.0 or later
+- [oci - cli](https://github.com/oracle/oci-cli)
+
+## User
+
+The OELZ should be deployed by a user who is a member of the Administrators group for the tenancy. This user need to have an api key entry defined as decribed [here](https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/terraformproviderconfiguration.htm). Once the user and API Key are defined your oci-cli config should resemble.
+
+```text
+[DEFAULT]
+user=ocid1.xxxxxx.xxxxxx.xxxxxx..... #ocid of the user
+fingerprint=xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx #user api key fingerprint
+tenancy=ocid1.xxxxxx.xxxxxx.xxxxxx..... #tenancy ocid
+region=us-phoenix-1 #or desired region
+key_file= # TODO
+```
+
+## Region
+
+The OELZ should be deployed to the tenancy's Home Region.
+
+## Tenancy
+
+The tenancy you intend to deploy the OELZ to.
+
+### Logging Analytics
+
+The Logging Analytics service should be enabled for the tenancy.
+To check the current status of Logging Analytics for a tenancy, visit the [Logging Analytics home page][1].
+There will be a dark grey box at the top of the page. On the right hand side of that box, if Logging analytics has *not* been enabled, there will be a notice that Logging Analytics has not been enabled for the tenancy, and a blue button to enable it. To enable it, click the blue button, and wait for the 3 onboarding steps to complete. No further action will be required, as the Enterprise Scale Baseline Landing Zone will configure the needed datasources.
+
+### Resource Limits
+
+Most of the initial resource limits a new tenancy comes with should be sufficient to deploy 1 OELZ, with 1 environments and 1 workload each.
+
+However, there are some resource limits that will need to be increased in order to deploy the Enterprise Scale Baseline Landing Zone. Below is a table listing the Terraform OCI resource names and numbers deployed please ensure your tenancy has sufficient limts before deploying the Enterprise Scale Baseline Landing Zone:
+
+https://docs.oracle.com/en-us/iaas/Content/General/Concepts/servicelimits.htm
+
+Requests to raise these limits can be done through the [request a service limit increase][2] page.
+
+[1]: https://cloud.oracle.com/loganalytics/home "Logging Analytics Home page."
+[2]: https://cloud.oracle.com/support/create?type=limit "Request a service Limit Increase."
+
+## Enterprise Scale Baseline Landing Zone Compartment Architecture
+
+---
+![Architecture](<../../images/LZ-v2.0.png> "Architecture")
+
+This architecture diagram illustrates the compartments Enterprise LZ deployments
+
+### Compartment Structure
+
+For the Enterprise Scale Baseline Landing Zone, we have the below compartment architecture:
+
+* Enterprise Scale Baseline Landing Zone Home Compartment
+ * Prod
+ * Shared Infrastructure
+ * Network
+ * Security
+ * Workload
+ * Logging
+ * Backup
+
+## Environments
+
+---
+Environments are each full infrastructure deployments with their own hub-and-spoke network, Identity domain, user groups, etc.
+
+
+## Workloads
+
+---
+Workloads are the "shell" for you to deploy an application or service into. They provide infrastructure such as a compartment you can place application resources in, user groups to manage the application, network and logging infrastructure, etc. Workloads exist within Environments.
+
+
+## Identity Domain
+
+---
+Environment will have its own identity domain with free tier identity domain. This lives in the Security compartment of each environment. The identity domain applies to all resources under the environment compartment.OELZ will only support the new identity domains in OCI(Henosis) and not the old IDCS domains.Each domain has it's own users and groups, and can be federated and configured separately.
+
+## Networking
+
+---
+Each environment will have it's own independent network configuration. The network architecture is a "Hub and Spoke" design. It is built around OCI's Dynamic Routing Gateway (DRG), which acts as central router. It can connect together multiple virtual networks like hub and spoke vcn.
+
+## Deployment of The Enterprise Scale Baseline Landing Zone
+
+## For customers who already have Infrastructure in OCI
+
+If you already have infrastructure deployed in OCI and are looking to explore a best-practices infrastructure architecture with Enterprise Scale Baseline Landing Zone, you may want to create a new [Child Tenancy](https://docs.oracle.com/en-us/iaas/Content/General/Concepts/organization_management_overview.htm) to deploy the Enterprise Scale Baseline Landing Zone in. This will guarantee there are no conflicts with existing infrastructure.
+
+Note that child tenancies have their own [resource limits](#resource-limits), which should be checked to confirm the Enterprise Scale Baseline Landing Zone can be deployed.
+
+## How to Deploy
+
+---
+The Enterprise Scale Baseline Landing Zone can be launched through Oracle Resource Manager or from the Terraform CLI.
+
+## Terraform CLI
+
+* Clone the OELZ Terraform templates from the [oelz_github](https://github.com/oracle-quickstart/oci-landing-zones/tree/master).
+* Go to Directory landing-zones/templates/freetrial-landing-zone.
+* Configure Variables on the file landing-zones/templates/freetrial-landing-zone/livelab.tfvars and save the file.
+ - Check Configuration Guide for Variables Deceralation.
+
+* Validate the changes . Issue the command "terraform validate".
+ ![terraform_validate](<./images/terraform_validate.png> "terraform_validate")
+* Initializes Terraform Configuration files via "terraform init".
+ ![terraform_init](<.images/terraform_init.png> "terraform_init")
+* Preview the changes that Terraform will to make to your infrastructure via "terraform plan -var-file=\"livelab.tfvars\"".
+ ![terraform_plan_1](<./images/terraform_plan_1.png> "terraform_plan_1")
+ ![terraform_plan_2](<./images/terraform_plan_2.png> "terraform_plan_2")
+* Executes the changes defined by your Terraform configuration to create or update resources via "terraform apply -var-file=\"livelab.tfvars\"" and wait for atleast 10 min to finish provisioning.
+ ![terraform_apply_1](<./images/terraform_apply_1.png> "terraform_apply_1")
+ ![terraform_apply_2](<./images/terraform_apply_2.png> "terraform_apply_2")
+ ![terraform_apply_3](<./images/terraform_apply_3.png> "terraform_apply_3")
+
+
+### For more information
+
+- [Deploy to OCI using Terraform tutorials](https://docs.oracle.com/en-us/iaas/developer-tutorials/tutorials/tf-provider/01-summary.htm).
+
+- [OCI provider documentation](https://registry.terraform.io/providers/oracle/oci/latest/docs).
+
+## Resource Manager
+
+To deploy using Resource Manager, the stack must be imported into the console in one of 2 ways:
+
+Use the `Deploy to Oracle Cloud` button which will take you directly to OCI Resource Manager if you are logged in. You can skip to step 11 if you use this.
+Or you can select the stack manually through the console starting from step 1.
+
+1. From the console home page, navigate to `Developer Services -> Resource Manager -> Stacks`
+2. Select the compartment you want to create the stack in and select `Create stack`.
+3. Select `Source code control system` for the Terraform source.
+4. In the `Stack Configuration` box, under `Source Code Management Type`, select `GitHub`.
+5. Under `Configuration source provider`, if you have a provider set up for public GitHub, you can select it, then skip to step 9. Otherwise select `Create configuration source provider`.
+6. If you do not already have a Personal Access Token for your GitHub account, log in to GitHub and create one. The option can be found under `Settings -> Developer settings -> Personal access tokens -> Tokens (classic)` on the [GitHub site](https://github.com). The token must have the `repo` scope.
+7. To create the configuration provider for GitHub in OCI, fill in the "Create configuration source provider" form as follows:
+ * Name: GitHub
+ * Description: (optional) Public Github Repositories
+ * Select the `Public Endpoint` option
+ * Type: GitHub
+ * Server URL: https://github.com/
+ * Personal Access Token: #Your Personal Access Token#
+8. Click `Create` to create the config provider
+9. For Repository select `oci-landing-zones`
+10. For Branch select `main`
+11. for Working directory, select `templates/enterprise-landing-zone`
+
+12. For Name, give the stack a name or accept the default.
+13. For the Create in Compartment dropdown, select the compartment to store the Stack.
+14. For Terraform Version dropdown, make sure to select 1.0.x at least. Lower Terraform versions are not supported.
+
+After completing the Stack Creation Wizard, the subsequent step prompts for variables values. **For reference on the configuration variable values read the [Configuration Guide](CONFIGURATION.md). For a full list of all available configuration variables see the [Input Variables Reference in the README](README.md#inputs)**
+
+After filling in the required input variables, click next to review the stack values and create the stack.
+
+In the Stack page use the appropriate buttons to plan/apply/destroy your stack.
+
+### For more information
+
+- [Resource Manager Overview](https://docs.oracle.com/en-us/iaas/Content/ResourceManager/Concepts/resourcemanager.htm)
+
+## Teardown and destroy of an Oracle Enterprise Landing Zone Infrastructure
+
+* Destroy the terraform configuration resources via "terraform destroy -var-file=\"livelab.tfvars\"".
+ ![terraform_destroy_1](<./images/terraform_destroy_1.png> "terraform_destroy_1")
+ ![terraform_destroy_2](<./images/terraform_destroy_2.png> "terraform_destroy_2")
+
+#### Cleanup Script
+A clean up script is provided to assist in cleaning up lingering resources that block terraform destroy.
+It can be found at `./destroy_lz.py`
+
+Once the script has been run, service connectors, buckets, and log analytics log groups will be deleted, identity domains deactivated, and vaults moved to the root compartment.
+Terraform destroy will need to be run after.
+
+1. To run the script ensure you have **python3** installed as well as an **oci api key**.
+ * install python [here](https://www.python.org/downloads/)
+ * set up api keys [here](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm)
+
+2. Verify the profile name(eg. DEFAULT) by checking the config file found at `~/.oci/config` (if the profile you want to use is not DEFAULT use the `--profile` flag to indicate).
+
+3. Install dependencies using the command:
+ ```
+ pip install oci tqdm
+ ```
+
+4. Run the command (from the templates/enterprise-landing-zone directory)
+ ```
+ python destroy_lz.py -r IAD -e P N -c OCI-ELZ-CMP-HOME
+ ```
+
+The `-r` flag indicates the 3 letter region key, the `-e` indicates the environment prefix, such as production and non-production, and the `-c` indicating the home compartment.
+
+For more information on flag usage for the script use the `--help` flag.
+```
+python destroy_lz.py --help
+```
+
+## Known Issues
+
+---
+These are some known temporary issues that can occur while deploying the Enterprise Scale Baseline Landing Zone.
+
+* 400-InvalidParameter Error in CreateServiceConnector operation: This can occasionally happen due to logs taking longer than normal to create while setting up the logging infrastructure. This will correct itself when the logs finish creating. Later Apply jobs in ORM or invocations of `terraform apply` should succeed.
+* 429-TooManyRequests Error: A tenancy making a large number of OCI API requests in rapid succession may be throttled by the API. The solution is to wait some period of time (a few minutes) and retry the terraform operation again. This is rarely seen on `apply` but may occasionally be seen on `destroy` runs, as the delete operations are much faster than create, and Terraform makes many API calls.
\ No newline at end of file
diff --git a/templates/freetrial-landing-zone/README.md b/templates/freetrial-landing-zone/README.md
new file mode 100644
index 00000000..7e242c79
--- /dev/null
+++ b/templates/freetrial-landing-zone/README.md
@@ -0,0 +1,181 @@
+# Enterprise Scale Baseline Landing Zone
+
+Version 2 of Enterprise Scale Baseline Landing Zone
+
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.0.0 |
+| [oci](#requirement\_oci) | 4.96.0 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [oci](#provider\_oci) | 4.96.0 |
+| [random](#provider\_random) | 3.4.3 |
+
+## Modules
+
+| Name | Source | Version |
+|------|--------|---------|
+| [architecture\_tag](#module\_architecture\_tag) | ../../modules/tag | n/a |
+| [archive\_bucket](#module\_archive\_bucket) | ../../modules/bucket | n/a |
+| [archive\_key](#module\_archive\_key) | ../../modules/key | n/a |
+| [authentication\_policy](#module\_authentication\_policy) | ../../modules/authentication-policy | n/a |
+| [break\_glass\_users](#module\_break\_glass\_users) | ../../modules/break_glass_user | n/a |
+| [cloud\_guard\_root\_policy](#module\_cloud\_guard\_root\_policy) | ../../modules/policies | n/a |
+| [cloud\_guard\_target\_policy](#module\_cloud\_guard\_target\_policy) | ../../modules/policies | n/a |
+| [home\_compartment](#module\_home\_compartment) | ../../modules/compartment | n/a |
+| [key\_archive\_policy](#module\_key\_archive\_policy) | ../../modules/policies | n/a |
+| [logging\_analytics\_namespace](#module\_logging\_analytics\_namespace) | ../../modules/log-analytics-namespace | n/a |
+| [osms\_dg\_policy](#module\_osms\_dg\_policy) | ../../modules/policies | n/a |
+| [osms\_dynamic\_group](#module\_osms\_dynamic\_group) | ../../modules/dynamic-group | n/a |
+| [osms\_policy](#module\_osms\_policy) | ../../modules/policies | n/a |
+| [prod\_archive\_audit\_log\_service\_connector](#module\_prod\_archive\_audit\_log\_service\_connector) | ../../modules/service-connector | n/a |
+| [prod\_archive\_default\_log\_service\_connector](#module\_prod\_archive\_default\_log\_service\_connector) | ../../modules/service-connector | n/a |
+| [prod\_archive\_service\_events\_service\_connector](#module\_prod\_archive\_service\_events\_service\_connector) | ../../modules/service-connector | n/a |
+| [prod\_environment](#module\_prod\_environment) | ../elz-environment | n/a |
+| [prod\_platform\_admin\_policy](#module\_prod\_platform\_admin\_policy) | ../../modules/policies | n/a |
+| [service\_connector\_archive\_policy](#module\_service\_connector\_archive\_policy) | ../../modules/policies | n/a |
+| [service\_connector\_policy](#module\_service\_connector\_policy) | ../../modules/policies | n/a |
+| [vault\_policy](#module\_vault\_policy) | ../../modules/policies | n/a |
+| [vss\_policy](#module\_vss\_policy) | ../../modules/policies | n/a |
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [random_id.tag](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource |
+| [oci_identity_region_subscriptions.regions](https://registry.terraform.io/providers/oracle/oci/4.96.0/docs/data-sources/identity_region_subscriptions) | data source |
+| [oci_objectstorage_namespace.ns](https://registry.terraform.io/providers/oracle/oci/4.96.0/docs/data-sources/objectstorage_namespace) | data source |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [api\_fingerprint](#input\_api\_fingerprint) | The fingerprint of API | `string` | `""` | no |
+| [api\_private\_key](#input\_api\_private\_key) | The API private key | `string` | `""` | no |
+| [api\_private\_key\_path](#input\_api\_private\_key\_path) | The local path to the API private key | `string` | `""` | no |
+| [archive\_log\_retention\_policy\_duration\_amount](#input\_archive\_log\_retention\_policy\_duration\_amount) | The timeAmount is interpreted in units defined by the timeUnit parameter, and is calculated in relation to each object's Last-Modified timestamp. | `string` | `"1"` | no |
+| [archive\_log\_retention\_policy\_duration\_time\_unit](#input\_archive\_log\_retention\_policy\_duration\_time\_unit) | The unit that should be used to interpret timeAmount. | `string` | `"DAYS"` | no |
+| [bgp\_md5auth\_key](#input\_bgp\_md5auth\_key) | The key for BGP MD5 authentication. Only applicable if your system requires MD5 authentication | `string` | `""` | no |
+| [break\_glass\_user\_email\_list](#input\_break\_glass\_user\_email\_list) | Unique list of break glass user email addresses that do not exist in the tenancy. These users are added to the Administrator group. | `list(string)` | `[]` | no |
+| [cloud\_guard\_target\_tenancy](#input\_cloud\_guard\_target\_tenancy) | true if cloud guard targets to tenancy, false if cloud guard targets to Landing Zone home compartment | `bool` | `false` | no |
+| [current\_user\_ocid](#input\_current\_user\_ocid) | The OCID of the current user | `string` | `""` | no |
+| [customer\_onprem\_ip\_cidr](#input\_customer\_onprem\_ip\_cidr) | n/a | `list(string)` | `[]` | no |
+| [customer\_primary\_bgp\_peering\_ip](#input\_customer\_primary\_bgp\_peering\_ip) | The primary BGP IPv4 address of the customer's router | `string` | `""` | no |
+| [customer\_secondary\_bgp\_peering\_ip](#input\_customer\_secondary\_bgp\_peering\_ip) | [Optional] The secondary BGP IPv4 address of the customer's router | `string` | `""` | no |
+| [domain\_license\_type](#input\_domain\_license\_type) | Identity Domain License Type. | `string` | `"premium"` | no |
+| [enable\_cloud\_guard](#input\_enable\_cloud\_guard) | true if you don't have cloud guard enabled, false if you've already have cloud guard enabled. | `bool` | `true` | no |
+| [enable\_compartment\_delete](#input\_enable\_compartment\_delete) | Set to true to allow the compartments to delete on terraform destroy. | `bool` | `true` | no |
+| [enable\_vpn\_or\_fastconnect](#input\_enable\_vpn\_or\_fastconnect) | Option to enable VPN or FASTCONNECT service. Options are NONE, VPN, FASTCONNECT. | `string` | `"NONE"` | no |
+| [fastconnect\_provider](#input\_fastconnect\_provider) | Fastconnect provider. Please choose from: AT&T, Azure, Megaport, QTS, CEintro, Cologix, CoreSite, Digitial Realty, EdgeConneX, Epsilon, Equinix, InterCloud, Lumen, Neutrona, OMCS, OracleL2ItegDeployment, OracleL3ItegDeployment, Orange, Verizon, Zayo | `string` | `""` | no |
+| [fastconnect\_routing\_policy](#input\_fastconnect\_routing\_policy) | Available FastConnect routing policies: ORACLE\_SERVICE\_NETWORK, REGIONAL, MARKET\_LEVEL, GLOBAL | `list(string)` | `[]` | no |
+| [home\_compartment\_name](#input\_home\_compartment\_name) | The name of the Landing Zone home compartment. | `string` | `"OCI-ELZ-CMP-HOME"` | no |
+| [igw\_hub\_check](#input\_igw\_hub\_check) | n/a | `list(string)` |
[ "" ]
| no |
+| [is\_create\_alarms](#input\_is\_create\_alarms) | Enable Alarms Creation in all Compartment | `bool` | `true` | no |
+| [nat\_gw\_hub\_check](#input\_nat\_gw\_hub\_check) | n/a | `list(string)` |
[ "" ]
| no |
+| [nat\_gw\_spoke\_check](#input\_nat\_gw\_spoke\_check) | n/a | `list(string)` |
[ "" ]
| no |
+| [nonprod\_application\_admin\_group\_name](#input\_nonprod\_application\_admin\_group\_name) | The group name for the OCI Application Administrators Group. Defaults to OCI-ELZ-UGP-N-APP-ADMIN if blank or not provided. | `string` | `""` | no |
+| [nonprod\_budget\_alert\_rule\_message](#input\_nonprod\_budget\_alert\_rule\_message) | The alert message for budget alerts. Required *if* nonprod\_enable\_budget is true. | `string` | `""` | no |
+| [nonprod\_budget\_alert\_rule\_recipients](#input\_nonprod\_budget\_alert\_rule\_recipients) | The delimited list of email addresses to receive the alert when it triggers. Delimiter characters can be a comma, space, TAB, or semicolon. Required *if* nonprod\_enable\_budget is true. | `string` | `""` | no |
+| [nonprod\_budget\_alert\_rule\_threshold](#input\_nonprod\_budget\_alert\_rule\_threshold) | The threshold for the budget alert. Required *if* nonprod\_enable\_budget is true. | `string` | `""` | no |
+| [nonprod\_budget\_amount](#input\_nonprod\_budget\_amount) | The amount of the budget expressed as a whole number in the currency of the customer's rate card. Required *if* nonprod\_enable\_budget is true. | `string` | `""` | no |
+| [nonprod\_database\_admin\_group\_name](#input\_nonprod\_database\_admin\_group\_name) | The group name for the OCI Database Logging Administrators Group. Defaults to OCI-ELZ-UGP-N-DB-ADMIN if blank or not provided. | `string` | `""` | no |
+| [nonprod\_domain\_admin\_email](#input\_nonprod\_domain\_admin\_email) | The email address for the non prod identity domain admin. | `string` | `""` | no |
+| [nonprod\_enable\_budget](#input\_nonprod\_enable\_budget) | Non-Production Enable Budget. | `bool` | `false` | no |
+| [nonprod\_iam\_admin\_group\_name](#input\_nonprod\_iam\_admin\_group\_name) | The group name for the OCI Landing Zone IAM Administrators Group. Defaults to OCI-ELZ-UGP-N-IDP-ADMIN if blank or not provided. | `string` | `""` | no |
+| [nonprod\_network\_admin\_group\_name](#input\_nonprod\_network\_admin\_group\_name) | The group name for the OCI Landing Zone Network Administrators Group. Defaults to OCI-ELZ-UGP-N-NET-ADMIN if blank or not provided. | `string` | `""` | no |
+| [nonprod\_ops\_admin\_group\_name](#input\_nonprod\_ops\_admin\_group\_name) | The group name for the OCI Landing Zone Ops Administrators Group. Defaults to OCI-ELZ-UGP-N-OPS-ADMIN if blank or not provided. | `string` | `""` | no |
+| [nonprod\_platform\_admin\_group\_name](#input\_nonprod\_platform\_admin\_group\_name) | The group name for the OCI Landing Zone Platform Administrators Group. Defaults to OCI-ELZ-UGP-N-PLT-ADMIN if blank or not provided. | `string` | `""` | no |
+| [nonprod\_retention\_policy\_duration\_amount](#input\_nonprod\_retention\_policy\_duration\_amount) | The timeAmount is interpreted in units defined by the timeUnit parameter, and is calculated in relation to each object's Last-Modified timestamp. | `string` | `"1"` | no |
+| [nonprod\_retention\_policy\_duration\_time\_unit](#input\_nonprod\_retention\_policy\_duration\_time\_unit) | The unit that should be used to interpret timeAmount. | `string` | `"DAYS"` | no |
+| [nonprod\_security\_admin\_group\_name](#input\_nonprod\_security\_admin\_group\_name) | The group name for the OCI Landing Zone Security Administrators Group. Defaults to OCI-ELZ-UGP-N-SEC-ADMIN if blank or not provided. | `string` | `""` | no |
+| [nonprod\_workload\_admin\_group\_name](#input\_nonprod\_workload\_admin\_group\_name) | The group name for the OCI Workload Administrators Group. Defaults to OCI-ELZ-UGP-N-WRK-ADMIN if blank or not provided. | `string` | `""` | no |
+| [onboard\_log\_analytics](#input\_onboard\_log\_analytics) | Set to true to onboard the tenancy to logging analytics. | `bool` | `true` | no |
+| [oracle\_primary\_bgp\_peering\_ip](#input\_oracle\_primary\_bgp\_peering\_ip) | The primary BGP IPv4 address for Oracle's end of the BGP session | `string` | `""` | no |
+| [oracle\_secondary\_bgp\_peering\_ip](#input\_oracle\_secondary\_bgp\_peering\_ip) | [Optional] Secondary IPv4 address for Oracle's end of the BGP session | `string` | `""` | no |
+| [prod\_additional\_workload\_subnets\_cidr\_blocks](#input\_prod\_additional\_workload\_subnets\_cidr\_blocks) | A list of subnets cidr blocks in additional workload stack in prod | `list(string)` | `[]` | no |
+| [prod\_application\_admin\_group\_name](#input\_prod\_application\_admin\_group\_name) | The group name for the OCI Application Administrators Group. Defaults to OCI-ELZ-UGP-P-APP-ADMIN if blank or not provided. | `string` | `""` | no |
+| [prod\_bastion\_client\_cidr\_block\_allow\_list](#input\_prod\_bastion\_client\_cidr\_block\_allow\_list) | A list of address ranges in CIDR notation that you want to allow to connect to sessions hosted by this bastion. | `list(string)` | n/a | yes |
+| [prod\_bgp\_cust\_tunnela\_ip](#input\_prod\_bgp\_cust\_tunnela\_ip) | The IP address for the CPE end of the inside tunnel interface. | `string` | `""` | no |
+| [prod\_bgp\_oci\_tunnela\_ip](#input\_prod\_bgp\_oci\_tunnela\_ip) | The IP address for the Oracle end of the inside tunnel interface. | `string` | `""` | no |
+| [prod\_budget\_alert\_rule\_message](#input\_prod\_budget\_alert\_rule\_message) | The alert message for budget alerts. Required *if* prod\_enable\_budget is true. | `string` | `""` | no |
+| [prod\_budget\_alert\_rule\_recipients](#input\_prod\_budget\_alert\_rule\_recipients) | The delimited list of email addresses to receive the alert when it triggers. Delimiter characters can be a comma, space, TAB, or semicolon. Required *if* prod\_enable\_budget is true. | `string` | `""` | no |
+| [prod\_budget\_alert\_rule\_threshold](#input\_prod\_budget\_alert\_rule\_threshold) | The threshold for the budget alert. Required *if* prod\_enable\_budget is true. | `string` | `""` | no |
+| [prod\_budget\_amount](#input\_prod\_budget\_amount) | The amount of the budget expressed as a whole number in the currency of the customer's rate card. Required *if* prod\_enable\_budget is true. | `string` | `""` | no |
+| [prod\_cost\_center\_tagging](#input\_prod\_cost\_center\_tagging) | Production Cost Center. | `string` | n/a | yes |
+| [prod\_cpe\_display\_name](#input\_prod\_cpe\_display\_name) | Customer Premises Equipment name. Recommendation: OCI-ELZ-CPE-[Environment]-HUB-[Region] 001 | `string` | `""` | no |
+| [prod\_cpe\_ip\_address](#input\_prod\_cpe\_ip\_address) | Customer Premises Equipment (CPE) IP address | `string` | `""` | no |
+| [prod\_cpe\_vendor](#input\_prod\_cpe\_vendor) | Type corresponding number as your CPE vendor: Yamaha-RTX1210 0, Other 1, Cisco-9.7.1-or-later 2, Yamaha-RTX830 3, Libreswan 4, Fortinet 5, NEC 6, Cisco-8.5+ 7, Cisco-IOS 8, WatchGuard 9, Juniper-MX 10, Juniper-SRX 11, Furukawa 12, Check\_Point 13, Palo\_Alto 14 | `number` | `0` | no |
+| [prod\_create\_master\_encryption\_key](#input\_prod\_create\_master\_encryption\_key) | Option create master encryption key | `bool` | `true` | no |
+| [prod\_customer\_bgp\_asn](#input\_prod\_customer\_bgp\_asn) | ASN is required and used for the tunnel's BGP session | `string` | `""` | no |
+| [prod\_database\_admin\_group\_name](#input\_prod\_database\_admin\_group\_name) | The group name for the OCI Database Logging Administrators Group. Defaults to OCI-ELZ-UGP-P-DB-ADMIN if blank or not provided. | `string` | `""` | no |
+| [prod\_domain\_admin\_email](#input\_prod\_domain\_admin\_email) | The email address for the prod identity domain admin. | `string` | n/a | yes |
+| [prod\_enable\_bastion](#input\_prod\_enable\_bastion) | Option to enable bastion service | `bool` | n/a | yes |
+| [prod\_enable\_budget](#input\_prod\_enable\_budget) | Production Enable Budget. | `bool` | `false` | no |
+| [prod\_enable\_fastconnect](#input\_prod\_enable\_fastconnect) | [Please don't change this value] Enable fastconnect in prod environment. | `bool` | `true` | no |
+| [prod\_enable\_internet\_gateway\_hub](#input\_prod\_enable\_internet\_gateway\_hub) | Option to enable TRUE and Disable false. | `string` | `"false"` | no |
+| [prod\_enable\_nat\_gateway\_hub](#input\_prod\_enable\_nat\_gateway\_hub) | Option to enable TRUE and Disable false. | `string` | `"false"` | no |
+| [prod\_enable\_nat\_gateway\_spoke](#input\_prod\_enable\_nat\_gateway\_spoke) | Option to enable TRUE and Disable false. | `string` | `"false"` | no |
+| [prod\_enable\_network\_monitoring\_alarms](#input\_prod\_enable\_network\_monitoring\_alarms) | Enable Network Monitoring Alarms in Production Network Compartment | `bool` | `false` | no |
+| [prod\_enable\_security\_monitoring\_alarms](#input\_prod\_enable\_security\_monitoring\_alarms) | Enable Security Monitoring Alarms in Production Security Compartment | `bool` | `false` | no |
+| [prod\_enable\_service\_gateway\_hub](#input\_prod\_enable\_service\_gateway\_hub) | Option to enable TRUE and Disable false. | `string` | `"false"` | no |
+| [prod\_enable\_service\_gateway\_spoke](#input\_prod\_enable\_service\_gateway\_spoke) | Option to enable TRUE and Disable false. | `string` | `"false"` | no |
+| [prod\_enable\_tagging](#input\_prod\_enable\_tagging) | Option to enable Tagging gateway in Production environment | `bool` | `false` | no |
+| [prod\_enable\_vault\_replication](#input\_prod\_enable\_vault\_replication) | Option to enable vault replication | `bool` | `false` | no |
+| [prod\_enable\_vpn](#input\_prod\_enable\_vpn) | Enable VPN in prod environment | `bool` | `false` | no |
+| [prod\_enable\_workload\_monitoring\_alarms](#input\_prod\_enable\_workload\_monitoring\_alarms) | Enable Workload Monitoring Alarms in Production Workload Compartment | `bool` | `false` | no |
+| [prod\_geo\_location\_tagging](#input\_prod\_geo\_location\_tagging) | Production Geo Center. | `string` | n/a | yes |
+| [prod\_hub\_private\_subnet\_cidr\_block](#input\_prod\_hub\_private\_subnet\_cidr\_block) | Production Enivornment HUB Private Subnet CIDR Block. | `string` | n/a | yes |
+| [prod\_hub\_public\_subnet\_cidr\_block](#input\_prod\_hub\_public\_subnet\_cidr\_block) | Production Enivornment HUB Public Subnet CIDR Block. | `string` | n/a | yes |
+| [prod\_hub\_vcn\_cidr\_block](#input\_prod\_hub\_vcn\_cidr\_block) | Production Enivornment HUB VCN CIDR Block. | `string` | n/a | yes |
+| [prod\_iam\_admin\_group\_name](#input\_prod\_iam\_admin\_group\_name) | The group name for the OCI Landing Zone IAM Administrators Group. Defaults to OCI-ELZ-UGP-P-IDP-ADMIN if blank or not provided. | `string` | `""` | no |
+| [prod\_identity\_topic\_endpoints](#input\_prod\_identity\_topic\_endpoints) | List of email addresses for Identity notifications. | `list(string)` | `[]` | no |
+| [prod\_ipsec\_connection\_static\_routes](#input\_prod\_ipsec\_connection\_static\_routes) | n/a | `list(string)` |
[ "" ]
| no |
+| [prod\_ipsec\_display\_name](#input\_prod\_ipsec\_display\_name) | IPsec display name. Recommendation: OCI-ELZ-IPS-[Environment]-HUB-[Region] 001 | `string` | `""` | no |
+| [prod\_ipsec\_routing\_type](#input\_prod\_ipsec\_routing\_type) | BGP dynamic routing, STATIC routing. Type BGP or STATIC | `string` | `"STATIC"` | no |
+| [prod\_network\_admin\_group\_name](#input\_prod\_network\_admin\_group\_name) | The group name for the OCI Landing Zone Network Administrators Group. Defaults to OCI-ELZ-UGP-P-NET-ADMIN if blank or not provided. | `string` | `""` | no |
+| [prod\_network\_topic\_endpoints](#input\_prod\_network\_topic\_endpoints) | List of email addresses for Network Warning and Critical notifications. | `list(string)` | `[]` | no |
+| [prod\_ops\_admin\_group\_name](#input\_prod\_ops\_admin\_group\_name) | The group name for the OCI Landing Zone Ops Administrators Group. Defaults to OCI-ELZ-UGP-P-OPS-ADMIN if blank or not provided. | `string` | `""` | no |
+| [prod\_platform\_admin\_group\_name](#input\_prod\_platform\_admin\_group\_name) | The group name for the OCI Landing Zone Platform Administrators Group. Defaults to OCI-ELZ-UGP-P-PLT-ADMIN if blank or not provided. | `string` | `""` | no |
+| [prod\_platform\_topic\_endpoints](#input\_prod\_platform\_topic\_endpoints) | List of email addresses for Platform notifications. | `list(string)` | `[]` | no |
+| [prod\_retention\_policy\_duration\_amount](#input\_prod\_retention\_policy\_duration\_amount) | The timeAmount is interpreted in units defined by the timeUnit parameter, and is calculated in relation to each object's Last-Modified timestamp. | `string` | `"1"` | no |
+| [prod\_retention\_policy\_duration\_time\_unit](#input\_prod\_retention\_policy\_duration\_time\_unit) | The unit that should be used to interpret timeAmount. | `string` | `"DAYS"` | no |
+| [prod\_secops\_topic\_endpoints](#input\_prod\_secops\_topic\_endpoints) | List of email addresses for Secops Warning and Critical notifications. | `list(string)` | `[]` | no |
+| [prod\_security\_admin\_group\_name](#input\_prod\_security\_admin\_group\_name) | The group name for the OCI Landing Zone Security Administrators Group. Defaults to OCI-ELZ-UGP-P-SEC-ADMIN if blank or not provided. | `string` | `""` | no |
+| [prod\_shared\_secret](#input\_prod\_shared\_secret) | The shared secret (pre-shared key) to use for the IPSec tunnel | `string` | `"example"` | no |
+| [prod\_spoke\_subnet\_app\_cidr\_block](#input\_prod\_spoke\_subnet\_app\_cidr\_block) | Production Enivornment Spoke App Subnet CIDR Block. | `string` | n/a | yes |
+| [prod\_spoke\_subnet\_db\_cidr\_block](#input\_prod\_spoke\_subnet\_db\_cidr\_block) | Production Enivornment Spoke DB Subnet CIDR Block. | `string` | n/a | yes |
+| [prod\_spoke\_subnet\_web\_cidr\_block](#input\_prod\_spoke\_subnet\_web\_cidr\_block) | Production Enivornment Spoke Web Subnet CIDR Block. | `string` | n/a | yes |
+| [prod\_spoke\_vcn\_cidr](#input\_prod\_spoke\_vcn\_cidr) | Production Enivornment Spoke VCN CIDR Block. | `string` | n/a | yes |
+| [prod\_tunnel\_a\_display\_name](#input\_prod\_tunnel\_a\_display\_name) | Tunnel A display name. Recommendation: | `string` | `""` | no |
+| [prod\_tunnel\_b\_display\_name](#input\_prod\_tunnel\_b\_display\_name) | Tunnel B display name. Recommendation: | `string` | `""` | no |
+| [prod\_vault\_replica\_region](#input\_prod\_vault\_replica\_region) | the region to be created replica to. Required *if* prod\_enable\_vault\_replication is true. | `string` | `""` | no |
+| [prod\_vault\_type](#input\_prod\_vault\_type) | The type of vault to create. | `string` | `"DEFAULT"` | no |
+| [prod\_workload\_admin\_group\_name](#input\_prod\_workload\_admin\_group\_name) | The group name for the OCI Workload Administrators Group. Defaults to OCI-ELZ-UGP-P-WRK-ADMIN if blank or not provided. | `string` | `""` | no |
+| [prod\_workload\_topic\_endpoints](#input\_prod\_workload\_topic\_endpoints) | List of email addresses for Prod Workload notifications. | `list(string)` | `[]` | no |
+| [provider\_service\_key\_name](#input\_provider\_service\_key\_name) | The provider service key that the provider gives you when you set up a virtual circuit connection from the provider to OCI | `string` | `""` | no |
+| [region](#input\_region) | The OCI region | `string` | n/a | yes |
+| [resource\_label](#input\_resource\_label) | A prefix used to avoid naming conflicts if multiple Landing Zones are deployed. | `string` | `""` | no |
+| [service\_gw\_hub\_check](#input\_service\_gw\_hub\_check) | n/a | `list(string)` |
[ "" ]
| no |
+| [service\_gw\_spoke\_check](#input\_service\_gw\_spoke\_check) | n/a | `list(string)` |
[ "" ]
| no |
+| [tenancy\_ocid](#input\_tenancy\_ocid) | The OCID of tenancy | `string` | n/a | yes |
+| [virtual\_circuit\_bandwidth\_shape](#input\_virtual\_circuit\_bandwidth\_shape) | The provisioned data rate of the connection | `string` | `"1500"` | no |
+| [virtual\_circuit\_customer\_asn](#input\_virtual\_circuit\_customer\_asn) | The BGP ASN of the network at the other end of the BGP session from Oracle | `string` | `0` | no |
+| [virtual\_circuit\_display\_name](#input\_virtual\_circuit\_display\_name) | The display name of this virtual circuit. Recommendation: OCI-ELZ-FCN-P-HUB-[REGION] 001 | `string` | `""` | no |
+| [virtual\_circuit\_is\_bfd\_enabled](#input\_virtual\_circuit\_is\_bfd\_enabled) | Set to true to enable BFD for IPv4 BGP peering, or set to false to disable BFD | `bool` | `false` | no |
+| [virtual\_circuit\_type](#input\_virtual\_circuit\_type) | The type of IP addresses used in this virtual circuit. PRIVATE or PUBLIC | `string` | `""` | no |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [dynamic\_group\_detail](#output\_dynamic\_group\_detail) | n/a |
+| [subnets](#output\_subnets) | The subnet OCID |
+| [vcn](#output\_vcn) | n/a |
+| [workload\_compartment\_id](#output\_workload\_compartment\_id) | n/a |
+
\ No newline at end of file
diff --git a/templates/freetrial-landing-zone/backend.tf b/templates/freetrial-landing-zone/backend.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/templates/freetrial-landing-zone/datasources.tf b/templates/freetrial-landing-zone/datasources.tf
new file mode 100644
index 00000000..3131c438
--- /dev/null
+++ b/templates/freetrial-landing-zone/datasources.tf
@@ -0,0 +1,18 @@
+# -----------------------------------------------------------------------------
+# Support for multi-region deployments
+# -----------------------------------------------------------------------------
+
+locals {
+ region_subscriptions = data.oci_identity_region_subscriptions.regions.region_subscriptions
+ home_region = [for region in local.region_subscriptions : region.region_name if region.is_home_region == true]
+ region_key = [for region in local.region_subscriptions : region.region_key if region.region_name == var.region]
+}
+
+data "oci_identity_region_subscriptions" "regions" {
+ tenancy_id = var.tenancy_ocid
+}
+
+data "oci_objectstorage_namespace" "ns" {
+ compartment_id = var.tenancy_ocid
+}
+
diff --git a/templates/freetrial-landing-zone/destroy_lz.py b/templates/freetrial-landing-zone/destroy_lz.py
new file mode 100644
index 00000000..727dc2b7
--- /dev/null
+++ b/templates/freetrial-landing-zone/destroy_lz.py
@@ -0,0 +1,391 @@
+import argparse
+from concurrent.futures import ThreadPoolExecutor
+from datetime import datetime
+from typing import Dict, List
+
+import oci
+from tqdm import tqdm
+
+
+class DestroyLandingZone:
+ def __init__(self, parent_cmp: str, region_key: str, resource_label: str, oci_config: str = "~/.oci/config", profile_name: str = "DEFAULT"):
+
+ self.config = oci.config.from_file(
+ file_location=oci_config,
+ profile_name=profile_name
+ )
+
+ self.identity_client = oci.identity.IdentityClient(self.config)
+ self.os_client = oci.object_storage.ObjectStorageClient(self.config)
+ self.log_analytics_client = oci.log_analytics.LogAnalyticsClient(
+ self.config)
+ self.identity_client = oci.identity.IdentityClient(self.config)
+ self.key_management_client = oci.key_management.KmsVaultClient(
+ self.config)
+ self.sch_client = oci.sch.ServiceConnectorClient(self.config)
+
+ self.tenancy_id = self.config["tenancy"]
+ self.os_namespace = self.get_os_namespace()
+
+ self.parent_cmp = parent_cmp
+ self.region_key = region_key
+ self.resource_label = resource_label
+
+ def get_os_namespace(self) -> str:
+ os_namespace = self.os_client.get_namespace()
+ return os_namespace.data
+
+ def get_elz_cmps(self, env_prefix: str) -> Dict[str, str]:
+ parent_cmps_response = self.identity_client.list_compartments(
+ compartment_id=self.tenancy_id,
+ name=self.parent_cmp
+ )
+ parent_cmp_id = parent_cmps_response.data[0].id
+
+ env_cmp_name = f"OCI-ELZ-{env_prefix}-CMP"
+ env_cmps_response = self.identity_client.list_compartments(
+ compartment_id=parent_cmp_id,
+ name=env_cmp_name
+ )
+ env_cmp_id = env_cmps_response.data[0].id
+
+ log_cmp_name = f"OCI-ELZ-{env_prefix}-LOG-{self.region_key}"
+ log_cmps_response = self.identity_client.list_compartments(
+ compartment_id=env_cmp_id,
+ name=log_cmp_name
+ )
+ log_cmp_id = log_cmps_response.data[0].id
+
+ shared_cmp_name = f"OCI-ELZ-{env_prefix}-SRD-CMP-{self.region_key}"
+ shared_cmps_response = self.identity_client.list_compartments(
+ compartment_id=env_cmp_id,
+ name=shared_cmp_name
+ )
+ shared_cmp_id = shared_cmps_response.data[0].id
+
+ security_cmp_name = f"OCI-ELZ-{env_prefix}-SRD-SEC"
+ security_cmps_response = self.identity_client.list_compartments(
+ compartment_id=shared_cmp_id,
+ name=security_cmp_name
+ )
+ security_cmp_id = security_cmps_response.data[0].id
+
+ cmp_map = {
+ "parent": parent_cmp_id,
+ "env": env_cmp_id,
+ "log": log_cmp_id,
+ "shared": shared_cmp_id,
+ "security": security_cmp_id
+ }
+
+ return cmp_map
+
+ def get_scca_cmps(self) -> Dict[str, str]:
+ parent_cmps_response = self.identity_client.list_compartments(
+ compartment_id=self.tenancy_id,
+ name=self.parent_cmp
+ )
+ parent_cmp_id = parent_cmps_response.data[0].id
+
+ vdms_cmp_name = f"OCI-SCCA-LZ-VDMS-{self.region_key}-{self.resource_label}"
+ vdms_cmps_response = self.identity_client.list_compartments(
+ compartment_id=parent_cmp_id,
+ name=vdms_cmp_name
+ )
+ vdms_cmp_id = vdms_cmps_response.data[0].id
+
+ vdss_cmp_name = f"OCI-SCCA-LZ-VDSS-{self.region_key}-{self.resource_label}"
+ vdss_cmps_response = self.identity_client.list_compartments(
+ compartment_id=parent_cmp_id,
+ name=vdss_cmp_name
+ )
+ vdss_cmp_id = vdss_cmps_response.data[0].id
+
+ log_cmp_name = f"OCI-SCCA-LZ-Logging-{self.region_key}-{self.resource_label}"
+ log_cmps_response = self.identity_client.list_compartments(
+ compartment_id=parent_cmp_id,
+ name=log_cmp_name
+ )
+ log_cmp_id = log_cmps_response.data[0].id
+
+ iac_cmp_name = f"OCI-SCCA-LZ-IAC-TF-Configbackup-{self.resource_label}"
+ iac_cmps_response = self.identity_client.list_compartments(
+ compartment_id=parent_cmp_id,
+ name=iac_cmp_name
+ )
+ iac_cmp_id = iac_cmps_response.data[0].id
+
+ cmp_map = {
+ "parent": parent_cmp_id,
+ "vdms": vdms_cmp_id,
+ "vdss": vdss_cmp_id,
+ "log": log_cmp_id,
+ "iac": iac_cmp_id
+ }
+
+ return cmp_map
+
+ def get_sch_ids(self, cmp_id: str) -> List[str]:
+ list_service_connectors_response = self.sch_client.list_service_connectors(
+ compartment_id=cmp_id
+ )
+ sch_ids = [d.id for d in list_service_connectors_response.data.items]
+ return sch_ids
+
+ def delete_sch(self, sch_id: str):
+ delete_service_connector_response = self.sch_client.delete_service_connector(
+ service_connector_id=sch_id
+ )
+
+ def get_bucket_names(self, cmp_id: str) -> List[str]:
+ buckets_response = self.os_client.list_buckets(
+ compartment_id=cmp_id,
+ namespace_name=self.os_namespace
+ )
+
+ bucket_names = [d.name for d in buckets_response.data]
+ return bucket_names
+
+ def delete_retention_rules(self, bucket_name: str):
+ retention_rule_response = self.os_client.list_retention_rules(
+ namespace_name=self.os_namespace,
+ bucket_name=bucket_name
+ )
+ retention_rules = retention_rule_response.data.items
+
+ for rule in retention_rules:
+ retention_rule_response = self.os_client.delete_retention_rule(
+ namespace_name=self.os_namespace,
+ bucket_name=bucket_name,
+ retention_rule_id=rule.id
+ )
+
+ def delete_bucket_contents(self, bucket_name: str):
+ bucket_files = []
+ next_start_with = ""
+ while next_start_with != None:
+ list_files = self.os_client.list_objects(
+ self.os_namespace,
+ bucket_name,
+ start=next_start_with
+ )
+
+ next_start_with = list_files.data.next_start_with
+ if not list_files.data.objects:
+ break
+ bucket_files += list_files.data.objects
+
+ for filenames in tqdm(bucket_files, desc=f'bucket {bucket_name}'):
+ self.os_client.delete_object(
+ self.os_namespace,
+ bucket_name,
+ filenames.name
+ )
+
+ def delete_bucket(self, bucket_name: str):
+ delete_bucket_response = self.os_client.delete_bucket(
+ namespace_name=self.os_namespace,
+ bucket_name=bucket_name
+ )
+
+ def delete_bucket_all(self, bucket_name: str):
+ self.delete_retention_rules(bucket_name)
+ self.delete_bucket_contents(bucket_name)
+ self.delete_bucket(bucket_name)
+
+ def purge_log_analytics(self, cmp_id: str):
+ purge_storage_data_response = self.log_analytics_client.purge_storage_data(
+ namespace_name=self.os_namespace,
+ purge_storage_data_details=oci.log_analytics.models.PurgeStorageDataDetails(
+ compartment_id=cmp_id,
+ time_data_ended=datetime.now().strftime("%Y-%m-%d") + "T23:59",
+ purge_query_string="*",
+ compartment_id_in_subtree=True
+ ),
+ )
+
+ wait_for_resource_id = purge_storage_data_response.headers['opc-work-request-id']
+ waiter_result = oci.wait_until(
+ self.log_analytics_client,
+ self.log_analytics_client.get_storage_work_request(
+ wait_for_resource_id, self.os_namespace),
+ "status",
+ "SUCCEEDED"
+ )
+
+ def delete_log_analytics_group(self, cmp_id: str):
+ list_log_analytics_log_groups_response = self.log_analytics_client.list_log_analytics_log_groups(
+ namespace_name=self.os_namespace,
+ compartment_id=cmp_id
+ )
+ log_groups = list_log_analytics_log_groups_response.data.items
+
+ for group in log_groups:
+ delete_log_analytics_log_group_response = self.log_analytics_client.delete_log_analytics_log_group(
+ namespace_name=self.os_namespace,
+ log_analytics_log_group_id=group.id
+ )
+ print(delete_log_analytics_log_group_response.data)
+
+ def move_vaults(self, cmp_id: str):
+ list_vaults_response = self.key_management_client.list_vaults(
+ compartment_id=cmp_id
+ )
+ vaults = list_vaults_response.data
+
+ for vault in vaults:
+ if vault.lifecycle_state != "CREATED":
+ print(
+ f"ignoring vault {vault.display_name} not in created state")
+ continue
+
+ change_vault_compartment_response = self.key_management_client.change_vault_compartment(
+ vault_id=vault.id,
+ change_vault_compartment_details=oci.key_management.models.ChangeVaultCompartmentDetails(
+ compartment_id=self.tenancy_id
+ )
+ )
+
+ def deactivate_domains(self, cmp_id: str):
+ list_domains_response = self.identity_client.list_domains(
+ compartment_id=cmp_id
+ )
+ domains = list_domains_response.data
+
+ for domain in domains:
+ deactivate_domain_response = self.identity_client.deactivate_domain(
+ domain_id=domain.id
+ )
+
+ def delete_environment(self, env_prefix: str):
+ print(f"beginning env {env_prefix} destroy")
+
+ print("fetching compartment ids")
+ compartments = self.get_elz_cmps(env_prefix)
+
+ print("deactivating domains")
+ self.deactivate_domains(compartments["security"])
+
+ # vault only needs to be moved out of the landing zone compartments
+ # - once you run destroy, terraform will destroy it where it is
+ # also note vault can only be moved in an ACTIVE state
+ print("beginning vault move")
+ self.move_vaults(compartments["security"])
+
+ # delete sc hubs to stop logs flowing into buckets and log groups
+ print("beginning service connector destroy")
+ sch_ids = self.get_sch_ids(compartments["security"])
+ for sch in sch_ids:
+ self.delete_sch(sch)
+
+ print("beginning bucket destroy")
+ bucket_cmps = [compartments["parent"], compartments["log"]]
+ bucket_names = []
+ for cmp in bucket_cmps:
+ bucket_names += self.get_bucket_names(cmp)
+
+ with ThreadPoolExecutor(max_workers=3) as p:
+ p.map(self.delete_bucket_all, bucket_names)
+
+ print("beginning log analytics destroy")
+ self.purge_log_analytics(compartments["security"])
+ self.delete_log_analytics_group(compartments["security"])
+
+ print("finished destroying ___\n\n")
+
+ def destroy_scca(self):
+ print("beginning elz destroy")
+
+ print("fetching compartment ids")
+ compartments = self.get_scca_cmps()
+
+ print("deactivating domains")
+ self.deactivate_domains(compartments["vdms"])
+
+ print("beginning vault move")
+ self.move_vaults(compartments["vdms"])
+
+ print("beginning service connector destroy")
+ sch_ids = self.get_sch_ids(compartments["vdms"])
+ for sch in sch_ids:
+ self.delete_sch(sch)
+
+ print("beginning bucket destroy")
+ bucket_cmps = [compartments["iac"], compartments["log"]]
+ bucket_names = []
+ for cmp in bucket_cmps:
+ bucket_names += self.get_bucket_names(cmp)
+
+ with ThreadPoolExecutor(max_workers=3) as p:
+ p.map(self.delete_bucket_all, bucket_names)
+
+ print("beginning log analytics destroy")
+ self.purge_log_analytics(compartments["vdms"])
+ self.delete_log_analytics_group(compartments["vdms"])
+
+
+if __name__ == "__main__":
+ '''
+ The script cleans up lingering resources that block terraform destroy. Once the
+ script has been run, service connectors, buckets, and log analytics log groups
+ will be deleted, identity domains deactivated, and vaults moved to the root
+ compartment. Terraform destroy will need to be run after.
+
+ To run the script ensure you have python3 installed as well as an oci api key.
+ Verify the profile name(eg. DEFAULT) by checking the config file found at ~/.oci/config.
+ Install dependencies using the command:
+ pip install oci tqdm.
+ Run the command (from the templates/enterprise-landing-zone directory)
+ for ELZ:
+ python destroy_lz.py -r IAD -e P N -c OCI-ELZ-CMP-HOME
+ for SCCA:
+ python destroy_lz.py -r IAD -l ARJ2 -c OCI-SCCA-LZ-Home-IAD-ARJ2
+ '''
+
+ parser = argparse.ArgumentParser(
+ description="Destroy Landing Zone Lingering Resources")
+
+ parser.add_argument("-c", "--cmp",
+ default="OCI-ELZ-CMP-HOME",
+ help="Name of the parent cmp")
+
+ parser.add_argument("-r", "--region_key",
+ help="Region Key used in compartment naming eg. IAD, PHX")
+
+ parser.add_argument("-e", "--elz_envs", nargs="+",
+ default=["P", "N"],
+ help="Delete ELZ Landing Zone Environments by prefix eg. P, N")
+
+ parser.add_argument("-l", "--scca_label",
+ help="Delete SCCA Landing Zone with specified resource label")
+
+ parser.add_argument("--delete_buckets", nargs="+",
+ help="Delete buckets by bucket name")
+
+ parser.add_argument("--profile",
+ default="DEFAULT",
+ help="OCI profile you want to use in the specified region")
+
+ parser.add_argument("--oci_config",
+ default="~/.oci/config",
+ help="Path to the OCI Configuration file")
+
+ args = parser.parse_args()
+ destroy_lz = DestroyLandingZone(
+ parent_cmp=args.cmp,
+ region_key=args.region_key,
+ resource_label=args.scca_label,
+ oci_config=args.oci_config,
+ profile_name=args.profile
+ )
+
+ if args.delete_buckets:
+ for bucket in args.delete_buckets:
+ destroy_lz.delete_bucket_all(bucket)
+ elif args.scca_label:
+ destroy_lz.destroy_scca()
+ elif args.elz_envs:
+ for env in args.elz_envs:
+ destroy_lz.delete_environment(env)
+ else:
+ print("Select only one of the following flags: delete_buckets, scca_label, or elz_envs.")
diff --git a/templates/freetrial-landing-zone/environment.tf b/templates/freetrial-landing-zone/environment.tf
new file mode 100644
index 00000000..eb460e08
--- /dev/null
+++ b/templates/freetrial-landing-zone/environment.tf
@@ -0,0 +1,135 @@
+# -----------------------------------------------------------------------------
+# Prod Enviroment Resources
+# -----------------------------------------------------------------------------
+locals {
+ prod_environment = {
+ environment_prefix = "L"
+ enable_tf_state_backup = false
+ enable_logging = true
+ }
+}
+
+module "prod_environment" {
+ source = "../elz-environment"
+
+ tenancy_ocid = var.tenancy_ocid
+ region = var.region
+ resource_label = var.resource_label
+
+ home_compartment_id = module.home_compartment.compartment_id
+ environment_prefix = local.prod_environment.environment_prefix
+ enable_tf_state_backup = local.prod_environment.enable_tf_state_backup
+ enable_logging = local.prod_environment.enable_logging
+ domain_admin_email = var.prod_domain_admin_email
+ network_admin_group_name = var.prod_network_admin_group_name
+ iam_admin_group_name = var.prod_iam_admin_group_name
+ platform_admin_group_name = var.prod_platform_admin_group_name
+ ops_admin_group_name = var.prod_ops_admin_group_name
+ security_admin_group_name = var.prod_security_admin_group_name
+
+ workload_admin_group_name = var.prod_workload_admin_group_name
+ application_admin_group_name = var.prod_application_admin_group_name
+ database_admin_group_name = var.prod_database_admin_group_name
+
+ enable_budget = var.prod_enable_budget
+ budget_amount = var.prod_budget_amount
+ budget_alert_rule_threshold = var.prod_budget_alert_rule_threshold
+ budget_alert_rule_message = var.prod_budget_alert_rule_message
+ budget_alert_rule_recipients = var.prod_budget_alert_rule_recipients
+ enable_cloud_guard = var.enable_cloud_guard
+ is_create_alarms = var.is_create_alarms
+ domain_license_type = var.domain_license_type
+
+ cloud_guard_target_tenancy = var.cloud_guard_target_tenancy
+ home_compartment_name = var.home_compartment_name
+ enable_vpn_or_fastconnect = var.enable_vpn_or_fastconnect
+ cpe_ip_address = var.prod_cpe_ip_address
+ ipsec_connection_static_routes = var.prod_ipsec_connection_static_routes
+ enable_vpn_on_environment = var.prod_enable_vpn
+ cpe_display_name = var.prod_cpe_display_name
+ ipsec_display_name = var.prod_ipsec_display_name
+ cpe_vendor = var.prod_cpe_vendor
+ routing = var.prod_ipsec_routing_type
+ tunnel_a_display_name = var.prod_tunnel_a_display_name
+ customer_bgp_asn = var.prod_customer_bgp_asn
+ bgp_cust_tunnela_ip = var.prod_bgp_cust_tunnela_ip
+ bgp_oci_tunnela_ip = var.prod_bgp_oci_tunnela_ip
+ shared_secret = var.prod_shared_secret
+ tunnel_b_display_name = var.prod_tunnel_b_display_name
+ fastconnect_provider = var.fastconnect_provider
+ region_key = local.region_key[0]
+ virtual_circuit_bandwidth_shape = format("%s %s", var.virtual_circuit_bandwidth_shape, "Gbps")
+ virtual_circuit_display_name = var.virtual_circuit_display_name
+ provider_service_key_name = var.provider_service_key_name
+ fastconnect_routing_policy = var.fastconnect_routing_policy
+ virtual_circuit_type = var.virtual_circuit_type
+ customer_primary_bgp_peering_ip = var.customer_primary_bgp_peering_ip
+ oracle_primary_bgp_peering_ip = var.oracle_primary_bgp_peering_ip
+ customer_secondary_bgp_peering_ip = var.customer_secondary_bgp_peering_ip
+ oracle_secondary_bgp_peering_ip = var.oracle_secondary_bgp_peering_ip
+ virtual_circuit_customer_asn = var.virtual_circuit_customer_asn
+ virtual_circuit_is_bfd_enabled = var.virtual_circuit_is_bfd_enabled
+ bgp_md5auth_key = var.bgp_md5auth_key
+ enable_fastconnect_on_environment = var.prod_enable_fastconnect
+ customer_onprem_ip_cidr = var.customer_onprem_ip_cidr
+
+ enable_internet_gateway_hub = var.prod_enable_internet_gateway_hub
+ enable_nat_gateway_hub = var.prod_enable_nat_gateway_hub
+ enable_service_gateway_hub = var.prod_enable_service_gateway_hub
+ enable_nat_gateway_spoke = var.prod_enable_nat_gateway_spoke
+ enable_service_gateway_spoke = var.prod_enable_service_gateway_spoke
+
+ igw_hub_check = var.igw_hub_check
+ nat_gw_hub_check = var.nat_gw_hub_check
+ service_gw_hub_check = var.service_gw_hub_check
+ nat_gw_spoke_check = var.nat_gw_spoke_check
+ service_gw_spoke_check = var.service_gw_spoke_check
+
+ vcn_cidr_block = var.prod_hub_vcn_cidr_block
+ public_subnet_cidr_block = var.prod_hub_public_subnet_cidr_block
+ private_subnet_cidr_block = var.prod_hub_private_subnet_cidr_block
+
+ spoke_vcn_cidr = var.prod_spoke_vcn_cidr
+ private_spoke_subnet_web_cidr_block = var.prod_spoke_subnet_web_cidr_block
+ private_spoke_subnet_app_cidr_block = var.prod_spoke_subnet_app_cidr_block
+ private_spoke_subnet_db_cidr_block = var.prod_spoke_subnet_db_cidr_block
+
+ enable_bastion = var.prod_enable_bastion
+ bastion_client_cidr_block_allow_list = var.prod_bastion_client_cidr_block_allow_list
+ vault_type = var.prod_vault_type
+ vault_replica_region = var.prod_vault_replica_region
+ enable_vault_replication = var.prod_enable_vault_replication
+ create_master_encryption_key = var.prod_create_master_encryption_key
+
+ retention_policy_duration_amount = var.prod_retention_policy_duration_amount
+ retention_policy_duration_time_unit = var.prod_retention_policy_duration_time_unit
+
+ enable_tagging = var.prod_enable_tagging
+ cost_center_tagging = var.prod_cost_center_tagging
+ geo_location_tagging = var.prod_geo_location_tagging
+
+ network_topic_endpoints = var.prod_network_topic_endpoints
+ secops_topic_endpoints = var.prod_secops_topic_endpoints
+ platform_topic_endpoints = var.prod_platform_topic_endpoints
+ identity_topic_endpoints = var.prod_identity_topic_endpoints
+
+ workload_topic_endpoints = var.prod_workload_topic_endpoints
+ enable_security_monitoring_alarms = var.prod_enable_security_monitoring_alarms
+ enable_network_monitoring_alarms = var.prod_enable_network_monitoring_alarms
+ enable_workload_monitoring_alarms = var.prod_enable_workload_monitoring_alarms
+
+ additional_workload_subnets_cidr_blocks = var.prod_additional_workload_subnets_cidr_blocks
+
+ providers = {
+ oci = oci
+ oci.home_region = oci.home_region
+ }
+
+ depends_on = [
+ module.cloud_guard_root_policy,
+ module.cloud_guard_target_policy,
+ module.vss_policy,
+ module.home_compartment
+ ]
+}
+
diff --git a/templates/freetrial-landing-zone/example.tfvars b/templates/freetrial-landing-zone/example.tfvars
new file mode 100644
index 00000000..af8a6599
--- /dev/null
+++ b/templates/freetrial-landing-zone/example.tfvars
@@ -0,0 +1,97 @@
+# Provider
+current_user_ocid = "## YOUR USER OCID ##"
+region = "## OCI REGION TO DEPLOY TO"
+tenancy_ocid = "## YOUR TENANCY OCID ##"
+api_fingerprint = "## YOUR OCI API KEY FINGERPRINT ##"
+api_private_key_path = "## YOUR OCI API PRIVATE KEY FILE ##"
+
+# iam
+resource_label = "DEMO"
+prod_domain_admin_email = "an-example-email-address@oracle.com"
+nonprod_domain_admin_email = "an-example-email-address@oracle.com"
+enable_compartment_delete = false
+
+# security
+enable_cloud_guard = true
+cloud_guard_target_tenancy = false
+nonprod_enable_bastion = true
+prod_enable_bastion = true
+prod_bastion_client_cidr_block_allow_list = ["10.0.0.0/16", "10.0.0.0/24"]
+nonprod_bastion_client_cidr_block_allow_list = ["10.0.0.0/16", "10.0.0.0/24"]
+
+# budget
+nonprod_enable_budget = true
+prod_enable_budget = true
+nonprod_budget_alert_rule_message = "test"
+nonprod_budget_alert_rule_recipients = "an-example-email-address@oracle.com"
+nonprod_budget_alert_rule_threshold = 1000000
+nonprod_budget_amount = 10000000
+prod_budget_alert_rule_message = "test"
+prod_budget_alert_rule_recipients = "an-example-email-address@oracle.com"
+prod_budget_alert_rule_threshold = 1000000
+prod_budget_amount = 10000000
+
+# network extension
+enable_vpn_or_fastconnect = "NONE"
+prod_enable_vpn = true
+prod_cpe_ip_address = "10.0.0.0"
+prod_cpe_display_name = "OCI-ELZ-CPE-P-HUB-001"
+prod_cpe_vendor = 4
+prod_ipsec_connection_static_routes = ["10.0.0.0/16", "11.0.0.0/16"]
+nonprod_enable_vpn = false
+
+# network
+prod_enable_internet_gateway_hub = "true"
+prod_enable_nat_gateway_hub = "true"
+prod_enable_service_gateway_hub = "true"
+prod_enable_nat_gateway_spoke = "true"
+prod_enable_service_gateway_spoke = "true"
+
+nonprod_enable_internet_gateway_hub = "true"
+nonprod_enable_nat_gateway_hub = "true"
+nonprod_enable_service_gateway_hub = "true"
+nonprod_enable_nat_gateway_spoke = "true"
+nonprod_enable_service_gateway_spoke = "true"
+
+prod_hub_vcn_cidr_block = "10.1.0.0/16"
+prod_hub_public_subnet_cidr_block = "10.1.1.0/24"
+prod_hub_private_subnet_cidr_block = "10.1.2.0/24"
+
+prod_spoke_vcn_cidr = "10.2.0.0/16"
+prod_spoke_subnet_web_cidr_block = "10.2.1.0/24"
+prod_spoke_subnet_app_cidr_block = "10.2.2.0/24"
+prod_spoke_subnet_db_cidr_block = "10.2.3.0/24"
+
+nonprod_hub_vcn_cidr_block = "10.3.0.0/16"
+nonprod_hub_public_subnet_cidr_block = "10.3.1.0/24"
+nonprod_hub_private_subnet_cidr_block = "10.3.2.0/24"
+
+nonprod_spoke_vcn_cidr = "10.4.0.0/16"
+nonprod_spoke_subnet_web_cidr_block = "10.4.1.0/24"
+nonprod_spoke_subnet_app_cidr_block = "10.4.2.0/24"
+nonprod_spoke_subnet_db_cidr_block = "10.4.3.0/24"
+
+# Tagging
+prod_enable_tagging = true
+nonprod_enable_tagging = true
+nonprod_cost_center_tagging = "n_cost_tag"
+nonprod_geo_location_tagging = "n_geo_tag"
+prod_cost_center_tagging = "p_cost_tag"
+prod_geo_location_tagging = "p_geo_tag"
+onboard_log_analytics = false
+
+# Monitoring (Optional)
+prod_network_topic_endpoints = []
+prod_secops_topic_endpoints = []
+prod_platform_topic_endpoints = []
+prod_identity_topic_endpoints = []
+prod_workload_topic_endpoints = []
+nonprod_network_topic_endpoints = []
+nonprod_secops_topic_endpoints = []
+nonprod_platform_topic_endpoints = []
+nonprod_identity_topic_endpoints = []
+nonprod_workload_topic_endpoints = []
+
+# Workload Expansion
+prod_additional_workload_subnets_cidr_blocks = []
+nonprod_additional_workload_subnets_cidr_blocks = []
\ No newline at end of file
diff --git a/templates/freetrial-landing-zone/iam.tf b/templates/freetrial-landing-zone/iam.tf
new file mode 100644
index 00000000..48913552
--- /dev/null
+++ b/templates/freetrial-landing-zone/iam.tf
@@ -0,0 +1,59 @@
+# -----------------------------------------------------------------------------
+# Compartment Resources
+# -----------------------------------------------------------------------------
+locals {
+ home_compartment = {
+ description = "Enterprise Landing Zone Home Compartment:Live-Lab"
+ }
+}
+
+module "home_compartment" {
+ source = "../../modules/compartment"
+
+ compartment_parent_id = var.tenancy_ocid
+ compartment_name = var.home_compartment_name
+ compartment_description = local.home_compartment.description
+ enable_compartment_delete = var.enable_compartment_delete
+
+ providers = {
+ oci = oci.home_region
+ }
+}
+
+module "break_glass_users" {
+ for_each = { for index, email in var.break_glass_user_email_list : index => email }
+ source = "../../modules/break_glass_user"
+ tenancy_ocid = var.tenancy_ocid
+
+ break_glass_user_index = each.key
+ break_glass_user_email = each.value
+
+ providers = {
+ oci = oci.home_region
+ }
+}
+
+# -----------------------------------------------------------------------------
+# Authentication Policy
+# -----------------------------------------------------------------------------
+locals {
+ authentication_policy = {
+ authentication_policy_password_policy_is_lowercase_characters_required = true
+ authentication_policy_password_policy_is_numeric_characters_required = true
+ authentication_policy_password_policy_is_special_characters_required = true
+ authentication_policy_password_policy_is_uppercase_characters_required = true
+ authentication_policy_password_policy_is_username_containment_allowed = false
+ authentication_policy_password_policy_minimum_password_length = 14
+ }
+}
+
+module "authentication_policy" {
+ source = "../../modules/authentication-policy"
+ tenancy_ocid = var.tenancy_ocid
+ authentication_policy_password_policy_is_lowercase_characters_required = local.authentication_policy.authentication_policy_password_policy_is_lowercase_characters_required
+ authentication_policy_password_policy_is_numeric_characters_required = local.authentication_policy.authentication_policy_password_policy_is_numeric_characters_required
+ authentication_policy_password_policy_is_special_characters_required = local.authentication_policy.authentication_policy_password_policy_is_special_characters_required
+ authentication_policy_password_policy_is_uppercase_characters_required = local.authentication_policy.authentication_policy_password_policy_is_uppercase_characters_required
+ authentication_policy_password_policy_is_username_containment_allowed = local.authentication_policy.authentication_policy_password_policy_is_username_containment_allowed
+ authentication_policy_password_policy_minimum_password_length = local.authentication_policy.authentication_policy_password_policy_minimum_password_length
+}
diff --git a/templates/freetrial-landing-zone/images/CIS1.2Level1.xlsx b/templates/freetrial-landing-zone/images/CIS1.2Level1.xlsx
new file mode 100644
index 00000000..1baacdcb
Binary files /dev/null and b/templates/freetrial-landing-zone/images/CIS1.2Level1.xlsx differ
diff --git a/templates/freetrial-landing-zone/images/Compartment.png b/templates/freetrial-landing-zone/images/Compartment.png
new file mode 100644
index 00000000..8811e62c
Binary files /dev/null and b/templates/freetrial-landing-zone/images/Compartment.png differ
diff --git a/templates/freetrial-landing-zone/images/Monitoring.png b/templates/freetrial-landing-zone/images/Monitoring.png
new file mode 100644
index 00000000..7f66ce64
Binary files /dev/null and b/templates/freetrial-landing-zone/images/Monitoring.png differ
diff --git a/templates/freetrial-landing-zone/images/enterprise-landing-zone-v2.svg b/templates/freetrial-landing-zone/images/enterprise-landing-zone-v2.svg
new file mode 100644
index 00000000..922c5265
--- /dev/null
+++ b/templates/freetrial-landing-zone/images/enterprise-landing-zone-v2.svg
@@ -0,0 +1,1802 @@
+
diff --git a/templates/freetrial-landing-zone/images/mushop-service.png b/templates/freetrial-landing-zone/images/mushop-service.png
new file mode 100644
index 00000000..dacafb90
Binary files /dev/null and b/templates/freetrial-landing-zone/images/mushop-service.png differ
diff --git a/templates/freetrial-landing-zone/images/mushop-topology.png b/templates/freetrial-landing-zone/images/mushop-topology.png
new file mode 100644
index 00000000..f109fba7
Binary files /dev/null and b/templates/freetrial-landing-zone/images/mushop-topology.png differ
diff --git a/templates/freetrial-landing-zone/images/terraform_apply_1.png b/templates/freetrial-landing-zone/images/terraform_apply_1.png
new file mode 100644
index 00000000..c341ef8a
Binary files /dev/null and b/templates/freetrial-landing-zone/images/terraform_apply_1.png differ
diff --git a/templates/freetrial-landing-zone/images/terraform_apply_2.png b/templates/freetrial-landing-zone/images/terraform_apply_2.png
new file mode 100644
index 00000000..b63f9334
Binary files /dev/null and b/templates/freetrial-landing-zone/images/terraform_apply_2.png differ
diff --git a/templates/freetrial-landing-zone/images/terraform_apply_3.png b/templates/freetrial-landing-zone/images/terraform_apply_3.png
new file mode 100644
index 00000000..adb9b143
Binary files /dev/null and b/templates/freetrial-landing-zone/images/terraform_apply_3.png differ
diff --git a/templates/freetrial-landing-zone/images/terraform_destroy_1.png b/templates/freetrial-landing-zone/images/terraform_destroy_1.png
new file mode 100644
index 00000000..98458d7b
Binary files /dev/null and b/templates/freetrial-landing-zone/images/terraform_destroy_1.png differ
diff --git a/templates/freetrial-landing-zone/images/terraform_destroy_2.png b/templates/freetrial-landing-zone/images/terraform_destroy_2.png
new file mode 100644
index 00000000..b5f8e60d
Binary files /dev/null and b/templates/freetrial-landing-zone/images/terraform_destroy_2.png differ
diff --git a/templates/freetrial-landing-zone/images/terraform_init.png b/templates/freetrial-landing-zone/images/terraform_init.png
new file mode 100644
index 00000000..a6589aa4
Binary files /dev/null and b/templates/freetrial-landing-zone/images/terraform_init.png differ
diff --git a/templates/freetrial-landing-zone/images/terraform_plan_1.png b/templates/freetrial-landing-zone/images/terraform_plan_1.png
new file mode 100644
index 00000000..299ecb5d
Binary files /dev/null and b/templates/freetrial-landing-zone/images/terraform_plan_1.png differ
diff --git a/templates/freetrial-landing-zone/images/terraform_plan_2.png b/templates/freetrial-landing-zone/images/terraform_plan_2.png
new file mode 100644
index 00000000..43acddb9
Binary files /dev/null and b/templates/freetrial-landing-zone/images/terraform_plan_2.png differ
diff --git a/templates/freetrial-landing-zone/images/terraform_validate.png b/templates/freetrial-landing-zone/images/terraform_validate.png
new file mode 100644
index 00000000..b0fa85de
Binary files /dev/null and b/templates/freetrial-landing-zone/images/terraform_validate.png differ
diff --git a/templates/freetrial-landing-zone/livelab.tfvars b/templates/freetrial-landing-zone/livelab.tfvars
new file mode 100644
index 00000000..26ed04a2
--- /dev/null
+++ b/templates/freetrial-landing-zone/livelab.tfvars
@@ -0,0 +1,61 @@
+#tfvars file for the ci pipline
+
+#Tenancy Related Variables
+
+#current_user_ocid = ""
+#region = ""
+#tenancy_ocid = ""
+#api_fingerprint = ""
+#api_private_key_path = ""
+
+
+# iam
+resource_label = "LIVELAB"
+enable_compartment_delete = false
+prod_domain_admin_email = ""
+# security
+enable_cloud_guard = false
+cloud_guard_target_tenancy = false
+prod_enable_bastion = true
+prod_bastion_client_cidr_block_allow_list = ["0.0.0.0/0"]
+
+
+# budget
+prod_budget_alert_rule_message = "LIVELAB_BUDGET"
+prod_budget_alert_rule_threshold = 1000000
+prod_budget_amount = 10000000
+prod_enable_budget = true
+
+#monitoring
+is_create_alarms = false
+
+#Identity
+domain_license_type = "free"
+
+# network extension
+prod_enable_vpn = false
+
+# Network
+
+prod_enable_internet_gateway_hub = "true"
+prod_enable_nat_gateway_hub = "true"
+prod_enable_service_gateway_hub = "true"
+prod_enable_nat_gateway_spoke = "true"
+prod_enable_service_gateway_spoke = "true"
+
+prod_hub_vcn_cidr_block = "10.1.0.0/16"
+prod_hub_public_subnet_cidr_block = "10.1.1.0/24"
+prod_hub_private_subnet_cidr_block = "10.1.2.0/24"
+
+prod_spoke_vcn_cidr = "10.2.0.0/16"
+prod_spoke_subnet_web_cidr_block = "10.2.1.0/24"
+prod_spoke_subnet_app_cidr_block = "10.2.2.0/24"
+prod_spoke_subnet_db_cidr_block = "10.2.3.0/24"
+
+#tagging
+prod_cost_center_tagging = "LIVELAB_COST_TAG"
+prod_geo_location_tagging = "LIVELAB_GEO_TAG"
+prod_enable_tagging = true
+
+# logging
+onboard_log_analytics = false
diff --git a/templates/freetrial-landing-zone/logging-variables.tf b/templates/freetrial-landing-zone/logging-variables.tf
new file mode 100644
index 00000000..aab4a19d
--- /dev/null
+++ b/templates/freetrial-landing-zone/logging-variables.tf
@@ -0,0 +1,35 @@
+variable "prod_retention_policy_duration_amount" {
+ type = string
+ description = "The timeAmount is interpreted in units defined by the timeUnit parameter, and is calculated in relation to each object's Last-Modified timestamp."
+ default = "1"
+}
+
+variable "prod_retention_policy_duration_time_unit" {
+ type = string
+ description = "The unit that should be used to interpret timeAmount."
+ default = "DAYS"
+}
+
+variable "nonprod_retention_policy_duration_amount" {
+ type = string
+ description = "The timeAmount is interpreted in units defined by the timeUnit parameter, and is calculated in relation to each object's Last-Modified timestamp."
+ default = "1"
+}
+
+variable "nonprod_retention_policy_duration_time_unit" {
+ type = string
+ description = "The unit that should be used to interpret timeAmount."
+ default = "DAYS"
+}
+
+variable "archive_log_retention_policy_duration_amount" {
+ type = string
+ description = "The timeAmount is interpreted in units defined by the timeUnit parameter, and is calculated in relation to each object's Last-Modified timestamp."
+ default = "1"
+}
+
+variable "archive_log_retention_policy_duration_time_unit" {
+ type = string
+ description = "The unit that should be used to interpret timeAmount."
+ default = "DAYS"
+}
\ No newline at end of file
diff --git a/templates/freetrial-landing-zone/logging.tf b/templates/freetrial-landing-zone/logging.tf
new file mode 100644
index 00000000..cff6481d
--- /dev/null
+++ b/templates/freetrial-landing-zone/logging.tf
@@ -0,0 +1,253 @@
+locals {
+ service_connector_policy = {
+ name = "${var.resource_label}-OCI-ELZ-SC-Policy"
+ description = "OCI ELZ Service Connector Policy"
+ statements = [
+ "Allow any-user to read log-content in compartment id ${module.home_compartment.compartment_id} where all {request.principal.type='serviceconnector'}",
+ "Allow any-user to read log-groups in compartment id ${module.home_compartment.compartment_id} where all {request.principal.type='serviceconnector'}",
+ "Allow any-user to {STREAM_READ, STREAM_CONSUME} in compartment id ${module.prod_environment.compartment.security.id} where all {request.principal.type='serviceconnector', target.stream.id='${module.prod_environment.stream_id}', request.principal.compartment.id='${module.prod_environment.compartment.security.id}'}",
+ "Allow any-user to manage objects in compartment id ${module.prod_environment.compartment.logging.id} where all {request.principal.type='serviceconnector', target.bucket.name='*_standard', request.principal.compartment.id='${module.prod_environment.compartment.security.id}'}",
+ "Allow any-user to manage objects in compartment id ${module.prod_environment.compartment.logging.id} where all {request.principal.type='serviceconnector', any{target.bucket.name='${var.resource_label}_${local.prod_environment.environment_prefix}_auditLogs_standard', target.bucket.name='${var.resource_label}_${local.prod_environment.environment_prefix}_defaultLogs_standard', target.bucket.name='${var.resource_label}_${local.prod_environment.environment_prefix}_serviceEvents_standard'}, request.principal.compartment.id='${module.prod_environment.compartment.security.id}'}",
+ ]
+ }
+
+
+ service_connector_archive_policy = {
+ name = "${var.resource_label}-OCI-ELZ-SC-ARC-Policy"
+ description = "OCI ELZ Service Connector Policy For Archive"
+ statements = [
+ "Allow any-user to read log-content in compartment id ${module.home_compartment.compartment_id} where all {request.principal.type='serviceconnector'}",
+ "Allow any-user to read log-groups in compartment id ${module.home_compartment.compartment_id} where all {request.principal.type='serviceconnector'}",
+ "Allow any-user to {STREAM_READ, STREAM_CONSUME} in compartment id ${module.home_compartment.compartment_id} where all {request.principal.type='serviceconnector'}",
+ "Allow any-user to manage objects in compartment id ${module.home_compartment.compartment_id} where all {request.principal.type='serviceconnector', target.bucket.name='${local.archive_log_bucket.name}'}"
+ ]
+ }
+
+ key_archive_policy = {
+ name = "${var.resource_label}-OCI-ELZ-KEY-ARC-Policy"
+ description = "OCI Enterprise Landing Zone Key Policy For Archive"
+
+ statements = [
+ "Allow service objectstorage-${var.region} to use keys in compartment id ${module.prod_environment.compartment.security.id}",
+ "Allow service blockstorage,FssOc1Prod, OKE, streaming to use keys in compartment id ${module.prod_environment.compartment.security.id}"
+ ]
+ }
+
+ archive_log_bucket = {
+ name = "${var.resource_label}_logs_archive"
+ description = "Archive Log bucket"
+ retention_rule_display_name = "archive log bucket retention rule"
+ retention_policy_duration_amount = var.archive_log_retention_policy_duration_amount
+ retention_policy_duration_time_unit = var.archive_log_retention_policy_duration_time_unit
+ bucket_storage_tier = "Archive"
+ }
+
+ prod_archive_audit_log_service_connector = {
+ display_name = "${var.resource_label}_schAuditLog_archive_${local.prod_environment.environment_prefix}"
+ source_kind = "logging"
+ target_kind = "objectStorage"
+ log_group_id = "_Audit_Include_Subcompartment"
+ target_bucket = module.archive_bucket.bucket.name
+ }
+
+ prod_archive_default_log_service_connector = {
+ display_name = "${var.resource_label}_schDefaultLog_archive_${local.prod_environment.environment_prefix}"
+ source_kind = "logging"
+ target_kind = "objectStorage"
+ target_bucket = module.archive_bucket.bucket.name
+ }
+
+ prod_archive_service_events_service_connector = {
+ display_name = "${var.resource_label}_schServiceEvents_archive_${local.prod_environment.environment_prefix}"
+ source_kind = "streaming"
+ target_kind = "objectStorage"
+ target_bucket = module.archive_bucket.bucket.name
+ cursor_kind = "TRIM_HORIZON"
+ }
+
+ archive_key = {
+ name = "${var.resource_label}-OCI-ELZ-ARC-KEY-${local.prod_environment.environment_prefix}"
+ shape_algorithm = "AES"
+ shape_length = 32
+ protection_mode = "SOFTWARE"
+ }
+
+ group_names = {
+ prod_platform_admin_group_name : var.prod_platform_admin_group_name != "" ? var.prod_platform_admin_group_name : "OCI-ELZ-UGP-${local.prod_environment.environment_prefix}-PLT-ADMIN",
+ nonprod_platform_admin_group_name : var.nonprod_platform_admin_group_name != "" ? var.nonprod_platform_admin_group_name : "OCI-ELZ-UGP-${local.prod_environment.environment_prefix}-PLT-ADMIN",
+ }
+
+ prod_platform_admin_policy = {
+ name = "OCI-ELZ-UGP-${local.prod_environment.environment_prefix}-PLT-ADMIN-POLICY-ARCHIVE"
+ description = "OCI Landing Zone Platform Admin Group Policy To Manage Archive Bucket"
+
+ statements = [
+ "Allow group ${local.group_names["prod_platform_admin_group_name"]} to manage buckets in compartment ${module.home_compartment.compartment_name}",
+ "Allow group ${local.group_names["prod_platform_admin_group_name"]} to manage objects in compartment ${module.home_compartment.compartment_name}"
+ ]
+ }
+}
+
+module "service_connector_policy" {
+ source = "../../modules/policies"
+ compartment_ocid = module.home_compartment.compartment_id
+ policy_name = local.service_connector_policy.name
+ description = local.service_connector_policy.description
+ statements = local.service_connector_policy.statements
+
+ depends_on = [module.prod_environment, module.home_compartment]
+}
+
+module "service_connector_archive_policy" {
+ source = "../../modules/policies"
+ compartment_ocid = module.home_compartment.compartment_id
+ policy_name = local.service_connector_archive_policy.name
+ description = local.service_connector_archive_policy.description
+ statements = local.service_connector_archive_policy.statements
+
+ depends_on = [module.prod_environment, module.home_compartment]
+}
+
+module "archive_key" {
+ source = "../../modules/key"
+ compartment_ocid = module.prod_environment.compartment.security.id
+ display_name = local.archive_key.name
+ shape_algorithm = local.archive_key.shape_algorithm
+ shape_length = local.archive_key.shape_length
+ protection_mode = local.archive_key.protection_mode
+ management_endpoint = module.prod_environment.vault_id
+
+ depends_on = [module.prod_environment, module.home_compartment]
+}
+
+module "key_archive_policy" {
+ source = "../../modules/policies"
+ compartment_ocid = module.home_compartment.compartment_id
+ policy_name = local.key_archive_policy.name
+ description = local.key_archive_policy.description
+ statements = local.key_archive_policy.statements
+
+ depends_on = [module.prod_environment, module.home_compartment]
+}
+
+module "archive_bucket" {
+ source = "../../modules/bucket"
+ tenancy_ocid = var.tenancy_ocid
+ compartment_id = module.home_compartment.compartment_id
+ name = local.archive_log_bucket.name
+ kms_key_id = module.archive_key.key_ocid
+ storage_tier = local.archive_log_bucket.bucket_storage_tier
+ retention_rule_display_name = local.archive_log_bucket.retention_rule_display_name
+ retention_policy_duration_amount = local.archive_log_bucket.retention_policy_duration_amount
+ retention_policy_duration_time_unit = local.archive_log_bucket.retention_policy_duration_time_unit
+ namespace = data.oci_objectstorage_namespace.ns.namespace
+
+ depends_on = [module.prod_environment, module.home_compartment, module.archive_key, module.key_archive_policy]
+}
+
+module "prod_archive_audit_log_service_connector" {
+ source = "../../modules/service-connector"
+ tenancy_ocid = var.tenancy_ocid
+ compartment_id = module.prod_environment.compartment.security.id
+ source_compartment_id = module.home_compartment.compartment_id
+ display_name = local.prod_archive_audit_log_service_connector.display_name
+ source_kind = local.prod_archive_audit_log_service_connector.source_kind
+ target_kind = local.prod_archive_audit_log_service_connector.target_kind
+ log_group_id = local.prod_archive_audit_log_service_connector.log_group_id
+ target_bucket = local.prod_archive_audit_log_service_connector.target_bucket
+
+ depends_on = [module.archive_bucket, module.service_connector_archive_policy]
+}
+/*
+module "nonprod_archive_audit_log_service_connector" {
+ source = "../../modules/service-connector"
+ tenancy_ocid = var.tenancy_ocid
+ compartment_id = module.nonprod_environment.compartment.security.id
+ source_compartment_id = module.home_compartment.compartment_id
+ display_name = local.nonprod_archive_audit_log_service_connector.display_name
+ source_kind = local.nonprod_archive_audit_log_service_connector.source_kind
+ target_kind = local.nonprod_archive_audit_log_service_connector.target_kind
+ log_group_id = local.nonprod_archive_audit_log_service_connector.log_group_id
+ target_bucket = local.nonprod_archive_audit_log_service_connector.target_bucket
+
+ depends_on = [module.archive_bucket, module.service_connector_archive_policy]
+}
+*/
+module "prod_archive_default_log_service_connector" {
+ source = "../../modules/service-connector"
+ tenancy_ocid = var.tenancy_ocid
+ compartment_id = module.prod_environment.compartment.security.id
+ source_compartment_id = module.prod_environment.compartment.security.id
+ display_name = local.prod_archive_default_log_service_connector.display_name
+ source_kind = local.prod_archive_default_log_service_connector.source_kind
+ target_kind = local.prod_archive_default_log_service_connector.target_kind
+ log_group_id = module.prod_environment.default_group_id
+ target_bucket = local.prod_archive_default_log_service_connector.target_bucket
+
+ depends_on = [module.archive_bucket, module.service_connector_archive_policy]
+}
+/*
+module "nonprod_archive_default_log_service_connector" {
+ source = "../../modules/service-connector"
+ tenancy_ocid = var.tenancy_ocid
+ compartment_id = module.nonprod_environment.compartment.security.id
+ source_compartment_id = module.nonprod_environment.compartment.security.id
+ display_name = local.nonprod_archive_default_log_service_connector.display_name
+ source_kind = local.nonprod_archive_default_log_service_connector.source_kind
+ target_kind = local.nonprod_archive_default_log_service_connector.target_kind
+ log_group_id = module.nonprod_environment.default_group_id
+ target_bucket = local.nonprod_archive_default_log_service_connector.target_bucket
+
+ depends_on = [module.archive_bucket, module.service_connector_archive_policy]
+}
+*/
+module "prod_archive_service_events_service_connector" {
+ source = "../../modules/service-connector"
+ tenancy_ocid = var.tenancy_ocid
+ compartment_id = module.prod_environment.compartment.security.id
+ source_compartment_id = module.prod_environment.compartment.security.id
+ display_name = local.prod_archive_service_events_service_connector.display_name
+ source_kind = local.prod_archive_service_events_service_connector.source_kind
+ target_kind = local.prod_archive_service_events_service_connector.target_kind
+ stream_id = module.prod_environment.stream_id
+ cursor_kind = local.prod_archive_service_events_service_connector.cursor_kind
+ target_bucket = local.prod_archive_service_events_service_connector.target_bucket
+
+ depends_on = [module.archive_bucket, module.service_connector_archive_policy]
+}
+/*
+module "nonprod_archive_service_events_service_connector" {
+ source = "../../modules/service-connector"
+ tenancy_ocid = var.tenancy_ocid
+ compartment_id = module.nonprod_environment.compartment.security.id
+ source_compartment_id = module.nonprod_environment.compartment.security.id
+ display_name = local.nonprod_archive_service_events_service_connector.display_name
+ source_kind = local.nonprod_archive_service_events_service_connector.source_kind
+ target_kind = local.nonprod_archive_service_events_service_connector.target_kind
+ stream_id = module.nonprod_environment.stream_id
+ cursor_kind = local.nonprod_archive_service_events_service_connector.cursor_kind
+ target_bucket = local.nonprod_archive_service_events_service_connector.target_bucket
+
+ depends_on = [module.archive_bucket, module.service_connector_archive_policy]
+}
+*/
+module "prod_platform_admin_policy" {
+ source = "../../modules/policies"
+ compartment_ocid = module.home_compartment.compartment_id
+ policy_name = local.prod_platform_admin_policy.name
+ description = local.prod_platform_admin_policy.description
+ statements = local.prod_platform_admin_policy.statements
+
+ depends_on = [module.home_compartment]
+}
+/*
+module "nonprod_platform_admin_policy" {
+ source = "../../modules/policies"
+ compartment_ocid = module.home_compartment.compartment_id
+ policy_name = local.nonprod_platform_admin_policy.name
+ description = local.nonprod_platform_admin_policy.description
+ statements = local.nonprod_platform_admin_policy.statements
+
+ depends_on = [module.home_compartment]
+}
+*/
diff --git a/templates/freetrial-landing-zone/monitoring.tf b/templates/freetrial-landing-zone/monitoring.tf
new file mode 100644
index 00000000..8edd59b6
--- /dev/null
+++ b/templates/freetrial-landing-zone/monitoring.tf
@@ -0,0 +1,14 @@
+locals {
+ logging_analytics = {
+ is_onboarded = true
+ }
+}
+
+module "logging_analytics_namespace" {
+ count = var.onboard_log_analytics ? 1 : 0
+ source = "../../modules/log-analytics-namespace"
+ compartment_id = var.tenancy_ocid
+ is_onboarded = local.logging_analytics.is_onboarded
+ tenancy_ocid = var.tenancy_ocid
+ resource_label = var.resource_label
+}
diff --git a/templates/freetrial-landing-zone/network-extension-variables.tf b/templates/freetrial-landing-zone/network-extension-variables.tf
new file mode 100644
index 00000000..2adaf167
--- /dev/null
+++ b/templates/freetrial-landing-zone/network-extension-variables.tf
@@ -0,0 +1,172 @@
+variable "enable_vpn_or_fastconnect" {
+ type = string
+ description = "Option to enable VPN or FASTCONNECT service. Options are NONE, VPN, FASTCONNECT."
+ default = "NONE"
+}
+
+variable "prod_enable_vpn" {
+ type = bool
+ description = "Enable VPN in prod environment"
+ default = false
+}
+
+variable "prod_cpe_display_name" {
+ type = string
+ description = "Customer Premises Equipment name. Recommendation: OCI-ELZ-CPE-[Environment]-HUB-[Region] 001"
+ default = ""
+}
+
+variable "prod_cpe_ip_address" {
+ type = string
+ description = "Customer Premises Equipment (CPE) IP address"
+ default = ""
+}
+variable "prod_ipsec_display_name" {
+ type = string
+ description = "IPsec display name. Recommendation: OCI-ELZ-IPS-[Environment]-HUB-[Region] 001"
+ default = ""
+}
+variable "prod_ipsec_connection_static_routes" {
+ type = list(string)
+ description = ""
+ default = [""]
+}
+variable "prod_cpe_vendor" {
+ type = number
+ description = "Type corresponding number as your CPE vendor: Yamaha-RTX1210 0, Other 1, Cisco-9.7.1-or-later 2, Yamaha-RTX830 3, Libreswan 4, Fortinet 5, NEC 6, Cisco-8.5+ 7, Cisco-IOS 8, WatchGuard 9, Juniper-MX 10, Juniper-SRX 11, Furukawa 12, Check_Point 13, Palo_Alto 14"
+ default = 0
+}
+
+variable "prod_ipsec_routing_type" {
+ type = string
+ description = "BGP dynamic routing, STATIC routing. Type BGP or STATIC"
+ default = "STATIC"
+}
+
+variable "prod_tunnel_a_display_name" {
+ type = string
+ description = "Tunnel A display name. Recommendation: "
+ default = ""
+}
+
+variable "prod_customer_bgp_asn" {
+ type = string
+ description = "ASN is required and used for the tunnel's BGP session"
+ default = ""
+}
+
+variable "prod_bgp_cust_tunnela_ip" {
+ type = string
+ description = "The IP address for the CPE end of the inside tunnel interface."
+ default = ""
+}
+
+variable "prod_bgp_oci_tunnela_ip" {
+ type = string
+ description = "The IP address for the Oracle end of the inside tunnel interface."
+ default = ""
+
+}
+
+variable "prod_shared_secret" {
+ type = string
+ description = "The shared secret (pre-shared key) to use for the IPSec tunnel"
+ default = "example"
+
+}
+
+variable "prod_tunnel_b_display_name" {
+ type = string
+ description = "Tunnel B display name. Recommendation: "
+ default = ""
+}
+# Fastconnect Variables
+variable "fastconnect_provider" {
+ type = string
+ description = "Fastconnect provider. Please choose from: AT&T, Azure, Megaport, QTS, CEintro, Cologix, CoreSite, Digitial Realty, EdgeConneX, Epsilon, Equinix, InterCloud, Lumen, Neutrona, OMCS, OracleL2ItegDeployment, OracleL3ItegDeployment, Orange, Verizon, Zayo"
+ default = ""
+}
+
+
+variable "virtual_circuit_bandwidth_shape" {
+ type = string
+ description = "The provisioned data rate of the connection"
+ default = "1500"
+}
+
+variable "virtual_circuit_display_name" {
+ type = string
+ description = "The display name of this virtual circuit. Recommendation: OCI-ELZ-FCN-P-HUB-[REGION] 001"
+ default = ""
+}
+
+variable "provider_service_key_name" {
+ type = string
+ description = "The provider service key that the provider gives you when you set up a virtual circuit connection from the provider to OCI"
+ default = ""
+}
+
+variable "fastconnect_routing_policy" {
+ type = list(string)
+ description = "Available FastConnect routing policies: ORACLE_SERVICE_NETWORK, REGIONAL, MARKET_LEVEL, GLOBAL"
+ default = []
+}
+
+variable "virtual_circuit_type" {
+ type = string
+ description = "The type of IP addresses used in this virtual circuit. PRIVATE or PUBLIC"
+ default = ""
+}
+
+variable "customer_primary_bgp_peering_ip" {
+ type = string
+ description = "The primary BGP IPv4 address of the customer's router"
+ default = ""
+
+}
+
+variable "oracle_primary_bgp_peering_ip" {
+ type = string
+ description = "The primary BGP IPv4 address for Oracle's end of the BGP session"
+ default = ""
+}
+
+variable "customer_secondary_bgp_peering_ip" {
+ type = string
+ description = "[Optional] The secondary BGP IPv4 address of the customer's router"
+ default = ""
+}
+
+variable "oracle_secondary_bgp_peering_ip" {
+ type = string
+ description = "[Optional] Secondary IPv4 address for Oracle's end of the BGP session"
+ default = ""
+}
+
+variable "virtual_circuit_customer_asn" {
+ type = string
+ description = "The BGP ASN of the network at the other end of the BGP session from Oracle"
+ default = 0
+}
+
+variable "virtual_circuit_is_bfd_enabled" {
+ type = bool
+ description = "Set to true to enable BFD for IPv4 BGP peering, or set to false to disable BFD"
+ default = false
+}
+
+variable "bgp_md5auth_key" {
+ type = string
+ description = "The key for BGP MD5 authentication. Only applicable if your system requires MD5 authentication"
+ default = ""
+}
+
+variable "prod_enable_fastconnect" {
+ type = bool
+ default = true
+ description = "[Please don't change this value] Enable fastconnect in prod environment."
+}
+variable "customer_onprem_ip_cidr" {
+ type = list(string)
+ default = []
+}
diff --git a/templates/freetrial-landing-zone/outputs.tf b/templates/freetrial-landing-zone/outputs.tf
new file mode 100644
index 00000000..0d548592
--- /dev/null
+++ b/templates/freetrial-landing-zone/outputs.tf
@@ -0,0 +1,16 @@
+output "subnets" {
+ value = module.prod_environment.subnets
+ description = "The subnet OCID"
+}
+
+output "vcn" {
+ value = module.prod_environment.vcn
+}
+
+output "dynamic_group_detail" {
+ value = module.osms_dynamic_group
+}
+
+output "workload_compartment_id" {
+ value = module.prod_environment.workload_compartment_id
+}
\ No newline at end of file
diff --git a/templates/freetrial-landing-zone/provider.tf b/templates/freetrial-landing-zone/provider.tf
new file mode 100644
index 00000000..d9301434
--- /dev/null
+++ b/templates/freetrial-landing-zone/provider.tf
@@ -0,0 +1,81 @@
+# # -----------------------------------------------------------------------------
+# # Provider Requirements if using stack as a module
+# # -----------------------------------------------------------------------------
+# terraform {
+# required_version = ">= 1.0.0"
+
+# required_providers {
+# oci = {
+# source = "oracle/oci"
+# version = "4.96.0" # October 05, 2022 Release
+# configuration_aliases = [oci, oci.home_region]
+# }
+# }
+# }
+
+# -----------------------------------------------------------------------------
+# WARNING!
+# UNCOMMENT EVERYTHING BELOW AND COMMENT EVERYTHING ABOVE IF YOU WISH TO USE THIS
+# STACK AS A STANDALONE - DO NOT TOUCH IF USING THIS STACK IN A MODULE CALL
+# Provider Requirements if using stack as standalone
+# -----------------------------------------------------------------------------
+terraform {
+ required_version = ">= 1.0.0"
+
+ required_providers {
+ oci = {
+ source = "oracle/oci"
+ version = "4.96.0" # October 05, 2022 Release
+ }
+ }
+}
+
+
+# -----------------------------------------------------------------------------
+# Provider blocks for home region and alternate region(s)
+# -----------------------------------------------------------------------------
+provider "oci" {
+ tenancy_ocid = var.tenancy_ocid
+ user_ocid = var.current_user_ocid
+ fingerprint = var.api_fingerprint
+ private_key = var.api_private_key # if both set this takes precidence
+ private_key_path = var.api_private_key_path
+ region = var.region
+}
+
+provider "oci" {
+ alias = "home_region"
+ tenancy_ocid = var.tenancy_ocid
+ user_ocid = var.current_user_ocid
+ fingerprint = var.api_fingerprint
+ private_key = var.api_private_key # if both set this takes precidence
+ private_key_path = var.api_private_key_path
+ region = local.home_region[0]
+}
+
+# -----------------------------------------------------------------------------
+# Provider Variables
+# -----------------------------------------------------------------------------
+variable "current_user_ocid" {
+ type = string
+ description = "The OCID of the current user"
+ default = ""
+}
+
+variable "api_fingerprint" {
+ type = string
+ description = "The fingerprint of API"
+ default = ""
+}
+
+variable "api_private_key_path" {
+ type = string
+ description = "The local path to the API private key"
+ default = ""
+}
+
+variable "api_private_key" {
+ type = string
+ description = "The API private key"
+ default = ""
+}
\ No newline at end of file
diff --git a/templates/freetrial-landing-zone/regenerate_docs.sh b/templates/freetrial-landing-zone/regenerate_docs.sh
new file mode 100755
index 00000000..30d3de60
--- /dev/null
+++ b/templates/freetrial-landing-zone/regenerate_docs.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+###########################################################
+## This will update all our autogenerated README.md files.
+##
+## The autogenerated content is placed between:
+##
+## ... and ...
+##
+## tags in the README.md files. DO NOT edit those sections
+## manually! Any changes there will be lost!
+##
+## Note: this script actually generates the main
+## enterprise-landing-zone/README.md twice,
+## which is unavoidable due to our directory layout.
+## We may need to revisit this if ve decide to use
+## different documentation parameters in modules/
+## and templates/ folders.
+###########################################################
+
+terraform-docs .
+terraform-docs -c .module-tf-docs.yml .
+
diff --git a/templates/freetrial-landing-zone/schema.yaml b/templates/freetrial-landing-zone/schema.yaml
new file mode 100644
index 00000000..2462837a
--- /dev/null
+++ b/templates/freetrial-landing-zone/schema.yaml
@@ -0,0 +1,579 @@
+title: Oracle-Enterprise-Landing-Zone-(OELZ)
+description: Oracle Enterprise Landing Zone (OELZ) developed by OCI
+schemaVersion: 1.0.0
+version: "1.0.0"
+locale: en
+variableGroups:
+ - title: Provider Variables
+ visible: false
+ variables:
+ - api_fingerprint
+ - api_private_key_path
+ - api_private_key
+ - region
+ - tenancy_ocid
+ - current_user_ocid
+ - title: IAM Variables
+ visible: true
+ variables:
+ - resource_label
+ - enable_compartment_delete
+ - home_compartment_name
+ - title: Identity
+ visible: true
+ variables:
+ - domain_license_type
+ - prod_domain_admin_email
+ - title: Security Variables
+ visible: true
+ variables:
+ - prod_enable_bastion
+ - prod_bastion_client_cidr_block_allow_list
+ - title: Budget Variables
+ visible: true
+ variables:
+ - prod_budget_alert_rule_message
+ - prod_enable_budget
+ - prod_budget_alert_rule_threshold
+ - prod_budget_amount
+ - title: Network Variables
+ visible: true
+ variables:
+ - prod_enable_internet_gateway_hub
+ - prod_enable_nat_gateway_hub
+ - prod_enable_service_gateway_hub
+ - prod_enable_nat_gateway_spoke
+ - prod_enable_service_gateway_spoke
+ - prod_hub_vcn_cidr_block
+ - prod_hub_public_subnet_cidr_block
+ - prod_hub_private_subnet_cidr_block
+ - prod_spoke_vcn_cidr
+ - prod_spoke_subnet_web_cidr_block
+ - prod_spoke_subnet_app_cidr_block
+ - prod_spoke_subnet_db_cidr_block
+ - title: Tagging Variables
+ visible: true
+ variables:
+ - prod_enable_tagging
+ - prod_cost_center_tagging
+ - prod_geo_location_tagging
+ - title: Logging Variables
+ visible: false
+ variables:
+ - archive_log_retention_policy_duration_amount
+ - archive_log_retention_policy_duration_time_unit
+ - prod_retention_policy_duration_amount
+ - prod_retention_policy_duration_time_unit
+ - title: Monitoring Variables
+ visible: false
+ variables:
+ - onboard_log_analytics
+ - is_create_alarms
+ - prod_enable_security_monitoring_alarms
+ - prod_enable_network_monitoring_alarms
+ - prod_enable_workload_monitoring_alarms
+
+ - title: Invisible Variables
+ visible: false
+ variables:
+ - igw_hub_check
+ - nat_gw_hub_check
+ - nat_gw_spoke_check
+ - service_gw_hub_check
+ - service_gw_spoke_check
+ - prod_create_master_encryption_key
+ - prod_enable_vault_replication
+ - prod_vault_replica_region
+ - prod_vault_type
+ - prod_enable_fastconnect
+ - nonprod_retention_policy_duration_amount
+ - nonprod_retention_policy_duration_time_unit
+ - nonprod_application_admin_group_name
+ - nonprod_budget_alert_rule_message
+ - nonprod_budget_alert_rule_recipients
+ - nonprod_budget_alert_rule_threshold
+ - nonprod_budget_amount
+ - nonprod_database_admin_group_name
+ - nonprod_domain_admin_email
+ - nonprod_enable_budget
+ - nonprod_iam_admin_group_name
+ - nonprod_network_admin_group_name
+ - nonprod_ops_admin_group_name
+ - nonprod_platform_admin_group_name
+ - nonprod_security_admin_group_name
+ - nonprod_workload_admin_group_name
+ - prod_additional_workload_subnets_cidr_blocks
+ - bgp_md5auth_key
+ - customer_onprem_ip_cidr
+ - customer_primary_bgp_peering_ip
+ - customer_secondary_bgp_peering_ip
+ - fastconnect_provider
+ - oracle_primary_bgp_peering_ip
+ - oracle_secondary_bgp_peering_ip
+ - prod_bgp_cust_tunnela_ip
+ - prod_bgp_oci_tunnela_ip
+ - prod_cpe_display_name
+ - prod_cpe_ip_address
+ - prod_cpe_vendor
+ - prod_customer_bgp_asn
+ - prod_ipsec_connection_static_routes
+ - prod_ipsec_display_name
+ - prod_ipsec_routing_type
+ - prod_shared_secret
+ - prod_tunnel_a_display_name
+ - prod_tunnel_b_display_name
+ - provider_service_key_name
+ - virtual_circuit_bandwidth_shape
+ - virtual_circuit_customer_asn
+ - virtual_circuit_display_name
+ - virtual_circuit_type
+ - cloud_guard_target_tenancy
+ - enable_cloud_guard
+ - prod_application_admin_group_name
+ - prod_network_admin_group_name
+ - prod_security_admin_group_name
+ - prod_iam_admin_group_name
+ - prod_platform_admin_group_name
+ - prod_ops_admin_group_name
+ - prod_log_admin_group_name
+ - prod_workload_admin_group_name
+ - prod_database_admin_group_name
+ - enable_vpn_or_fastconnect
+ - prod_enable_vpn
+ - prod_budget_alert_rule_recipients
+ - prod_network_topic_endpoints
+ - prod_platform_topic_endpoints
+ - prod_secops_topic_endpoints
+ - prod_workload_topic_endpoints
+ - virtual_circuit_is_bfd_enabled
+ - fastconnect_routing_policy
+ - prod_identity_topic_endpoint
+ - break_glass_user_email_list
+ - prod_identity_topic_endpoints
+ - prod_budget_alert_rule_recipients
+
+variables:
+ #Provider Variables
+ api_fingerprint:
+ type: string
+ description: The fingerprint of API
+ default: "Value not required in Oracle Resource Manager."
+ title: Api Fingerprint
+ api_private_key_path:
+ type: string
+ description: The local path to the API private key
+ default: "Value not required in Oracle Resource Manager."
+ title: Api Private Key Path
+ region:
+ type: string
+ description: the OCI region LZ is deployed to.
+ title: Region
+ required: true
+ tenancy_ocid:
+ type: string
+ description: The OCID of tenancy
+ title: Tenancy OCID
+ current_user_ocid:
+ type: string
+ description: OCID of the current user
+ title: Current User OCID
+
+ # IAM variables
+ resource_label:
+ type: string
+ description: "The prefix used to avoid naming conflict"
+ default: "livelab"
+ required: true
+ title: Resource Label
+ home_compartment_name:
+ type: string
+ description: "The name of the Landing Zone home compartment"
+ default: "LIVELAB-OCI-CMP-HOME"
+ required: true
+ title: Home Compartment Name
+ domain_license_type:
+ type: string
+ description: "Identity Domain License Type"
+ default: "free"
+ required: false
+ title: Domain license type
+ prod_domain_admin_email:
+ type: string
+ description: "The email address for the prod identity domain admin"
+ required: true
+ title: Domain Admin Email in Prod
+ enable_compartment_delete:
+ type: boolean
+ description: "Set to true to allow the compartments to delete on terraform destroy."
+ required: true
+ title: Enable Compartment Delete
+ break_glass_user_email_list:
+ type: array
+ items:
+ type: string
+ pattern: ^[^\s@]+@([^\s@.,]+\.)+[^\s@.,]{2,}$
+ description:
+ "Unique list of break glass user email addresses that do not exist. These users are added to the Administrator group.
+ in the tenancy"
+ required: true
+ title: Break Glass User Email List
+ prod_network_admin_group_name:
+ type: string
+ description: "The group name for the OCI Landing Zone Network Administrators Group"
+ required: false
+ default: ""
+ visible: show_extra_group_names
+ pattern: ^([\w\.-]){1,100}$
+ title: Network Admin Group Name in Prod
+ prod_security_admin_group_name:
+ type: string
+ description: "The group name for the OCI Landing Zone Security Administrators Group"
+ required: false
+ default: ""
+ visible: show_extra_group_names
+ pattern: ^([\w\.-]){1,100}$
+ title: Security Admin Group Name in Prod
+ prod_iam_admin_group_name:
+ type: string
+ description: "The group name for the OCI Landing Zone IAM Administrators Group"
+ required: false
+ default: ""
+ visible: show_extra_group_names
+ pattern: ^([\w\.-]){1,100}$
+ title: IAM Admin Group Name in Prod
+ prod_platform_admin_group_name:
+ type: string
+ description: "The group name for the OCI Landing Zone Platform Administrators Group"
+ required: false
+ default: ""
+ visible: show_extra_group_names
+ pattern: ^([\w\.-]){1,100}$
+ title: Platform Admin Group Name in Prod
+ prod_ops_admin_group_name:
+ type: string
+ description: "The group name for the OCI Landing Zone Ops Administrators Group"
+ required: false
+ default: ""
+ visible: show_extra_group_names
+ pattern: ^([\w\.-]){1,100}$
+ title: Ops Admin Group Name in Prod
+ prod_log_admin_group_name:
+ type: string
+ description: "The group name for the OCI Landing Zone Log Administrators Group"
+ required: false
+ default: ""
+ visible: show_extra_group_names
+ pattern: ^([\w\.-]){1,100}$
+ title: Log Admin Group Name in Prod
+ prod_workload_admin_group_name:
+ type: string
+ description: "The group name for the OCI Landing Zone Workload Administrators Group"
+ required: false
+ default: ""
+ visible: show_extra_group_names
+ pattern: ^([\w\.-]){1,100}$
+ title: Workload Admin Group Name in Prod
+ prod_application_admin_group_name:
+ type: string
+ description: "The group name for the OCI Landing Zone Application Administrators Group"
+ required: false
+ default: ""
+ visible: show_extra_group_names
+ pattern: ^([\w\.-]){1,100}$
+ title: Application Admin Group Name in Prod
+ prod_database_admin_group_name:
+ type: string
+ description: "The group name for the OCI Landing Zone Database Administrators Group"
+ required: false
+ default: ""
+ visible: show_extra_group_names
+ pattern: ^([\w\.-]){1,100}$
+ title: Database Admin Group Name in Prod
+
+ # Security Variables
+ enable_cloud_guard:
+ type: boolean
+ description: "true if you don't have cloud guard enabled, false if you've already have cloud guard enabled."
+ default: false
+ required: false
+ title: Enable Cloud Guard
+ cloud_guard_target_tenancy:
+ type: boolean
+ description: "true if cloud guard targets to tenancy, false if cloud guard targets to Landing Zone home compartment."
+ default: false
+ required: false
+ title: Cloud Guard Target Tenancy
+ prod_enable_bastion:
+ type: boolean
+ description: "Option to enable bastion service in prod"
+ default: true
+ required: true
+ title: Enable Bastion in Prod
+ prod_bastion_client_cidr_block_allow_list:
+ type: array
+ items:
+ type: string
+ pattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1][0-9]|[2][0-9]))$
+ description: "A list of address ranges in CIDR notation that bastion is allowed to connect"
+ required: true
+ default: "10.0.0.0/16,10.0.0.0/24"
+ visible: prod_enable_bastion
+ title: Bastion Client CIDR Block Allow List in Prod
+ # Budget Variables
+ prod_enable_budget:
+ type: boolean
+ description: "Option to enable budget service in prod."
+ default: true
+ required: true
+ title: Enable Budget Service in Prod
+ prod_budget_alert_rule_message:
+ type: string
+ description: "The alert message for budget alerts."
+ required: true
+ default: "LIVELAB-TEST"
+ visible: prod_enable_budget
+ title: Budget Alert Rule Message in Prod
+ prod_budget_alert_rule_recipients:
+ type: string
+ description: "The delimited list of email addresses to receive the alert when it triggers. Delimiter characters can be a comma, space, TAB, or semicolon"
+ required: false
+ default: ""
+ visible: prod_budget_alert_rule_recipients
+ title: Budget Alert Rule Recipients in Prod
+ prod_budget_alert_rule_threshold:
+ type: string
+ description: "The threshold for the budget alert."
+ required: true
+ default: "1000000"
+ visible: prod_budget_alert_rule_threshold
+ title: Budget Alert Rule Threshold in Prod
+ prod_budget_amount:
+ type: string
+ description: "The amount of the budget expressed as a whole number in the currency of the customer's rate card."
+ required: true
+ default: "10000000"
+ visible: prod_budget_amount
+ title: Budget Amount in Prod
+
+ # Tagging Variables
+ prod_enable_tagging:
+ type: boolean
+ description: "Option to enable tagging service in prod."
+ default: true
+ required: true
+ title: Enable Tagging Service in Prod
+ prod_cost_center_tagging:
+ type: string
+ default: "LIVELAB_COST_TAG"
+ description: "Cost center tagging in prod."
+ required: true
+ title: Cost Center Tagging in Prod
+ prod_geo_location_tagging:
+ type: string
+ default: "LIVELAB_GEO_TAG"
+ description: "Geo location tagging in prod."
+ required: true
+ title: Geo Location Tagging in Prod
+
+ # Logging Variables
+ archive_log_retention_policy_duration_amount:
+ type: string
+ description: "The timeAmount is interpreted in units defined by the timeUnit parameter, and is calculated in relation to each object's Last-Modified timestamp"
+ required: true
+ default: "1"
+ title: Retention Policy Duration Amount for Archive Log Bucket
+ archive_log_retention_policy_duration_time_unit:
+ type: string
+ description: "The unit that should be used to interpret timeAmount. Options: DAYS, YEARS"
+ required: true
+ default: "DAYS"
+ title: Retention Policy Duration Time Unit for Archive Log Bucket
+ prod_retention_policy_duration_amount:
+ type: string
+ description: "The timeAmount is interpreted in units defined by the timeUnit parameter, and is calculated in relation to each object's Last-Modified timestamp"
+ required: true
+ default: "1"
+ title: Retention Policy Duration Amount for Standard Log Bucket in Prod
+ prod_retention_policy_duration_time_unit:
+ type: string
+ description: "The unit that should be used to interpret timeAmount. Options: DAYS, YEARS"
+ required: true
+ default: "DAYS"
+ title: Retention Policy Duration Time Unit for Standard Log Bucket in Prod
+
+ # Monitoring Variables
+ onboard_log_analytics:
+ type: boolean
+ description: "Set to true to onboard log analytics service. Set to false if it's already onboarded"
+ default: false
+ required: false
+ title: Onboard Log Analytics
+ is_create_alarms:
+ type: boolean
+ description: "Set to true to enable Alarms"
+ default: false
+ required: false
+ title: To Create Alarms
+ prod_network_topic_endpoints:
+ type: array
+ items:
+ type: string
+ pattern: ^[^\s@]+@([^\s@.,]+\.)+[^\s@.,]{2,}$
+ description: "List of email addresses for Network Warning and Critical notifications."
+ required: false
+ default: []
+ title: Network Warning and Critical Notification Recipient Email List in Prod"
+ prod_secops_topic_endpoints:
+ type: array
+ items:
+ type: string
+ pattern: ^[^\s@]+@([^\s@.,]+\.)+[^\s@.,]{2,}$
+ description: "List of email addresses for SecOps Warning and Critical notifications."
+ required: false
+ default: []
+ title: SecOps Warning and Critical Notification Recipient Email List in Prod"
+ prod_platform_topic_endpoints:
+ type: array
+ items:
+ type: string
+ pattern: ^[^\s@]+@([^\s@.,]+\.)+[^\s@.,]{2,}$
+ description: "List of email addresses for Platform notifications."
+ required: false
+ default: []
+ title: Platform Notification Recipient Email List in Prod"
+ prod_identity_topic_endpoints:
+ type: array
+ items:
+ type: string
+ pattern: ^[^\s@]+@([^\s@.,]+\.)+[^\s@.,]{2,}$
+ description: "List of email addresses for Identity notifications."
+ required: false
+ default: []
+ title: Identity Notification Recipient Email List in Prod"
+ prod_workload_topic_endpoints:
+ type: array
+ items:
+ type: string
+ pattern: ^[^\s@]+@([^\s@.,]+\.)+[^\s@.,]{2,}$
+ description: "List of email addresses for Workload notifications."
+ required: false
+ default: []
+ title: Workload Notification Recipient Email List in Prod"
+ prod_enable_security_monitoring_alarms:
+ type: boolean
+ description: "Enable Security Monitoring Alarms in Production Security Compartment."
+ default: false
+ required: false
+ title: Enable Security Monitoring Alarms in Prod
+ prod_enable_network_monitoring_alarms:
+ type: boolean
+ description: "Enable Network Monitoring Alarms in Production Network Compartment."
+ default: false
+ required: false
+ title: Enable Network Monitoring Alarms in Prod
+ prod_enable_workload_monitoring_alarms:
+ type: boolean
+ description: "Enable Workload Monitoring Alarms in Production Workload Compartment."
+ default: false
+ required: false
+ title: Enable Workload Monitoring Alarms in Prod
+
+ # Network Variables
+ prod_enable_internet_gateway_hub:
+ type: boolean
+ description: "Option to enable internet gateway in prod hub"
+ default: true
+ required: true
+ title: Enable Internet Gateway in Prod Hub
+ prod_enable_nat_gateway_hub:
+ type: boolean
+ description: "Option to enable nat gateway in prod hub"
+ default: true
+ required: true
+ title: Enable NAT Gateway in Prod Hub
+ prod_enable_service_gateway_hub:
+ type: boolean
+ description: "Option to enable service gateway in prod hub"
+ default: true
+ required: true
+ title: Enable Service Gateway in Prod Hub
+ prod_enable_nat_gateway_spoke:
+ type: boolean
+ description: "Option to enable nat gateway in prod spoke"
+ default: true
+ required: true
+ title: Enable NAT Gateway in Prod Spoke
+ prod_enable_service_gateway_spoke:
+ type: boolean
+ description: "Option to enable service gateway in prod spoke"
+ default: true
+ required: true
+ title: Enable Service Gateway in Prod Spoke
+ prod_hub_vcn_cidr_block:
+ type: string
+ description: "Vcn CIDR block in Prod Hub"
+ required: true
+ default: "10.1.0.0/16"
+ pattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1][0-9]|[2][0-9]))$
+ title: Vcn CIDR Block in Prod Hub
+ prod_hub_public_subnet_cidr_block:
+ type: string
+ description: "Public subnet CIDR block in Prod Hub"
+ default: "10.1.1.0/24"
+ required: true
+ pattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1][0-9]|[2][0-9]))$
+ title: Public Subnet CIDR Block in Prod Hub
+ prod_hub_private_subnet_cidr_block:
+ type: string
+ default: "10.1.2.0/24"
+ description: "Private subnet CIDR block in Prod Hub"
+ required: true
+ pattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1][0-9]|[2][0-9]))$
+ title: Private Subnet CIDR Block in Prod Hub
+ prod_spoke_vcn_cidr:
+ type: string
+ default: "10.2.0.0/16"
+ description: "Vcn CIDR block in Prod Spoke"
+ required: true
+ pattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1][0-9]|[2][0-9]))$
+ title: Vcn CIDR Block in Prod Spoke
+ prod_spoke_subnet_web_cidr_block:
+ type: string
+ default: "10.2.1.0/24"
+ description: "Web subnet CIDR block in Prod Spoke"
+ required: true
+ pattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1][0-9]|[2][0-9]))$
+ title: Web Subnet CIDR Block in Prod Spoke
+ prod_spoke_subnet_app_cidr_block:
+ type: string
+ default: "10.2.2.0/24"
+ description: "App subnet CIDR block in Prod Spoke"
+ required: true
+ pattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1][0-9]|[2][0-9]))$
+ title: App Subnet CIDR Block in Prod Spoke
+ prod_spoke_subnet_db_cidr_block:
+ default: "10.2.3.0/24"
+ type: string
+ description: "Database subnet CIDR block in Prod Spoke"
+ required: true
+ pattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1][0-9]|[2][0-9]))$
+ title: Database Subnet CIDR Block in Prod Spoke
+
+ # Network Extension Variables
+ enable_vpn_or_fastconnect:
+ type: enum
+ description: "Enable VPN or FASTCONNECT. Options: NONE, VPN, FASTCONNECT"
+ enum:
+ - "NONE"
+ - "VPN"
+ - "FASTCONNECT"
+ required: false
+ default: "NONE"
+ title: Enable VPN or Fastconnect
+ prod_enable_vpn:
+ type: boolean
+ description: "Enable VPN in prod environment"
+ required: false
+ default: false
+ visible: show_vpn_variables
+ title: Enable VPN in Prod
diff --git a/templates/freetrial-landing-zone/security.tf b/templates/freetrial-landing-zone/security.tf
new file mode 100644
index 00000000..56c6f899
--- /dev/null
+++ b/templates/freetrial-landing-zone/security.tf
@@ -0,0 +1,177 @@
+locals {
+ cloud_guard_policy = {
+ name = "${var.resource_label}-OCI-ELZ-CG-Policy"
+ description = "OCI Enterprise Landing Zone Cloud Guard Policy"
+
+ statements = [
+ "Allow service cloudguard to read vaults in tenancy",
+ "Allow service cloudguard to read keys in tenancy",
+ "Allow service cloudguard to read compartments in tenancy",
+ "Allow service cloudguard to read tenancies in tenancy",
+ "Allow service cloudguard to read audit-events in tenancy",
+ "Allow service cloudguard to read compute-management-family in tenancy",
+ "Allow service cloudguard to read instance-family in tenancy",
+ "Allow service cloudguard to read virtual-network-family in tenancy",
+ "Allow service cloudguard to read volume-family in tenancy",
+ "Allow service cloudguard to read database-family in tenancy",
+ "Allow service cloudguard to read object-family in tenancy",
+ "Allow service cloudguard to read load-balancers in tenancy",
+ "Allow service cloudguard to read users in tenancy",
+ "Allow service cloudguard to read groups in tenancy",
+ "Allow service cloudguard to read policies in tenancy",
+ "Allow service cloudguard to read dynamic-groups in tenancy",
+ "Allow service cloudguard to read authentication-policies in tenancy",
+ "Allow service cloudguard to use network-security-groups in tenancy",
+ "Allow service cloudguard to read data-safe-family in tenancy",
+ "Allow service cloudguard to read autonomous-database-family in tenancy",
+ "Allow service cloudguard to manage cloudevents-rules in tenancy where target.rule.type='managed'"
+ ]
+ }
+
+ cloud_guard_target_policy = {
+ name = "${var.resource_label}-OCI-ELZ-CGTarget-Policy"
+ description = "OCI Enterprise Landing Zone Cloud Guard Target Policy"
+
+ statements = var.cloud_guard_target_tenancy ? [
+ "Allow service cloudguard to manage instance-family in tenancy",
+ "Allow service cloudguard to manage object-family in tenancy",
+ "Allow service cloudguard to manage buckets in tenancy",
+ "Allow service cloudguard to manage users in tenancy",
+ "Allow service cloudguard to manage policies in tenancy",
+ "Allow service cloudguard to manage keys in tenancy"
+ ] : [
+ "Allow service cloudguard to manage instance-family in compartment ${var.home_compartment_name}",
+ "Allow service cloudguard to manage object-family in compartment ${var.home_compartment_name}",
+ "Allow service cloudguard to manage buckets in compartment ${var.home_compartment_name}",
+ "Allow service cloudguard to manage users in compartment ${var.home_compartment_name}",
+ "Allow service cloudguard to manage policies in compartment ${var.home_compartment_name}",
+ "Allow service cloudguard to manage keys in compartment ${var.home_compartment_name}"
+ ]
+ }
+
+ vss_policy = {
+ name = "${var.resource_label}-OCI-ELZ-VSS-Policy"
+ description = "OCI Enterprise Landing Zone VSS Policy"
+
+ statements = [
+ "Allow service vulnerability-scanning-service to manage instances in compartment ${var.home_compartment_name}",
+ "Allow service vulnerability-scanning-service to read compartments in compartment ${var.home_compartment_name}",
+ "Allow service vulnerability-scanning-service to read vnics in compartment ${var.home_compartment_name}",
+ "Allow service vulnerability-scanning-service to read vnic-attachments in compartment ${var.home_compartment_name}"
+ ]
+ }
+
+ vault_policy = {
+ name = "${var.resource_label}-OCI-ELZ-Vault-Policy"
+ description = "OCI Enterprise Landing Zone Vault Policy"
+ statements = [
+ "Allow service keymanagementservice to manage vaults in compartment ${var.home_compartment_name}"
+ ]
+ }
+
+ osms_dynamic_group = {
+ dynamic_group_name = "${var.resource_label}-OCI-ELZ-DG"
+ dynamic_group_description = "OCI ELZ Dynamic Group"
+
+ general_matching_rule = < 0]
+ ) == length(var.prod_network_topic_endpoints)
+ error_message = "Validation failed: invalid email address."
+ }
+}
+
+variable "prod_secops_topic_endpoints" {
+ type = list(string)
+ default = []
+ description = "List of email addresses for Secops Warning and Critical notifications."
+ validation {
+ condition = length(
+ [for e in var.prod_secops_topic_endpoints :
+ e if length(regexall("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$", e)) > 0]
+ ) == length(var.prod_secops_topic_endpoints)
+ error_message = "Validation failed: invalid email address."
+ }
+}
+
+variable "prod_platform_topic_endpoints" {
+ type = list(string)
+ default = []
+ description = "List of email addresses for Platform notifications."
+ validation {
+ condition = length(
+ [for e in var.prod_platform_topic_endpoints :
+ e if length(regexall("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$", e)) > 0]
+ ) == length(var.prod_platform_topic_endpoints)
+ error_message = "Validation failed: invalid email address."
+ }
+}
+
+variable "prod_identity_topic_endpoints" {
+ type = list(string)
+ default = []
+ description = "List of email addresses for Identity notifications."
+ validation {
+ condition = length(
+ [for e in var.prod_identity_topic_endpoints :
+ e if length(regexall("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$", e)) > 0]
+ ) == length(var.prod_identity_topic_endpoints)
+ error_message = "Validation failed: invalid email address."
+ }
+}
+variable "prod_workload_topic_endpoints" {
+ type = list(string)
+ default = []
+ description = "List of email addresses for Prod Workload notifications."
+ validation {
+ condition = length(
+ [for e in var.prod_workload_topic_endpoints :
+ e if length(regexall("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$", e)) > 0]
+ ) == length(var.prod_workload_topic_endpoints)
+ error_message = "Validation failed: invalid email address."
+ }
+}
+
+variable "is_create_alarms" {
+ type = bool
+ default = false
+ description = "Enable Alarms Creation in all Compartment"
+}
+variable "prod_enable_security_monitoring_alarms" {
+ type = bool
+ default = false
+ description = "Enable Security Monitoring Alarms in Production Security Compartment"
+}
+variable "prod_enable_network_monitoring_alarms" {
+ type = bool
+ default = false
+ description = "Enable Network Monitoring Alarms in Production Network Compartment"
+}
+variable "prod_enable_workload_monitoring_alarms" {
+ type = bool
+ default = false
+ description = "Enable Workload Monitoring Alarms in Production Workload Compartment"
+}
+# -----------------------------------------------------------------------------
+# Workload Network Variables
+# -----------------------------------------------------------------------------
+variable "prod_additional_workload_subnets_cidr_blocks" {
+ type = list(string)
+ default = []
+ description = "A list of subnets cidr blocks in additional workload stack in prod"
+}
\ No newline at end of file
diff --git a/test/TestCompartmentModule1.py b/test/TestCompartmentModule1.py
deleted file mode 100755
index 3c307047..00000000
--- a/test/TestCompartmentModule1.py
+++ /dev/null
@@ -1,162 +0,0 @@
-import oci
-from oci.config import from_file
-import pytest
-import sys
-
-# Get Ocid From the Compartment Name
-def getOcidFromCompName (compartmentName, compartmentData):
- thiscompartment=[comp for comp in compartmentData if comp.name==compartmentName][0]
- return thiscompartment.id
-
-# Get all the Children Compartment Inside the Compartment
-def getCompTree (compartmentId):
- list_compartments_response = identity_client.list_compartments(
- compartment_id=compartmentId,
- compartment_id_in_subtree=True)
- return list_compartments_response.data
-
-# Check the Compartment Name Exist the Compartment Tree
-def checkCompInData (compartmentName, compartmentData):
- thiscompartment=[comp for comp in compartmentData if comp.name==compartmentName][0]
- return "True" if thiscompartment else "False"
-
-# Create Compartment
-def createCompartment (rootCompartmentOcid, compartmentName, compartmentDescription):
- createCompartmentOcidResponse = identity_client.CreateCompartmentDetails(
- compartment_id = rootCompartmentOcid,
- name = compartmentName,
- description = compartmentDescription
- )
- return createCompartmentOcidResponse.data.id
-
-# Delete Compartment
-def deleteCompartment (compartmentOcid):
- deleteCompartmentOcidResponse = identity_client.delete_compartment(
- compartment_id=compartmentId
- )
-
-def checkL1CompName:
- compartmentlist = getCompTree(rootCompId)
- returnFlag = checkCompInData("L1CompName", compartmentlist)
- if returnFlag:
- print ("Found L1 Compartment Inside the Root compartment")
- else:
- print ("Not Found L1 Compartment Inside the Root compartment")
- sys.exit()
-
-def checkL2ProdCompName:
- compartmentlist = getCompTree(l1OcidValue)
- returnFlag = checkCompInData("L2CompProdName", compartmentlist)
- if returnFlag:
- print ("Found L2 Prod Compartment Inside the L1 compartment")
- else:
- print ("Not Found L2 Prod Compartment Inside the L1 compartment")
- sys.exit()
-
-def checkL2NonProdCompName:
- compartmentlist = getCompTree(l1OcidValue)
- returnFlag = checkCompInData("L2CompNonProdName", compartmentlist)
- if returnFlag:
- print ("Found L2 Non Prod Compartment Inside the L1 compartment")
- else:
- print ("Not Found L2 Non Prod Compartment Inside the L1 compartment")
- sys.exit()
-
-def checkL2Prodcheck(compartmentName):
- compartmentlist = getCompTree(l2ProdOcidValue)
- returnFlag = checkCompInData(compartmentName, compartmentlist)
- if returnFlag:
- print ("Found New L3 Network Compartment Inside the L2 Prod compartment")
- else:
- print ("Not Found New L3 Network Compartment Inside the L2 Prod compartment")
- sys.exit()
-
-def checkCompInsideProdEnv:
- compartmentlist = getCompTree(l2ProdOcidValue)
- returnFlag = checkCompInData("L3CompNameProd", compartmentlist)
- if returnFlag:
- print ("Found L3 Compartment Inside the L2 Prod compartment")
- else:
- print ("Not Found L3 Compartment Inside the L2 Prod compartment")
- sys.exit()
-
- returnFlag = checkCompInData("L4CompNameProd", compartmentlist)
- if returnFlag:
- print ("Found L4 Compartment Inside the L2 Prod compartment")
- else:
- print ("Not Found L4 Compartment Inside the L2 Prod compartment")
- sys.exit()
-
-def checkCompInsideNonProdEnv:
- compartmentlist = getCompTree(l2NonProdOcidValue)
- returnFlag = checkCompInData("L3CompNameNonProd", compartmentlist)
- if returnFlag:
- print ("Found L3 Compartment Inside the L2 Non Prod compartment")
- else:
- print ("Not Found L3 Compartment Inside the L2 Non Prod compartment")
- sys.exit()
-
- returnFlag = checkCompInData("L4CompNameNonProd", compartmentlist)
-
- if returnFlag:
- print ("Found L4 Compartment Inside the L2 Non Prod compartment")
- else:
- print ("Not Found L4 Compartment Inside the L2 Non Prod compartment")
- sys.exit()
-
-# Config file is read from user's home location i.e., ~/.oci/config
-config = from_file()
-
-rootCompId="ocid1.tenancy.oc1..aaaaaaaaxbchsnzhdxyoewmoqiqzvltba2ri7gijhbd2z5ybpgorv7yhxeeq" # root compartment OCID
-
-#L1CompName =
-#L2CompProdName =
-#L2CompNonProdName
-#L3CompNameProdSharedInfra=
-#L4CompNameProdNetwork =
-#L4CompNameProdSecurity =
-#L3CompNameNonProd =
-#L4CompNameNonProdNetwork =
-#L4CompNameNonProdSecurity =
-
-# Please fill up the following Information
-#config_with_key_file = {
-# "user": ,
-# "key_file": ,
-# "fingerprint": ,
-# "tenancy": ,
-# "region":
-#}
-
-oci.config.validate_config(config_with_key_file)
-identity_client = oci.identity.IdentityClient(config)
-
-# Get the list of compartments including child compartments except root compartment
-compartmentlist = getCompTree(rootCompId)
-
-# Get the OCID From the Compartment Name
-l1OcidValue = getOcidFromCompName(L1CompName)
-l2ProdOcidValue = getOcidFromCompName(L2CompProdName)
-
-l2NonProdOcidValue = getOcidFromCompName(L2CompNonProdName)
-l4ProdNetworkOcid = getOcidFromCompName(L4CompNameProdNetwork)
-l2ProdSharedInfraOcid = getOcidFromCompName(L3CompNameProdSharedInfra)
-
-# Check the Compartment Module Usecase
-checkL1CompName()
-checkL2ProdCompName()
-checkL2NonProdCompName()
-checkCompInsideProdEnv()
-checkCompInsideNonProdEnv()
-
-# LANZ-902 : Delete the previous compartment and create new with different Name
-
-deleteCompartment(l4ProdNetworkOcid)
-newL3NetworkCompName = "L3ProdSharedNetwork"
-newl4ProdNetworkOcid = createCompartment(l2ProdSharedInfraOcid, newL3NetworkCompName, "L3 Prod Shared Network Compartment")
-checkL2Prodcheck(newL3NetworkCompName)
-
-
-
-
-
diff --git a/test/terraform/budget/terraform.tfvars.example b/test/terraform/budget/terraform.tfvars.example
deleted file mode 100644
index 38e4ad2f..00000000
--- a/test/terraform/budget/terraform.tfvars.example
+++ /dev/null
@@ -1,6 +0,0 @@
-environment_prefix = "P"
-enable_budget = true
-budget_amount = "10000"
-budget_alert_rule_threshold = "100"
-budget_alert_rule_message = "testing prod"
-budget_alert_rule_recipients = "example@example.com"
diff --git a/test/terraform/budget/variables.tf b/test/terraform/budget/variables.tf
index 2f0b4343..b5cb9f16 100644
--- a/test/terraform/budget/variables.tf
+++ b/test/terraform/budget/variables.tf
@@ -1,18 +1,18 @@
variable "environment_prefix" {
type = string
description = "the 1 character string representing the environment eg. P (prod), N (non-prod), D, T, U"
- default = "P"
+ default = "T"
}
variable "enable_budget" {
- type = bool
+ type = bool
default = true
}
variable "budget_amount" {
description = "The amount of the budget expressed as a whole number in the currency of the customer's rate card."
type = string
- default = "10000"
+ default = "100000"
}
variable "budget_alert_rule_threshold" {
diff --git a/test/terraform/compartment/main.tf b/test/terraform/compartment/main.tf
new file mode 100644
index 00000000..2be9b9b7
--- /dev/null
+++ b/test/terraform/compartment/main.tf
@@ -0,0 +1,35 @@
+locals {
+ home_compartment = {
+ description = "Enterprise Landing Zone Home Compartment"
+ }
+}
+
+module "home_compartment" {
+ source = "../../../modules/compartment"
+
+ compartment_parent_id = var.tenancy_ocid
+ compartment_name = var.home_compartment_name
+ compartment_description = local.home_compartment.description
+ enable_compartment_delete = var.enable_compartment_delete
+
+ providers = {
+ oci = oci.home_region
+ }
+}
+
+module "compartment" {
+ source = "../../../templates/elz-compartment"
+ tenancy_ocid = var.tenancy_ocid
+ region = var.region
+ environment_prefix = var.environment_prefix
+ enable_compartment_delete = var.enable_compartment_delete
+ home_compartment_id = module.home_compartment.compartment_id # changed
+ environment_compartment_name = var.environment_compartment_name
+ enable_tf_state_backup = var.enable_tf_state_backup
+ enable_logging = var.enable_logging
+
+ providers = {
+ oci = oci
+ oci.home_region = oci.home_region
+ }
+}
diff --git a/test/terraform/compartment/outputs.tf b/test/terraform/compartment/outputs.tf
new file mode 100644
index 00000000..b08600fa
--- /dev/null
+++ b/test/terraform/compartment/outputs.tf
@@ -0,0 +1,7 @@
+output "compartment" {
+ value = module.compartment.compartments
+}
+
+output "home_compartment_id" {
+ value = module.home_compartment.compartment_id
+}
\ No newline at end of file
diff --git a/test/terraform/compartment/variables.tf b/test/terraform/compartment/variables.tf
new file mode 100644
index 00000000..054f44e4
--- /dev/null
+++ b/test/terraform/compartment/variables.tf
@@ -0,0 +1,38 @@
+variable "home_compartment_name" {
+ type = string
+ default = "OCI-ELZ-CMP-HOME-TEST"
+ description = "The name of the Landing Zone home compartment."
+}
+
+variable "enable_compartment_delete" {
+ type = bool
+ description = "Set to true to allow the compartments to delete on terraform destroy."
+ default = true
+}
+
+#
+variable "environment_prefix" {
+ type = string
+ description = "the 1 character string representing the environment eg. P (prod), N (non-prod), D, T, U"
+ default = "T"
+}
+
+#
+variable "environment_compartment_name" {
+ type = string
+ description = "The name of the compartment that acts as the main compartment for the environment. Resources related to this environment will be created under this compartment. "
+ default = ""
+}
+
+variable "enable_tf_state_backup" {
+ type = bool
+ description = "Set to true to enable logging compartment which contains the bucket for the log files."
+ default = false
+}
+
+variable "enable_logging" {
+ type = bool
+ description = "Set to true to enable logging compartment which stores the configuration information that landing zones is setting up for the customer."
+ default = true
+ # default = false
+}
diff --git a/test/terraform/network/main.tf b/test/terraform/network/main.tf
index 043ebe88..d14cecd2 100644
--- a/test/terraform/network/main.tf
+++ b/test/terraform/network/main.tf
@@ -89,10 +89,9 @@ module "network" {
igw_hub_check = [""]
service_gw_spoke_check = [""]
-
- workload_compartment_name = local.workload_compartment_name
workload_compartment_id = module.workload_compartment.compartment_id
- network_compartment_name = local.network_compartment_name
+ additional_workload_subnets_cidr_blocks = var.additional_workload_subnets_cidr_blocks
+ workload_compartment_name = local.workload_compartment_name
providers = {
oci = oci
diff --git a/test/terraform/network/variables.tf b/test/terraform/network/variables.tf
index c71309d4..0f593747 100644
--- a/test/terraform/network/variables.tf
+++ b/test/terraform/network/variables.tf
@@ -76,4 +76,9 @@ variable "private_spoke_subnet_db_cidr_block" {
variable "spoke_vcn_cidr" {
type = string
default = "10.1.0.0/16"
+}
+
+variable "additional_workload_subnets_cidr_blocks" {
+ type = list(string)
+ default = []
}
\ No newline at end of file
diff --git a/test/test_budget.py b/test/test_budget.py
index fbbd6c06..f4aa23db 100644
--- a/test/test_budget.py
+++ b/test/test_budget.py
@@ -1,33 +1,35 @@
from pytest_terraform import terraform
import pytest
-#unit tests for budget module
-@pytest.mark.skip(reason="Budget tests currently broken, due to 404 error. We need to fix this.")
+# unit tests for budget module
@pytest.mark.unit
@terraform("budget", scope="session")
def test_oci_budget_target_name(budget):
print(budget)
- # actual_budget_target_name = budget["oci_budget_budget.oci_budget.display_name"]
- # expected_budget_target_name = "budget-test-target-name-budget"
- # assert actual_budget_target_name == expected_budget_target_name
+ actual_budget_target_name = budget["oci_budget_budget.oci_budget.display_name"]
+ expected_budget_target_name = "OCI-ELZ-BGT-T"
+ assert actual_budget_target_name == expected_budget_target_name
-# @pytest.mark.unit
-# @terraform("budget", scope="session")
-# def test_oci_budget_amount(budget):
-# actual_budget_amount = budget["oci_budget_budget.oci_budget.amount"]
-# expected_budget_amount = 100000
-# assert actual_budget_amount == expected_budget_amount
-# @pytest.mark.unit
-# @terraform("budget", scope="session")
-# def test_oci_budget_alert_rule_threshold(budget):
-# actual_budget_alert_rule_threshold = budget["oci_budget_alert_rule.oci_budget_rule.threshold"]
-# expected_budget_alert_rule_threshold = 100
-# assert actual_budget_alert_rule_threshold == expected_budget_alert_rule_threshold
+@pytest.mark.unit
+@terraform("budget", scope="session")
+def test_oci_budget_amount(budget):
+ actual_budget_amount = budget["oci_budget_budget.oci_budget.amount"]
+ expected_budget_amount = 100000
+ assert actual_budget_amount == expected_budget_amount
+
-# @pytest.mark.unit
-# @terraform("budget", scope="session")
-# def test_oci_budget_alert_rule_recipients(budget):
-# actual_budget_alert_rule_recipients = budget["oci_budget_alert_rule.oci_budget_rule.recipients"]
-# expected_budget_alert_rule_recipients = "example@test.com"
-# assert actual_budget_alert_rule_recipients == expected_budget_alert_rule_recipients
+@pytest.mark.unit
+@terraform("budget", scope="session")
+def test_oci_budget_alert_rule_threshold(budget):
+ actual_budget_alert_rule_threshold = budget["oci_budget_alert_rule.oci_budget_rule.threshold"]
+ expected_budget_alert_rule_threshold = 100
+ assert actual_budget_alert_rule_threshold == expected_budget_alert_rule_threshold
+
+
+@pytest.mark.unit
+@terraform("budget", scope="session")
+def test_oci_budget_alert_rule_recipients(budget):
+ actual_budget_alert_rule_recipients = budget["oci_budget_alert_rule.oci_budget_rule.recipients"]
+ expected_budget_alert_rule_recipients = "example@example.com"
+ assert actual_budget_alert_rule_recipients == expected_budget_alert_rule_recipients
diff --git a/test/test_compartment.py b/test/test_compartment.py
new file mode 100644
index 00000000..6f1bd12d
--- /dev/null
+++ b/test/test_compartment.py
@@ -0,0 +1,104 @@
+from pytest_terraform import terraform
+import pytest
+import oci
+
+from test_helpers.oci import get_test_config
+
+
+# Deploy compartments module with all input variables changed to a custom value
+# Validate the compartment structure
+@pytest.mark.skip(reason="Compartment delete too slow")
+@pytest.mark.unit
+@terraform("compartment", scope="session")
+def test_l1_compartment_create(compartment):
+ config = get_test_config()
+ identity_client = oci.identity.IdentityClient(config)
+
+ out_parent_cmp_id = compartment.outputs["home_compartment_id"]["value"]
+ out_env_cmp_id = compartment.outputs["compartment"]["value"]["environment"]["id"]
+ env_prefix = "T"
+ region_key = "IAD"
+
+ env_cmp_name = f"OCI-ELZ-{env_prefix}-CMP"
+ env_cmps_response = identity_client.list_compartments(
+ compartment_id=out_parent_cmp_id,
+ name=env_cmp_name
+ )
+
+ # assert api found cmp tree match
+ assert len(env_cmps_response.data) > 0
+ env_cmp_id = env_cmps_response.data[0].id
+
+ # assert output matches actual api output
+ assert out_env_cmp_id == env_cmp_id
+
+@pytest.mark.skip(reason="Compartment delete too slow")
+@pytest.mark.unit
+@terraform("compartment", scope="session")
+def test_l2_compartment_create(compartment):
+ config = get_test_config()
+ identity_client = oci.identity.IdentityClient(config)
+
+ env_prefix = "T"
+ region_key = "IAD"
+ out_env_cmp_id = compartment.outputs["compartment"]["value"]["environment"]["id"]
+ out_shared_cmp_id = compartment.outputs["compartment"]["value"]["shared"]["id"]
+ out_log_cmp_id = compartment.outputs["compartment"]["value"]["logging"]["id"]
+
+ log_cmp_name = f"OCI-ELZ-{env_prefix}-LOG-{region_key}"
+ log_cmps_response = identity_client.list_compartments(
+ compartment_id=out_env_cmp_id,
+ name=log_cmp_name
+ )
+ assert len(log_cmps_response.data) > 0
+ log_cmp_id = log_cmps_response.data[0].id
+ assert out_log_cmp_id == log_cmp_id
+
+ shared_cmp_name = f"OCI-ELZ-{env_prefix}-SRD-CMP-{region_key}"
+ shared_cmps_response = identity_client.list_compartments(
+ compartment_id=out_env_cmp_id,
+ name=shared_cmp_name
+ )
+ assert len(shared_cmps_response.data) > 0
+ shared_cmp_id = shared_cmps_response.data[0].id
+ assert out_shared_cmp_id == shared_cmp_id
+
+ # # workload is created in environment template not compartment template
+ # workload_cmp_name = f"OCI-ELZ-{env_prefix}-Workload1-{region_key}"
+ # workload_cmps_response = identity_client.list_compartments(
+ # compartment_id=out_env_cmp_id,
+ # name=workload_cmp_name
+ # )
+ # assert len(workload_cmps_response.data) > 0
+ # workload_cmp_id = workload_cmps_response.data[0].id
+
+@pytest.mark.skip(reason="Compartment delete too slow")
+@pytest.mark.unit
+@terraform("compartment", scope="session")
+def test_l3_compartment_create(compartment):
+ config = get_test_config()
+ identity_client = oci.identity.IdentityClient(config)
+
+ env_prefix = "T"
+ region_key = "IAD"
+ out_shared_cmp_id = compartment.outputs["compartment"]["value"]["shared"]["id"]
+ out_net_cmp_id = compartment.outputs["compartment"]["value"]["network"]["id"]
+ out_security_cmp_id = compartment.outputs["compartment"]["value"]["security"]["id"]
+
+ security_cmp_name = f"OCI-ELZ-{env_prefix}-SRD-SEC"
+ security_cmps_response = identity_client.list_compartments(
+ compartment_id=out_shared_cmp_id,
+ name=security_cmp_name
+ )
+ assert len(security_cmps_response.data) > 0
+ security_cmp_id = security_cmps_response.data[0].id
+ assert security_cmp_id == out_security_cmp_id
+
+ net_cmp_name = f"OCI-ELZ-{env_prefix}-SRD-NET"
+ net_cmps_response = identity_client.list_compartments(
+ compartment_id=out_shared_cmp_id,
+ name=net_cmp_name
+ )
+ assert len(net_cmps_response.data) > 0
+ net_cmp_id = net_cmps_response.data[0].id
+ assert net_cmp_id == out_net_cmp_id