" # It defaults to tenancy home region if undefined.
security_zones = {
SECURITY-ZONE = {
diff --git a/security-zones/examples/vision/main.tf b/security-zones/examples/vision/main.tf
index ab9046e..f717beb 100644
--- a/security-zones/examples/vision/main.tf
+++ b/security-zones/examples/vision/main.tf
@@ -3,5 +3,6 @@
module "vision_security_zones" {
source = "github.com/oracle-quickstart/terraform-oci-cis-landing-zone-security/security_zones"
+ tenancy_ocid = var.tenancy_ocid
security_zones_configuration = var.security_zones_configuration
}
diff --git a/security-zones/main.tf b/security-zones/main.tf
index b0ba483..bd98bc5 100644
--- a/security-zones/main.tf
+++ b/security-zones/main.tf
@@ -24,18 +24,16 @@ locals {
# "ocid1.securityzonessecuritypolicy.oc1..aaaaaaaaff6n52aojbgdg46jpm3kn7nizmh6iwvr7myez7svtfxsfs7irigq"
is_cloud_guard_enabled = data.oci_cloud_guard_cloud_guard_configuration.this.status == "ENABLED" ? true : length(oci_cloud_guard_cloud_guard_configuration.this) > 0 ? (oci_cloud_guard_cloud_guard_configuration.this[0].status == "ENABLED" ? true : false) : false
+
+ regions_map = { for r in data.oci_identity_regions.these.regions : r.key => r.name } # All regions indexed by region key.
+ home_region_key = data.oci_identity_tenancy.this.home_region_key # Home region key obtained from the tenancy data source
+ home_region = local.regions_map[local.home_region_key]
}
resource "oci_cloud_guard_cloud_guard_configuration" "this" {
- lifecycle {
- precondition {
- condition = data.oci_cloud_guard_cloud_guard_configuration.this.status == "ENABLED" ? true : var.security_zones_configuration.reporting_region != null ? true : false
- error_message = "VALIDATION FAILURE: reporting_region must be provided when enabling Cloud Guard."
- }
- }
count = data.oci_cloud_guard_cloud_guard_configuration.this.status == "DISABLED" ? 1 : 0 # we only manage this resource if Cloud Guard is currently disabled, which means we have to enable it.
- compartment_id = var.security_zones_configuration.tenancy_ocid
- reporting_region = var.security_zones_configuration.reporting_region
+ compartment_id = var.tenancy_ocid
+ reporting_region = coalesce(var.security_zones_configuration.reporting_region, local.home_region)
status = "ENABLED"
self_manage_resources = var.security_zones_configuration.self_manage_resources != null ? (var.security_zones_configuration.self_manage_resources == true ? true : false) : false
}
diff --git a/security-zones/variables.tf b/security-zones/variables.tf
index 12d6e08..37614de 100644
--- a/security-zones/variables.tf
+++ b/security-zones/variables.tf
@@ -4,7 +4,6 @@
variable "security_zones_configuration" {
description = "Security Zones configuration."
type = object({
- tenancy_ocid = string # The tenancy OCID
default_cis_level = optional(string) # The default CIS level for all recipes with an unspecified cis_level. Valid values: "1" and "2". Default: "1"
default_security_policies_ocids = optional(list(string)) # The list of default Security Zone policies OCIDs for all recipes with an unspecified security_policies_ocids. These are merged with CIS Security Zone policies driven off cis_level.
default_defined_tags = optional(map(string))
@@ -34,6 +33,11 @@ variable "security_zones_configuration" {
default = null
}
+variable "tenancy_ocid" {
+ description = "The tenancy OCID."
+ type = string
+}
+
variable compartments_dependency {
description = "A map of objects containing the externally managed compartments this module may depend on. All map objects must have the same type and must contain at least an 'id' attribute (representing the compartment OCID) of string type."
type = map(object({
diff --git a/vaults/SPEC.md b/vaults/SPEC.md
index 51af6b1..e1033c6 100644
--- a/vaults/SPEC.md
+++ b/vaults/SPEC.md
@@ -24,6 +24,7 @@ No modules.
| [oci_kms_key.these](https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/kms_key) | resource |
| [oci_kms_key_version.these](https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/kms_key_version) | resource |
| [oci_kms_vault.these](https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/kms_vault) | resource |
+| [oci_kms_vault_replication.these](https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/kms_vault_replication) | resource |
| [oci_identity_compartment.existing_keys](https://registry.terraform.io/providers/oracle/oci/latest/docs/data-sources/identity_compartment) | data source |
| [oci_identity_compartment.managed_keys](https://registry.terraform.io/providers/oracle/oci/latest/docs/data-sources/identity_compartment) | data source |
@@ -34,7 +35,7 @@ No modules.
| [compartments\_dependency](#input\_compartments\_dependency) | A map of objects containing the externally managed compartments this module may depend on. All map objects must have the same type and must contain at least an 'id' attribute (representing the compartment OCID) of string type. | map(object({
id = string # the compartment OCID
}))
| `null` | no |
| [enable\_output](#input\_enable\_output) | Whether Terraform should enable module output. | `bool` | `true` | no |
| [module\_name](#input\_module\_name) | The module name. | `string` | `"vaults"` | no |
-| [vaults\_configuration](#input\_vaults\_configuration) | Vaults configuration settings, defining all aspects to manage vaults and keys in OCI. Please see the comments within each attribute for details. | object({
default_compartment_id = string, # the default compartment where all resources are defined. It's overriden by the compartment_id attribute within vaults and keys attributes. It can be either a compartment OCID or a reference (a key) to the compartment OCID.
default_defined_tags = optional(map(string)), # the default defined tags. It's overriden by the defined_tags attribute within each object.
default_freeform_tags = optional(map(string)), # the default freeform tags. It's overriden by the frreform_tags attribute within each object.
vaults = optional(map(object({ # the vaults to manage in this configuration.
compartment_id = optional(string) # the compartment where the vault is created. default_compartment_id is used if undefined. It can be either a compartment OCID or a reference (a key) to the compartment OCID.
name = string # vault name.
type = optional(string) # vault type. Default is "DEFAULT", a regular virtual vault, in shared HSM partition. For an isolated partition, use "VIRTUAL_PRIVATE".
defined_tags = optional(map(string)) # vault defined_tags. default_defined_tags is used if undefined.
freeform_tags = optional(map(string)) # vault freeform_tags. default_freeform_tags is used if undefined.
})))
keys = optional(map(object({
compartment_id = optional(string) # the compartment where the key is created. The vault compartment_id is used if undefined. It can be either a compartment OCID or a reference (a key) to the compartment OCID.
name = string # key name.
vault_key = optional(string) # the index name (key) in the vaults attribute where this key belongs to.
vault_management_endpoint = optional(string) # the vault management endpoint where this key belongs to. If provided, this value takes precedence over vault_key. Use this attribute to add this key to a Vault that is managed elsewhere. It can be assigned either a literal endpoint URL or a reference (a key) to an endpoint URL.
algorithm = optional(string) # key encryption algorithm. Valid values: "AES", "RSA", and "ECDSA". Defaults is "AES".
length = optional(number) # key length in bytes. "AES" lengths: 16, 24, 32. "RSA" lengths: 256, 384, 512. ECDSA lengths: 32, 48, 66. Default is 32.
curve_id = optional(string) # curve id for "ECDSA" keys.
protection_mode = optional(string) # indicates how the key is persisted and where crypto operations are performed. Valid values: "HSM" and "SOFTWARE". Default is "HSM".
service_grantees = optional(list(string)) # the OCI service names allowed to use the key.
group_grantees = optional(list(string)) # the IAM group names allowed to use the key-delegate.
defined_tags = optional(map(string)) # key freeform_tags. The vault freeform_tags is used if undefined.
freeform_tags = optional(map(string)) # key freeform_tags. The vault freeform_tags is used if undefined.
versions = optional(list(string)) # a list of strings representing key versions. Use this to rotate keys.
})))
existing_keys_grants = optional(map(object({ # Use this attribute to create IAM policies for existing keys if needed
key_id = string # the existing key. It can be either a key OCID or a reference (a key) to the key OCID.
compartment_id = string # the compartment of the existing key. It can be either a compartment OCID or a reference (a key) to the compartment OCID.
service_grantees = optional(list(string)) # the OCI service names allowed to use the key.
group_grantees = optional(list(string)) # the IAM group names allowed to use the key-delegate.
})))
})
| `null` | no |
+| [vaults\_configuration](#input\_vaults\_configuration) | Vaults configuration settings, defining all aspects to manage vaults and keys in OCI. Please see the comments within each attribute for details. | object({
default_compartment_id = string, # the default compartment where all resources are defined. It's overriden by the compartment_id attribute within vaults and keys attributes. It can be either a compartment OCID or a reference (a key) to the compartment OCID.
default_defined_tags = optional(map(string)), # the default defined tags. It's overriden by the defined_tags attribute within each object.
default_freeform_tags = optional(map(string)), # the default freeform tags. It's overriden by the frreform_tags attribute within each object.
vaults = optional(map(object({ # the vaults to manage in this configuration.
compartment_id = optional(string) # the compartment where the vault is created. default_compartment_id is used if undefined. It can be either a compartment OCID or a reference (a key) to the compartment OCID.
name = string # vault name.
type = optional(string) # vault type. Default is "DEFAULT", a regular virtual vault, in shared HSM partition. For an isolated partition, use "VIRTUAL_PRIVATE".
defined_tags = optional(map(string)) # vault defined_tags. default_defined_tags is used if undefined.
freeform_tags = optional(map(string)) # vault freeform_tags. default_freeform_tags is used if undefined.
replica_region = optional(string) # only available if the vault is a VPV (virtual private vault) and you want to replicate it to another region
})))
keys = optional(map(object({
compartment_id = optional(string) # the compartment where the key is created. The vault compartment_id is used if undefined. It can be either a compartment OCID or a reference (a key) to the compartment OCID.
name = string # key name.
vault_key = optional(string) # the index name (key) in the vaults attribute where this key belongs to.
vault_management_endpoint = optional(string) # the vault management endpoint where this key belongs to. If provided, this value takes precedence over vault_key. Use this attribute to add this key to a Vault that is managed elsewhere. It can be assigned either a literal endpoint URL or a reference (a key) to an endpoint URL.
algorithm = optional(string) # key encryption algorithm. Valid values: "AES", "RSA", and "ECDSA". Defaults is "AES".
length = optional(number) # key length in bytes. "AES" lengths: 16, 24, 32. "RSA" lengths: 256, 384, 512. ECDSA lengths: 32, 48, 66. Default is 32.
curve_id = optional(string) # curve id for "ECDSA" keys.
protection_mode = optional(string) # indicates how the key is persisted and where crypto operations are performed. Valid values: "HSM" and "SOFTWARE". Default is "HSM".
service_grantees = optional(list(string)) # the OCI service names allowed to use the key.
group_grantees = optional(list(string)) # the IAM group names allowed to use the key-delegate.
defined_tags = optional(map(string)) # key freeform_tags. The vault freeform_tags is used if undefined.
freeform_tags = optional(map(string)) # key freeform_tags. The vault freeform_tags is used if undefined.
versions = optional(list(string)) # a list of strings representing key versions. Use this to rotate keys.
})))
existing_keys_grants = optional(map(object({ # Use this attribute to create IAM policies for existing keys if needed
key_id = string # the existing key. It can be either a key OCID or a reference (a key) to the key OCID.
compartment_id = string # the compartment of the existing key. It can be either a compartment OCID or a reference (a key) to the compartment OCID.
service_grantees = optional(list(string)) # the OCI service names allowed to use the key.
group_grantees = optional(list(string)) # the IAM group names allowed to use the key-delegate.
})))
})
| `null` | no |
| [vaults\_dependency](#input\_vaults\_dependency) | A map of objects containing the externally managed vaults this module may depend on. All map objects must have the same type and must contain at least a 'management\_endpoint' attribute (representing the management endpoint URL) of string type. | map(object({
management_endpoint = string # the vault management endpoint URL.
}))
| `null` | no |
## Outputs
diff --git a/vaults/examples/vision/input.auto.tfvars.template b/vaults/examples/vision/input.auto.tfvars.template
index 544ba73..277f52e 100644
--- a/vaults/examples/vision/input.auto.tfvars.template
+++ b/vaults/examples/vision/input.auto.tfvars.template
@@ -29,6 +29,7 @@ vaults_configuration = {
vaults = {
VISION-VAULT = {
name = "vision-vault"
+ # replica_region = "" # available if your vault is a VPV (virtual private vault) and you want to replicate it to another region. for instance "us-phoenix-1", "us-ashburn-1"
}
}
keys = {
diff --git a/vaults/main.tf b/vaults/main.tf
index c6d8e25..5af6a9e 100644
--- a/vaults/main.tf
+++ b/vaults/main.tf
@@ -122,4 +122,12 @@ resource "oci_identity_policy" "existing_keys" {
each.value.group_grantees != null ? [for gg in each.value.group_grantees : "Allow group ${gg} to use key-delegate in compartment ${data.oci_identity_compartment.existing_keys[each.key].name} where target.key.id = '${length(regexall("^ocid1.*$", each.value.key_id)) > 0 ? each.value.key_id : var.vaults_dependency[each.value.key_id].id}'"] : [])
defined_tags = var.vaults_configuration.default_defined_tags
freeform_tags = merge(local.cislz_module_tag, var.vaults_configuration.default_freeform_tags)
-}
\ No newline at end of file
+}
+
+resource "oci_kms_vault_replication" "these" {
+ for_each = { for k, v in var.vaults_configuration != null ? var.vaults_configuration.vaults : {} : k => v
+ if v.replica_region != null
+ }
+ vault_id = oci_kms_vault.these[each.key].id
+ replica_region = each.value.replica_region
+}
diff --git a/vaults/variables.tf b/vaults/variables.tf
index 789ae3f..2ee1b38 100644
--- a/vaults/variables.tf
+++ b/vaults/variables.tf
@@ -15,6 +15,7 @@ variable "vaults_configuration" {
type = optional(string) # vault type. Default is "DEFAULT", a regular virtual vault, in shared HSM partition. For an isolated partition, use "VIRTUAL_PRIVATE".
defined_tags = optional(map(string)) # vault defined_tags. default_defined_tags is used if undefined.
freeform_tags = optional(map(string)) # vault freeform_tags. default_freeform_tags is used if undefined.
+ replica_region = optional(string) # only available if the vault is a VPV (virtual private vault) and you want to replicate it to another region
})))
keys = optional(map(object({
diff --git a/vss/examples/vss-cmp-composite/README.md b/vss/examples/vss-cmp-composite/README.md
new file mode 100644
index 0000000..2a7fc81
--- /dev/null
+++ b/vss/examples/vss-cmp-composite/README.md
@@ -0,0 +1,15 @@
+# CIS OCI Vulnerability Scanning Module Example - VSS/Compartments Composite
+
+## Introduction
+
+This example shows how to deploy Vulnerability Scanning resources in OCI using the [VSS module](https://github.com/oracle-quickstart/terraform-oci-cis-landing-zone-security/tree/main/vss). It deploys a sample compartment and the VSS resources in the same configuration. The intent here is showing how the output of the compartments module is used as an input in *scanning_configuration* variable. See in [main.tf](./main.tf) how both *compartments_configuration* and *scanning_configuration* variables are defined.
+
+## Using this example
+1. Rename *input.auto.tfvars.template* to *\.auto.tfvars*, where *\* is any name of your choice.
+
+2. Within *\.auto.tfvars*, provide tenancy connectivity information and run the typical Terraform workflow:
+```
+terraform init
+terraform plan -out plan.out
+terraform apply plan.out
+```
\ No newline at end of file
diff --git a/vss/examples/vss-cmp-composite/input.auto.tfvars.template b/vss/examples/vss-cmp-composite/input.auto.tfvars.template
new file mode 100644
index 0000000..92c1e68
--- /dev/null
+++ b/vss/examples/vss-cmp-composite/input.auto.tfvars.template
@@ -0,0 +1,18 @@
+# Copyright (c) 2024 Oracle and/or its affiliates.
+# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
+
+#--------------------------------------------------------------------------------------------------------------------------------------
+# 1. Rename this file to .auto.tfvars, where is a name of your choice.
+# 2. Provide values for "Tenancy Connectivity Variables".
+#--------------------------------------------------------------------------------------------------------------------------------------
+
+#---------------------------------------
+# Tenancy Connectivity Variables
+#---------------------------------------
+
+tenancy_ocid = "" # Get this from OCI Console (after logging in, go to top-right-most menu item and click option "Tenancy: ").
+user_ocid = "" # Get this from OCI Console (after logging in, go to top-right-most menu item and click option "My profile").
+fingerprint = "" # The fingerprint can be gathered from your user account. In the "My profile page, click "API keys" on the menu in left hand side.
+private_key_path = "" # This is the full path on your local system to the API signing private key.
+private_key_password = "" # This is the password that protects the private key, if any.
+region = "" # This is your region, where all other events are created. It can be the same as home_region.
\ No newline at end of file
diff --git a/vss/examples/vss-cmp-composite/main.tf b/vss/examples/vss-cmp-composite/main.tf
new file mode 100644
index 0000000..6255eca
--- /dev/null
+++ b/vss/examples/vss-cmp-composite/main.tf
@@ -0,0 +1,43 @@
+# Copyright (c) 2024 Oracle and/or its affiliates.
+# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
+
+locals {
+ compartments_configuration = {
+ enable_delete = true
+ compartments = {
+ TOP-CMP = {
+ parent_id = "TENANCY-ROOT"
+ name = "vss-cmp-composite-cmp",
+ description = "VSS cmp composite sample compartment"
+ }
+ }
+ }
+
+ scanning_configuration = {
+ default_compartment_id = module.compartments.compartments["TOP-CMP"].id
+ host_recipes = {
+ DEFAULT-RECIPE = {
+ name = "vss-cmp-composite-recipe"
+ }
+ }
+ host_targets = {
+ CMP-TARGET = {
+ name = "vss-cmp-composite-target"
+ target_compartment_id = module.compartments.compartments["TOP-CMP"].id
+ host_recipe_id = "DEFAULT-RECIPE"
+ }
+ }
+ }
+}
+
+module "compartments" {
+ source = "github.com/oracle-quickstart/terraform-oci-cis-landing-zone-iam/compartments"
+ tenancy_ocid = var.tenancy_ocid
+ compartments_configuration = local.compartments_configuration
+}
+
+module "vss" {
+ source = "../.."
+ scanning_configuration = local.scanning_configuration
+ enable_output = true
+}
\ No newline at end of file
diff --git a/vss/examples/vss-cmp-composite/outputs.tf b/vss/examples/vss-cmp-composite/outputs.tf
new file mode 100644
index 0000000..8e582b2
--- /dev/null
+++ b/vss/examples/vss-cmp-composite/outputs.tf
@@ -0,0 +1,6 @@
+# Copyright (c) 2024 Oracle and/or its affiliates.
+# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
+
+output "host_scanning_plugin_state" {
+ value = module.vss.host_scanning_plugin_state
+}
\ No newline at end of file
diff --git a/vss/examples/vss-cmp-composite/variables.tf b/vss/examples/vss-cmp-composite/variables.tf
new file mode 100644
index 0000000..4a0618f
--- /dev/null
+++ b/vss/examples/vss-cmp-composite/variables.tf
@@ -0,0 +1,9 @@
+# Copyright (c) 2024 Oracle and/or its affiliates.
+# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
+
+variable "tenancy_ocid" {}
+variable "region" {description = "Your tenancy region"}
+variable "user_ocid" {default = ""}
+variable "fingerprint" {default = ""}
+variable "private_key_path" {default = ""}
+variable "private_key_password" {default = ""}
\ No newline at end of file
diff --git a/vss/main.tf b/vss/main.tf
index 14a8e97..8bbf04e 100644
--- a/vss/main.tf
+++ b/vss/main.tf
@@ -98,15 +98,15 @@ resource "oci_vulnerability_scanning_container_scan_target" "these" {
}
locals {
- target_host_scan_cmps = var.scanning_configuration != null ? ([for t in (var.scanning_configuration.host_targets != null ? var.scanning_configuration.host_targets : {}) : length(regexall("^ocid1.*$", t.target_compartment_id)) > 0 ? t.target_compartment_id : var.compartments_dependency[t.target_compartment_id].id]) : []
+ target_host_scan_cmps = var.scanning_configuration != null ? ({for k,v in (var.scanning_configuration.host_targets != null ? var.scanning_configuration.host_targets : {}) : k => (length(regexall("^ocid1.*$", v.target_compartment_id)) > 0 ? v.target_compartment_id : var.compartments_dependency[v.target_compartment_id].id)}) : {}
instances = flatten([
- for cmp_id in local.target_host_scan_cmps : [
- for i in data.oci_core_instances.these[cmp_id].instances : [{"id" : i.id, "compartment_id" : i.compartment_id}]
+ for k, v in local.target_host_scan_cmps : [
+ for i in data.oci_core_instances.these[k].instances : [{"id" : i.id, "compartment_id" : i.compartment_id}]
]
])
vss_plugin_state = flatten([
- for cmp_id in local.target_host_scan_cmps : [
- for i in data.oci_core_instances.these[cmp_id].instances : [
+ for k, v in local.target_host_scan_cmps : [
+ for i in data.oci_core_instances.these[k].instances : [
#{"name" : i.display_name, "ocid" : i.id, "plugin_name" : data.oci_computeinstanceagent_instance_agent_plugins.these[i.id].name, "plugin_enabled" : i.agent_config[0].plugins_config[0].desired_state == "ENABLED" ? true : false, "plugin_status" : data.oci_computeinstanceagent_instance_agent_plugins.these[i.id].status, "plugin_message" : data.oci_computeinstanceagent_instance_agent_plugins.these[i.id].message} :
{"instance_name" : i.display_name, "instance_ocid" : i.id, "instance_state": i.state, "is_cloud_agent_plugin_enabled" : (length(i.agent_config[0].plugins_config) > 0 ? (i.agent_config[0].plugins_config[0].desired_state == "ENABLED" ? true : false) : false), "reminder" : "Make sure the Vulnerability Scanning plugin is ENABLED and RUNNING."}
]
@@ -115,8 +115,8 @@ locals {
}
data "oci_core_instances" "these" {
- for_each = toset(local.target_host_scan_cmps)
- compartment_id = each.key
+ for_each = local.target_host_scan_cmps
+ compartment_id = each.value
}
/*