diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index f101930..c3e1f6f 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,9 +1,24 @@ +# May 22, 2024 Release Notes - 0.1.5 + +## Updates +1. [Vaults module](./vaults/) + - Virtual private vaults can now be configured for cross-region replication via the newly added *replica-region* attribute. Only applicable to virtual private vaults (VPVs). +2. [Security Zones module](./security-zones/) + - *tenancy_ocid* attribute, once required in the *security_zones_configuration*, becomes a variable of its own. + - *reporting_region* attribute of *security_zones_configuration* defaults to tenancy home region if not defined. + +## Fixes +1. [VSS module](./vss/) + - dynamic runtime dependency issue in *local.target_host_scan_cmps*. [Issue 541](https://orahub.oci.oraclecorp.com/nace-shared-services/cis-oci-landing-zone/-/issues/541). + + # April 16, 2024 Release Notes - 0.1.4 ## Updates 1. [Cloud Guard module](./cloud-guard/): ability to use "TENANCY-ROOT" key for referring to tenancy OCID in *cloud_guard_configuration*. *tenancy_ocid* becomes a variable of its own. 2. All modules: all dependency variables are now strongly typed, enhancing usage guidance. + # March 20, 2024 Release Notes - 0.1.3 ## New @@ -13,6 +28,7 @@ 1. Examples code in all modules updated with remote source references. 2. Examples documentation in all modules updated with remote link references. + # January 08, 2024 Release Notes - 0.1.2 ## Updates @@ -20,7 +36,7 @@ 1. All modules now accept null value as the input variable assignment. This allows for easier automation of composed solutions. ## Updates -1. [VSS Module](#0-1-1-vss-updates) +1. [VSS module](#0-1-1-vss-updates) ### VSS Module 1. *image_count* attribute in *container_recipes* defaulted to 1. @@ -30,6 +46,7 @@ 5. *host_recipe_id* can be assigned either a literal OCID or a referring key from *host_recipes*. 6. *container_recipe_id* can be assigned either a literal OCID or a referring key from *container_recipes*. + # July 03, 2023 Release Notes - 0.1.0 ## New diff --git a/cloud-guard/README.md b/cloud-guard/README.md index 1e76b7f..805f89c 100644 --- a/cloud-guard/README.md +++ b/cloud-guard/README.md @@ -71,10 +71,9 @@ For referring to a specific module version, append *ref=\* to the *sou ## Module Functioning In this module, Cloud Guard settings are defined using the *cloud_guard_configuration* object, that supports the following attributes: -- **tenancy_ocid**: the tenancy OCID. -- **default_defined_tags**: the default defined tags that are applied to all resources managed by this module. It can be overriden by *defined_tags* attribute in each resource. -- **default_freeform_tags**: the default freeform tags that are applied to all resources managed by this module. It can be overriden by *freeform_tags* attribute in each resource. -- **reporting_region**: the Cloud Guard reporting region, where all API calls, except reads, are made on. You can choose the reporting region among the available regions when enabling Cloud Guard. After Cloud Guard is enabled, you cannot change the reporting region without disabling and re-enabling Cloud Guard. Setting this attribute is required if Cloud Guard is enabled by this module. +- **default_defined_tags**: the default defined tags that are applied to all resources managed by this module. It can be overridden by *defined_tags* attribute in each resource. +- **default_freeform_tags**: the default freeform tags that are applied to all resources managed by this module. It can be overridden by *freeform_tags* attribute in each resource. +- **reporting_region**: the Cloud Guard reporting region, where all API calls, except reads, are made on. You can choose the reporting region among the available regions when enabling Cloud Guard. After Cloud Guard is enabled, you cannot change the reporting region without disabling and re-enabling Cloud Guard. Setting this attribute is required if Cloud Guard is enabled by this module. It defaults to tenancy home region if undefined. - **self_manage_resources**: whether Oracle managed resources are created by customers. Default: false. - **cloned_recipes_prefix**: a prefix to cloned recipe names. Default: "oracle-cloned-". - **targets**: the Cloud Guard targets. @@ -101,8 +100,7 @@ The *targets* attribute supports the following attributes: The following snippet enables Cloud Guard service (if not already enabled), setting Ashburn as the reporting region and defining two targets. Both targets monitor compartments under *resource_ocid* compartment and are created in *resource_ocid* compartment. First target (*CLOUD-GUARD-TARGET-1*) uses Oracle provided recipes while the second one (*CLOUD-GUARD-TARGET-2*) uses cloned recipes. ``` cloud_guard_configuration = { - tenancy_ocid = "ocid1.tenancy.oc1..aaaaaa...nuq" - reporting_region = "us-ashburn-1" + reporting_region = "us-ashburn-1" # It defaults to tenancy home region if undefined. targets = { CLOUD-GUARD-TARGET-1 = { @@ -127,7 +125,7 @@ Rewriting the example above with the external dependency: ``` cloud_guard_configuration = { - reporting_region = "us-ashburn-1" + reporting_region = "us-ashburn-1" # It defaults to tenancy home region if undefined. targets = { CLOUD-GUARD-TARGET-1 = { diff --git a/release.txt b/release.txt index 446ba66..def9a01 100644 --- a/release.txt +++ b/release.txt @@ -1 +1 @@ -0.1.4 \ No newline at end of file +0.1.5 \ No newline at end of file diff --git a/security-zones/README.md b/security-zones/README.md index 7c3bbd3..47f2ecf 100644 --- a/security-zones/README.md +++ b/security-zones/README.md @@ -71,12 +71,11 @@ For referring to a specific module version, append *ref=\* to the *sou ## Module Functioning In this module, Security Zones settings are defined using the *security_zones_configuration* object, that supports the following attributes: -- **tenancy_ocid**: the tenancy OCID. - **default_cis_level**: the default CIS level setting for all recipes with an unspecified *cis_level* attribute. Valid values: "1" and "2". Default: "1". See [CIS Level Setting](#cis_level_setting) for details. - **default_defined_tags**: the default defined tags that are applied to all resources managed by this module. It can be overriden by *defined_tags* attribute in each resource. - **default_freeform_tags**: the default freeform tags that are applied to all resources managed by this module. It can be overriden by *freeform_tags* attribute in each resource. - **default_security_policies_ocids**: a list of default security zone policies OCIDs for all recipes with an unspecified *security_policies_ocids* attribute. These are merged with CIS security zone policies driven off *cis_level* attribute. -- **reporting_region**: the Cloud Guard reporting region, where all API calls, except reads, are made on. You can choose the reporting region among the available regions when enabling Cloud Guard. After Cloud Guard is enabled, you cannot change the reporting region without disabling and re-enabling Cloud Guard. Setting this attribute is required if Cloud Guard is enabled by this module. +- **reporting_region**: the Cloud Guard reporting region, where all API calls, except reads, are made on. You can choose the reporting region among the available regions when enabling Cloud Guard. After Cloud Guard is enabled, you cannot change the reporting region without disabling and re-enabling Cloud Guard. Setting this attribute is required if Cloud Guard is enabled by this module. It defaults to tenancy home region if undefined. - **self_manage_resources**: whether Oracle managed resources are created by customers. Default: false. - **recipes**: the Security Zone recipes. A recipe is a set of policies. - **security_zones**: the Security Zones. @@ -131,8 +130,7 @@ The following snippet enables Cloud Guard service (if not already enabled), sett ``` security_zones_configuration = { - tenancy_ocid = "ocid1.tenancy.oc1..aaaaaa...nuq" - reporting_region = "us-ashburn-1" + reporting_region = "us-ashburn-1" # It defaults to tenancy home region if undefined. recipes = { CIS-L1-RECIPE = { @@ -166,9 +164,7 @@ Rewriting the example above with the external dependency: ``` security_zones_configuration = { - tenancy_ocid = "ocid1.tenancy.oc1..aaaaaa...nuq" - reporting_region = "us-ashburn-1" - + reporting_region = "us-ashburn-1" # It defaults to tenancy home region if undefined. recipes = { CIS-L1-RECIPE = { name = "vision-security-zone-cis-level-1-recipe" diff --git a/security-zones/SPEC.md b/security-zones/SPEC.md index d69e7fe..906051d 100644 --- a/security-zones/SPEC.md +++ b/security-zones/SPEC.md @@ -23,6 +23,8 @@ No modules. | [oci_cloud_guard_security_zone.these](https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/cloud_guard_security_zone) | resource | | [oci_cloud_guard_cloud_guard_configuration.this](https://registry.terraform.io/providers/oracle/oci/latest/docs/data-sources/cloud_guard_cloud_guard_configuration) | data source | | [oci_cloud_guard_security_policies.these](https://registry.terraform.io/providers/oracle/oci/latest/docs/data-sources/cloud_guard_security_policies) | data source | +| [oci_identity_regions.these](https://registry.terraform.io/providers/oracle/oci/latest/docs/data-sources/identity_regions) | data source | +| [oci_identity_tenancy.this](https://registry.terraform.io/providers/oracle/oci/latest/docs/data-sources/identity_tenancy) | data source | ## Inputs @@ -31,7 +33,8 @@ 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` | `"security-zones"` | no | -| [security\_zones\_configuration](#input\_security\_zones\_configuration) | Security Zones configuration. |
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))
default_freeform_tags = optional(map(string))
reporting_region = optional(string) # the reporting region.
self_manage_resources = optional(bool) # whether Oracle managed resources are created by customers. Default: false.

recipes = optional(map(object({
name = string
compartment_id = string # the compartment where the Security Zone Recipe is created. It can be either the compartment OCID or a reference (a key) to the compartment OCID.
description = optional(string)
cis_level = optional(string) # Valid values: "1" and "2". Default: "1"
security_policies_ocids = optional(list(string)) # List of default Security Zone policies OCIDs that are merged with CIS Security Zone policies. These are merged with CIS Security Zone policies driven off cis_level.
defined_tags = optional(map(string))
freeform_tags = optional(map(string))
})))

security_zones = map(object({
name = string # The Security Zone name.
compartment_id = string # The Security Zone compartment. It can be either the compartment OCID or a reference (a key) to the compartment OCID. Any existing Cloud Guard target for this compartment is replaced with the security zone. The security zone includes the default Oracle-managed configuration and activity detector recipes in Cloud Guard, and also scans resources in the zone for policy violations.
recipe_key = string # The recipe key in recipes attribute.
description = optional(string) # The security zone description.
defined_tags = optional(map(string))
freeform_tags = optional(map(string))
}))
})
| `null` | no | +| [security\_zones\_configuration](#input\_security\_zones\_configuration) | Security Zones configuration. |
object({
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))
default_freeform_tags = optional(map(string))
reporting_region = optional(string) # the reporting region.
self_manage_resources = optional(bool) # whether Oracle managed resources are created by customers. Default: false.

recipes = optional(map(object({
name = string
compartment_id = string # the compartment where the Security Zone Recipe is created. It can be either the compartment OCID or a reference (a key) to the compartment OCID.
description = optional(string)
cis_level = optional(string) # Valid values: "1" and "2". Default: "1"
security_policies_ocids = optional(list(string)) # List of default Security Zone policies OCIDs that are merged with CIS Security Zone policies. These are merged with CIS Security Zone policies driven off cis_level.
defined_tags = optional(map(string))
freeform_tags = optional(map(string))
})))

security_zones = map(object({
name = string # The Security Zone name.
compartment_id = string # The Security Zone compartment. It can be either the compartment OCID or a reference (a key) to the compartment OCID. Any existing Cloud Guard target for this compartment is replaced with the security zone. The security zone includes the default Oracle-managed configuration and activity detector recipes in Cloud Guard, and also scans resources in the zone for policy violations.
recipe_key = string # The recipe key in recipes attribute.
description = optional(string) # The security zone description.
defined_tags = optional(map(string))
freeform_tags = optional(map(string))
}))
})
| `null` | no | +| [tenancy\_ocid](#input\_tenancy\_ocid) | The tenancy OCID. | `string` | n/a | yes | ## Outputs diff --git a/security-zones/data_sources.tf b/security-zones/data_sources.tf index f464be1..e1def67 100644 --- a/security-zones/data_sources.tf +++ b/security-zones/data_sources.tf @@ -1,10 +1,16 @@ # Copyright (c) 2023 Oracle and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +data "oci_identity_regions" "these" {} + +data "oci_identity_tenancy" "this" { + tenancy_id = var.tenancy_ocid +} + data "oci_cloud_guard_security_policies" "these" { - compartment_id = var.security_zones_configuration != null ? var.security_zones_configuration.tenancy_ocid : "void" + compartment_id = var.security_zones_configuration != null ? var.tenancy_ocid : "__void__" } data "oci_cloud_guard_cloud_guard_configuration" "this" { - compartment_id = var.security_zones_configuration != null ? var.security_zones_configuration.tenancy_ocid : "Void" + compartment_id = var.security_zones_configuration != null ? var.tenancy_ocid : "__void__" } \ No newline at end of file diff --git a/security-zones/examples/external_dependency/README.md b/security-zones/examples/external_dependency/README.md index 1ee49bc..3c8787d 100644 --- a/security-zones/examples/external_dependency/README.md +++ b/security-zones/examples/external_dependency/README.md @@ -18,7 +18,6 @@ allow group to read objects in compartment whe 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 adjust the *security_zones_configuration* input variable, by making the appropriate substitutions: - - Replace *\* placeholder by the tenancy OCID. - Replace *\* placeholder by the actual reporting region name. Example: "us-ashburn-1". - Replace *\* placeholder by the appropriate security zone compartment reference, expected to be found in the OCI Object Storage object referred by *\*. - Replace *\* placeholders by the appropriate security zone recipe compartment references, expected to be found in the OCI Object Storage object referred by *\*. diff --git a/security-zones/examples/external_dependency/input.auto.tfvars.template b/security-zones/examples/external_dependency/input.auto.tfvars.template index 5639810..828de1e 100644 --- a/security-zones/examples/external_dependency/input.auto.tfvars.template +++ b/security-zones/examples/external_dependency/input.auto.tfvars.template @@ -4,14 +4,13 @@ #--------------------------------------------------------------------------------------------------------------------------------------------------- # 1. Rename this file to .auto.tfvars, where is a name of your choice. # 2. Provide values for "Tenancy Connectivity Variables". -# 3. Replace placeholder by the appropriate compartment OCID. -# 4. Replace placeholder by the reporting region name. Example: "us-ashburn-1". -# 5. Replace placeholder by the appropriate security zone compartment reference, +# 3. Replace placeholder by the reporting region name. Example: "us-ashburn-1". +# 4. Replace placeholder by the appropriate security zone compartment reference, # expected to be found in the OCI Object Storage object referred by . -# 6. Replace placeholders by the appropriate security zone recipe compartment references, +# 5. Replace placeholders by the appropriate security zone recipe compartment references, # expected to be found in the OCI Object Storage object referred by . -# 7. Replace placeholder by the OCI Object Storage bucket that contains the object referred by . -# 8. Replace placeholder by the OCI Object Storage object that has the compartment references. This object is supposedly +# 6. Replace placeholder by the OCI Object Storage bucket that contains the object referred by . +# 7. Replace placeholder by the OCI Object Storage object that has the compartment references. This object is supposedly # stored in OCI Object Storage by the module that manages compartments. #--------------------------------------------------------------------------------------------------------------------------------------------------- @@ -31,8 +30,7 @@ region = "" # This is your region, where #--------------------------------------- security_zones_configuration = { - tenancy_ocid = "" - reporting_region = "" + reporting_region = "" # It defaults to tenancy home region if undefined. security_zones = { SECURITY-ZONE = { diff --git a/security-zones/examples/external_dependency/main.tf b/security-zones/examples/external_dependency/main.tf index 57072ff..f622dc5 100644 --- a/security-zones/examples/external_dependency/main.tf +++ b/security-zones/examples/external_dependency/main.tf @@ -15,6 +15,7 @@ data "oci_objectstorage_object" "compartments" { 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 enable_output = true compartments_dependency = var.oci_compartments_dependency != null ? jsondecode(data.oci_objectstorage_object.compartments[0].content) : null diff --git a/security-zones/examples/vision/README.md b/security-zones/examples/vision/README.md index 6b4f3a6..78cd4cc 100644 --- a/security-zones/examples/vision/README.md +++ b/security-zones/examples/vision/README.md @@ -10,7 +10,7 @@ It enables Cloud Guard service (if not already enabled), setting Ashburn as the 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 adjust the *security_zones_configuration* input variable, by making the appropriate substitutions: - - Replace *\* placeholder by the tenancy OCID. + - Replace *\* placeholder by the reporting region name. Example: "us-ashburn-1". - Replace *\* placeholder by the appropriate compartment OCID. - Replace *\* placeholders by the appropriate compartment OCIDs. diff --git a/security-zones/examples/vision/input.auto.tfvars.template b/security-zones/examples/vision/input.auto.tfvars.template index f1380d2..5879f44 100644 --- a/security-zones/examples/vision/input.auto.tfvars.template +++ b/security-zones/examples/vision/input.auto.tfvars.template @@ -4,10 +4,9 @@ #-------------------------------------------------------------------------------------------------------------------------------------- # 1. Rename this file to .auto.tfvars, where is a name of your choice. # 2. Provide values for "Tenancy Connectivity Variables". -# 3. Replace placeholder by the appropriate compartment OCID. -# 4. Replace placeholder by the reporting region name. Example: "us-ashburn-1". -# 5. Replace placeholder by the appropriate compartment OCID. -# 6. Replace placeholders by the appropriate compartment OCIDs. +# 3. Replace placeholder by the reporting region name. Example: "us-ashburn-1". +# 4. Replace placeholder by the appropriate compartment OCID. +# 5. Replace placeholders by the appropriate compartment OCIDs. #-------------------------------------------------------------------------------------------------------------------------------------- #--------------------------------------- @@ -26,8 +25,7 @@ region = "" # This is your region, where #--------------------------------------- security_zones_configuration = { - tenancy_ocid = "" - reporting_region = "" + reporting_region = "" # 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 } /*