From b0c0a5a22b14a56b78d2f570519fefe5916cb27f Mon Sep 17 00:00:00 2001 From: Olaf Heimburger Date: Fri, 30 Jun 2023 15:41:44 +0200 Subject: [PATCH 01/29] First draft for Custom Group Names. --- DEPLOYMENT-GUIDE.md | 47 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/DEPLOYMENT-GUIDE.md b/DEPLOYMENT-GUIDE.md index 79da60c8..d6154e5e 100644 --- a/DEPLOYMENT-GUIDE.md +++ b/DEPLOYMENT-GUIDE.md @@ -150,15 +150,15 @@ Two extra compartments can be provisioned based on user choice: By default, the Landing Zone defines the following personas that account for most organization needs: -- **Security Administrators**: manages security services and resources including Vaults, Keys, Logging, Vulnerability Scanning, Web Application Firewall, Bastion, Service Connector Hub. -- **Network Administrators**: manages OCI network family, including VCNs, DRGs, VNICs, IP addresses. -- **Application Administrators**: manages application related resources including Compute images, OCI Functions, Kubernetes clusters, Streams, Object Storage, Block Storage, File Storage. -- **Database Administrators**: manages database services, including Oracle VMDB (Virtual Machine), BMDB (Bare Metal), ADB (Autonomous databases), Exadata databases, MySQL, NoSQL, etc. - **IAM Administrators**: manages IAM services and resources including compartments, groups, dynamic groups, policies, identity providers, authentication policies, network sources, tag defaults. However, this group is not allowed to manage the out-of-box *Administrators* and *Credential Administrators* groups. It's also not allowed to touch the out-of-box *Tenancy Admin Policy* policy. - **Credential Administrators**: manages a users’ capabilities and users credentials in general, including API keys, authentication tokens and secret keys. - **Cost Administrators**: manages budgets and usage reports. - **Auditors**: entitled with read-only access across the tenancy and the ability to use cloud-shell to run the *cis_reports.py* script. - **Announcement Readers**: for reading announcements displayed in OCI Console. +- **Security Administrators**: manages security services and resources including Vaults, Keys, Logging, Vulnerability Scanning, Web Application Firewall, Bastion, Service Connector Hub. +- **Network Administrators**: manages OCI network family, including VCNs, DRGs, VNICs, IP addresses. +- **Application Administrators**: manages application related resources including Compute images, OCI Functions, Kubernetes clusters, Streams, Object Storage, Block Storage, File Storage. +- **Database Administrators**: manages database services, including Oracle VMDB (Virtual Machine), BMDB (Bare Metal), ADB (Autonomous databases), Exadata databases, MySQL, NoSQL, etc. - **ExaCS Administrators** (only created when ExaCS compartment is created): manages Exadata infrastructure and VM clusters in the ExaCS compartment. @@ -273,6 +273,25 @@ In these cases, simply provide the existing OCI group names to the appropriate c - **existing_compute_agent_dyn_group_name**: existing dynamic group for Compute management agent access. - **existing_database_kms_dyn_group_name**: existing dynamic group for databases to access OCI KMS Keys. +### Custom Group Names + +By default, the group names are following the convention `${var.service_label}-group_name` using the `service-label` defined in the `tfvars` file. When a different naming convention should be used, for example, to match an established naming convention, these names can be customized using the Terraform Override technique. + +The supported variables are: +- **custom_iam_admin_group_name** +- **custom_cred_admin_group_name** +- **custom_cost_admin_group_name** +- **custom_auditor_group_name** +- **custom_announcement_reader_group_name** +- **custom_network_admin_group_name** +- **custom_security_admin_group_name** +- **custom_appdev_admin_group_name** +- **custom_database_admin_group_name** +- **custom_exainfra_admin_group_name** +- **custom_storage_admin_group_name** + +For an example see [Example 4: Using Custom Group Names](#example-4-using-custom-group-names) + ### Extending Landing Zone to a New Region When you run Landing Zone's Terraform, some resources are created in the home region, while others are created in a region of choice. Among home region resources are compartments, groups, dynamic groups, policies, tag defaults and an infrastructure for IAM related notifications (including events, topics and subscriptions). Among resources created in the region of choice are VCNs, Log Groups, and those pertaining to security services like Vault Service, Vulnerability Scanning, Service Connector Hub, Bastion. The home region resources are automatically made available by OCI in all subscribed regions. @@ -1031,6 +1050,26 @@ Now, we're placing ```vision_stage2_override.tf``` into the ```config``` directo When you run ```terraform apply``` the defined tags of your components will be updated accordingly. +### Example 4: Using Custom Group Names + +To define group names that follow the company naming convention, create a file `custom_group_names_override.tf` containing the following lines: + + locals { + custom_iam_admin_group_name = "grp-iam-admins" + custom_cred_admin_group_name = "grp-credentials-admins" + custom_cost_admin_group_name = "grp-cost-admins" + custom_auditor_group_name = "grp-auditors" + custom_announcement_reader_group_name = "grp-announcement-readers" + custom_network_admin_group_name = "grp-network-admins" + custom_security_admin_group_name = "grp-security-admins" + custom_appdev_admin_group_name = "grp-application-admins" + custom_database_admin_group_name = "grp-database-admins" + custom_exainfra_admin_group_name = "grp-exainfra-admins" + custom_storage_admin_group_name = "grp-storage-admins" + } + +When done, move it to the `config` directory and verify it with `terraform plan`. + # 7. Deployment Samples In this section we give deployment examples of Landing Zone variables input file (*config/quickstart-input.tfvars* or *config/terraform.tfvars*) for common scenarios. The list is not exhaustive. From 1e2620aedb7b19870cc0657b086de1c4a3d57c4d Mon Sep 17 00:00:00 2001 From: Olaf Heimburger Date: Thu, 6 Jul 2023 17:25:16 +0200 Subject: [PATCH 02/29] Added example code for the custom group names. --- DEPLOYMENT-GUIDE.md | 2 +- .../iam_goups_override.tf | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 examples/deployment_override_iam_groups/iam_goups_override.tf diff --git a/DEPLOYMENT-GUIDE.md b/DEPLOYMENT-GUIDE.md index d6154e5e..9072c3a3 100644 --- a/DEPLOYMENT-GUIDE.md +++ b/DEPLOYMENT-GUIDE.md @@ -1052,7 +1052,7 @@ When you run ```terraform apply``` the defined tags of your components will be u ### Example 4: Using Custom Group Names -To define group names that follow the company naming convention, create a file `custom_group_names_override.tf` containing the following lines: +To define group names that follow the company naming convention, create a file `iam_groups_override.tf` containing the following lines: locals { custom_iam_admin_group_name = "grp-iam-admins" diff --git a/examples/deployment_override_iam_groups/iam_goups_override.tf b/examples/deployment_override_iam_groups/iam_goups_override.tf new file mode 100644 index 00000000..a06eddbc --- /dev/null +++ b/examples/deployment_override_iam_groups/iam_goups_override.tf @@ -0,0 +1,13 @@ +locals { + custom_iam_admin_group_name = "grp-iam-admins" + custom_cred_admin_group_name = "grp-credentials-admins" + custom_cost_admin_group_name = "grp-cost-admins" + custom_auditor_group_name = "grp-auditors" + custom_announcement_reader_group_name = "grp-announcement-readers" + custom_network_admin_group_name = "grp-network-admins" + custom_security_admin_group_name = "grp-security-admins" + custom_appdev_admin_group_name = "grp-application-admins" + custom_database_admin_group_name = "grp-database-admins" + custom_exainfra_admin_group_name = "grp-exainfra-admins" + custom_storage_admin_group_name = "grp-storage-admins" +} From 82962459259688841f66ac99a7d2e5fb6d2ddae8 Mon Sep 17 00:00:00 2001 From: Andre Correa Date: Fri, 7 Jul 2023 14:20:32 -0300 Subject: [PATCH 03/29] doc: storage administrators description added --- DEPLOYMENT-GUIDE.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/DEPLOYMENT-GUIDE.md b/DEPLOYMENT-GUIDE.md index 9072c3a3..c3293ddb 100644 --- a/DEPLOYMENT-GUIDE.md +++ b/DEPLOYMENT-GUIDE.md @@ -150,17 +150,17 @@ Two extra compartments can be provisioned based on user choice: By default, the Landing Zone defines the following personas that account for most organization needs: -- **IAM Administrators**: manages IAM services and resources including compartments, groups, dynamic groups, policies, identity providers, authentication policies, network sources, tag defaults. However, this group is not allowed to manage the out-of-box *Administrators* and *Credential Administrators* groups. It's also not allowed to touch the out-of-box *Tenancy Admin Policy* policy. -- **Credential Administrators**: manages a users’ capabilities and users credentials in general, including API keys, authentication tokens and secret keys. -- **Cost Administrators**: manages budgets and usage reports. +- **IAM Administrators**: manage IAM services and resources including compartments, groups, dynamic groups, policies, identity providers, authentication policies, network sources, tag defaults. However, this group is not allowed to manage the out-of-box *Administrators* and *Credential Administrators* groups. It's also not allowed to touch the out-of-box *Tenancy Admin Policy* policy. +- **Credential Administrators**: manage users capabilities and users credentials in general, including API keys, authentication tokens and secret keys. +- **Cost Administrators**: manage budgets and usage reports. - **Auditors**: entitled with read-only access across the tenancy and the ability to use cloud-shell to run the *cis_reports.py* script. - **Announcement Readers**: for reading announcements displayed in OCI Console. -- **Security Administrators**: manages security services and resources including Vaults, Keys, Logging, Vulnerability Scanning, Web Application Firewall, Bastion, Service Connector Hub. -- **Network Administrators**: manages OCI network family, including VCNs, DRGs, VNICs, IP addresses. -- **Application Administrators**: manages application related resources including Compute images, OCI Functions, Kubernetes clusters, Streams, Object Storage, Block Storage, File Storage. -- **Database Administrators**: manages database services, including Oracle VMDB (Virtual Machine), BMDB (Bare Metal), ADB (Autonomous databases), Exadata databases, MySQL, NoSQL, etc. - -- **ExaCS Administrators** (only created when ExaCS compartment is created): manages Exadata infrastructure and VM clusters in the ExaCS compartment. +- **Security Administrators**: manage security services and resources including Vaults, Keys, Logging, Vulnerability Scanning, Web Application Firewall, Bastion, Service Connector Hub. +- **Network Administrators**: manage OCI network family, including VCNs, DRGs, VNICs, IP addresses. +- **Application Administrators**: manage application related resources including Compute images, OCI Functions, Kubernetes clusters, Streams, Object Storage, Block Storage, File Storage. +- **Database Administrators**: manage database services, including Oracle VMDB (Virtual Machine), BMDB (Bare Metal), ADB (Autonomous databases), Exadata databases, MySQL, NoSQL, etc. +- **ExaCS Administrators** (only created when ExaCS compartment is created): manage Exadata infrastructure and VM clusters in the ExaCS compartment. +- **Storage Administrators**: the only group allowed to delete storage resources, including buckets, volumes and files. Used as a protection measure against inadvertent deletion of storage resources. > **_NOTE:_** following least privilege principle, groups are only entitled to manage, use, read or inspect the necessary resources to fulfill their duties. From d0b350878465eb01a482b8c5e4980fba2c05c8e3 Mon Sep 17 00:00:00 2001 From: Andre Correa Date: Fri, 14 Jul 2023 17:01:09 +0000 Subject: [PATCH 04/29] Release 2.6.0 --- VARIABLES.md | 3 +- config/data_sources.tf | 62 +-- config/iam_compartments.tf | 273 +++++++++---- config/iam_dynamic_groups.tf | 172 ++++++--- config/iam_groups.tf | 304 ++++++++++++--- config/iam_policies.tf | 656 ++++++++++++++++++-------------- config/iam_service_policies.tf | 66 ++-- config/iam_template_policies.tf | 173 +++++++++ config/locals.tf | 60 +-- config/outputs.tf | 14 +- config/provider.tf | 2 +- config/quickstart-input.tfvars | 3 +- config/schema.yml | 81 +++- config/security_zones.tf | 10 +- config/variables.tf | 10 +- images/landing_zone_130.png | Bin 0 -> 12915 bytes release-notes.md | 13 + release.txt | 1 + scripts/cis_reports.py | 6 +- 19 files changed, 1309 insertions(+), 600 deletions(-) create mode 100644 config/iam_template_policies.tf create mode 100644 images/landing_zone_130.png create mode 100644 release.txt diff --git a/VARIABLES.md b/VARIABLES.md index 23fe4e33..db166f5b 100644 --- a/VARIABLES.md +++ b/VARIABLES.md @@ -16,10 +16,11 @@ Variable Name | Description | Required | Default Value **region** \* | The tenancy region identifier where the Terraform should provision the resources. | Yes | None **service_label** | A label used as a prefix for naming resources. | Yes | None **cis_level** | Determines CIS OCI Benchmark Level to apply on Landing Zone managed resources. Level 1 is be practical and prudent. Level 2 is intended for environments where security is more critical than manageability and usability. Level 2 drives the creation of an OCI Vault, buckets encryption with a customer managed key, write logs for buckets and the usage of specific policies in Security Zones. For more information please review the CIS OCI Benchmark available [here](https://www.cisecurity.org/benchmark/oracle_cloud). Acceptable inputs are "1" or "2". | Yes | "2" -**use_enclosing_compartment** | A boolean flag indicating whether or not to provision the Landing Zone within an enclosing compartment other than the root compartment. **When provisioning the Landing Zone as a _narrower-permissioned_ user, make sure to set this variable value to true**. | Yes | false +**use_enclosing_compartment** | A boolean flag indicating whether or not to provision the Landing Zone within an enclosing compartment other than the root compartment. **When provisioning the Landing Zone as a _narrower-permissioned_ user, make sure to set this variable value to true**. | Yes | true **existing_enclosing_compartment_ocid** | The OCID of a pre-existing enclosing compartment where Landing Zone compartments are to be created. If *use_enclosing_compartment* is false, the module creates the Landing Zone compartments in the root compartment as long as the executing user has the required permissions. | No | None **extend_landing_zone_to_new_region** | Whether Landing Zone is being extended to another region. When set to true, compartments, groups, policies and resources at the home region are not provisioned. Use this when you want provision a Landing Zone in a new region, but reuse existing Landing Zone resources in the home region. | No | false **policies_in_root_compartment** | The Landing Zone requires policies attached to the root compartment to work at full capacity. For instance, security administrators are expect to manage Cloud Guard, Tag Namespaces, Tag Defaults, Event Rules, and others. Likewise, IAM administrators are expected to manage IAM resources in general. Such capabilities are only enabled if policies are created at the root compartment, as they apply to the tenancy as a whole. A *narrower-permissioned* user will not likely have the permissions to create such policies. As a consequence, it is expected that these policies are previously created by a *wide-permissioned* user. Therefore, **when provisioning the Landing Zone as a _narrower-permissioned_ user, make sure to set this variable value to "USE", in which case permissions are not created at the root compartment**. Default is "CREATE", meaning the module will provision the policies at the root compartment, as long as the executing user has the required permissions. | Yes | "CREATE" +**enable_template_policies** | Whether policies should be created based on metadata associated with compartments. This is an alternative way of managing policies, enabled by the [CIS Landing Zone standalone IAM policy module](https://github.com/oracle-quickstart/terraform-oci-cis-landing-zone-iam/tree/main/policies). When set to true, the grants to resources belonging to a specific compartment are combined into a single policy that is attached to the compartment itself. This differs from the existing approach, where grants are combined per grantee and attached to the enclosing compartment. | No | false **existing_iam_admin_group_name** | The name or OCID of an existing group for IAM administrators. | No | None **existing_cred_admin_group_name** | The name or OCID of an existing group for credential administrators. | No | None **existing_security_admin_group_name** | The name or OCID of an existing group for security administrators. | No | None diff --git a/config/data_sources.tf b/config/data_sources.tf index 2c87b197..eb960f6f 100644 --- a/config/data_sources.tf +++ b/config/data_sources.tf @@ -3,6 +3,10 @@ data "oci_identity_regions" "these" {} +data "oci_identity_region_subscriptions" "these" { + tenancy_id = var.tenancy_ocid +} + data "oci_identity_tenancy" "this" { tenancy_id = var.tenancy_ocid } @@ -15,135 +19,135 @@ data "oci_identity_group" "existing_iam_admin_group" { group_id = length(trimspace(var.existing_iam_admin_group_name)) > 0 ? var.existing_iam_admin_group_name : "nogroup" } -data "oci_identity_groups" "existing_iam_admin_group" { +/* data "oci_identity_groups" "existing_iam_admin_group" { compartment_id = var.tenancy_ocid filter { name = "name" values = [var.existing_iam_admin_group_name] } -} +} */ data "oci_identity_group" "existing_cred_admin_group" { group_id = length(trimspace(var.existing_cred_admin_group_name)) > 0 ? var.existing_cred_admin_group_name : "nogroup" } -data "oci_identity_groups" "existing_cred_admin_group" { +/* data "oci_identity_groups" "existing_cred_admin_group" { compartment_id = var.tenancy_ocid filter { name = "name" values = [var.existing_cred_admin_group_name] } -} +} */ data "oci_identity_group" "existing_security_admin_group" { group_id = length(trimspace(var.existing_security_admin_group_name)) > 0 ? var.existing_security_admin_group_name : "nogroup" } -data "oci_identity_groups" "existing_security_admin_group" { +/* data "oci_identity_groups" "existing_security_admin_group" { compartment_id = var.tenancy_ocid filter { name = "name" values = [var.existing_security_admin_group_name] } -} +} */ data "oci_identity_group" "existing_network_admin_group" { group_id = length(trimspace(var.existing_network_admin_group_name)) > 0 ? var.existing_network_admin_group_name : "nogroup" } -data "oci_identity_groups" "existing_network_admin_group" { +/* data "oci_identity_groups" "existing_network_admin_group" { compartment_id = var.tenancy_ocid filter { name = "name" values = [var.existing_network_admin_group_name] } -} +} */ data "oci_identity_group" "existing_appdev_admin_group" { group_id = length(trimspace(var.existing_appdev_admin_group_name)) > 0 ? var.existing_appdev_admin_group_name : "nogroup" } -data "oci_identity_groups" "existing_appdev_admin_group" { +/* data "oci_identity_groups" "existing_appdev_admin_group" { compartment_id = var.tenancy_ocid filter { name = "name" values = [var.existing_appdev_admin_group_name] } -} +} */ data "oci_identity_group" "existing_database_admin_group" { group_id = length(trimspace(var.existing_database_admin_group_name)) > 0 ? var.existing_database_admin_group_name : "nogroup" } -data "oci_identity_groups" "existing_database_admin_group" { +/* data "oci_identity_groups" "existing_database_admin_group" { compartment_id = var.tenancy_ocid filter { name = "name" values = [var.existing_database_admin_group_name] } -} +} */ data "oci_identity_group" "existing_auditor_group" { group_id = length(trimspace(var.existing_auditor_group_name)) > 0 ? var.existing_auditor_group_name : "nogroup" } -data "oci_identity_groups" "existing_auditor_group" { +/* data "oci_identity_groups" "existing_auditor_group" { compartment_id = var.tenancy_ocid filter { name = "name" values = [var.existing_auditor_group_name] } -} +} */ data "oci_identity_group" "existing_announcement_reader_group" { group_id = length(trimspace(var.existing_announcement_reader_group_name)) > 0 ? var.existing_announcement_reader_group_name : "nogroup" } -data "oci_identity_groups" "existing_announcement_reader_group" { +/* data "oci_identity_groups" "existing_announcement_reader_group" { compartment_id = var.tenancy_ocid filter { name = "name" values = [var.existing_announcement_reader_group_name] } -} +} */ data "oci_identity_group" "existing_exainfra_admin_group" { group_id = length(trimspace(var.existing_exainfra_admin_group_name)) > 0 ? var.existing_exainfra_admin_group_name : "nogroup" } -data "oci_identity_groups" "existing_exainfra_admin_group" { +/* data "oci_identity_groups" "existing_exainfra_admin_group" { compartment_id = var.tenancy_ocid filter { name = "name" values = [var.existing_exainfra_admin_group_name] } -} +} */ data "oci_identity_group" "existing_cost_admin_group" { group_id = length(trimspace(var.existing_cost_admin_group_name)) > 0 ? var.existing_cost_admin_group_name : "nogroup" } -data "oci_identity_groups" "existing_cost_admin_group" { +/* data "oci_identity_groups" "existing_cost_admin_group" { compartment_id = var.tenancy_ocid filter { name = "name" values = [var.existing_cost_admin_group_name] } -} +} */ data "oci_identity_group" "existing_storage_admin_group" { group_id = length(trimspace(var.existing_storage_admin_group_name)) > 0 ? var.existing_storage_admin_group_name : "nogroup" } -data "oci_identity_groups" "existing_storage_admin_group" { +/* data "oci_identity_groups" "existing_storage_admin_group" { compartment_id = var.tenancy_ocid filter { name = "name" values = [var.existing_storage_admin_group_name] } -} +} */ -data "oci_identity_dynamic_groups" "existing_security_fun_dyn_group" { +/* data "oci_identity_dynamic_groups" "existing_security_fun_dyn_group" { compartment_id = var.tenancy_ocid filter { name = "name" @@ -173,7 +177,7 @@ data "oci_identity_dynamic_groups" "existing_database_kms_dyn_group" { name = "name" values = [var.existing_database_kms_dyn_group_name] } -} +} */ data "oci_cloud_guard_cloud_guard_configuration" "this" { compartment_id = var.tenancy_ocid @@ -187,7 +191,7 @@ data "oci_identity_compartments" "network" { compartment_id = local.enclosing_compartment_id filter { name = "name" - values = [local.network_compartment.name] + values = [local.provided_network_compartment_name] } filter { name = "state" @@ -199,7 +203,7 @@ data "oci_identity_compartments" "security" { compartment_id = local.enclosing_compartment_id filter { name = "name" - values = [local.security_compartment.name] + values = [local.provided_security_compartment_name] } filter { name = "state" @@ -211,7 +215,7 @@ data "oci_identity_compartments" "appdev" { compartment_id = local.enclosing_compartment_id filter { name = "name" - values = [local.appdev_compartment.name] + values = [local.provided_appdev_compartment_name] } filter { name = "state" @@ -223,7 +227,7 @@ data "oci_identity_compartments" "database" { compartment_id = local.enclosing_compartment_id filter { name = "name" - values = [local.database_compartment.name] + values = [local.provided_database_compartment_name] } filter { name = "state" @@ -235,7 +239,7 @@ data "oci_identity_compartments" "exainfra" { compartment_id = local.enclosing_compartment_id filter { name = "name" - values = [local.exainfra_compartment.name] + values = [local.provided_exainfra_compartment_name] } filter { name = "state" diff --git a/config/iam_compartments.tf b/config/iam_compartments.tf index b0dabc76..09aef2ea 100644 --- a/config/iam_compartments.tf +++ b/config/iam_compartments.tf @@ -1,86 +1,219 @@ -# Copyright (c) 2021 Oracle and/or its affiliates. +# 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. -### This Terraform configuration provisions compartments in the tenancy. locals { + #------------------------------------------------------------------------------------------------------ + #-- Any of these local variables can be overriden in a _override.tf file + #------------------------------------------------------------------------------------------------------ + + custom_cmps_defined_tags = null + custom_cmps_freeform_tags = null + + custom_enclosing_compartment_name = null + custom_security_compartment_name = null + custom_network_compartment_name = null + custom_appdev_compartment_name = null + custom_database_compartment_name = null + custom_exainfra_compartment_name = null +} + +module "lz_top_compartment" { + count = var.extend_landing_zone_to_new_region == false && var.use_enclosing_compartment == true && var.existing_enclosing_compartment_ocid == null ? 1 : 0 + source = "github.com/oracle-quickstart/terraform-oci-cis-landing-zone-iam/compartments" + providers = { oci = oci.home } + tenancy_ocid = var.tenancy_ocid + compartments_configuration = local.enclosing_compartment_configuration +} + +module "lz_compartments" { + source = "github.com/oracle-quickstart/terraform-oci-cis-landing-zone-iam/compartments" + providers = { oci = oci.home } + tenancy_ocid = var.tenancy_ocid + compartments_configuration = var.extend_landing_zone_to_new_region == false ? local.enclosed_compartments_configuration : local.empty_compartments_configuration +} + +locals { + #------------------------------------------------------------------------------------------------------ + #-- These variables are not meant to be overriden + #------------------------------------------------------------------------------------------------------ - all_compartments_defined_tags = {} - all_compartments_freeform_tags = {} + #-- Enable compartment variables for future usage. + enable_enclosing_compartment = true + enable_network_compartment = true + enable_security_compartment = true + enable_appdev_compartment = true + enable_database_compartment = true + enable_exainfra_compartment = var.deploy_exainfra_cmp - default_cmps = { - (local.security_compartment.key) = { - parent_id = local.enclosing_compartment_id - name = local.security_compartment.name - description = "Landing Zone compartment for all security related resources: vaults, topics, notifications, logging, scanning, and others." - enable_delete = local.enable_cmp_delete - defined_tags = local.compartments_defined_tags - freeform_tags = local.compartments_freeform_tags - }, - (local.network_compartment.key) = { - parent_id = local.enclosing_compartment_id - name = local.network_compartment.name - description = "Landing Zone compartment for all network related resources: VCNs, subnets, network gateways, security lists, NSGs, load balancers, VNICs, and others." - enable_delete = local.enable_cmp_delete - defined_tags = local.compartments_defined_tags - freeform_tags = local.compartments_freeform_tags - }, - (local.appdev_compartment.key) = { - parent_id = local.enclosing_compartment_id - name = local.appdev_compartment.name - description = "Landing Zone compartment for all resources related to application development: compute instances, storage, functions, OKE, API Gateway, streaming, and others." - enable_delete = local.enable_cmp_delete - defined_tags = local.compartments_defined_tags - freeform_tags = local.compartments_freeform_tags - }, - (local.database_compartment.key) = { - parent_id = local.enclosing_compartment_id - name = local.database_compartment.name - description = "Landing Zone compartment for all database related resources." - enable_delete = local.enable_cmp_delete - defined_tags = local.compartments_defined_tags - freeform_tags = local.compartments_freeform_tags - } - } - exainfra_cmp = var.deploy_exainfra_cmp == true ? { - (local.exainfra_compartment.key) = { - parent_id = local.enclosing_compartment_id - name = local.exainfra_compartment.name - description = "Landing Zone compartment for Exadata infrastructure." - enable_delete = local.enable_cmp_delete - defined_tags = local.compartments_defined_tags - freeform_tags = local.compartments_freeform_tags + #----------------------------------------------------------- + #----- Tags to apply to compartments + #----------------------------------------------------------- + default_cmps_defined_tags = null + default_cmps_freeform_tags = local.landing_zone_tags + + cmps_defined_tags = local.custom_cmps_defined_tags != null ? merge(local.custom_cmps_defined_tags, local.default_cmps_defined_tags) : local.default_cmps_defined_tags + cmps_freeform_tags = local.custom_cmps_freeform_tags != null ? merge(local.custom_cmps_freeform_tags, local.default_cmps_freeform_tags) : local.default_cmps_freeform_tags + + #----------------------------------------------------------- + #----- Enclosing compartment definition + #----------------------------------------------------------- + enclosing_compartment_key = "${var.service_label}-top-cmp" + default_enclosing_compartment_name = "top-cmp" + provided_enclosing_compartment_name = local.custom_enclosing_compartment_name != null ? local.custom_enclosing_compartment_name : "${var.service_label}-${local.default_enclosing_compartment_name}" + + cislz_enclosing_compartment_tags = var.enable_template_policies == true ? { + "cislz-cmp-type":"enclosing" + } : {} + + enclosing_cmp = local.enable_enclosing_compartment ? { + (local.enclosing_compartment_key) : { + name : local.provided_enclosing_compartment_name, + description : "CIS Landing Zone enclosing compartment", + defined_tags : local.cmps_defined_tags, + freeform_tags : merge(local.cmps_freeform_tags, local.cislz_enclosing_compartment_tags), + children : {} + } + } : {} + + #----------------------------------------------------------- + #----- Enclosed compartments definition + #----------------------------------------------------------- + #enclosing_compartment_id = var.existing_enclosing_compartment_ocid != null ? var.existing_enclosing_compartment_ocid : module.lz_top_compartment.compartments[local.enclosing_compartment_key].id + + network_compartment_key = "${var.service_label}-network-cmp" + default_network_compartment_name = "network-cmp" + provided_network_compartment_name = local.custom_network_compartment_name != null ? local.custom_network_compartment_name : "${var.service_label}-${local.default_network_compartment_name}" + + cislz_network_compartment_tags = var.enable_template_policies == true ? { + "cislz-cmp-type":"network" + } : {} + + network_cmp = local.enable_network_compartment ? { + (local.network_compartment_key) : { + name : local.provided_network_compartment_name, + description : "CIS Landing Zone compartment for all network related resources: VCNs, subnets, network gateways, security lists, NSGs, load balancers, VNICs, and others.", + defined_tags : local.cmps_defined_tags, + freeform_tags : merge(local.cmps_freeform_tags, local.cislz_network_compartment_tags), + children : {} } } : {} - cmps = merge(local.default_cmps, local.exainfra_cmp) + security_compartment_key = "${var.service_label}-security-cmp" + default_security_compartment_name = "security-cmp" + provided_security_compartment_name = local.custom_security_compartment_name != null ? local.custom_security_compartment_name : "${var.service_label}-${local.default_security_compartment_name}" + + cislz_security_compartment_tags = var.enable_template_policies == true ? { + "cislz-cmp-type":"security" + } : {} + + security_cmp = local.enable_security_compartment ? { + (local.security_compartment_key) : { + name : local.provided_security_compartment_name, + description : "CIS Landing Zone compartment for all security related resources: vaults, topics, notifications, logging, scanning, and others.", + defined_tags : local.cmps_defined_tags, + freeform_tags : merge(local.cmps_freeform_tags, local.cislz_security_compartment_tags), + children : {} + } + } : {} - ### DON'T TOUCH THESE ### - default_compartments_defined_tags = null - default_compartments_freeform_tags = local.landing_zone_tags + appdev_compartment_key = "${var.service_label}-appdev-cmp" + default_appdev_compartment_name = "appdev-cmp" + provided_appdev_compartment_name = local.custom_appdev_compartment_name != null ? local.custom_appdev_compartment_name : "${var.service_label}-${local.default_appdev_compartment_name}" - compartments_defined_tags = length(local.all_compartments_defined_tags) > 0 ? local.all_compartments_defined_tags : local.default_compartments_defined_tags - compartments_freeform_tags = length(local.all_compartments_freeform_tags) > 0 ? merge(local.all_compartments_freeform_tags, local.default_compartments_freeform_tags) : local.default_compartments_freeform_tags + cislz_appdev_compartment_tags = var.enable_template_policies == true ? { + "cislz-cmp-type":"application" + } : {} -} + appdev_cmp = local.enable_appdev_compartment ? { + (local.appdev_compartment_key) : { + name : local.provided_appdev_compartment_name, + description : "CIS Landing Zone compartment for all resources related to application development: compute instances, storage, functions, OKE, API Gateway, streaming, and others.", + defined_tags : local.cmps_defined_tags, + freeform_tags : merge(local.cmps_freeform_tags, local.cislz_appdev_compartment_tags), + children : {} + } + } : {} + + database_compartment_key = "${var.service_label}-database-cmp" + default_database_compartment_name = "database-cmp" + provided_database_compartment_name = local.custom_database_compartment_name != null ? local.custom_database_compartment_name : "${var.service_label}-${local.default_database_compartment_name}" -module "lz_top_compartment" { - count = var.extend_landing_zone_to_new_region == false && var.use_enclosing_compartment == true && var.existing_enclosing_compartment_ocid == null ? 1 : 0 - source = "../modules/iam/iam-compartment" - providers = { oci = oci.home } - compartments = { - (local.enclosing_compartment.key) = { - parent_id = var.tenancy_ocid - name = local.enclosing_compartment.name - description = "Landing Zone enclosing compartment, enclosing all Landing Zone compartments." - enable_delete = local.enable_cmp_delete - defined_tags = local.compartments_defined_tags - freeform_tags = local.compartments_freeform_tags + cislz_database_compartment_tags = var.enable_template_policies == true ? { + "cislz-cmp-type":"database" + } : {} + + database_cmp = local.enable_database_compartment ? { + (local.database_compartment_key) : { + name : local.provided_database_compartment_name, + description : "CIS Landing Zone compartment for all database related resources.", + defined_tags : local.cmps_defined_tags, + freeform_tags : merge(local.cmps_freeform_tags, local.cislz_database_compartment_tags), + children : {} } + } : {} + + exainfra_compartment_key = "${var.service_label}-exainfra-cmp" + default_exainfra_compartment_name = "exainfra-cmp" + provided_exainfra_compartment_name = local.custom_exainfra_compartment_name != null ? local.custom_exainfra_compartment_name : "${var.service_label}-${local.default_exainfra_compartment_name}" + + cislz_exainfra_compartment_tags = var.enable_template_policies == true ? { + "cislz-cmp-type":"exainfra" + } : {} + + exainfra_cmp = local.enable_exainfra_compartment ? { + (local.exainfra_compartment_key) : { + name : local.provided_exainfra_compartment_name, + description : "CIS Landing Zone compartment for Exadata Cloud Service infrastructure.", + defined_tags : local.cmps_defined_tags, + freeform_tags : merge(local.cmps_freeform_tags, local.cislz_exainfra_compartment_tags), + children : {} + } + } : {} + + #------------------------------------------------------------------------ + #----- Enclosing compartment configuration definition. Input to module. + #------------------------------------------------------------------------ + enclosing_compartment_configuration = { + default_parent_ocid : var.tenancy_ocid + compartments : local.enclosing_cmp } -} -module "lz_compartments" { - source = "../modules/iam/iam-compartment" - providers = { oci = oci.home } - compartments = var.extend_landing_zone_to_new_region == false ? local.cmps : {} + #------------------------------------------------------------------------ + #----- Enclosing compartment configuration definition. Input to module. + #------------------------------------------------------------------------ + enclosed_compartments_configuration = { + default_parent_ocid : local.enclosing_compartment_id + compartments : merge(local.network_cmp, local.security_cmp, local.appdev_cmp, local.database_cmp, local.exainfra_cmp) + } + + empty_compartments_configuration = { + default_parent_ocid : null + compartments : {} + } + + #---------------------------------------------------------------------------------- + #----- Variables with compartment names and OCIDs per compartments module output + #---------------------------------------------------------------------------------- + enclosing_compartment_name = var.use_enclosing_compartment == true ? (var.existing_enclosing_compartment_ocid != null ? data.oci_identity_compartment.existing_enclosing_compartment.name : local.provided_enclosing_compartment_name /*module.lz_top_compartment[0].compartments[local.enclosing_compartment_key].name*/) : "tenancy" + enclosing_compartment_id = var.use_enclosing_compartment == true ? (var.existing_enclosing_compartment_ocid != null ? var.existing_enclosing_compartment_ocid : module.lz_top_compartment[0].compartments[local.enclosing_compartment_key].id) : var.tenancy_ocid + + security_compartment_name = var.extend_landing_zone_to_new_region == false ? module.lz_compartments.compartments[local.security_compartment_key].name : local.provided_security_compartment_name + #security_compartment_name = local.provided_security_compartment_name + security_compartment_id = var.extend_landing_zone_to_new_region == false ? module.lz_compartments.compartments[local.security_compartment_key].id : data.oci_identity_compartments.security.compartments[0].id + + network_compartment_name = var.extend_landing_zone_to_new_region == false ? module.lz_compartments.compartments[local.network_compartment_key].name : local.provided_network_compartment_name + #network_compartment_name = local.provided_network_compartment_name + network_compartment_id = var.extend_landing_zone_to_new_region == false ? module.lz_compartments.compartments[local.network_compartment_key].id : data.oci_identity_compartments.network.compartments[0].id + + appdev_compartment_name = var.extend_landing_zone_to_new_region == false ? module.lz_compartments.compartments[local.appdev_compartment_key].name : local.provided_appdev_compartment_name + #appdev_compartment_name = local.provided_appdev_compartment_name + appdev_compartment_id = var.extend_landing_zone_to_new_region == false ? module.lz_compartments.compartments[local.appdev_compartment_key].id : data.oci_identity_compartments.appdev.compartments[0].id + + database_compartment_name = var.extend_landing_zone_to_new_region == false ? module.lz_compartments.compartments[local.database_compartment_key].name : local.provided_database_compartment_name + #database_compartment_name = local.provided_database_compartment_name + database_compartment_id = var.extend_landing_zone_to_new_region == false ? module.lz_compartments.compartments[local.database_compartment_key].id : data.oci_identity_compartments.database.compartments[0].id + + exainfra_compartment_name = var.extend_landing_zone_to_new_region == false && var.deploy_exainfra_cmp == true ? module.lz_compartments.compartments[local.exainfra_compartment_key].name : local.provided_exainfra_compartment_name + #exainfra_compartment_name = local.provided_exainfra_compartment_name + exainfra_compartment_id = var.extend_landing_zone_to_new_region == false && var.deploy_exainfra_cmp == true ? module.lz_compartments.compartments[local.exainfra_compartment_key].id : length(data.oci_identity_compartments.exainfra.compartments) > 0 ? data.oci_identity_compartments.exainfra.compartments[0].id : "exainfra_cmp_undefined" } \ No newline at end of file diff --git a/config/iam_dynamic_groups.tf b/config/iam_dynamic_groups.tf index b251a9a0..7fafe008 100644 --- a/config/iam_dynamic_groups.tf +++ b/config/iam_dynamic_groups.tf @@ -1,63 +1,133 @@ -# Copyright (c) 2021 Oracle and/or its affiliates. +# 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. locals { - all_dynamic_groups = {} - all_dynamic_groups_defined_tags = {} - all_dynamic_groups_freeform_tags = {} - - # Names - security_functions_dynamic_group_name = length(trimspace(var.existing_security_fun_dyn_group_name)) == 0 ? "${var.service_label}-sec-fun-dynamic-group" : data.oci_identity_dynamic_groups.existing_security_fun_dyn_group.dynamic_groups[0].name - appdev_functions_dynamic_group_name = length(trimspace(var.existing_appdev_fun_dyn_group_name)) == 0 ? "${var.service_label}-appdev-fun-dynamic-group" : data.oci_identity_dynamic_groups.existing_appdev_fun_dyn_group.dynamic_groups[0].name - appdev_computeagent_dynamic_group_name = length(trimspace(var.existing_compute_agent_dyn_group_name)) == 0 ? "${var.service_label}-appdev-computeagent-dynamic-group" : data.oci_identity_dynamic_groups.existing_compute_agent_dyn_group.dynamic_groups[0].name - database_kms_dynamic_group_name = length(trimspace(var.existing_database_kms_dyn_group_name)) == 0 ? "${var.service_label}-database-kms-dynamic-group" : data.oci_identity_dynamic_groups.existing_database_kms_dyn_group.dynamic_groups[0].name - - - default_dynamic_groups = merge( - { for i in [1] : (local.security_functions_dynamic_group_name) => { - compartment_id = var.tenancy_ocid - description = "Landing Zone dynamic group for functions in ${local.security_compartment.name} compartment." - matching_rule = "ALL {resource.type = 'fnfunc',resource.compartment.id = '${local.security_compartment_id}'}" - defined_tags = local.dynamic_groups_defined_tags - freeform_tags = local.dynamic_groups_freeform_tags - } if length(trimspace(var.existing_security_fun_dyn_group_name)) == 0}, - { for i in [1] : (local.appdev_functions_dynamic_group_name) => { - compartment_id = var.tenancy_ocid - description = "Landing Zone dynamic group for functions in ${local.appdev_compartment.name} compartment." - matching_rule = "ALL {resource.type = 'fnfunc',resource.compartment.id = '${local.appdev_compartment_id}'}" - defined_tags = local.dynamic_groups_defined_tags + #------------------------------------------------------------------------------------------------------ + #-- Any of these local variables can be overriden in a _override.tf file + #------------------------------------------------------------------------------------------------------ + custom_dynamic_groups_configuration = null + + custom_security_fun_dyn_group_name = null + custom_appdev_fun_dyn_group_name = null + custom_appdev_computeagent_dyn_group_name = null + custom_database_kms_dyn_group_name = null + + custom_dynamic_groups_defined_tags = null + custom_dynamic_groups_freeform_tags = null +} + +module "lz_dynamic_groups" { + source = "github.com/oracle-quickstart/terraform-oci-cis-landing-zone-iam/dynamic-groups" + providers = { oci = oci.home } + tenancy_ocid = var.tenancy_ocid + dynamic_groups_configuration = var.extend_landing_zone_to_new_region == false ? (local.custom_dynamic_groups_configuration != null ? local.custom_dynamic_groups_configuration : local.dynamic_groups_configuration) : local.empty_dynamic_groups_configuration +} + +locals { + #------------------------------------------------------------------------------------------------------ + #-- These variables are not meant to be overriden + #------------------------------------------------------------------------------------------------------ + + #----------------------------------------------------------- + #----- Tags to apply to dynamic groups + #----------------------------------------------------------- + default_dynamic_groups_defined_tags = null + default_dynamic_groups_freeform_tags = local.landing_zone_tags + + dynamic_groups_defined_tags = local.custom_dynamic_groups_defined_tags != null ? merge(local.custom_dynamic_groups_defined_tags, local.default_dynamic_groups_defined_tags) : local.default_dynamic_groups_defined_tags + dynamic_groups_freeform_tags = local.custom_dynamic_groups_freeform_tags != null ? merge(local.custom_dynamic_groups_freeform_tags, local.default_dynamic_groups_freeform_tags) : local.default_dynamic_groups_freeform_tags + + #-------------------------------------------------------------------- + #-- Security functions Dynamic Group + #-------------------------------------------------------------------- + security_functions_dynamic_group_key = "${var.service_label}-sec-fun-dynamic-group" + default_security_functions_dynamic_group_name = "sec-fun-dynamic-group" + provided_security_functions_dynamic_group_name = local.custom_security_fun_dyn_group_name != null ? local.custom_security_fun_dyn_group_name : "${var.service_label}-${local.default_security_functions_dynamic_group_name}" #data.oci_identity_dynamic_groups.existing_security_fun_dyn_group.dynamic_groups[0].name + + security_functions_dynamic_group = length(trimspace(var.existing_security_fun_dyn_group_name)) == 0 ? { + (local.security_functions_dynamic_group_key) = { + name = local.provided_security_functions_dynamic_group_name + description = "CIS Landing Zone dynamic group for security functions execution." + matching_rule = "ALL {resource.type = 'fnfunc',resource.compartment.id = '${local.security_compartment_id}'}" + defined_tags = local.dynamic_groups_defined_tags freeform_tags = local.dynamic_groups_freeform_tags - } if length(trimspace(var.existing_appdev_fun_dyn_group_name)) == 0}, - { for i in [1] : (local.appdev_computeagent_dynamic_group_name) => { - compartment_id = var.tenancy_ocid - description = "Landing Zone dynamic group for compute agents in ${local.appdev_compartment.name} compartment." - matching_rule = "ALL {resource.type = 'managementagent',resource.compartment.id = '${local.appdev_compartment_id}'}" - defined_tags = local.dynamic_groups_defined_tags + } + } : {} + + #-------------------------------------------------------------------- + #-- AppDev functions Dynamic Group + #-------------------------------------------------------------------- + appdev_functions_dynamic_group_key = "${var.service_label}-appdev-fun-dynamic-group" + default_appdev_functions_dynamic_group_name = "appdev-fun-dynamic-group" + provided_appdev_functions_dynamic_group_name = local.custom_appdev_fun_dyn_group_name != null ? local.custom_appdev_fun_dyn_group_name : "${var.service_label}-${local.default_appdev_functions_dynamic_group_name}" #data.oci_identity_dynamic_groups.existing_appdev_fun_dyn_group.dynamic_groups[0].name + + appdev_functions_dynamic_group = length(trimspace(var.existing_appdev_fun_dyn_group_name)) == 0 ? { + (local.appdev_functions_dynamic_group_key) = { + name = local.provided_appdev_functions_dynamic_group_name + description = "CIS Landing Zone dynamic group for application functions execution." + matching_rule = "ALL {resource.type = 'fnfunc',resource.compartment.id = '${local.appdev_compartment_id}'}" + defined_tags = local.dynamic_groups_defined_tags freeform_tags = local.dynamic_groups_freeform_tags - } if length(trimspace(var.existing_compute_agent_dyn_group_name)) == 0}, - { for i in [1] : (local.database_kms_dynamic_group_name) => { - compartment_id = var.tenancy_ocid - description = "Landing Zone dynamic group for databases in ${local.database_compartment.name} compartment." - matching_rule = "ALL {resource.compartment.id = '${local.database_compartment_id}'}" - defined_tags = local.dynamic_groups_defined_tags + } + } : {} + + #-------------------------------------------------------------------- + #-- AppDev compute agent Dynamic Group + #-------------------------------------------------------------------- + appdev_computeagent_dynamic_group_key = "${var.service_label}-appdev-computeagent-dynamic-group" + default_appdev_computeagent_dynamic_group_name = "appdev-computeagent-dynamic-group" + provided_appdev_computeagent_dynamic_group_name = local.custom_appdev_computeagent_dyn_group_name != null ? local.custom_appdev_computeagent_dyn_group_name : "${var.service_label}-${local.default_appdev_computeagent_dynamic_group_name}" #data.oci_identity_dynamic_groups.existing_compute_agent_dyn_group.dynamic_groups[0].name + + appdev_computeagent_dynamic_group = length(trimspace(var.existing_compute_agent_dyn_group_name)) == 0 ? { + (local.appdev_computeagent_dynamic_group_key) = { + name = local.provided_appdev_computeagent_dynamic_group_name + description = "CIS Landing Zone dynamic group for Compute Agent plugin execution." + matching_rule = "ALL {resource.type = 'managementagent',resource.compartment.id = '${local.appdev_compartment_id}'}" + defined_tags = local.dynamic_groups_defined_tags freeform_tags = local.dynamic_groups_freeform_tags - } if length(trimspace(var.existing_database_kms_dyn_group_name)) == 0} - ) + } + } : {} - ### DON'T TOUCH THESE ### - default_dynamic_groups_defined_tags = null - default_dynamic_groups_freeform_tags = local.landing_zone_tags + #-------------------------------------------------------------------- + #-- Database KMS Dynamic Group + #-------------------------------------------------------------------- + database_kms_dynamic_group_key = "${var.service_label}-database-kms-dynamic-group" + default_database_kms_dynamic_group_name = "database-kms-dynamic-group" + provided_database_kms_dynamic_group_name = local.custom_database_kms_dyn_group_name != null ? local.custom_database_kms_dyn_group_name : "${var.service_label}-${local.default_database_kms_dynamic_group_name}" #data.oci_identity_dynamic_groups.existing_database_kms_dyn_group.dynamic_groups[0].name - dynamic_groups_defined_tags = length(local.all_dynamic_groups_defined_tags) > 0 ? local.all_dynamic_groups_defined_tags : local.default_dynamic_groups_defined_tags - dynamic_groups_freeform_tags = length(local.all_dynamic_groups_freeform_tags) > 0 ? merge(local.all_dynamic_groups_freeform_tags, local.default_dynamic_groups_freeform_tags) : local.default_dynamic_groups_freeform_tags + database_kms_dynamic_group = length(trimspace(var.existing_database_kms_dyn_group_name)) == 0 ? { + (local.database_kms_dynamic_group_key) = { + name = local.provided_database_kms_dynamic_group_name + description = "CIS Landing Zone dynamic group for databases accessing Key Management service (aka Vault service)." + matching_rule = "ALL {resource.compartment.id = '${local.database_compartment_id}'}" + defined_tags = local.dynamic_groups_defined_tags + freeform_tags = local.dynamic_groups_freeform_tags + } + } : {} -} + #------------------------------------------------------------------------ + #----- Dynamic groups configuration definition. Input to module. + #------------------------------------------------------------------------ + dynamic_groups_configuration = { + dynamic_groups : merge(local.security_functions_dynamic_group, local.appdev_functions_dynamic_group, + local.appdev_computeagent_dynamic_group, local.database_kms_dynamic_group) + } -module "lz_dynamic_groups" { - depends_on = [module.lz_compartments] - source = "../modules/iam/iam-dynamic-group" - providers = { oci = oci.home } - #dynamic_groups = length(local.all_dynamic_groups) > 0 ? local.all_dynamic_groups : local.default_dynamic_groups - dynamic_groups = var.extend_landing_zone_to_new_region == false ? (length(local.all_dynamic_groups) > 0 ? local.all_dynamic_groups : local.default_dynamic_groups) : {} + empty_dynamic_groups_configuration = { + dynamic_groups : {} + } + + #---------------------------------------------------------------------------------------- + #----- We cannot reference the module output for obtaining dynamic group names, + #----- because it creates a TF cycle issue with the compartments module that may + #----- reference the dynamic group that references the compartment in the matching + #----- clause that references the dynamic group that references the compartment that ... + #----- Hence the usage of provided_* local variables instead of the dynamic groups + #----- module output for the true case in the assignments below. + #---------------------------------------------------------------------------------------- + security_functions_dynamic_group_name = length(trimspace(var.existing_security_fun_dyn_group_name)) == 0 ? local.provided_security_functions_dynamic_group_name : var.existing_security_fun_dyn_group_name + appdev_functions_dynamic_group_name = length(trimspace(var.existing_appdev_fun_dyn_group_name)) == 0 ? local.provided_appdev_functions_dynamic_group_name : var.existing_appdev_fun_dyn_group_name + appdev_computeagent_dynamic_group_name = length(trimspace(var.existing_compute_agent_dyn_group_name)) == 0 ? local.provided_appdev_computeagent_dynamic_group_name : var.existing_compute_agent_dyn_group_name + database_kms_dynamic_group_name = length(trimspace(var.existing_database_kms_dyn_group_name)) == 0 ? local.provided_database_kms_dynamic_group_name : var.existing_database_kms_dyn_group_name } diff --git a/config/iam_groups.tf b/config/iam_groups.tf index 12e0f36a..a4f6b5bb 100644 --- a/config/iam_groups.tf +++ b/config/iam_groups.tf @@ -1,97 +1,275 @@ -# Copyright (c) 2021 Oracle and/or its affiliates. +# 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. ### This Terraform configuration provisions Landing Zone groups. locals { - all_groups_defined_tags = {} - all_groups_freeform_tags = {} + #------------------------------------------------------------------------------------------------------ + #-- Any of these local variables can be overriden in a _override.tf file + #------------------------------------------------------------------------------------------------------ + custom_groups_defined_tags = null + custom_groups_freeform_tags = null - default_groups = merge( - { for i in [1] : (local.network_admin_group_name) => { - description = "Landing Zone group for managing networking in compartment ${local.network_compartment.name}." - user_ids = [] + custom_iam_admin_group_name = null + custom_cred_admin_group_name = null + custom_cost_admin_group_name = null + custom_network_admin_group_name = null + custom_security_admin_group_name = null + custom_appdev_admin_group_name = null + custom_database_admin_group_name = null + custom_exainfra_admin_group_name = null + custom_storage_admin_group_name = null + custom_auditor_group_name = null + custom_announcement_reader_group_name = null +} + +module "lz_groups" { + source = "github.com/oracle-quickstart/terraform-oci-cis-landing-zone-iam/groups" + providers = { oci = oci.home } + tenancy_ocid = var.tenancy_ocid + groups_configuration = var.extend_landing_zone_to_new_region == false ? local.groups_configuration : local.empty_groups_configuration +} + +locals { + #------------------------------------------------------------------------------------------------------ + #-- These variables are not meant to be overriden + #------------------------------------------------------------------------------------------------------ + + #----------------------------------------------------------- + #----- Tags to apply to groups + #----------------------------------------------------------- + default_groups_defined_tags = null + default_groups_freeform_tags = local.landing_zone_tags + + groups_defined_tags = local.custom_groups_defined_tags != null ? merge(local.custom_groups_defined_tags, local.default_groups_defined_tags) : local.default_groups_defined_tags + groups_freeform_tags = local.custom_groups_freeform_tags != null ? merge(local.custom_groups_freeform_tags, local.default_groups_freeform_tags) : local.default_groups_freeform_tags + + #-------------------------------------------------------------------- + #-- IAM Admin + #-------------------------------------------------------------------- + iam_admin_group_key = "${var.service_label}-iam-admin-group" + default_iam_admin_group_name = "iam-admin-group" + provided_iam_admin_group_name = local.custom_iam_admin_group_name != null ? local.custom_iam_admin_group_name : "${var.service_label}-${local.default_iam_admin_group_name}" + + iam_admin_group = length(trimspace(var.existing_iam_admin_group_name)) == 0 ? { + (local.iam_admin_group_key) = { + name = local.provided_iam_admin_group_name + description = "CIS Landing Zone group for managing IAM resources in the tenancy." + members = [] defined_tags = local.groups_defined_tags freeform_tags = local.groups_freeform_tags - } if length(trimspace(var.existing_network_admin_group_name)) == 0 }, - { for i in [1] : (local.security_admin_group_name) => { - description = "Landing Zone group for managing security services in compartment ${local.security_compartment.name}." - user_ids = [] + } + } : {} + + #-------------------------------------------------------------------- + #-- Credentials Admin + #-------------------------------------------------------------------- + cred_admin_group_key = "${var.service_label}-cred-admin-group" + default_cred_admin_group_name = "cred-admin-group" + provided_cred_admin_group_name = local.custom_cred_admin_group_name != null ? local.custom_cred_admin_group_name : "${var.service_label}-${local.default_cred_admin_group_name}" + + cred_admin_group = length(trimspace(var.existing_cred_admin_group_name)) == 0 ? { + (local.cred_admin_group_key) = { + name = local.provided_cred_admin_group_name + description = "CIS Landing Zone group for managing users credentials in the tenancy." + members = [] defined_tags = local.groups_defined_tags freeform_tags = local.groups_freeform_tags - } if length(trimspace(var.existing_security_admin_group_name)) == 0 }, - { for i in [1] : (local.appdev_admin_group_name) => { - description = "Landing Zone group for managing app development related services in compartment ${local.appdev_compartment.name}." - user_ids = [] + } + } : {} + + #-------------------------------------------------------------------- + #-- Cost Admin + #-------------------------------------------------------------------- + cost_admin_group_key = "${var.service_label}-cost-admin-group" + default_cost_admin_group_name = "cost-admin-group" + provided_cost_admin_group_name = local.custom_cost_admin_group_name != null ? local.custom_cost_admin_group_name : "${var.service_label}-${local.default_cost_admin_group_name}" + + cost_admin_group = length(trimspace(var.existing_cost_admin_group_name)) == 0 ? { + (local.cost_admin_group_key) = { + name = local.provided_cost_admin_group_name + description = "CIS Landing Zone group for Cost management." + members = [] defined_tags = local.groups_defined_tags freeform_tags = local.groups_freeform_tags - } if length(trimspace(var.existing_appdev_admin_group_name)) == 0 }, - { for i in [1] : (local.database_admin_group_name) => { - description = "Landing Zone group for managing databases in compartment ${local.database_compartment.name}." - user_ids = [] + } + } : {} + + #-------------------------------------------------------------------- + #-- Network Admin + #-------------------------------------------------------------------- + network_admin_group_key = "${var.service_label}-network-admin-group" + default_network_admin_group_name = "network-admin-group" + provided_network_admin_group_name = local.custom_network_admin_group_name != null ? local.custom_network_admin_group_name : "${var.service_label}-${local.default_network_admin_group_name}" + + network_admin_group = length(trimspace(var.existing_network_admin_group_name)) == 0 ? { + (local.network_admin_group_key) = { + name = local.provided_network_admin_group_name + description = "CIS Landing Zone group for network management." + members = [] defined_tags = local.groups_defined_tags freeform_tags = local.groups_freeform_tags - } if length(trimspace(var.existing_database_admin_group_name)) == 0 }, - { for i in [1] : (local.auditor_group_name) => { - description = "Landing Zone group for auditing the tenancy." - user_ids = [] + } + } : {} + + #-------------------------------------------------------------------- + #-- Security Admin + #-------------------------------------------------------------------- + security_admin_group_key = "${var.service_label}-security-admin-group" + default_security_admin_group_name = "security-admin-group" + provided_security_admin_group_name = local.custom_security_admin_group_name != null ? local.custom_security_admin_group_name : "${var.service_label}-${local.default_security_admin_group_name}" + + security_admin_group = length(trimspace(var.existing_security_admin_group_name)) == 0 ? { + (local.security_admin_group_key) = { + name = local.provided_security_admin_group_name + description = "CIS Landing Zone group for security services management." + members = [] defined_tags = local.groups_defined_tags freeform_tags = local.groups_freeform_tags - } if length(trimspace(var.existing_auditor_group_name)) == 0 }, - { for i in [1] : (local.announcement_reader_group_name) => { - description = "Landing Zone group for reading Console announcements." - user_ids = [] + } + } : {} + + #-------------------------------------------------------------------- + #-- AppDev Admin + #-------------------------------------------------------------------- + appdev_admin_group_key = "${var.service_label}-appdev-admin-group" + default_appdev_admin_group_name = "appdev-admin-group" + provided_appdev_admin_group_name = local.custom_appdev_admin_group_name != null ? local.custom_appdev_admin_group_name : "${var.service_label}-${local.default_appdev_admin_group_name}" + + appdev_admin_group = length(trimspace(var.existing_appdev_admin_group_name)) == 0 ? { + (local.appdev_admin_group_key) = { + name = local.provided_appdev_admin_group_name + description = "CIS Landing Zone group for managing app development related services." + members = [] defined_tags = local.groups_defined_tags freeform_tags = local.groups_freeform_tags - } if length(trimspace(var.existing_announcement_reader_group_name)) == 0 }, - { for i in [1] : (local.iam_admin_group_name) => { - description = "Landing Zone group for managing IAM resources in the tenancy." - user_ids = [] + } + } : {} + + #-------------------------------------------------------------------- + #-- Database Admin + #-------------------------------------------------------------------- + database_admin_group_key = "${var.service_label}-database-admin-group" + default_database_admin_group_name = "database-admin-group" + provided_database_admin_group_name = local.custom_database_admin_group_name != null ? local.custom_database_admin_group_name : "${var.service_label}-${local.default_database_admin_group_name}" + + database_admin_group = length(trimspace(var.existing_database_admin_group_name)) == 0 ? { + (local.database_admin_group_key) = { + name = local.provided_database_admin_group_name + description = "CIS Landing Zone group for managing databases." + members = [] defined_tags = local.groups_defined_tags freeform_tags = local.groups_freeform_tags - } if length(trimspace(var.existing_iam_admin_group_name)) == 0 }, - { for i in [1] : (local.cred_admin_group_name) => { - description = "Landing Zone group for managing users credentials in the tenancy." - user_ids = [] + } + } : {} + + #-------------------------------------------------------------------- + #-- Exainfra Admin + #-------------------------------------------------------------------- + exainfra_admin_group_key = "${var.service_label}-exainfra-admin-group" + default_exainfra_admin_group_name = "exainfra-admin-group" + provided_exainfra_admin_group_name = local.custom_exainfra_admin_group_name != null ? local.custom_exainfra_admin_group_name : "${var.service_label}-${local.default_exainfra_admin_group_name}" + + exainfra_admin_group = var.deploy_exainfra_cmp == true && length(trimspace(var.existing_exainfra_admin_group_name)) == 0 ? { + (local.exainfra_admin_group_key) = { + name = local.provided_exainfra_admin_group_name + description = "CIS Landing Zone group for managing Exadata Cloud Service infrastructure." + members = [] defined_tags = local.groups_defined_tags freeform_tags = local.groups_freeform_tags - } if length(trimspace(var.existing_cred_admin_group_name)) == 0 }, - { for i in [1] : (local.cost_admin_group_name) => { - description = "Landing Zone group for Cost Management." - user_ids = [] + } + } : {} + + #------------------------------------------------------------------------ + #-- Storage admin + #------------------------------------------------------------------------ + storage_admin_group_key = "${var.service_label}-storage-admin-group" + default_storage_admin_group_name = "storage-admin-group" + provided_storage_admin_group_name = local.custom_storage_admin_group_name != null ? local.custom_storage_admin_group_name : "${var.service_label}-${local.default_storage_admin_group_name}" + + storage_admin_group = length(trimspace(var.existing_storage_admin_group_name)) == 0 ? { + (local.storage_admin_group_key) = { + name = local.provided_storage_admin_group_name + description = "CIS Landing Zone group for storage services management." + members = [] defined_tags = local.groups_defined_tags freeform_tags = local.groups_freeform_tags - } if length(trimspace(var.existing_cost_admin_group_name)) == 0 }, - { for i in [1] : (local.storage_admin_group_name) => { - description = "Landing Zone group for Storage Management." - user_ids = [] + } + } : {} + + #------------------------------------------------------------------------ + #-- Auditors + #------------------------------------------------------------------------ + auditor_group_key = "${var.service_label}-auditor-group" + default_auditor_group_name = "auditor-group" + provided_auditor_group_name = local.custom_auditor_group_name != null ? local.custom_auditor_group_name : "${var.service_label}-${local.default_auditor_group_name}" + + auditor_group = length(trimspace(var.existing_auditor_group_name)) == 0 ? { + (local.auditor_group_key) = { + name = local.provided_auditor_group_name + description = "CIS Landing Zone group for auditing the tenancy." + members = [] defined_tags = local.groups_defined_tags freeform_tags = local.groups_freeform_tags - } if length(trimspace(var.existing_storage_admin_group_name)) == 0 } - ) - exainfra_group = var.deploy_exainfra_cmp == true && length(trimspace(var.existing_exainfra_admin_group_name)) == 0 ? { - (local.exainfra_admin_group_name) = { - description = "Landing Zone group for managing Exadata infrastructure in the tenancy." - user_ids = [] + } + } : {} + + #------------------------------------------------------------------------ + #-- Announcement readers + #------------------------------------------------------------------------ + announcement_reader_group_key = "${var.service_label}-announcement-reader-group" + default_announcement_reader_group_name = "announcement-reader-group" + provided_announcement_reader_group_name = local.custom_announcement_reader_group_name != null ? local.custom_announcement_reader_group_name : "${var.service_label}-${local.default_announcement_reader_group_name}" + + announcement_reader_group = length(trimspace(var.existing_announcement_reader_group_name)) == 0 ? { + (local.announcement_reader_group_key) = { + name = local.provided_announcement_reader_group_name + description = "CIS Landing Zone group for reading Console announcements." + members = [] defined_tags = local.groups_defined_tags freeform_tags = local.groups_freeform_tags } } : {} - - groups = merge(local.default_groups,local.exainfra_group) - ### DON'T TOUCH THESE ### - default_groups_defined_tags = null - default_groups_freeform_tags = local.landing_zone_tags + #------------------------------------------------------------------------ + #----- Groups configuration definition. Input to module. + #------------------------------------------------------------------------ + groups_configuration = { + groups : merge(local.iam_admin_group, local.cred_admin_group, local.cost_admin_group, + local.network_admin_group, local.security_admin_group, + local.appdev_admin_group, local.database_admin_group, local.exainfra_admin_group, + local.storage_admin_group, local.auditor_group, local.announcement_reader_group) + } - groups_defined_tags = length(local.all_groups_defined_tags) > 0 ? local.all_groups_defined_tags : local.default_groups_defined_tags - groups_freeform_tags = length(local.all_groups_freeform_tags) > 0 ? merge(local.all_groups_freeform_tags, local.default_groups_freeform_tags) : local.default_groups_freeform_tags + empty_groups_configuration = { + groups : {} + } -} + #---------------------------------------------------------------------------------- + #----- Variables with group names per groups module output + #---------------------------------------------------------------------------------- + iam_admin_group_name = length(trimspace(var.existing_iam_admin_group_name)) == 0 ? module.lz_groups.groups[local.iam_admin_group_key].name : (length(regexall("^ocid1.group.oc.*$", var.existing_iam_admin_group_name)) > 0 ? data.oci_identity_group.existing_iam_admin_group.name : var.existing_iam_admin_group_name) + cred_admin_group_name = length(trimspace(var.existing_cred_admin_group_name)) == 0 ? module.lz_groups.groups[local.cred_admin_group_key].name : (length(regexall("^ocid1.group.oc.*$", var.existing_cred_admin_group_name)) > 0 ? data.oci_identity_group.existing_cred_admin_group.name : var.existing_cred_admin_group_name) + security_admin_group_name = length(trimspace(var.existing_security_admin_group_name)) == 0 ? module.lz_groups.groups[local.security_admin_group_key].name : (length(regexall("^ocid1.group.oc.*$", var.existing_security_admin_group_name)) > 0 ? data.oci_identity_group.existing_security_admin_group.name : var.existing_security_admin_group_name) + network_admin_group_name = length(trimspace(var.existing_network_admin_group_name)) == 0 ? module.lz_groups.groups[local.network_admin_group_key].name : (length(regexall("^ocid1.group.oc.*$", var.existing_network_admin_group_name)) > 0 ? data.oci_identity_group.existing_network_admin_group.name : var.existing_network_admin_group_name) + database_admin_group_name = length(trimspace(var.existing_database_admin_group_name)) == 0 ? module.lz_groups.groups[local.database_admin_group_key].name : (length(regexall("^ocid1.group.oc.*$", var.existing_database_admin_group_name)) > 0 ? data.oci_identity_group.existing_database_admin_group.name : var.existing_database_admin_group_name) + appdev_admin_group_name = length(trimspace(var.existing_appdev_admin_group_name)) == 0 ? module.lz_groups.groups[local.appdev_admin_group_key].name : (length(regexall("^ocid1.group.oc.*$", var.existing_appdev_admin_group_name)) > 0 ? data.oci_identity_group.existing_appdev_admin_group.name : var.existing_appdev_admin_group_name) + auditor_group_name = length(trimspace(var.existing_auditor_group_name)) == 0 ? module.lz_groups.groups[local.auditor_group_key].name : (length(regexall("^ocid1.group.oc.*$", var.existing_auditor_group_name)) > 0 ? data.oci_identity_group.existing_auditor_group.name : var.existing_auditor_group_name) + announcement_reader_group_name = length(trimspace(var.existing_announcement_reader_group_name)) == 0 ? module.lz_groups.groups[local.announcement_reader_group_key].name : (length(regexall("^ocid1.group.oc.*$", var.existing_announcement_reader_group_name)) > 0 ? data.oci_identity_group.existing_announcement_reader_group.name : var.existing_announcement_reader_group_name) + cost_admin_group_name = length(trimspace(var.existing_cost_admin_group_name)) == 0 ? module.lz_groups.groups[local.cost_admin_group_key].name : (length(regexall("^ocid1.group.oc.*$", var.existing_cost_admin_group_name)) > 0 ? data.oci_identity_group.existing_cost_admin_group.name : var.existing_cost_admin_group_name) + storage_admin_group_name = length(trimspace(var.existing_storage_admin_group_name)) == 0 ? module.lz_groups.groups[local.storage_admin_group_key].name : (length(regexall("^ocid1.group.oc.*$", var.existing_storage_admin_group_name)) > 0 ? data.oci_identity_group.existing_storage_admin_group.name : var.existing_storage_admin_group_name) + exainfra_admin_group_name = var.deploy_exainfra_cmp ? ((trimspace(var.existing_exainfra_admin_group_name)) == 0 ? module.lz_groups.groups[local.exainfra_admin_group_key].name : (length(regexall("^ocid1.group.oc.*$", var.existing_exainfra_admin_group_name)) > 0 ? data.oci_identity_group.existing_exainfra_admin_group.name : var.existing_exainfra_admin_group_name)) : var.existing_exainfra_admin_group_name -module "lz_groups" { - source = "../modules/iam/iam-group" - providers = { oci = oci.home } - tenancy_ocid = var.tenancy_ocid - groups = var.extend_landing_zone_to_new_region == false ? local.groups : {} -} \ No newline at end of file + /* iam_admin_group_name = length(trimspace(var.existing_iam_admin_group_name)) == 0 ? local.provided_iam_admin_group_name : (length(regexall("^ocid1.group.oc.*$", var.existing_iam_admin_group_name)) > 0 ? data.oci_identity_group.existing_iam_admin_group.name : var.existing_iam_admin_group_name) + cred_admin_group_name = length(trimspace(var.existing_cred_admin_group_name)) == 0 ? local.provided_cred_admin_group_name : (length(regexall("^ocid1.group.oc.*$", var.existing_cred_admin_group_name)) > 0 ? data.oci_identity_group.existing_cred_admin_group.name : var.existing_cred_admin_group_name) + security_admin_group_name = length(trimspace(var.existing_security_admin_group_name)) == 0 ? local.provided_security_admin_group_name : (length(regexall("^ocid1.group.oc.*$", var.existing_security_admin_group_name)) > 0 ? data.oci_identity_group.existing_security_admin_group.name : var.existing_security_admin_group_name) + network_admin_group_name = length(trimspace(var.existing_network_admin_group_name)) == 0 ? local.provided_network_admin_group_name : (length(regexall("^ocid1.group.oc.*$", var.existing_network_admin_group_name)) > 0 ? data.oci_identity_group.existing_network_admin_group.name : var.existing_network_admin_group_name) + database_admin_group_name = length(trimspace(var.existing_database_admin_group_name)) == 0 ? local.provided_database_admin_group_name : (length(regexall("^ocid1.group.oc.*$", var.existing_database_admin_group_name)) > 0 ? data.oci_identity_group.existing_database_admin_group.name : var.existing_database_admin_group_name) + appdev_admin_group_name = length(trimspace(var.existing_appdev_admin_group_name)) == 0 ? local.provided_appdev_admin_group_name : (length(regexall("^ocid1.group.oc.*$", var.existing_appdev_admin_group_name)) > 0 ? data.oci_identity_group.existing_appdev_admin_group.name : var.existing_appdev_admin_group_name) + auditor_group_name = length(trimspace(var.existing_auditor_group_name)) == 0 ? local.provided_auditor_group_name : (length(regexall("^ocid1.group.oc.*$", var.existing_auditor_group_name)) > 0 ? data.oci_identity_group.existing_auditor_group.name : var.existing_auditor_group_name) + announcement_reader_group_name = length(trimspace(var.existing_announcement_reader_group_name)) == 0 ? local.provided_announcement_reader_group_name : (length(regexall("^ocid1.group.oc.*$", var.existing_announcement_reader_group_name)) > 0 ? data.oci_identity_group.existing_announcement_reader_group.name : var.existing_announcement_reader_group_name) + cost_admin_group_name = length(trimspace(var.existing_cost_admin_group_name)) == 0 ? local.provided_cost_admin_group_name : (length(regexall("^ocid1.group.oc.*$", var.existing_cost_admin_group_name)) > 0 ? data.oci_identity_group.existing_cost_admin_group.name : var.existing_cost_admin_group_name) + storage_admin_group_name = length(trimspace(var.existing_storage_admin_group_name)) == 0 ? local.provided_storage_admin_group_name : (length(regexall("^ocid1.group.oc.*$", var.existing_storage_admin_group_name)) > 0 ? data.oci_identity_group.existing_storage_admin_group.name : var.existing_storage_admin_group_name) + exainfra_admin_group_name = var.deploy_exainfra_cmp ? ((trimspace(var.existing_exainfra_admin_group_name)) == 0 ? local.provided_exainfra_admin_group_name : (length(regexall("^ocid1.group.oc.*$", var.existing_exainfra_admin_group_name)) > 0 ? data.oci_identity_group.existing_exainfra_admin_group.name : var.existing_exainfra_admin_group_name)) : var.existing_exainfra_admin_group_name + */ + } \ No newline at end of file diff --git a/config/iam_policies.tf b/config/iam_policies.tf index 42dc562a..394b278a 100644 --- a/config/iam_policies.tf +++ b/config/iam_policies.tf @@ -1,16 +1,36 @@ -# Copyright (c) 2022 Oracle and/or its affiliates. +# 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. -### This Terraform configuration provisions Landing Zone policies. - locals { - all_policies_defined_tags = {} - all_policies_freeform_tags = {} + #-------------------------------------------------------------------------- + #-- Any of these custom variables can be overriden in a _override.tf file + #-------------------------------------------------------------------------- + custom_policies_defined_tags = null + custom_policies_freeform_tags = null + + # Policy names + basic_root_policy_name = "${var.service_label}-basic-root-policy" + security_admin_policy_name = "${var.service_label}-security-admin-policy" + security_admin_root_policy_name = "${var.service_label}-security-admin-root-policy" + network_admin_policy_name = "${var.service_label}-network-admin-policy" + compute_agent_policy_name = "${var.service_label}-compute-agent-policy" + database_admin_policy_name = "${var.service_label}-database-admin-policy" + database_dynamic_group_policy_name = "${var.service_label}-database-dynamic_group-policy" + appdev_admin_policy_name = "${var.service_label}-appdev-admin-policy" + iam_admin_policy_name = "${var.service_label}-iam-admin-policy" + iam_admin_root_policy_name = "${var.service_label}-iam-admin-root-policy" + cred_admin_policy_name = "${var.service_label}-credential-admin-policy" + auditor_policy_name = "${var.service_label}-auditor-policy" + announcement_reader_policy_name = "${var.service_label}-announcement-reader-policy" + exainfra_admin_policy_name = "${var.service_label}-exainfra-admin-policy" + cost_admin_root_policy_name = "${var.service_label}-cost-admin-root-policy" + storage_admin_policy_name = "${var.service_label}-storage-admin-policy" ### User Group Policies ### ## IAM admin grants at the root compartment iam_admin_grants_on_root_cmp = [ "allow group ${local.iam_admin_group_name} to inspect users in tenancy", + "allow group ${local.iam_admin_group_name} to manage users in tenancy where all {request.operation != 'ListApiKeys',request.operation != 'ListAuthTokens',request.operation != 'ListCustomerSecretKeys',request.operation != 'UploadApiKey',request.operation != 'DeleteApiKey',request.operation != 'UpdateAuthToken',request.operation != 'CreateAuthToken',request.operation != 'DeleteAuthToken',request.operation != 'CreateSecretKey',request.operation != 'UpdateCustomerSecretKey',request.operation != 'DeleteCustomerSecretKey'}", # Users should be manage users and groups permissions via IDP "allow group ${local.iam_admin_group_name} to inspect groups in tenancy", "allow group ${local.iam_admin_group_name} to read policies in tenancy", @@ -57,131 +77,157 @@ locals { ## Security admin grants on Security compartment security_admin_grants_on_security_cmp = [ - "allow group ${local.security_admin_group_name} to read all-resources in compartment ${local.security_compartment.name}", - "allow group ${local.security_admin_group_name} to manage instance-family in compartment ${local.security_compartment.name}", + "allow group ${local.security_admin_group_name} to read all-resources in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to manage instance-family in compartment ${local.security_compartment_name}", # CIS 1.2 - 1.14 Level 2 - "allow group ${local.security_admin_group_name} to manage volume-family in compartment ${local.security_compartment.name} where all{request.permission != 'VOLUME_BACKUP_DELETE', request.permission != 'VOLUME_DELETE', request.permission != 'BOOT_VOLUME_BACKUP_DELETE'}", - "allow group ${local.security_admin_group_name} to manage object-family in compartment ${local.security_compartment.name} where all{request.permission != 'OBJECT_DELETE', request.permission != 'BUCKET_DELETE'}", - "allow group ${local.security_admin_group_name} to manage file-family in compartment ${local.security_compartment.name} where all{request.permission != 'FILE_SYSTEM_DELETE', request.permission != 'MOUNT_TARGET_DELETE', request.permission != 'EXPORT_SET_DELETE', request.permission != 'FILE_SYSTEM_DELETE_SNAPSHOT', request.permission != 'FILE_SYSTEM_NFSv3_UNEXPORT'}", - "allow group ${local.security_admin_group_name} to manage vaults in compartment ${local.security_compartment.name}", - "allow group ${local.security_admin_group_name} to manage keys in compartment ${local.security_compartment.name}", - "allow group ${local.security_admin_group_name} to manage secret-family in compartment ${local.security_compartment.name}", - "allow group ${local.security_admin_group_name} to manage logging-family in compartment ${local.security_compartment.name}", - "allow group ${local.security_admin_group_name} to manage serviceconnectors in compartment ${local.security_compartment.name}", - "allow group ${local.security_admin_group_name} to manage streams in compartment ${local.security_compartment.name}", - "allow group ${local.security_admin_group_name} to manage ons-family in compartment ${local.security_compartment.name}", - "allow group ${local.security_admin_group_name} to manage functions-family in compartment ${local.security_compartment.name}", - "allow group ${local.security_admin_group_name} to manage waas-family in compartment ${local.security_compartment.name}", - "allow group ${local.security_admin_group_name} to manage security-zone in compartment ${local.security_compartment.name}", - "allow group ${local.security_admin_group_name} to manage orm-stacks in compartment ${local.security_compartment.name}", - "allow group ${local.security_admin_group_name} to manage orm-jobs in compartment ${local.security_compartment.name}", - "allow group ${local.security_admin_group_name} to manage orm-config-source-providers in compartment ${local.security_compartment.name}", - "allow group ${local.security_admin_group_name} to manage vss-family in compartment ${local.security_compartment.name}", - "allow group ${local.security_admin_group_name} to read work-requests in compartment ${local.security_compartment.name}", - "allow group ${local.security_admin_group_name} to manage bastion-family in compartment ${local.security_compartment.name}", - "allow group ${local.security_admin_group_name} to read instance-agent-plugins in compartment ${local.security_compartment.name}", - "allow group ${local.security_admin_group_name} to manage cloudevents-rules in compartment ${local.security_compartment.name}", - "allow group ${local.security_admin_group_name} to manage alarms in compartment ${local.security_compartment.name}", - "allow group ${local.security_admin_group_name} to manage metrics in compartment ${local.security_compartment.name}"] + "allow group ${local.security_admin_group_name} to manage volume-family in compartment ${local.security_compartment_name} where all{request.permission != 'VOLUME_BACKUP_DELETE', request.permission != 'VOLUME_DELETE', request.permission != 'BOOT_VOLUME_BACKUP_DELETE'}", + "allow group ${local.security_admin_group_name} to manage object-family in compartment ${local.security_compartment_name} where all{request.permission != 'OBJECT_DELETE', request.permission != 'BUCKET_DELETE'}", + "allow group ${local.security_admin_group_name} to manage file-family in compartment ${local.security_compartment_name} where all{request.permission != 'FILE_SYSTEM_DELETE', request.permission != 'MOUNT_TARGET_DELETE', request.permission != 'EXPORT_SET_DELETE', request.permission != 'FILE_SYSTEM_DELETE_SNAPSHOT', request.permission != 'FILE_SYSTEM_NFSv3_UNEXPORT'}", + "allow group ${local.security_admin_group_name} to manage vaults in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to manage keys in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to manage secret-family in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to manage logging-family in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to manage serviceconnectors in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to manage streams in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to manage ons-family in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to manage functions-family in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to manage waas-family in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to manage security-zone in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to manage orm-stacks in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to manage orm-jobs in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to manage orm-config-source-providers in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to manage vss-family in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to read work-requests in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to manage bastion-family in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to read instance-agent-plugins in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to manage cloudevents-rules in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to manage alarms in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to manage metrics in compartment ${local.security_compartment_name}", + "allow group ${local.security_admin_group_name} to use key-delegate in compartment ${local.security_compartment_name}"] ## Security admin grants on Network compartment security_admin_grants_on_network_cmp = [ - "allow group ${local.security_admin_group_name} to read virtual-network-family in compartment ${local.network_compartment.name}", - "allow group ${local.security_admin_group_name} to use subnets in compartment ${local.network_compartment.name}", - "allow group ${local.security_admin_group_name} to use network-security-groups in compartment ${local.network_compartment.name}", - "allow group ${local.security_admin_group_name} to use vnics in compartment ${local.network_compartment.name}"] + "allow group ${local.security_admin_group_name} to read virtual-network-family in compartment ${local.network_compartment_name}", + "allow group ${local.security_admin_group_name} to use subnets in compartment ${local.network_compartment_name}", + "allow group ${local.security_admin_group_name} to use network-security-groups in compartment ${local.network_compartment_name}", + "allow group ${local.security_admin_group_name} to use vnics in compartment ${local.network_compartment_name}", + "allow group ${local.security_admin_group_name} to manage private-ips in compartment ${local.network_compartment_name}", + "allow group ${local.security_admin_group_name} to read keys in compartment ${local.network_compartment_name}"] + + ## Security admin grants on AppDev compartment + security_admin_grants_on_appdev_cmp = [ + "allow group ${local.security_admin_group_name} to read keys in compartment ${local.appdev_compartment_name}" + ] + + ## Security admin grants on Database compartment + security_admin_grants_on_database_cmp = [ + "allow group ${local.security_admin_group_name} to read keys in compartment ${local.database_compartment_name}" + ] + + ## Security admin grants on Exainfra compartment + security_admin_grants_on_exainfra_cmp = var.deploy_exainfra_cmp == true ? [ + "allow group ${local.security_admin_group_name} to read keys in compartment ${local.exainfra_compartment_name}" + ] : [] ## All security admin grants - security_admin_grants = concat(local.security_admin_grants_on_enclosing_cmp, local.security_admin_grants_on_security_cmp, local.security_admin_grants_on_network_cmp) + security_admin_grants = concat(local.security_admin_grants_on_enclosing_cmp, local.security_admin_grants_on_security_cmp, local.security_admin_grants_on_network_cmp, + local.security_admin_grants_on_appdev_cmp, local.security_admin_grants_on_database_cmp, local.security_admin_grants_on_exainfra_cmp) ## Network admin grants on Network compartment network_admin_grants_on_network_cmp = [ - "allow group ${local.network_admin_group_name} to read all-resources in compartment ${local.network_compartment.name}", - "allow group ${local.network_admin_group_name} to manage virtual-network-family in compartment ${local.network_compartment.name}", - "allow group ${local.network_admin_group_name} to manage dns in compartment ${local.network_compartment.name}", - "allow group ${local.network_admin_group_name} to manage load-balancers in compartment ${local.network_compartment.name}", - "allow group ${local.network_admin_group_name} to manage alarms in compartment ${local.network_compartment.name}", - "allow group ${local.network_admin_group_name} to manage metrics in compartment ${local.network_compartment.name}", - "allow group ${local.network_admin_group_name} to manage ons-family in compartment ${local.network_compartment.name}", - "allow group ${local.network_admin_group_name} to manage orm-stacks in compartment ${local.network_compartment.name}", - "allow group ${local.network_admin_group_name} to manage orm-jobs in compartment ${local.network_compartment.name}", - "allow group ${local.network_admin_group_name} to manage orm-config-source-providers in compartment ${local.network_compartment.name}", - "allow group ${local.network_admin_group_name} to read audit-events in compartment ${local.network_compartment.name}", - "allow group ${local.network_admin_group_name} to read work-requests in compartment ${local.network_compartment.name}", - # CIS 1.2 - 1.14 Level 2 - "allow group ${local.network_admin_group_name} to manage instance-family in compartment ${local.network_compartment.name}", - "allow group ${local.network_admin_group_name} to manage volume-family in compartment ${local.network_compartment.name} where all{request.permission != 'VOLUME_BACKUP_DELETE', request.permission != 'VOLUME_DELETE', request.permission != 'BOOT_VOLUME_BACKUP_DELETE'}", - "allow group ${local.network_admin_group_name} to manage object-family in compartment ${local.network_compartment.name} where all{request.permission != 'OBJECT_DELETE', request.permission != 'BUCKET_DELETE'}", - "allow group ${local.network_admin_group_name} to manage file-family in compartment ${local.network_compartment.name} where all{request.permission != 'FILE_SYSTEM_DELETE', request.permission != 'MOUNT_TARGET_DELETE', request.permission != 'EXPORT_SET_DELETE', request.permission != 'FILE_SYSTEM_DELETE_SNAPSHOT', request.permission != 'FILE_SYSTEM_NFSv3_UNEXPORT'}", - - "allow group ${local.network_admin_group_name} to manage bastion-session in compartment ${local.network_compartment.name}", - "allow group ${local.network_admin_group_name} to manage cloudevents-rules in compartment ${local.network_compartment.name}", - "allow group ${local.network_admin_group_name} to manage alarms in compartment ${local.network_compartment.name}", - "allow group ${local.network_admin_group_name} to manage metrics in compartment ${local.network_compartment.name}", - "allow group ${local.network_admin_group_name} to read instance-agent-plugins in compartment ${local.network_compartment.name}"] + "allow group ${local.network_admin_group_name} to read all-resources in compartment ${local.network_compartment_name}", + "allow group ${local.network_admin_group_name} to manage virtual-network-family in compartment ${local.network_compartment_name}", + "allow group ${local.network_admin_group_name} to manage dns in compartment ${local.network_compartment_name}", + "allow group ${local.network_admin_group_name} to manage load-balancers in compartment ${local.network_compartment_name}", + "allow group ${local.network_admin_group_name} to manage alarms in compartment ${local.network_compartment_name}", + "allow group ${local.network_admin_group_name} to manage metrics in compartment ${local.network_compartment_name}", + "allow group ${local.network_admin_group_name} to manage ons-family in compartment ${local.network_compartment_name}", + "allow group ${local.network_admin_group_name} to manage orm-stacks in compartment ${local.network_compartment_name}", + "allow group ${local.network_admin_group_name} to manage orm-jobs in compartment ${local.network_compartment_name}", + "allow group ${local.network_admin_group_name} to manage orm-config-source-providers in compartment ${local.network_compartment_name}", + "allow group ${local.network_admin_group_name} to read audit-events in compartment ${local.network_compartment_name}", + "allow group ${local.network_admin_group_name} to read work-requests in compartment ${local.network_compartment_name}", + # CIS 1.2 - 1.14 Level 2 + "allow group ${local.network_admin_group_name} to manage instance-family in compartment ${local.network_compartment_name}", + "allow group ${local.network_admin_group_name} to manage volume-family in compartment ${local.network_compartment_name} where all{request.permission != 'VOLUME_BACKUP_DELETE', request.permission != 'VOLUME_DELETE', request.permission != 'BOOT_VOLUME_BACKUP_DELETE'}", + "allow group ${local.network_admin_group_name} to manage object-family in compartment ${local.network_compartment_name} where all{request.permission != 'OBJECT_DELETE', request.permission != 'BUCKET_DELETE'}", + "allow group ${local.network_admin_group_name} to manage file-family in compartment ${local.network_compartment_name} where all{request.permission != 'FILE_SYSTEM_DELETE', request.permission != 'MOUNT_TARGET_DELETE', request.permission != 'EXPORT_SET_DELETE', request.permission != 'FILE_SYSTEM_DELETE_SNAPSHOT', request.permission != 'FILE_SYSTEM_NFSv3_UNEXPORT'}", + + "allow group ${local.network_admin_group_name} to manage bastion-session in compartment ${local.network_compartment_name}", + "allow group ${local.network_admin_group_name} to manage cloudevents-rules in compartment ${local.network_compartment_name}", + "allow group ${local.network_admin_group_name} to manage alarms in compartment ${local.network_compartment_name}", + "allow group ${local.network_admin_group_name} to manage metrics in compartment ${local.network_compartment_name}", + "allow group ${local.network_admin_group_name} to read instance-agent-plugins in compartment ${local.network_compartment_name}", + "allow group ${local.network_admin_group_name} to manage keys in compartment ${local.network_compartment_name}", + "allow group ${local.network_admin_group_name} to use key-delegate in compartment ${local.network_compartment_name}", + "allow group ${local.network_admin_group_name} to manage secret-family in compartment ${local.network_compartment_name}"] ## Network admin grants on Security compartment network_admin_grants_on_security_cmp = [ - "allow group ${local.network_admin_group_name} to read vss-family in compartment ${local.security_compartment.name}", - "allow group ${local.network_admin_group_name} to use bastion in compartment ${local.security_compartment.name}", - "allow group ${local.network_admin_group_name} to manage bastion-session in compartment ${local.security_compartment.name}"] + "allow group ${local.network_admin_group_name} to read vss-family in compartment ${local.security_compartment_name}", + "allow group ${local.network_admin_group_name} to use bastion in compartment ${local.security_compartment_name}", + "allow group ${local.network_admin_group_name} to manage bastion-session in compartment ${local.security_compartment_name}", + "allow group ${local.network_admin_group_name} to use vaults in compartment ${local.security_compartment_name}", + "allow group ${local.network_admin_group_name} to read logging-family in compartment ${local.security_compartment_name}"] ## All network admin grants network_admin_grants = concat(local.network_admin_grants_on_network_cmp, local.network_admin_grants_on_security_cmp) ## Database admin grants on Database compartment database_admin_grants_on_database_cmp = [ - "allow group ${local.database_admin_group_name} to read all-resources in compartment ${local.database_compartment.name}", - "allow group ${local.database_admin_group_name} to manage database-family in compartment ${local.database_compartment.name}", - "allow group ${local.database_admin_group_name} to manage autonomous-database-family in compartment ${local.database_compartment.name}", - "allow group ${local.database_admin_group_name} to manage alarms in compartment ${local.database_compartment.name}", - "allow group ${local.database_admin_group_name} to manage metrics in compartment ${local.database_compartment.name}", - "allow group ${local.database_admin_group_name} to manage cloudevents-rules in compartment ${local.database_compartment.name}", + "allow group ${local.database_admin_group_name} to read all-resources in compartment ${local.database_compartment_name}", + "allow group ${local.database_admin_group_name} to manage database-family in compartment ${local.database_compartment_name}", + "allow group ${local.database_admin_group_name} to manage autonomous-database-family in compartment ${local.database_compartment_name}", + "allow group ${local.database_admin_group_name} to manage alarms in compartment ${local.database_compartment_name}", + "allow group ${local.database_admin_group_name} to manage metrics in compartment ${local.database_compartment_name}", + "allow group ${local.database_admin_group_name} to manage cloudevents-rules in compartment ${local.database_compartment_name}", # CIS 1.2 - 1.14 Level 2 - "allow group ${local.database_admin_group_name} to manage object-family in compartment ${local.database_compartment.name} where all{request.permission != 'OBJECT_DELETE', request.permission != 'BUCKET_DELETE'}", - "allow group ${local.database_admin_group_name} to manage instance-family in compartment ${local.database_compartment.name}", - "allow group ${local.database_admin_group_name} to manage volume-family in compartment ${local.database_compartment.name} where all{request.permission != 'VOLUME_BACKUP_DELETE', request.permission != 'VOLUME_DELETE', request.permission != 'BOOT_VOLUME_BACKUP_DELETE'}", - "allow group ${local.database_admin_group_name} to manage file-family in compartment ${local.database_compartment.name} where all{request.permission != 'FILE_SYSTEM_DELETE', request.permission != 'MOUNT_TARGET_DELETE', request.permission != 'EXPORT_SET_DELETE', request.permission != 'FILE_SYSTEM_DELETE_SNAPSHOT', request.permission != 'FILE_SYSTEM_NFSv3_UNEXPORT'}", - "allow group ${local.database_admin_group_name} to manage orm-stacks in compartment ${local.database_compartment.name}", - "allow group ${local.database_admin_group_name} to manage orm-jobs in compartment ${local.database_compartment.name}", - "allow group ${local.database_admin_group_name} to manage orm-config-source-providers in compartment ${local.database_compartment.name}", - "allow group ${local.database_admin_group_name} to manage ons-family in compartment ${local.database_compartment.name}", - "allow group ${local.database_admin_group_name} to manage logging-family in compartment ${local.database_compartment.name}", - "allow group ${local.database_admin_group_name} to read audit-events in compartment ${local.database_compartment.name}", - "allow group ${local.database_admin_group_name} to read work-requests in compartment ${local.database_compartment.name}", - "allow group ${local.database_admin_group_name} to manage bastion-session in compartment ${local.database_compartment.name}", - "allow group ${local.database_admin_group_name} to read instance-agent-plugins in compartment ${local.database_compartment.name}", - "allow group ${local.database_admin_group_name} to manage data-safe-family in compartment ${local.database_compartment.name}", - "allow group ${local.database_admin_group_name} to use vnics in compartment ${local.database_compartment.name}" - ] + "allow group ${local.database_admin_group_name} to manage object-family in compartment ${local.database_compartment_name} where all{request.permission != 'OBJECT_DELETE', request.permission != 'BUCKET_DELETE'}", + "allow group ${local.database_admin_group_name} to manage instance-family in compartment ${local.database_compartment_name}", + "allow group ${local.database_admin_group_name} to manage volume-family in compartment ${local.database_compartment_name} where all{request.permission != 'VOLUME_BACKUP_DELETE', request.permission != 'VOLUME_DELETE', request.permission != 'BOOT_VOLUME_BACKUP_DELETE'}", + "allow group ${local.database_admin_group_name} to manage file-family in compartment ${local.database_compartment_name} where all{request.permission != 'FILE_SYSTEM_DELETE', request.permission != 'MOUNT_TARGET_DELETE', request.permission != 'EXPORT_SET_DELETE', request.permission != 'FILE_SYSTEM_DELETE_SNAPSHOT', request.permission != 'FILE_SYSTEM_NFSv3_UNEXPORT'}", + "allow group ${local.database_admin_group_name} to manage orm-stacks in compartment ${local.database_compartment_name}", + "allow group ${local.database_admin_group_name} to manage orm-jobs in compartment ${local.database_compartment_name}", + "allow group ${local.database_admin_group_name} to manage orm-config-source-providers in compartment ${local.database_compartment_name}", + "allow group ${local.database_admin_group_name} to manage ons-family in compartment ${local.database_compartment_name}", + "allow group ${local.database_admin_group_name} to manage logging-family in compartment ${local.database_compartment_name}", + "allow group ${local.database_admin_group_name} to read audit-events in compartment ${local.database_compartment_name}", + "allow group ${local.database_admin_group_name} to read work-requests in compartment ${local.database_compartment_name}", + "allow group ${local.database_admin_group_name} to manage bastion-session in compartment ${local.database_compartment_name}", + "allow group ${local.database_admin_group_name} to read instance-agent-plugins in compartment ${local.database_compartment_name}", + "allow group ${local.database_admin_group_name} to manage data-safe-family in compartment ${local.database_compartment_name}", + "allow group ${local.database_admin_group_name} to use vnics in compartment ${local.database_compartment_name}", + "allow group ${local.database_admin_group_name} to manage keys in compartment ${local.database_compartment_name}", + "allow group ${local.database_admin_group_name} to use key-delegate in compartment ${local.database_compartment_name}", + "allow group ${local.database_admin_group_name} to manage secret-family in compartment ${local.database_compartment_name}"] ## Database admin grants on Network compartment database_admin_grants_on_network_cmp = [ - # https://docs.oracle.com/en-us/iaas/autonomous-database-shared/doc/iam-private-endpoint-configure-policies.html - "allow group ${local.database_admin_group_name} to read virtual-network-family in compartment ${local.network_compartment.name}", - "allow group ${local.database_admin_group_name} to use vnics in compartment ${local.network_compartment.name}", - "allow group ${local.database_admin_group_name} to manage private-ips in compartment ${local.network_compartment.name}", - "allow group ${local.database_admin_group_name} to use subnets in compartment ${local.network_compartment.name}", - "allow group ${local.database_admin_group_name} to use network-security-groups in compartment ${local.network_compartment.name}"] + # https://docs.oracle.com/en-us/iaas/autonomous-database-shared/doc/iam-private-endpoint-configure-policies.html + "allow group ${local.database_admin_group_name} to read virtual-network-family in compartment ${local.network_compartment_name}", + "allow group ${local.database_admin_group_name} to use vnics in compartment ${local.network_compartment_name}", + "allow group ${local.database_admin_group_name} to manage private-ips in compartment ${local.network_compartment_name}", + "allow group ${local.database_admin_group_name} to use subnets in compartment ${local.network_compartment_name}", + "allow group ${local.database_admin_group_name} to use network-security-groups in compartment ${local.network_compartment_name}"] ## Database admin grants on Security compartment database_admin_grants_on_security_cmp = [ - "allow group ${local.database_admin_group_name} to read vss-family in compartment ${local.security_compartment.name}", - "allow group ${local.database_admin_group_name} to read vaults in compartment ${local.security_compartment.name}", - "allow group ${local.database_admin_group_name} to read keys in compartment ${local.security_compartment.name}", - "allow group ${local.database_admin_group_name} to use bastion in compartment ${local.security_compartment.name}", - "allow group ${local.database_admin_group_name} to manage bastion-session in compartment ${local.security_compartment.name}"] + "allow group ${local.database_admin_group_name} to read vss-family in compartment ${local.security_compartment_name}", + "allow group ${local.database_admin_group_name} to use vaults in compartment ${local.security_compartment_name}", + "allow group ${local.database_admin_group_name} to read logging-family in compartment ${local.security_compartment_name}", + "allow group ${local.database_admin_group_name} to use bastion in compartment ${local.security_compartment_name}", + "allow group ${local.database_admin_group_name} to manage bastion-session in compartment ${local.security_compartment_name}"] ## Database admin grants on Exainfra compartment database_admin_grants_on_exainfra_cmp = var.deploy_exainfra_cmp == true ? [ - "allow group ${local.database_admin_group_name} to read cloud-exadata-infrastructures in compartment ${local.exainfra_compartment.name}", - "allow group ${local.database_admin_group_name} to use cloud-vmclusters in compartment ${local.exainfra_compartment.name}", - "allow group ${local.database_admin_group_name} to read work-requests in compartment ${local.exainfra_compartment.name}", - "allow group ${local.database_admin_group_name} to manage db-nodes in compartment ${local.exainfra_compartment.name}", - "allow group ${local.database_admin_group_name} to manage db-homes in compartment ${local.exainfra_compartment.name}", - "allow group ${local.database_admin_group_name} to manage databases in compartment ${local.exainfra_compartment.name}", - "allow group ${local.database_admin_group_name} to manage db-backups in compartment ${local.exainfra_compartment.name}", - "allow group ${local.database_admin_group_name} to manage data-safe-family in compartment ${local.exainfra_compartment.name}" + "allow group ${local.database_admin_group_name} to read cloud-exadata-infrastructures in compartment ${local.exainfra_compartment_name}", + "allow group ${local.database_admin_group_name} to use cloud-vmclusters in compartment ${local.exainfra_compartment_name}", + "allow group ${local.database_admin_group_name} to read work-requests in compartment ${local.exainfra_compartment_name}", + "allow group ${local.database_admin_group_name} to manage db-nodes in compartment ${local.exainfra_compartment_name}", + "allow group ${local.database_admin_group_name} to manage db-homes in compartment ${local.exainfra_compartment_name}", + "allow group ${local.database_admin_group_name} to manage databases in compartment ${local.exainfra_compartment_name}", + "allow group ${local.database_admin_group_name} to manage db-backups in compartment ${local.exainfra_compartment_name}", + "allow group ${local.database_admin_group_name} to manage data-safe-family in compartment ${local.exainfra_compartment_name}" ] : [] ## All database admin grants @@ -190,57 +236,62 @@ locals { ## AppDev admin grants on AppDev compartment appdev_admin_grants_on_appdev_cmp = [ - "allow group ${local.appdev_admin_group_name} to read all-resources in compartment ${local.appdev_compartment.name}", - "allow group ${local.appdev_admin_group_name} to manage functions-family in compartment ${local.appdev_compartment.name}", - "allow group ${local.appdev_admin_group_name} to manage api-gateway-family in compartment ${local.appdev_compartment.name}", - "allow group ${local.appdev_admin_group_name} to manage ons-family in compartment ${local.appdev_compartment.name}", - "allow group ${local.appdev_admin_group_name} to manage streams in compartment ${local.appdev_compartment.name}", - "allow group ${local.appdev_admin_group_name} to manage cluster-family in compartment ${local.appdev_compartment.name}", - "allow group ${local.appdev_admin_group_name} to manage alarms in compartment ${local.appdev_compartment.name}", - "allow group ${local.appdev_admin_group_name} to manage metrics in compartment ${local.appdev_compartment.name}", - "allow group ${local.appdev_admin_group_name} to manage logging-family in compartment ${local.appdev_compartment.name}", - "allow group ${local.appdev_admin_group_name} to manage instance-family in compartment ${local.appdev_compartment.name}", - # CIS 1.2 - 1.14 Level 2 - "allow group ${local.appdev_admin_group_name} to manage volume-family in compartment ${local.appdev_compartment.name} where all{request.permission != 'VOLUME_BACKUP_DELETE', request.permission != 'VOLUME_DELETE', request.permission != 'BOOT_VOLUME_BACKUP_DELETE'}", - "allow group ${local.appdev_admin_group_name} to manage object-family in compartment ${local.appdev_compartment.name} where all{request.permission != 'OBJECT_DELETE', request.permission != 'BUCKET_DELETE'}", - "allow group ${local.appdev_admin_group_name} to manage file-family in compartment ${local.appdev_compartment.name} where all{request.permission != 'FILE_SYSTEM_DELETE', request.permission != 'MOUNT_TARGET_DELETE', request.permission != 'EXPORT_SET_DELETE', request.permission != 'FILE_SYSTEM_DELETE_SNAPSHOT', request.permission != 'FILE_SYSTEM_NFSv3_UNEXPORT'}", - "allow group ${local.appdev_admin_group_name} to manage repos in compartment ${local.appdev_compartment.name}", - "allow group ${local.appdev_admin_group_name} to manage orm-stacks in compartment ${local.appdev_compartment.name}", - "allow group ${local.appdev_admin_group_name} to manage orm-jobs in compartment ${local.appdev_compartment.name}", - "allow group ${local.appdev_admin_group_name} to manage orm-config-source-providers in compartment ${local.appdev_compartment.name}", - "allow group ${local.appdev_admin_group_name} to read audit-events in compartment ${local.appdev_compartment.name}", - "allow group ${local.appdev_admin_group_name} to read work-requests in compartment ${local.appdev_compartment.name}", - "allow group ${local.appdev_admin_group_name} to manage bastion-session in compartment ${local.appdev_compartment.name}", - "allow group ${local.appdev_admin_group_name} to manage cloudevents-rules in compartment ${local.appdev_compartment.name}", - "allow group ${local.appdev_admin_group_name} to read instance-agent-plugins in compartment ${local.appdev_compartment.name}"] + "allow group ${local.appdev_admin_group_name} to read all-resources in compartment ${local.appdev_compartment_name}", + "allow group ${local.appdev_admin_group_name} to manage functions-family in compartment ${local.appdev_compartment_name}", + "allow group ${local.appdev_admin_group_name} to manage api-gateway-family in compartment ${local.appdev_compartment_name}", + "allow group ${local.appdev_admin_group_name} to manage ons-family in compartment ${local.appdev_compartment_name}", + "allow group ${local.appdev_admin_group_name} to manage streams in compartment ${local.appdev_compartment_name}", + "allow group ${local.appdev_admin_group_name} to manage cluster-family in compartment ${local.appdev_compartment_name}", + "allow group ${local.appdev_admin_group_name} to manage alarms in compartment ${local.appdev_compartment_name}", + "allow group ${local.appdev_admin_group_name} to manage metrics in compartment ${local.appdev_compartment_name}", + "allow group ${local.appdev_admin_group_name} to manage logging-family in compartment ${local.appdev_compartment_name}", + "allow group ${local.appdev_admin_group_name} to manage instance-family in compartment ${local.appdev_compartment_name}", + # CIS 1.2 - 1.14 Level 2 + "allow group ${local.appdev_admin_group_name} to manage volume-family in compartment ${local.appdev_compartment_name} where all{request.permission != 'VOLUME_BACKUP_DELETE', request.permission != 'VOLUME_DELETE', request.permission != 'BOOT_VOLUME_BACKUP_DELETE'}", + "allow group ${local.appdev_admin_group_name} to manage object-family in compartment ${local.appdev_compartment_name} where all{request.permission != 'OBJECT_DELETE', request.permission != 'BUCKET_DELETE'}", + "allow group ${local.appdev_admin_group_name} to manage file-family in compartment ${local.appdev_compartment_name} where all{request.permission != 'FILE_SYSTEM_DELETE', request.permission != 'MOUNT_TARGET_DELETE', request.permission != 'EXPORT_SET_DELETE', request.permission != 'FILE_SYSTEM_DELETE_SNAPSHOT', request.permission != 'FILE_SYSTEM_NFSv3_UNEXPORT'}", + "allow group ${local.appdev_admin_group_name} to manage repos in compartment ${local.appdev_compartment_name}", + "allow group ${local.appdev_admin_group_name} to manage orm-stacks in compartment ${local.appdev_compartment_name}", + "allow group ${local.appdev_admin_group_name} to manage orm-jobs in compartment ${local.appdev_compartment_name}", + "allow group ${local.appdev_admin_group_name} to manage orm-config-source-providers in compartment ${local.appdev_compartment_name}", + "allow group ${local.appdev_admin_group_name} to read audit-events in compartment ${local.appdev_compartment_name}", + "allow group ${local.appdev_admin_group_name} to read work-requests in compartment ${local.appdev_compartment_name}", + "allow group ${local.appdev_admin_group_name} to manage bastion-session in compartment ${local.appdev_compartment_name}", + "allow group ${local.appdev_admin_group_name} to manage cloudevents-rules in compartment ${local.appdev_compartment_name}", + "allow group ${local.appdev_admin_group_name} to read instance-agent-plugins in compartment ${local.appdev_compartment_name}", + "allow group ${local.appdev_admin_group_name} to manage keys in compartment ${local.appdev_compartment_name}", + "allow group ${local.appdev_admin_group_name} to use key-delegate in compartment ${local.appdev_compartment_name}", + "allow group ${local.appdev_admin_group_name} to manage secret-family in compartment ${local.appdev_compartment_name}"] ## AppDev admin grants on Network compartment appdev_admin_grants_on_network_cmp = [ - "allow group ${local.appdev_admin_group_name} to read virtual-network-family in compartment ${local.network_compartment.name}", - "allow group ${local.appdev_admin_group_name} to use subnets in compartment ${local.network_compartment.name}", - "allow group ${local.appdev_admin_group_name} to use network-security-groups in compartment ${local.network_compartment.name}", - "allow group ${local.appdev_admin_group_name} to use vnics in compartment ${local.network_compartment.name}", - "allow group ${local.appdev_admin_group_name} to use load-balancers in compartment ${local.network_compartment.name}"] + "allow group ${local.appdev_admin_group_name} to read virtual-network-family in compartment ${local.network_compartment_name}", + "allow group ${local.appdev_admin_group_name} to use subnets in compartment ${local.network_compartment_name}", + "allow group ${local.appdev_admin_group_name} to use network-security-groups in compartment ${local.network_compartment_name}", + "allow group ${local.appdev_admin_group_name} to use vnics in compartment ${local.network_compartment_name}", + "allow group ${local.appdev_admin_group_name} to manage private-ips in compartment ${local.network_compartment_name}", + "allow group ${local.appdev_admin_group_name} to use load-balancers in compartment ${local.network_compartment_name}"] ## AppDev admin grants on Security compartment appdev_admin_grants_on_security_cmp = [ - "allow group ${local.appdev_admin_group_name} to read vaults in compartment ${local.security_compartment.name}", - "allow group ${local.appdev_admin_group_name} to inspect keys in compartment ${local.security_compartment.name}", - "allow group ${local.appdev_admin_group_name} to manage instance-images in compartment ${local.security_compartment.name}", - "allow group ${local.appdev_admin_group_name} to read vss-family in compartment ${local.security_compartment.name}", - "allow group ${local.appdev_admin_group_name} to use bastion in compartment ${local.security_compartment.name}", - "allow group ${local.appdev_admin_group_name} to manage bastion-session in compartment ${local.security_compartment.name}"] + "allow group ${local.appdev_admin_group_name} to use vaults in compartment ${local.security_compartment_name}", + #"allow group ${local.appdev_admin_group_name} to inspect keys in compartment ${local.security_compartment_name}", + "allow group ${local.appdev_admin_group_name} to manage instance-images in compartment ${local.security_compartment_name}", + "allow group ${local.appdev_admin_group_name} to read vss-family in compartment ${local.security_compartment_name}", + "allow group ${local.appdev_admin_group_name} to use bastion in compartment ${local.security_compartment_name}", + "allow group ${local.appdev_admin_group_name} to manage bastion-session in compartment ${local.security_compartment_name}", + "allow group ${local.appdev_admin_group_name} to read logging-family in compartment ${local.security_compartment_name}"] ## AppDev admin grants on Database compartment appdev_admin_grants_on_database_cmp = [ - "allow group ${local.appdev_admin_group_name} to read autonomous-database-family in compartment ${local.database_compartment.name}", - "allow group ${local.appdev_admin_group_name} to read database-family in compartment ${local.database_compartment.name}"] + "allow group ${local.appdev_admin_group_name} to read autonomous-database-family in compartment ${local.database_compartment_name}", + "allow group ${local.appdev_admin_group_name} to read database-family in compartment ${local.database_compartment_name}"] ## AppDev admin grants on enclosing compartment appdev_admin_grants_on_enclosing_cmp = [ - "allow group ${local.appdev_admin_group_name} to read app-catalog-listing in ${local.policy_scope}", - "allow group ${local.appdev_admin_group_name} to read instance-images in ${local.policy_scope}", - "allow group ${local.appdev_admin_group_name} to read repos in ${local.policy_scope}"] + "allow group ${local.appdev_admin_group_name} to read app-catalog-listing in ${local.policy_scope}", + "allow group ${local.appdev_admin_group_name} to read instance-images in ${local.policy_scope}", + "allow group ${local.appdev_admin_group_name} to read repos in ${local.policy_scope}"] ## All AppDev admin grants appdev_admin_grants = concat(local.appdev_admin_grants_on_appdev_cmp, local.appdev_admin_grants_on_network_cmp, @@ -249,148 +300,165 @@ locals { ## Exainfra admin grants on Exinfra compartment exainfra_admin_grants_on_exainfra_cmp = [ - "allow group ${local.exainfra_admin_group_name} to manage cloud-exadata-infrastructures in compartment ${local.exainfra_compartment.name}", - "allow group ${local.exainfra_admin_group_name} to manage cloud-vmclusters in compartment ${local.exainfra_compartment.name}", - "allow group ${local.exainfra_admin_group_name} to read work-requests in compartment ${local.exainfra_compartment.name}", - "allow group ${local.exainfra_admin_group_name} to manage bastion-session in compartment ${local.exainfra_compartment.name}", - "allow group ${local.exainfra_admin_group_name} to manage instance-family in compartment ${local.exainfra_compartment.name}", - "allow group ${local.exainfra_admin_group_name} to read instance-agent-plugins in compartment ${local.exainfra_compartment.name}", - "allow group ${local.exainfra_admin_group_name} to manage ons-family in compartment ${local.exainfra_compartment.name}", - "allow group ${local.exainfra_admin_group_name} to manage alarms in compartment ${local.exainfra_compartment.name}", - "allow group ${local.exainfra_admin_group_name} to manage metrics in compartment ${local.exainfra_compartment.name}", - "allow group ${local.exainfra_admin_group_name} to manage data-safe-family in compartment ${local.exainfra_compartment.name}" - ] + "allow group ${local.exainfra_admin_group_name} to manage cloud-exadata-infrastructures in compartment ${local.exainfra_compartment_name}", + "allow group ${local.exainfra_admin_group_name} to manage cloud-vmclusters in compartment ${local.exainfra_compartment_name}", + "allow group ${local.exainfra_admin_group_name} to read work-requests in compartment ${local.exainfra_compartment_name}", + "allow group ${local.exainfra_admin_group_name} to manage bastion-session in compartment ${local.exainfra_compartment_name}", + "allow group ${local.exainfra_admin_group_name} to manage instance-family in compartment ${local.exainfra_compartment_name}", + "allow group ${local.exainfra_admin_group_name} to read instance-agent-plugins in compartment ${local.exainfra_compartment_name}", + "allow group ${local.exainfra_admin_group_name} to manage ons-family in compartment ${local.exainfra_compartment_name}", + "allow group ${local.exainfra_admin_group_name} to manage alarms in compartment ${local.exainfra_compartment_name}", + "allow group ${local.exainfra_admin_group_name} to manage metrics in compartment ${local.exainfra_compartment_name}", + "allow group ${local.exainfra_admin_group_name} to manage data-safe-family in compartment ${local.exainfra_compartment_name}", + "allow group ${local.exainfra_admin_group_name} to manage keys in compartment ${local.exainfra_compartment_name}", + "allow group ${local.exainfra_admin_group_name} to use key-delegate in compartment ${local.exainfra_compartment_name}", + "allow group ${local.exainfra_admin_group_name} to manage secret-family in compartment ${local.exainfra_compartment_name}"] ## Exainfra admin grants on Security compartment exainfra_admin_grants_on_security_cmp = [ - "allow group ${local.exainfra_admin_group_name} to use bastion in compartment ${local.security_compartment.name}", - "allow group ${local.exainfra_admin_group_name} to manage bastion-session in compartment ${local.security_compartment.name}"] - - ## Exainfra admin grants on Network compartment - exainfra_admin_grants_on_network_cmp = [ - "allow group ${local.exainfra_admin_group_name} to read virtual-network-family in compartment ${local.network_compartment.name}"] + "allow group ${local.exainfra_admin_group_name} to read vss-family in compartment ${local.security_compartment_name}", + "allow group ${local.exainfra_admin_group_name} to use vaults in compartment ${local.security_compartment_name}", + "allow group ${local.exainfra_admin_group_name} to read logging-family in compartment ${local.security_compartment_name}", + "allow group ${local.exainfra_admin_group_name} to use bastion in compartment ${local.security_compartment_name}", + "allow group ${local.exainfra_admin_group_name} to manage bastion-session in compartment ${local.security_compartment_name}"] + + ## Exainfra admin grants on Network compartment + exainfra_admin_grants_on_network_cmp = [ + "allow group ${local.exainfra_admin_group_name} to read virtual-network-family in compartment ${local.network_compartment_name}", + "allow group ${local.exainfra_admin_group_name} to use subnets in compartment ${local.network_compartment_name}", + "allow group ${local.exainfra_admin_group_name} to use network-security-groups in compartment ${local.network_compartment_name}", + "allow group ${local.exainfra_admin_group_name} to use vnics in compartment ${local.network_compartment_name}", + "allow group ${local.exainfra_admin_group_name} to manage private-ips in compartment ${local.network_compartment_name}"] ## All Exainfra admin grants exainfra_admin_grants = concat(local.exainfra_admin_grants_on_exainfra_cmp, local.exainfra_admin_grants_on_security_cmp, local.exainfra_admin_grants_on_network_cmp) ## Cost admin permissions to be created always at the Root compartment cost_root_permissions = ["define tenancy usage-report as ocid1.tenancy.oc1..aaaaaaaaned4fkpkisbwjlr56u7cj63lf3wffbilvqknstgtvzub7vhqkggq", + "endorse group ${local.cost_admin_group_name} to read objects in tenancy usage-report", "allow group ${local.cost_admin_group_name} to manage usage-report in tenancy", - "allow group ${local.cost_admin_group_name} to manage usage-budgets in tenancy", - "endorse group ${local.cost_admin_group_name} to read objects in tenancy usage-report"] + "allow group ${local.cost_admin_group_name} to manage usage-budgets in tenancy"] ### Dynamic Group Policies ### ## Compute Agent grants compute_agent_grants = [ - "allow dynamic-group ${local.appdev_computeagent_dynamic_group_name} to manage management-agents in compartment ${local.appdev_compartment.name}", - "allow dynamic-group ${local.appdev_computeagent_dynamic_group_name} to use metrics in compartment ${local.appdev_compartment.name}", - "allow dynamic-group ${local.appdev_computeagent_dynamic_group_name} to use tag-namespaces in compartment ${local.appdev_compartment.name}"] + "allow dynamic-group ${local.appdev_computeagent_dynamic_group_name} to manage management-agents in compartment ${local.appdev_compartment_name}", + "allow dynamic-group ${local.appdev_computeagent_dynamic_group_name} to use metrics in compartment ${local.appdev_compartment_name}", + "allow dynamic-group ${local.appdev_computeagent_dynamic_group_name} to use tag-namespaces in compartment ${local.appdev_compartment_name}"] ## ADB grants autonomous_database_grants = [ - "allow dynamic-group ${local.database_kms_dynamic_group_name} to use vaults in compartment ${local.security_compartment.name}", - "allow dynamic-group ${local.database_kms_dynamic_group_name} to use keys in compartment ${local.security_compartment.name}", - "allow dynamic-group ${local.database_kms_dynamic_group_name} to use secret-family in compartment ${local.security_compartment.name}"] + "allow dynamic-group ${local.database_kms_dynamic_group_name} to use vaults in compartment ${local.security_compartment_name}", + "allow dynamic-group ${local.database_kms_dynamic_group_name} to use keys in compartment ${local.database_compartment_name}", + "allow dynamic-group ${local.database_kms_dynamic_group_name} to use secret-family in compartment ${local.database_compartment_name}"] ## Storage admin grants storage_admin_grants = [ - # Grants in appdev compartment - # Object Storage - "allow group ${local.storage_admin_group_name} to read bucket in compartment ${local.appdev_compartment.name}", - "allow group ${local.storage_admin_group_name} to inspect object in compartment ${local.appdev_compartment.name}", - "allow group ${local.storage_admin_group_name} to manage object-family in compartment ${local.appdev_compartment.name} where any {request.permission = 'OBJECT_DELETE', request.permission = 'BUCKET_DELETE'}", - # Volume Storage - "allow group ${local.storage_admin_group_name} to read volume-family in compartment ${local.appdev_compartment.name}", - "allow group ${local.storage_admin_group_name} to manage volume-family in compartment ${local.appdev_compartment.name} where any {request.permission = 'VOLUME_DELETE', request.permission = 'VOLUME_BACKUP_DELETE', request.permission = 'BOOT_VOLUME_BACKUP_DELETE'}", - # File Storage - "allow group ${local.storage_admin_group_name} to read file-family in compartment ${local.appdev_compartment.name}", - "allow group ${local.storage_admin_group_name} to manage file-family in compartment ${local.appdev_compartment.name} where any {request.permission = 'FILE_SYSTEM_DELETE', request.permission = 'MOUNT_TARGET_DELETE', request.permission = 'EXPORT_SET_UPDATE', request.permission = 'FILE_SYSTEM_NFSv3_UNEXPORT', request.permission = 'EXPORT_SET_DELETE', request.permission = 'FILE_SYSTEM_DELETE_SNAPSHOT'}", - # Grants in database compartment - # Object Storage - "allow group ${local.storage_admin_group_name} to read bucket in compartment ${local.database_compartment.name}", - "allow group ${local.storage_admin_group_name} to inspect object in compartment ${local.database_compartment.name}", - "allow group ${local.storage_admin_group_name} to manage object-family in compartment ${local.database_compartment.name} where any {request.permission = 'OBJECT_DELETE', request.permission = 'BUCKET_DELETE'}", - # Volume Storage - "allow group ${local.storage_admin_group_name} to read volume-family in compartment ${local.database_compartment.name}", - "allow group ${local.storage_admin_group_name} to manage volume-family in compartment ${local.database_compartment.name} where any {request.permission = 'VOLUME_DELETE', request.permission = 'VOLUME_BACKUP_DELETE', request.permission = 'BOOT_VOLUME_BACKUP_DELETE'}", - # File Storage - "allow group ${local.storage_admin_group_name} to read file-family in compartment ${local.database_compartment.name}", - "allow group ${local.storage_admin_group_name} to manage file-family in compartment ${local.database_compartment.name} where any {request.permission = 'FILE_SYSTEM_DELETE', request.permission = 'MOUNT_TARGET_DELETE', request.permission = 'EXPORT_SET_UPDATE', request.permission = 'FILE_SYSTEM_NFSv3_UNEXPORT', request.permission = 'EXPORT_SET_DELETE', request.permission = 'FILE_SYSTEM_DELETE_SNAPSHOT'}", - # Grants in security compartment - # Object Storage - "allow group ${local.storage_admin_group_name} to read bucket in compartment ${local.security_compartment.name}", - "allow group ${local.storage_admin_group_name} to inspect object in compartment ${local.security_compartment.name}", - "allow group ${local.storage_admin_group_name} to manage object-family in compartment ${local.security_compartment.name} where any {request.permission = 'OBJECT_DELETE', request.permission = 'BUCKET_DELETE'}", - # Volume Storage - "allow group ${local.storage_admin_group_name} to read volume-family in compartment ${local.security_compartment.name}", - "allow group ${local.storage_admin_group_name} to manage volume-family in compartment ${local.security_compartment.name} where any {request.permission = 'VOLUME_DELETE', request.permission = 'VOLUME_BACKUP_DELETE', request.permission = 'BOOT_VOLUME_BACKUP_DELETE'}", - # File Storage - "allow group ${local.storage_admin_group_name} to read file-family in compartment ${local.security_compartment.name}", - "allow group ${local.storage_admin_group_name} to manage file-family in compartment ${local.security_compartment.name} where any {request.permission = 'FILE_SYSTEM_DELETE', request.permission = 'MOUNT_TARGET_DELETE', request.permission = 'EXPORT_SET_UPDATE', request.permission = 'FILE_SYSTEM_NFSv3_UNEXPORT', request.permission = 'EXPORT_SET_DELETE', request.permission = 'FILE_SYSTEM_DELETE_SNAPSHOT'}", - # Grants in network compartment - # Object Storage - "allow group ${local.storage_admin_group_name} to read bucket in compartment ${local.network_compartment.name}", - "allow group ${local.storage_admin_group_name} to inspect object in compartment ${local.network_compartment.name}", - "allow group ${local.storage_admin_group_name} to manage object-family in compartment ${local.network_compartment.name} where any {request.permission = 'OBJECT_DELETE', request.permission = 'BUCKET_DELETE'}", - # Volume Storage - "allow group ${local.storage_admin_group_name} to read volume-family in compartment ${local.network_compartment.name}", - "allow group ${local.storage_admin_group_name} to manage volume-family in compartment ${local.network_compartment.name} where any {request.permission = 'VOLUME_DELETE', request.permission = 'VOLUME_BACKUP_DELETE', request.permission = 'BOOT_VOLUME_BACKUP_DELETE'}", - # File Storage - "allow group ${local.storage_admin_group_name} to read file-family in compartment ${local.network_compartment.name}", - "allow group ${local.storage_admin_group_name} to manage file-family in compartment ${local.network_compartment.name} where any {request.permission = 'FILE_SYSTEM_DELETE', request.permission = 'MOUNT_TARGET_DELETE', request.permission = 'VNIC_DELETE', request.permission = 'SUBNET_DETACH', request.permission = 'VNIC_DETACH', request.permission = 'PRIVATE_IP_DELETE', request.permission = 'PRIVATE_IP_UNASSIGN', request.permission = 'VNIC_UNASSIGN', request.permission = 'EXPORT_SET_UPDATE', request.permission = 'FILE_SYSTEM_NFSv3_UNEXPORT', request.permission = 'EXPORT_SET_DELETE', request.permission = 'FILE_SYSTEM_DELETE_SNAPSHOT'}", + # Grants in appdev compartment + # Object Storage + "allow group ${local.storage_admin_group_name} to read bucket in compartment ${local.appdev_compartment_name}", + "allow group ${local.storage_admin_group_name} to inspect object in compartment ${local.appdev_compartment_name}", + "allow group ${local.storage_admin_group_name} to manage object-family in compartment ${local.appdev_compartment_name} where any {request.permission = 'OBJECT_DELETE', request.permission = 'BUCKET_DELETE'}", + # Volume Storage + "allow group ${local.storage_admin_group_name} to read volume-family in compartment ${local.appdev_compartment_name}", + "allow group ${local.storage_admin_group_name} to manage volume-family in compartment ${local.appdev_compartment_name} where any {request.permission = 'VOLUME_DELETE', request.permission = 'VOLUME_BACKUP_DELETE', request.permission = 'BOOT_VOLUME_BACKUP_DELETE'}", + # File Storage + "allow group ${local.storage_admin_group_name} to read file-family in compartment ${local.appdev_compartment_name}", + "allow group ${local.storage_admin_group_name} to manage file-family in compartment ${local.appdev_compartment_name} where any {request.permission = 'FILE_SYSTEM_DELETE', request.permission = 'MOUNT_TARGET_DELETE', request.permission = 'EXPORT_SET_UPDATE', request.permission = 'FILE_SYSTEM_NFSv3_UNEXPORT', request.permission = 'EXPORT_SET_DELETE', request.permission = 'FILE_SYSTEM_DELETE_SNAPSHOT'}", + # Grants in database compartment + # Object Storage + "allow group ${local.storage_admin_group_name} to read bucket in compartment ${local.database_compartment_name}", + "allow group ${local.storage_admin_group_name} to inspect object in compartment ${local.database_compartment_name}", + "allow group ${local.storage_admin_group_name} to manage object-family in compartment ${local.database_compartment_name} where any {request.permission = 'OBJECT_DELETE', request.permission = 'BUCKET_DELETE'}", + # Volume Storage + "allow group ${local.storage_admin_group_name} to read volume-family in compartment ${local.database_compartment_name}", + "allow group ${local.storage_admin_group_name} to manage volume-family in compartment ${local.database_compartment_name} where any {request.permission = 'VOLUME_DELETE', request.permission = 'VOLUME_BACKUP_DELETE', request.permission = 'BOOT_VOLUME_BACKUP_DELETE'}", + # File Storage + "allow group ${local.storage_admin_group_name} to read file-family in compartment ${local.database_compartment_name}", + "allow group ${local.storage_admin_group_name} to manage file-family in compartment ${local.database_compartment_name} where any {request.permission = 'FILE_SYSTEM_DELETE', request.permission = 'MOUNT_TARGET_DELETE', request.permission = 'EXPORT_SET_UPDATE', request.permission = 'FILE_SYSTEM_NFSv3_UNEXPORT', request.permission = 'EXPORT_SET_DELETE', request.permission = 'FILE_SYSTEM_DELETE_SNAPSHOT'}", + # Grants in security compartment + # Object Storage + "allow group ${local.storage_admin_group_name} to read bucket in compartment ${local.security_compartment_name}", + "allow group ${local.storage_admin_group_name} to inspect object in compartment ${local.security_compartment_name}", + "allow group ${local.storage_admin_group_name} to manage object-family in compartment ${local.security_compartment_name} where any {request.permission = 'OBJECT_DELETE', request.permission = 'BUCKET_DELETE'}", + # Volume Storage + "allow group ${local.storage_admin_group_name} to read volume-family in compartment ${local.security_compartment_name}", + "allow group ${local.storage_admin_group_name} to manage volume-family in compartment ${local.security_compartment_name} where any {request.permission = 'VOLUME_DELETE', request.permission = 'VOLUME_BACKUP_DELETE', request.permission = 'BOOT_VOLUME_BACKUP_DELETE'}", + # File Storage + "allow group ${local.storage_admin_group_name} to read file-family in compartment ${local.security_compartment_name}", + "allow group ${local.storage_admin_group_name} to manage file-family in compartment ${local.security_compartment_name} where any {request.permission = 'FILE_SYSTEM_DELETE', request.permission = 'MOUNT_TARGET_DELETE', request.permission = 'EXPORT_SET_UPDATE', request.permission = 'FILE_SYSTEM_NFSv3_UNEXPORT', request.permission = 'EXPORT_SET_DELETE', request.permission = 'FILE_SYSTEM_DELETE_SNAPSHOT'}", + # Grants in network compartment + # Object Storage + "allow group ${local.storage_admin_group_name} to read bucket in compartment ${local.network_compartment_name}", + "allow group ${local.storage_admin_group_name} to inspect object in compartment ${local.network_compartment_name}", + "allow group ${local.storage_admin_group_name} to manage object-family in compartment ${local.network_compartment_name} where any {request.permission = 'OBJECT_DELETE', request.permission = 'BUCKET_DELETE'}", + # Volume Storage + "allow group ${local.storage_admin_group_name} to read volume-family in compartment ${local.network_compartment_name}", + "allow group ${local.storage_admin_group_name} to manage volume-family in compartment ${local.network_compartment_name} where any {request.permission = 'VOLUME_DELETE', request.permission = 'VOLUME_BACKUP_DELETE', request.permission = 'BOOT_VOLUME_BACKUP_DELETE'}", + # File Storage + "allow group ${local.storage_admin_group_name} to read file-family in compartment ${local.network_compartment_name}", + "allow group ${local.storage_admin_group_name} to manage file-family in compartment ${local.network_compartment_name} where any {request.permission = 'FILE_SYSTEM_DELETE', request.permission = 'MOUNT_TARGET_DELETE', request.permission = 'VNIC_DELETE', request.permission = 'SUBNET_DETACH', request.permission = 'VNIC_DETACH', request.permission = 'PRIVATE_IP_DELETE', request.permission = 'PRIVATE_IP_UNASSIGN', request.permission = 'VNIC_UNASSIGN', request.permission = 'EXPORT_SET_UPDATE', request.permission = 'FILE_SYSTEM_NFSv3_UNEXPORT', request.permission = 'EXPORT_SET_DELETE', request.permission = 'FILE_SYSTEM_DELETE_SNAPSHOT'}", ] default_policies = { (local.compute_agent_policy_name) = { - compartment_id = local.enclosing_compartment_id - description = "Landing Zone policy for ${local.appdev_computeagent_dynamic_group_name} group to manage compute agent related services." - defined_tags = local.policies_defined_tags - freeform_tags = local.policies_freeform_tags - statements = local.compute_agent_grants + compartment_ocid = local.enclosing_compartment_id + name = local.compute_agent_policy_name + description = "Landing Zone policy for ${local.appdev_computeagent_dynamic_group_name} group to manage compute agent related services." + defined_tags = local.policies_defined_tags + freeform_tags = local.policies_freeform_tags + statements = local.compute_agent_grants }, (local.database_dynamic_group_policy_name) = { - compartment_id = local.enclosing_compartment_id - description = "Landing Zone policy for ${local.database_kms_dynamic_group_name} group to use keys in compartment ${local.security_compartment.name}." - defined_tags = local.policies_defined_tags - freeform_tags = local.policies_freeform_tags - statements = local.autonomous_database_grants + compartment_ocid = local.enclosing_compartment_id + name = local.database_dynamic_group_policy_name + description = "Landing Zone policy for ${local.database_kms_dynamic_group_name} group to use keys in compartment ${local.security_compartment_name}." + defined_tags = local.policies_defined_tags + freeform_tags = local.policies_freeform_tags + statements = local.autonomous_database_grants }, (local.network_admin_policy_name) = length(local.network_admin_grants) > 0 ? { - compartment_id = local.enclosing_compartment_id + compartment_ocid = local.enclosing_compartment_id + name = local.network_admin_policy_name description = "Landing Zone policy for ${local.network_admin_group_name} group to manage network related services." defined_tags = local.policies_defined_tags freeform_tags = local.policies_freeform_tags statements = local.network_admin_grants } : null, (local.security_admin_policy_name) = length(local.security_admin_grants) > 0 ? { - compartment_id = local.enclosing_compartment_id + compartment_ocid = local.enclosing_compartment_id + name = local.security_admin_policy_name description = "Landing Zone policy for ${local.security_admin_group_name} group to manage security related services in Landing Zone enclosing compartment (${local.policy_scope})." defined_tags = local.policies_defined_tags freeform_tags = local.policies_freeform_tags statements = local.security_admin_grants } : null, (local.database_admin_policy_name) = length(local.database_admin_grants) > 0 ? { - compartment_id = local.enclosing_compartment_id + compartment_ocid = local.enclosing_compartment_id + name = local.database_admin_policy_name description = "Landing Zone policy for ${local.database_admin_group_name} group to manage database related resources." defined_tags = local.policies_defined_tags freeform_tags = local.policies_freeform_tags statements = local.database_admin_grants } : null, (local.appdev_admin_policy_name) = length(local.appdev_admin_grants) > 0 ? { - compartment_id = local.enclosing_compartment_id + compartment_ocid = local.enclosing_compartment_id + name = local.appdev_admin_policy_name description = "Landing Zone policy for ${local.appdev_admin_group_name} group to manage app development related services." defined_tags = local.policies_defined_tags freeform_tags = local.policies_freeform_tags statements = local.appdev_admin_grants } : null, (local.iam_admin_policy_name) = length(local.iam_admin_grants_on_enclosing_cmp) > 0 ? { - compartment_id = local.enclosing_compartment_id + compartment_ocid = local.enclosing_compartment_id + name = local.iam_admin_policy_name description = "Landing Zone policy for ${local.iam_admin_group_name} group to manage IAM resources in Landing Zone enclosing compartment (${local.policy_scope})." defined_tags = local.policies_defined_tags freeform_tags = local.policies_freeform_tags statements = local.iam_admin_grants_on_enclosing_cmp } : null, (local.storage_admin_policy_name) = length(local.storage_admin_grants) > 0 ? { - compartment_id = local.enclosing_compartment_id + compartment_ocid = local.enclosing_compartment_id + name = local.storage_admin_policy_name description = "Landing Zone policy for ${local.storage_admin_group_name} group to manage storage resources." defined_tags = local.policies_defined_tags freeform_tags = local.policies_freeform_tags @@ -400,8 +468,9 @@ locals { exainfra_policy = var.deploy_exainfra_cmp == true ? { (local.exainfra_admin_policy_name) = length(local.exainfra_admin_grants) > 0 ? { - compartment_id = local.enclosing_compartment_id - description = "Landing Zone policy for ${local.exainfra_admin_group_name} group to manage Exadata infrastructures in compartment ${local.exainfra_compartment.name}." + compartment_ocid = local.enclosing_compartment_id + name = local.exainfra_admin_policy_name + description = "Landing Zone policy for ${local.exainfra_admin_group_name} group to manage Exadata infrastructures in compartment ${local.exainfra_compartment_name}." defined_tags = local.policies_defined_tags freeform_tags = local.policies_freeform_tags statements = local.exainfra_admin_grants @@ -410,51 +479,45 @@ locals { policies = merge(local.default_policies, local.exainfra_policy) + #-- Basic grants on Root compartment + basic_grants_default_grantees = [local.security_admin_group_name, local.network_admin_group_name, local.appdev_admin_group_name, local.database_admin_group_name, local.storage_admin_group_name] + basic_grants_grantees = var.deploy_exainfra_cmp == true ? concat(local.basic_grants_default_grantees,[local.exainfra_admin_group_name]) : local.basic_grants_default_grantees + basic_grants_on_root_cmp = [ + "allow group ${join(",",local.basic_grants_grantees)} to use cloud-shell in tenancy", + "allow group ${join(",",local.basic_grants_grantees)} to read usage-budgets in tenancy", + "allow group ${join(",",local.basic_grants_grantees)} to read usage-reports in tenancy", + "allow group ${join(",",local.basic_grants_grantees)} to read objectstorage-namespaces in tenancy" + ] + root_policies = { + (local.basic_root_policy_name) = { + compartment_ocid = var.tenancy_ocid + name = local.basic_root_policy_name + description = "CIS Landing Zone basic root compartment policy." + defined_tags = local.policies_defined_tags + freeform_tags = local.policies_freeform_tags + statements = local.basic_grants_on_root_cmp + } (local.security_admin_root_policy_name) = { - compartment_id = var.tenancy_ocid - description = "Landing Zone ${local.security_admin_group_name}'s root compartment policy." + compartment_ocid = var.tenancy_ocid + name = local.security_admin_root_policy_name + description = "CIS Landing Zone ${local.security_admin_group_name}'s root compartment policy." defined_tags = local.policies_defined_tags freeform_tags = local.policies_freeform_tags statements = local.security_admin_grants_on_root_cmp }, (local.iam_admin_root_policy_name) = { - compartment_id = var.tenancy_ocid - description = "Landing Zone ${local.iam_admin_group_name}'s root compartment policy." + compartment_ocid = var.tenancy_ocid + name = local.iam_admin_root_policy_name + description = "CIS Landing Zone ${local.iam_admin_group_name}'s root compartment policy." defined_tags = local.policies_defined_tags freeform_tags = local.policies_freeform_tags statements = local.iam_admin_grants_on_root_cmp }, - (local.network_admin_root_policy_name) = { - compartment_id = var.tenancy_ocid - description = "Landing Zone ${local.network_admin_group_name}'s root compartment policy." - defined_tags = local.policies_defined_tags - freeform_tags = local.policies_freeform_tags - statements = ["allow group ${local.network_admin_group_name} to use cloud-shell in tenancy", - "allow group ${local.network_admin_group_name} to read usage-budgets in tenancy", - "allow group ${local.network_admin_group_name} to read usage-reports in tenancy"] - }, - (local.appdev_admin_root_policy_name) = { - compartment_id = var.tenancy_ocid - description = "Landing Zone ${local.appdev_admin_group_name}'s root compartment policy." - defined_tags = local.policies_defined_tags - freeform_tags = local.policies_freeform_tags - statements = ["allow group ${local.appdev_admin_group_name} to use cloud-shell in tenancy", - "allow group ${local.appdev_admin_group_name} to read usage-budgets in tenancy", - "allow group ${local.appdev_admin_group_name} to read usage-reports in tenancy"] - }, - (local.database_admin_root_policy_name) = { - compartment_id = var.tenancy_ocid - description = "Landing Zone ${local.database_admin_group_name}'s root compartment policy." - defined_tags = local.policies_defined_tags - freeform_tags = local.policies_freeform_tags - statements = ["allow group ${local.database_admin_group_name} to use cloud-shell in tenancy", - "allow group ${local.database_admin_group_name} to read usage-budgets in tenancy", - "allow group ${local.database_admin_group_name} to read usage-reports in tenancy"] - }, (local.auditor_policy_name) = { - compartment_id = var.tenancy_ocid - description = "Landing Zone ${local.auditor_group_name}'s root compartment policy." + compartment_ocid = var.tenancy_ocid + name = local.auditor_policy_name + description = "CIS Landing Zone ${local.auditor_group_name}'s root compartment policy." defined_tags = local.policies_defined_tags freeform_tags = local.policies_freeform_tags statements = [ @@ -478,8 +541,9 @@ locals { ] }, (local.announcement_reader_policy_name) = { - compartment_id = var.tenancy_ocid - description = "Landing Zone ${local.announcement_reader_group_name}'s root compartment policy." + compartment_ocid = var.tenancy_ocid + name = local.announcement_reader_policy_name + description = "CIS Landing Zone ${local.announcement_reader_group_name}'s root compartment policy." defined_tags = local.policies_defined_tags freeform_tags = local.policies_freeform_tags statements = [ @@ -488,8 +552,9 @@ locals { ] }, (local.cred_admin_policy_name) = { - compartment_id = var.tenancy_ocid - description = "Landing Zone ${local.cred_admin_group_name}'s root compartment policy." + compartment_ocid = var.tenancy_ocid + name = local.cred_admin_policy_name + description = "CIS Landing Zone ${local.cred_admin_group_name}'s root compartment policy." defined_tags = local.policies_defined_tags freeform_tags = local.policies_freeform_tags statements = [ @@ -500,34 +565,59 @@ locals { ] }, (local.cost_admin_root_policy_name) = { - compartment_id = var.tenancy_ocid - description = "Landing Zone ${local.cost_admin_group_name}'s root compartment policy." + compartment_ocid = var.tenancy_ocid + name = local.cost_admin_root_policy_name + description = "CIS Landing Zone ${local.cost_admin_group_name}'s root compartment policy." defined_tags = local.policies_defined_tags freeform_tags = local.policies_freeform_tags statements = local.cost_root_permissions } } - - ### DON'T TOUCH THESE ### - default_policies_defined_tags = null - default_policies_freeform_tags = local.landing_zone_tags - - policies_defined_tags = length(local.all_policies_defined_tags) > 0 ? local.all_policies_defined_tags : local.default_policies_defined_tags - policies_freeform_tags = length(local.all_policies_freeform_tags) > 0 ? merge(local.all_policies_freeform_tags, local.default_policies_freeform_tags) : local.default_policies_freeform_tags - } module "lz_root_policies" { - source = "../modules/iam/iam-policy" + depends_on = [module.lz_top_compartment, module.lz_groups] ### Explicitly declaring dependencies on the group and compartments modules. + source = "github.com/oracle-quickstart/terraform-oci-cis-landing-zone-iam/policies" providers = { oci = oci.home } - depends_on = [module.lz_groups, module.lz_compartments] ### Explicitly declaring dependencies on the group and compartments modules. - policies = var.extend_landing_zone_to_new_region == false ? (local.use_existing_root_cmp_grants == true ? {} : local.root_policies) : {} - #policies = local.use_existing_root_cmp_grants == false || var.extend_landing_zone_to_new_region == false ? { + tenancy_ocid = var.tenancy_ocid + policies_configuration = var.extend_landing_zone_to_new_region == false && var.enable_template_policies == false ? (local.use_existing_root_cmp_grants == true ? local.empty_policies_configuration : local.root_policies_configuration) : local.empty_policies_configuration } module "lz_policies" { - source = "../modules/iam/iam-policy" - providers = { oci = oci.home } - depends_on = [module.lz_groups, module.lz_dynamic_groups, module.lz_compartments] ### Explicitly declaring dependencies on the group and compartments modules. - policies = var.extend_landing_zone_to_new_region == false ? local.policies : {} + depends_on = [module.lz_compartments, module.lz_groups, module.lz_dynamic_groups] + source = "github.com/oracle-quickstart/terraform-oci-cis-landing-zone-iam/policies" + providers = { oci = oci.home } + tenancy_ocid = var.tenancy_ocid + policies_configuration = var.extend_landing_zone_to_new_region == false && var.enable_template_policies == false ? local.policies_configuration : local.empty_policies_configuration } + +locals { + #----------------------------------------------------------------------- + #-- These variables are NOT meant to be overriden. + #----------------------------------------------------------------------- + default_policies_defined_tags = null + default_policies_freeform_tags = local.landing_zone_tags + + policies_defined_tags = local.custom_policies_defined_tags != null ? merge(local.custom_policies_defined_tags, local.default_policies_defined_tags) : local.default_policies_defined_tags + policies_freeform_tags = local.custom_policies_freeform_tags != null ? merge(local.custom_policies_freeform_tags, local.default_policies_freeform_tags) : local.default_policies_freeform_tags + + policy_scope = local.enclosing_compartment_name == "tenancy" ? "tenancy" : "compartment ${local.enclosing_compartment_name}" + + use_existing_root_cmp_grants = upper(var.policies_in_root_compartment) == "CREATE" ? false : true + + root_policies_configuration = { + enable_cis_benchmark_checks : true + supplied_policies : local.root_policies + } + + policies_configuration = { + enable_cis_benchmark_checks : true + supplied_policies : local.policies + } + + # Helper object meaning no policies. It satisfies Terraform's ternary operator. + empty_policies_configuration = { + enable_cis_benchmark_checks : false + supplied_policies : null + } +} \ No newline at end of file diff --git a/config/iam_service_policies.tf b/config/iam_service_policies.tf index 5816af0e..4ec5b6fa 100644 --- a/config/iam_service_policies.tf +++ b/config/iam_service_policies.tf @@ -10,16 +10,11 @@ locals { } module "lz_services_policy" { - source = "../modules/iam/iam-services-policy" - providers = { oci = oci.home } - depends_on = [null_resource.wait_on_compartments] - tenancy_id = var.tenancy_ocid - service_label = var.service_label - enable_tenancy_level_policies = var.extend_landing_zone_to_new_region == false ? (local.use_existing_root_cmp_grants == true ? false : true) : false - tenancy_policy_name = "${var.service_label}-services-policy" - defined_tags = local.service_policy_defined_tags - freeform_tags = local.service_policy_freeform_tags - policies = var.extend_landing_zone_to_new_region == false ? local.service_policies : {} + depends_on = [null_resource.wait_on_compartments] + source = "github.com/oracle-quickstart/terraform-oci-cis-landing-zone-iam/policies" + providers = { oci = oci.home } + tenancy_ocid = var.tenancy_ocid + policies_configuration = var.extend_landing_zone_to_new_region == false && var.enable_template_policies == false ? local.services_policies_configuration : local.empty_services_policies_configuration } locals { @@ -32,24 +27,43 @@ locals { service_policy_defined_tags = local.custom_service_policy_defined_tags != null ? merge(local.custom_service_policy_defined_tags, local.default_service_policy_defined_tags) : local.default_service_policy_defined_tags service_policy_freeform_tags = local.custom_service_policy_freeform_tags != null ? merge(local.custom_service_policy_freeform_tags, local.default_service_policy_freeform_tags) : local.default_service_policy_freeform_tags + cloud_guard_statements = ["Allow service cloudguard to read all-resources in tenancy", + "Allow service cloudguard to use network-security-groups in tenancy"] + + vss_statements = ["Allow service vulnerability-scanning-service to manage instances in tenancy", + "Allow service vulnerability-scanning-service to read compartments in tenancy", + "Allow service vulnerability-scanning-service to read repos in tenancy", + "Allow service vulnerability-scanning-service to read vnics in tenancy", + "Allow service vulnerability-scanning-service to read vnic-attachments in tenancy"] + + os_mgmt_statements = ["Allow service osms to read instances in tenancy"] + realm = split(".",trimprefix(data.oci_identity_tenancy.this.id, "ocid1.tenancy."))[0] - service_policies = { - ("VAULT-GLOBAL-POLICY") = { - name = "${var.service_label}-vault-policy" - compartment_id = local.enclosing_compartment_id - description = "Landing Zone policy for OCI services: Blockstorage, OKE and streams to use keys in the ${local.security_compartment.name} compartment." - statements = ["Allow service blockstorage, oke, streaming, Fss${local.realm}Prod to use keys in compartment ${local.security_compartment.name}"] - defined_tags = local.service_policy_defined_tags - freeform_tags = local.service_policy_freeform_tags - }, - ("VAULT-REGIONAL-POLICY") = { - name = "${var.service_label}-vault-${var.region}-policy" - compartment_id = local.enclosing_compartment_id - description = "Landing Zone policy for OCI services: Object Storage in ${var.region} to use keys in the ${local.security_compartment.name} compartment." - statements = ["Allow service objectstorage-${var.region} to use keys in compartment ${local.security_compartment.name}"] - defined_tags = local.service_policy_defined_tags - freeform_tags = local.service_policy_freeform_tags + object_storage_service_principals = join(",", [for region in data.oci_identity_region_subscriptions.these.region_subscriptions : "objectstorage-${region.region_name}"]) + + keys_access_statements = ["Allow service blockstorage, oke, streaming, Fss${local.realm}Prod, ${local.object_storage_service_principals} to use keys in tenancy"] + + services_policy = { + ("${var.service_label}-services-policy") : { + compartment_ocid = var.tenancy_ocid + name = "${var.service_label}-services-policy" + description = "CIS Landing Zone policy for OCI services." + statements = concat(local.cloud_guard_statements, local.vss_statements, local.os_mgmt_statements, local.keys_access_statements) + defined_tags = local.service_policy_defined_tags + freeform_tags = local.service_policy_freeform_tags } + } + + services_policies_configuration = { + enable_cis_benchmark_checks : true + supplied_policies : local.services_policy + } + + # Helper object meaning no policies. It satisfies Terraform's ternary operator. + empty_services_policies_configuration = { + enable_cis_benchmark_checks : false + supplied_policies : null } + } diff --git a/config/iam_template_policies.tf b/config/iam_template_policies.tf new file mode 100644 index 00000000..f51b5762 --- /dev/null +++ b/config/iam_template_policies.tf @@ -0,0 +1,173 @@ +# 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. + +#-- This file supports the creation of tag based policies, which are policies created based on tags that are applied to compartments. +#-- This functionality is supported by the policy module in https://github.com/oracle-quickstart/terraform-oci-cis-landing-zone-iam/tree/main/policies +#-- The default approach is using the supplied policies, defined in iam_policies.tf file. +#-- For using tag based policies, set variable enable_template_policies to true. + +locals { + #-------------------------------------------------------------------------- + #-- Any of these custom variables can be overriden in a _override.tf file + #-------------------------------------------------------------------------- + #-- Custom tags applied to tag based policies. + custom_template_policies_defined_tags = null + custom_template_policies_freeform_tags = null +} + +module "lz_template_policies" { + depends_on = [module.lz_top_compartment, module.lz_compartments, module.lz_groups, module.lz_dynamic_groups] + source = "github.com/oracle-quickstart/terraform-oci-cis-landing-zone-iam/policies" + providers = { oci = oci.home } + tenancy_ocid = var.tenancy_ocid + policies_configuration = var.extend_landing_zone_to_new_region == false && var.enable_template_policies == true ? local.template_policies_configuration : local.empty_template_policies_configuration +} + +locals { + #----------------------------------------------------------------------- + #-- These variables are NOT meant to be overriden. + #----------------------------------------------------------------------- + default_template_policies_defined_tags = null + default_template_policies_freeform_tags = local.landing_zone_tags + + template_policies_defined_tags = local.custom_template_policies_defined_tags != null ? merge(local.custom_template_policies_defined_tags, local.default_template_policies_defined_tags) : local.default_template_policies_defined_tags + template_policies_freeform_tags = local.custom_template_policies_freeform_tags != null ? merge(local.custom_template_policies_freeform_tags, local.default_template_policies_freeform_tags) : local.default_template_policies_freeform_tags + + #------------------------------------------------------------------------ + #----- Policies configuration definition. Input to module. + #------------------------------------------------------------------------ + template_policies_configuration = { + enable_cis_benchmark_checks : true + template_policies : { + tenancy_level_settings : { + groups_with_tenancy_level_roles : [ + {"name":"${local.iam_admin_group_name}", "roles":"iam"}, + {"name":"${local.cred_admin_group_name}", "roles":"cred"}, + {"name":"${local.cost_admin_group_name}", "roles":"cost"}, + {"name":"${local.security_admin_group_name}","roles":"security,basic"}, + {"name":"${local.network_admin_group_name}", "roles":"network,basic"}, + {"name":"${local.appdev_admin_group_name}", "roles":"application,basic"}, + {"name":"${local.database_admin_group_name}","roles":"database,basic"}, + {"name":"${local.exainfra_admin_group_name}","roles":"exainfra,basic"}, + {"name":"${local.storage_admin_group_name}", "roles":"basic"}, + {"name":"${local.auditor_group_name}", "roles":"auditor"}, + {"name":"${local.announcement_reader_group_name}","roles":"announcement-reader"} + ] + oci_services : { + enable_all_policies : true + } + policy_name_prefix : var.service_label + } + compartment_level_settings : { + #supplied_compartments : var.enable_template_policies == true ? {for k, v in merge(module.lz_compartments.compartments, local.enclosing_compartment_map) : k => {"name": v.name, "ocid": v.id, "cislz_metadata": local.cislz_compartments_metadata[v.freeform_tags["cislz-cmp-type"]]}} : {} + supplied_compartments : merge(local.enclosing_compartment_map, local.enclosed_compartments_map, local.exainfra_compartment_map) + } + } + defined_tags : local.template_policies_defined_tags + freeform_tags : local.template_policies_freeform_tags + } + + #-- This map satisfies managed, existing, and no enclosing compartments. It is merged with managed compartments in supplied_compartments attribute above. + /* enclosing_compartment_map = { + (local.enclosing_compartment_key) : { + name : local.enclosing_compartment_name + id : local.enclosing_compartment_id + freeform_tags : {"cislz-cmp-type" : "enclosing"} + } + } */ + + enclosing_compartment_map = { + (local.enclosing_compartment_key) : { + name : local.enclosing_compartment_name + ocid : local.enclosing_compartment_id + cislz_metadata : { + "cislz-cmp-type":"enclosing", + "cislz-consumer-groups-security":"${local.security_admin_group_name}", + "cislz-consumer-groups-application":"${local.appdev_admin_group_name}", + "cislz-consumer-groups-iam":"${local.iam_admin_group_name}" + } + } + } + + enclosed_compartments_map = { + (local.security_compartment_key) : { + name : local.provided_security_compartment_name + ocid : local.security_compartment_id + cislz_metadata : { + "cislz-cmp-type":"security", + "cislz-consumer-groups-security":"${local.security_admin_group_name}", + "cislz-consumer-groups-application":"${local.appdev_admin_group_name}", + "cislz-consumer-groups-database":"${local.database_admin_group_name}", + "cislz-consumer-groups-network":"${local.network_admin_group_name}", + "cislz-consumer-groups-storage":"${local.storage_admin_group_name}", + "cislz-consumer-groups-exainfra":"${local.exainfra_admin_group_name}", + "cislz-consumer-groups-dyn-database-kms":"${local.database_kms_dynamic_group_name}" + } + } + (local.network_compartment_key) : { + name : local.provided_network_compartment_name + ocid : local.network_compartment_id + cislz_metadata : { + "cislz-cmp-type":"network", + "cislz-consumer-groups-security":"${local.security_admin_group_name}", + "cislz-consumer-groups-application":"${local.appdev_admin_group_name}", + "cislz-consumer-groups-database":"${local.database_admin_group_name}", + "cislz-consumer-groups-network":"${local.network_admin_group_name}", + "cislz-consumer-groups-storage":"${local.storage_admin_group_name}", + "cislz-consumer-groups-exainfra":"${local.exainfra_admin_group_name}" + } + } + (local.appdev_compartment_key) : { + name : local.provided_appdev_compartment_name + ocid : local.appdev_compartment_id + cislz_metadata : { + "cislz-cmp-type":"application", + "cislz-consumer-groups-security":"${local.security_admin_group_name}", + "cislz-consumer-groups-application":"${local.appdev_admin_group_name}", + "cislz-consumer-groups-database":"${local.database_admin_group_name}", + "cislz-consumer-groups-network":"${local.network_admin_group_name}", + "cislz-consumer-groups-storage":"${local.storage_admin_group_name}", + "cislz-consumer-groups-exainfra":"${local.exainfra_admin_group_name}", + "cislz-consumer-groups-dyn-compute-agent":"${local.appdev_computeagent_dynamic_group_name}" + } + } + (local.database_compartment_key) : { + name : local.provided_database_compartment_name + ocid : local.database_compartment_id + cislz_metadata : { + "cislz-cmp-type":"database", + "cislz-consumer-groups-security":"${local.security_admin_group_name}", + "cislz-consumer-groups-application":"${local.appdev_admin_group_name}", + "cislz-consumer-groups-database":"${local.database_admin_group_name}", + "cislz-consumer-groups-network":"${local.network_admin_group_name}", + "cislz-consumer-groups-storage":"${local.storage_admin_group_name}", + "cislz-consumer-groups-exainfra":"${local.exainfra_admin_group_name}", + "cislz-consumer-groups-dyn-database-kms":"${local.database_kms_dynamic_group_name}" + } + } + } + + exainfra_compartment_map = local.enable_exainfra_compartment ? { + (local.exainfra_compartment_key) : { + name : local.provided_exainfra_compartment_name + ocid : local.exainfra_compartment_id + cislz_metadata : { + "cislz-cmp-type":"exainfra", + "cislz-consumer-groups-security":"${local.security_admin_group_name}", + "cislz-consumer-groups-application":"${local.appdev_admin_group_name}", + "cislz-consumer-groups-database":"${local.database_admin_group_name}", + "cislz-consumer-groups-network":"${local.network_admin_group_name}", + "cislz-consumer-groups-storage":"${local.storage_admin_group_name}", + "cislz-consumer-groups-exainfra":"${local.exainfra_admin_group_name}" + } + } + } : {} + + # Helper object meaning no policies. It satisfies Terraform's ternary operator. + empty_template_policies_configuration = { + enable_cis_benchmark_checks : false + template_policies : null + defined_tags : null + freeform_tags : null + } +} \ No newline at end of file diff --git a/config/locals.tf b/config/locals.tf index c88adfb5..5d326ef9 100644 --- a/config/locals.tf +++ b/config/locals.tf @@ -3,66 +3,12 @@ locals { - ### Discovering the home region name and region key. regions_map = { for r in data.oci_identity_regions.these.regions : r.key => r.name } # All regions indexed by region key. regions_map_reverse = { for r in data.oci_identity_regions.these.regions : r.name => r.key } # All regions indexed by region name. home_region_key = data.oci_identity_tenancy.this.home_region_key # Home region key obtained from the tenancy data source region_key = lower(local.regions_map_reverse[var.region]) # Region key obtained from the region name - ### IAM - # Default compartment names - enclosing_compartment = {key:"${var.service_label}-top-cmp", name: var.use_enclosing_compartment == true ? (var.existing_enclosing_compartment_ocid != null ? data.oci_identity_compartment.existing_enclosing_compartment.name : "${var.service_label}-top-cmp") : "tenancy"} - enclosing_compartment_id = var.use_enclosing_compartment == true ? (var.existing_enclosing_compartment_ocid != null ? var.existing_enclosing_compartment_ocid : module.lz_top_compartment[0].compartments[local.enclosing_compartment.key].id) : var.tenancy_ocid - - security_compartment = {key:"${var.service_label}-security-cmp", name: "${var.service_label}-security-cmp"} - security_compartment_id = var.extend_landing_zone_to_new_region == false ? module.lz_compartments.compartments[local.security_compartment.key].id : data.oci_identity_compartments.security.compartments[0].id - network_compartment = {key:"${var.service_label}-network-cmp", name: "${var.service_label}-network-cmp"} - network_compartment_id = var.extend_landing_zone_to_new_region == false ? module.lz_compartments.compartments[local.network_compartment.key].id : data.oci_identity_compartments.network.compartments[0].id - appdev_compartment = {key:"${var.service_label}-appdev-cmp", name: "${var.service_label}-appdev-cmp"} - appdev_compartment_id = var.extend_landing_zone_to_new_region == false ? module.lz_compartments.compartments[local.appdev_compartment.key].id : data.oci_identity_compartments.appdev.compartments[0].id - database_compartment = {key:"${var.service_label}-database-cmp", name: "${var.service_label}-database-cmp"} - database_compartment_id = var.extend_landing_zone_to_new_region == false ? module.lz_compartments.compartments[local.database_compartment.key].id : data.oci_identity_compartments.database.compartments[0].id - exainfra_compartment = {key:"${var.service_label}-exainfra-cmp", name: "${var.service_label}-exainfra-cmp"} - exainfra_compartment_id = var.extend_landing_zone_to_new_region == false && var.deploy_exainfra_cmp == true ? module.lz_compartments.compartments[local.exainfra_compartment.key].id : length(data.oci_identity_compartments.exainfra.compartments) > 0 ? data.oci_identity_compartments.exainfra.compartments[0].id : "exainfra_cmp_undefined" - - # Group names - # The logic for group names is the following: - # if an existing group isn't provided, create a name for the group. - # If an existing group **ocid** is provided (and this is used in Resource Manager groups drop down UI control), retrieve the group name using oci_identity_group data source. - # If an existing group **name** is provided, use oci_identity_groups (notice the 's') data source to make sure the group exists. - security_admin_group_name = length(trimspace(var.existing_security_admin_group_name)) == 0 ? "${var.service_label}-security-admin-group" : (length(regexall("^ocid1.group.oc.*$", var.existing_security_admin_group_name)) > 0 ? data.oci_identity_group.existing_security_admin_group.name : data.oci_identity_groups.existing_security_admin_group.groups[0].name) - network_admin_group_name = length(trimspace(var.existing_network_admin_group_name)) == 0 ? "${var.service_label}-network-admin-group" : (length(regexall("^ocid1.group.oc.*$", var.existing_network_admin_group_name)) > 0 ? data.oci_identity_group.existing_network_admin_group.name : data.oci_identity_groups.existing_network_admin_group.groups[0].name) - database_admin_group_name = length(trimspace(var.existing_database_admin_group_name)) == 0 ? "${var.service_label}-database-admin-group" : (length(regexall("^ocid1.group.oc.*$", var.existing_database_admin_group_name)) > 0 ? data.oci_identity_group.existing_database_admin_group.name : data.oci_identity_groups.existing_database_admin_group.groups[0].name) - appdev_admin_group_name = length(trimspace(var.existing_appdev_admin_group_name)) == 0 ? "${var.service_label}-appdev-admin-group" : (length(regexall("^ocid1.group.oc.*$", var.existing_appdev_admin_group_name)) > 0 ? data.oci_identity_group.existing_appdev_admin_group.name : data.oci_identity_groups.existing_appdev_admin_group.groups[0].name) - iam_admin_group_name = length(trimspace(var.existing_iam_admin_group_name)) == 0 ? "${var.service_label}-iam-admin-group" : (length(regexall("^ocid1.group.oc.*$", var.existing_iam_admin_group_name)) > 0 ? data.oci_identity_group.existing_iam_admin_group.name : data.oci_identity_groups.existing_iam_admin_group.groups[0].name) - cred_admin_group_name = length(trimspace(var.existing_cred_admin_group_name)) == 0 ? "${var.service_label}-cred-admin-group" : (length(regexall("^ocid1.group.oc.*$", var.existing_cred_admin_group_name)) > 0 ? data.oci_identity_group.existing_cred_admin_group.name : data.oci_identity_groups.existing_cred_admin_group.groups[0].name) - auditor_group_name = length(trimspace(var.existing_auditor_group_name)) == 0 ? "${var.service_label}-auditor-group" : (length(regexall("^ocid1.group.oc.*$", var.existing_auditor_group_name)) > 0 ? data.oci_identity_group.existing_auditor_group.name : data.oci_identity_groups.existing_auditor_group.groups[0].name) - announcement_reader_group_name = length(trimspace(var.existing_announcement_reader_group_name)) == 0 ? "${var.service_label}-announcement-reader-group" : (length(regexall("^ocid1.group.oc.*$", var.existing_announcement_reader_group_name)) > 0 ? data.oci_identity_group.existing_announcement_reader_group.name : data.oci_identity_groups.existing_announcement_reader_group.groups[0].name) - exainfra_admin_group_name = length(trimspace(var.existing_exainfra_admin_group_name)) == 0 ? "${var.service_label}-exainfra-admin-group" : (length(regexall("^ocid1.group.oc.*$", var.existing_exainfra_admin_group_name)) > 0 ? data.oci_identity_group.existing_exainfra_admin_group.name : data.oci_identity_groups.existing_exainfra_admin_group.groups[0].name) - cost_admin_group_name = length(trimspace(var.existing_cost_admin_group_name)) == 0 ? "${var.service_label}-cost-admin-group" : (length(regexall("^ocid1.group.oc.*$", var.existing_cost_admin_group_name)) > 0 ? data.oci_identity_group.existing_cost_admin_group.name : data.oci_identity_groups.existing_cost_admin_group.groups[0].name) - storage_admin_group_name = length(trimspace(var.existing_storage_admin_group_name)) == 0 ? "${var.service_label}-storage-admin-group" : (length(regexall("^ocid1.group.oc.*$", var.existing_storage_admin_group_name)) > 0 ? data.oci_identity_group.existing_storage_admin_group.name : data.oci_identity_groups.existing_storage_admin_group.groups[0].name) - - # Policy names - security_admin_policy_name = "${var.service_label}-security-admin-policy" - security_admin_root_policy_name = "${var.service_label}-security-admin-root-policy" - network_admin_policy_name = "${var.service_label}-network-admin-policy" - compute_agent_policy_name = "${var.service_label}-compute-agent-policy" - network_admin_root_policy_name = "${var.service_label}-network-admin-root-policy" - database_admin_policy_name = "${var.service_label}-database-admin-policy" - database_dynamic_group_policy_name = "${var.service_label}-database-dynamic_group-policy" - database_admin_root_policy_name = "${var.service_label}-database-admin-root-policy" - appdev_admin_policy_name = "${var.service_label}-appdev-admin-policy" - appdev_admin_root_policy_name = "${var.service_label}-appdev-admin-root-policy" - iam_admin_policy_name = "${var.service_label}-iam-admin-policy" - iam_admin_root_policy_name = "${var.service_label}-iam-admin-root-policy" - cred_admin_policy_name = "${var.service_label}-credential-admin-policy" - auditor_policy_name = "${var.service_label}-auditor-policy" - announcement_reader_policy_name = "${var.service_label}-announcement-reader-policy" - exainfra_admin_policy_name = "${var.service_label}-exainfra-admin-policy" - cost_admin_root_policy_name = "${var.service_label}-cost-admin-root-policy" - storage_admin_policy_name = "${var.service_label}-storage-admin-policy" - ### Network anywhere = "0.0.0.0/0" valid_service_gateway_cidrs = ["all-${local.region_key}-services-in-oracle-services-network", "oci-${local.region_key}-objectstorage"] @@ -92,10 +38,6 @@ locals { # Whether compartments should be deleted upon resource destruction. enable_cmp_delete = false - policy_scope = local.enclosing_compartment.name == "tenancy" ? "tenancy" : "compartment ${local.enclosing_compartment.name}" - - use_existing_root_cmp_grants = upper(var.policies_in_root_compartment) == "CREATE" ? false : true - # Delay in seconds for slowing down resource creation delay_in_secs = 70 @@ -103,7 +45,7 @@ locals { display_outputs = true # Tags - landing_zone_tags = {"cis-landing-zone" : "${var.service_label}-quickstart"} + landing_zone_tags = {"cis-landing-zone" : fileexists("${path.module}/../release.txt") ? "${var.service_label}-quickstart/${file("${path.module}/../release.txt")}" : "${var.service_label}-quickstart"} is_windows = substr(pathexpand("~"), 0, 1) == "/" ? false : true } diff --git a/config/outputs.tf b/config/outputs.tf index 5a763b83..12bcc587 100644 --- a/config/outputs.tf +++ b/config/outputs.tf @@ -6,7 +6,7 @@ output "service_label" { } output "compartments" { - value = local.display_outputs == true && var.extend_landing_zone_to_new_region == false ? {for k, v in module.lz_compartments.compartments : k => {name:v.name, id:v.id, parent_id:v.compartment_id, time_created:v.time_created}} : null + value = local.display_outputs == true && var.extend_landing_zone_to_new_region == false ? merge({for k, v in module.lz_compartments.compartments : k => {name:v.name, id:v.id, parent_id:v.compartment_id, time_created:v.time_created}}, length(module.lz_top_compartment) > 0 ? {for k, v in module.lz_top_compartment[0].compartments : k => {name:v.name, id:v.id, parent_id:v.compartment_id, time_created:v.time_created}} : {}) : null } output "vcns" { @@ -64,3 +64,15 @@ output "service_connector_target" { output "logging_analytics_log_group" { value = local.display_outputs == true ? (length(module.lz_logging_analytics) > 0 ? module.lz_logging_analytics[0].log_group : null) : null } + +output "cis_level" { + value = local.display_outputs == true ? var.cis_level : null +} + +output "region" { + value = local.display_outputs == true ? var.region : null +} + +output "release" { + value = local.display_outputs == true ? (fileexists("${path.module}/../release.txt") ? file("${path.module}/../release.txt") : "unknown") : null +} diff --git a/config/provider.tf b/config/provider.tf index 8e377227..1587f18a 100644 --- a/config/provider.tf +++ b/config/provider.tf @@ -21,7 +21,7 @@ provider "oci" { } terraform { - required_version = ">= 1.1.0" + required_version = ">= 1.2.0" required_providers { oci = { diff --git a/config/quickstart-input.tfvars b/config/quickstart-input.tfvars index b21e2fd4..20aa6191 100644 --- a/config/quickstart-input.tfvars +++ b/config/quickstart-input.tfvars @@ -24,13 +24,14 @@ cis_level = "1" # ------------------------------------------------------ # ----- IAM - Enclosing compartments #------------------------------------------------------- -# use_enclosing_compartment = false +# use_enclosing_compartment = true # existing_enclosing_compartment_ocid = "" # Compartment OCID where Landing Zone compartments are created. # ------------------------------------------------------ # ----- IAM - Policies #------------------------------------------------------- # policies_in_root_compartment = "CREATE" +# enable_template_policies = false # ------------------------------------------------------ # ----- IAM - Groups diff --git a/config/schema.yml b/config/schema.yml index a97ffb50..85c7b1b4 100644 --- a/config/schema.yml +++ b/config/schema.yml @@ -1,12 +1,17 @@ # Copyright (c) 2022 Oracle and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -title: "OCI Secure Landing Zone Quick Start Configuration" -stackDescription: "A stack to deploy a set of CIS (Center for Internet Security) compliant resources in an OCI tenancy. The Secure Landing Zone is the combination of CIS Foundations Benchmark for OCI with OCI architecture best practices." +title: "CIS (Center for Internet Security) OCI Landing Zone Quick Start" +stackDescription: "This stack deploys the CIS OCI Landing Zone Quick Start, a fully operational tenancy design that combines the recommendations of CIS Foundations Benchmark for OCI with OCI architecture best practices. For details, please see https://github.com/oracle-quickstart/oci-cis-landingzone-quickstart." +description: "This stack deploys the CIS OCI Landing Zone Quick Start, a fully operational tenancy design that combines the recommendations of CIS Foundations Benchmark for OCI with OCI architecture best practices. For details, please see CIS OCI Landing Zone Quick Start." +informationalText: "See below some of the outputs of the latest stack execution." schemaVersion: 1.1.0 -version: "0.0.1" +version: "2.6.0" locale: "en" +# URL of CIS Landing Zone logo icon used on Application Information tab. +logoUrl: "https://objectstorage.us-ashburn-1.oraclecloud.com/p/taf6kC9fSJyQDNSYbxvqxS_JsdnSu56oFZ3-1h5vI7-WfJUv77mplChopLxZPePW/n/ociateam/b/cis-landing-zone/o/landing_zone_130.png" + variableGroups: - title: "Environment" variables: @@ -18,6 +23,7 @@ variableGroups: - "env_advanced_options" - "extend_landing_zone_to_new_region" - "policies_in_root_compartment" + - "enable_template_policies" - "existing_iam_admin_group_name" - "existing_cred_admin_group_name" - "existing_security_admin_group_name" @@ -188,7 +194,7 @@ variables: type: boolean title: "Use an enclosing compartment?" description: "Whether the Landing Zone compartments are created within an enclosing compartment. If unchecked, the Landing Zone compartments are created in the Root compartment, in which case you must have the required permissions." - default: false + default: true existing_enclosing_compartment_ocid: type: oci:identity:compartment:id @@ -215,6 +221,13 @@ variables: default: "CREATE" visible: env_advanced_options + enable_template_policies: + type: boolean + title: "Enable template policies?" + description: "Whether policies should be created based on metadata associated to compartments. This is an alternative way of managing policies, enabled by the CIS Landing Zone standalone IAM policy module. When set to true, the grants to resources belonging to a specific compartment are combined into a single policy that is attached to the compartment itself. This differs from the default approach, where grants are combined per grantee and attached to the enclosing compartment." + default: false + visible: env_advanced_options + existing_iam_admin_group_name: type: oci:identity:groups:id dependsOn: @@ -1016,4 +1029,62 @@ variables: type: string private_key_password: - type: password \ No newline at end of file + type: password + +outputs: + release: + type: string + title: CIS Landing Zone Release + + region: + type: string + title: Region + + service_label: + type: string + title: Service Label + + cis_level: + type: string + title: CIS Profile Level + + compartments: + type: json + title: Compartments + + vcns: + type: json + title: (Spoke) Virtual Cloud Networks + + subnets: + type: json + title: (Spoke) Virtual Cloud Networks Subnets + + dmz_vcn: + type: json + title: DMZ (Hub) Virtual Cloud Network + + dmz_subnets: + type: json + title: DMZ (Hub) Virtual Cloud Network Subnets + + bastions: + type: json + title: Bastions + +outputGroups: + - title: Environment + outputs: + - ${release} + - ${region} + - ${service_label} + - ${cis_level} + - ${compartments} + + - title: Networking + outputs: + - ${vcns} + - ${subnets} + - ${dmz_vcn} + - ${dmz_subnets} + - ${bastions} \ No newline at end of file diff --git a/config/security_zones.tf b/config/security_zones.tf index f946b1ca..2f1c6e70 100644 --- a/config/security_zones.tf +++ b/config/security_zones.tf @@ -26,14 +26,14 @@ module "lz_security_zones" { locals { ### These variables are NOT meant to be overriden. managed_enclosing_target_sz_compartment = length(module.lz_top_compartment) > 0 ? { - "${local.enclosing_compartment.key}-security-zone" = { - "sz_compartment_name" : module.lz_top_compartment[0].compartments[local.enclosing_compartment.key].name, - "sz_compartment_id" : module.lz_top_compartment[0].compartments[local.enclosing_compartment.key].id + "${local.enclosing_compartment_key}-security-zone" = { + "sz_compartment_name" : module.lz_top_compartment[0].compartments[local.enclosing_compartment_key].name, + "sz_compartment_id" : module.lz_top_compartment[0].compartments[local.enclosing_compartment_key].id } } : {} existing_enclosing_target_sz_compartment = length(module.lz_top_compartment) == 0 && local.enclosing_compartment_id != var.tenancy_ocid ? { - "${local.enclosing_compartment.key}-security-zone" = { - "sz_compartment_name" : local.enclosing_compartment.name, + "${local.enclosing_compartment_key}-security-zone" = { + "sz_compartment_name" : local.network_compartment_name, "sz_compartment_id" : local.enclosing_compartment_id } } : {} diff --git a/config/variables.tf b/config/variables.tf index 83ca4204..ed7b1c01 100644 --- a/config/variables.tf +++ b/config/variables.tf @@ -53,8 +53,8 @@ variable "extend_landing_zone_to_new_region" { #------------------------------------------------------- variable "use_enclosing_compartment" { type = bool - default = false - description = "Whether the Landing Zone compartments are created within an enclosing compartment. If false, the Landing Zone compartments are created under the root compartment." + default = true + description = "Whether the Landing Zone compartments are created within an enclosing compartment. If false, the Landing Zone compartments are created under the root compartment. The recommendation is to utilize an enclosing compartment." } variable "existing_enclosing_compartment_ocid" { type = string @@ -75,6 +75,12 @@ variable "policies_in_root_compartment" { } } +variable "enable_template_policies" { + type = bool + default = false + description = "Whether policies should be created based on metadata associated to compartments. This is an alternative way of managing policies, enabled by the CIS Landing Zone standalone IAM policy module: https://github.com/oracle-quickstart/terraform-oci-cis-landing-zone-iam/tree/main/policies. When set to true, the grants to resources belonging to a specific compartment are combined into a single policy that is attached to the compartment itself. This differs from the default approach, where grants are combined per grantee and attached to the enclosing compartment." +} + # ------------------------------------------------------ # ----- IAM - Groups #------------------------------------------------------- diff --git a/images/landing_zone_130.png b/images/landing_zone_130.png new file mode 100644 index 0000000000000000000000000000000000000000..3d6183a75bab332a9075cf2e7c83fafc662ea3f8 GIT binary patch literal 12915 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 BOhEtu literal 0 HcmV?d00001 diff --git a/release-notes.md b/release-notes.md index c3f66569..cc7b3210 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,3 +1,16 @@ +# July 14, 2023 Release Notes - 2.6.0 +1. [Updates to Terraform Template](#2-6-0-tf-updates) + +## Updates to Terraform Template +Updates: +- IAM resources, including compartments, groups, dynamic groups and policies are now managed with new remote modules, available in https://github.com/oracle-quickstart/terraform-oci-cis-landing-zone-iam. The old local IAM modules are still kept in this repository. +- IAM policies can now be created based on metadata associated to compartments. This is an alternative way of managing policies, enabled by the [new IAM policy module](https://github.com/oracle-quickstart/terraform-oci-cis-landing-zone-iam/tree/main/policies). In this approach, the grants to resources belonging to a specific compartment are combined into a single policy that is attached to the compartment itself. This differs from the existing approach, where grants are combined per grantee and attached to the enclosing compartment. This alternative way is enabled by **Enable template policies?** checkbox (if using OCI Resource Manager) or by the **enable_template_policies** variable (if using Terraform CLI). The existing approach of deploying policies remains the default. +- Some policy grants have been updated, allowing admin groups to manage keys in their own compartments using the OCI Vault in the Security Compartment and deploy private endpoints in Network compartment. Additionally, some grants have been consolidated into a single grant with a comma-separated list of group principals. Service policies have been consolidated into a single policy with the new name *${var.service_label}-services-policy*. +- Deploying with an enclosing compartment becomes the default. Users who deploy without an enclosing compartment should unset **Use an enclosing compartment?** checkbox (if using OCI Resource Manager) or set **use_enclosing_compartment** variable to false (if using Terraform CLI). +- Quick Start release number added to cis-landing-zone freeform tag. +- Application Information tab is now enabled in OCI Resource Manager, displaying basic information about the stack and outputs of latest Terraform apply. + + # June 29, 2023 Release Notes - 2.5.12 1. [Fixes to the CIS Compliance Script](#2-5-12-script-fixes) diff --git a/release.txt b/release.txt new file mode 100644 index 00000000..914ec967 --- /dev/null +++ b/release.txt @@ -0,0 +1 @@ +2.6.0 \ No newline at end of file diff --git a/scripts/cis_reports.py b/scripts/cis_reports.py index 5f38c6f4..9b6d08b9 100644 --- a/scripts/cis_reports.py +++ b/scripts/cis_reports.py @@ -33,9 +33,9 @@ except: OUTPUT_TO_XLSX = False -RELEASE_VERSION = "2.5.12" -PYTHON_SDK_VERSION = "2.103.0" -UPDATED_DATE = "June 29, 2023" +RELEASE_VERSION = "2.6.0" +PYTHON_SDK_VERSION = "2.106.0" +UPDATED_DATE = "July 14, 2023" ########################################################################## # Print header centered From 6c400ef12d908b9eeca1652f43ff52b994abd4d6 Mon Sep 17 00:00:00 2001 From: Samratha S P Date: Tue, 25 Jul 2023 22:11:15 +0000 Subject: [PATCH 05/29] CIS Check 2.8 skips ADBs in the UNAVAILABLE state --- scripts/cis_reports.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/scripts/cis_reports.py b/scripts/cis_reports.py index 9b6d08b9..d4de0a12 100644 --- a/scripts/cis_reports.py +++ b/scripts/cis_reports.py @@ -3485,16 +3485,17 @@ def __report_cis_analyze_tenancy_data(self): # CIS 2.8 Check - Ensure Oracle Autonomous Shared Databases (ADB) access is restricted to allowed sources or deployed within a VCN # Iterating through ADB Checking for null NSGs, whitelisted ip or allowed IPs 0.0.0.0/0 for autonomous_database in self.__autonomous_databases: - if not(autonomous_database['whitelisted_ips']) and not(autonomous_database['nsg_ids']): - self.cis_foundations_benchmark_1_2['2.8']['Status'] = False - self.cis_foundations_benchmark_1_2['2.8']['Findings'].append( - autonomous_database) - elif autonomous_database['whitelisted_ips']: - for value in autonomous_database['whitelisted_ips']: - if '0.0.0.0/0' in str(autonomous_database['whitelisted_ips']): - self.cis_foundations_benchmark_1_2['2.8']['Status'] = False - self.cis_foundations_benchmark_1_2['2.8']['Findings'].append( - autonomous_database) + if autonomous_database['lifecycle_state']!="UNAVAILABLE": + if not(autonomous_database['whitelisted_ips']) and not(autonomous_database['nsg_ids']): + self.cis_foundations_benchmark_1_2['2.8']['Status'] = False + self.cis_foundations_benchmark_1_2['2.8']['Findings'].append( + autonomous_database) + elif autonomous_database['whitelisted_ips']: + for value in autonomous_database['whitelisted_ips']: + if '0.0.0.0/0' in str(autonomous_database['whitelisted_ips']): + self.cis_foundations_benchmark_1_2['2.8']['Status'] = False + self.cis_foundations_benchmark_1_2['2.8']['Findings'].append( + autonomous_database) # CIS Total 2.8 Adding - All ADBs to CIS Total self.cis_foundations_benchmark_1_2['2.8']['Total'] = self.__autonomous_databases From 0bbc521f5d480d8dfcf40c61d51f110fda6b1530 Mon Sep 17 00:00:00 2001 From: josh_hammer Date: Tue, 25 Jul 2023 22:16:25 +0000 Subject: [PATCH 06/29] docs: Added release notes for cis_reports.py --- image-1.png | Bin 0 -> 4416 bytes image-2.png | Bin 0 -> 909 bytes image.png | Bin 0 -> 4416 bytes release-notes.md | 6 ++++++ 4 files changed, 6 insertions(+) create mode 100644 image-1.png create mode 100644 image-2.png create mode 100644 image.png diff --git a/image-1.png b/image-1.png new file mode 100644 index 0000000000000000000000000000000000000000..36f020a7789c9c042a5acd29916eb1b6866b10fa GIT binary patch literal 4416 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 YE2rG=oBMy924*t`Pgg&ebxsLQ00XqFM*si- literal 0 HcmV?d00001 diff --git a/image.png b/image.png new file mode 100644 index 0000000000000000000000000000000000000000..36f020a7789c9c042a5acd29916eb1b6866b10fa GIT binary patch literal 4416 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 YlrD`oVUpdates to Terraform Template Updates: @@ -11,6 +12,11 @@ Updates: - Application Information tab is now enabled in OCI Resource Manager, displaying basic information about the stack and outputs of latest Terraform apply. +## Fixes to the CIS Compliance Script +Fixes: +-CIS check 2.8 now skips autonomous database in the UNAVAILABLE state + + # June 29, 2023 Release Notes - 2.5.12 1. [Fixes to the CIS Compliance Script](#2-5-12-script-fixes) From d0dcdea339e99d0ea311b6f32dfe222eb038dc2e Mon Sep 17 00:00:00 2001 From: Andre Correa Date: Tue, 25 Jul 2023 22:18:06 +0000 Subject: [PATCH 07/29] Issue 313 missing exa admin group in grants --- README.md | 5 +++++ config/iam_groups.tf | 2 +- config/provider.tf | 2 +- config/schema.yml | 7 +++---- images/livelab.png | Bin 0 -> 1655 bytes release-notes.md | 15 +++++++++++++++ release.txt | 2 +- 7 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 images/livelab.png diff --git a/README.md b/README.md index 89ad31ab..924669a7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,11 @@ [![Deploy_To_OCI](images/DeployToOCI.svg)](https://cloud.oracle.com/resourcemanager/stacks/create?zipUrl=https://github.com/oracle-quickstart/oci-cis-landingzone-quickstart/archive/refs/heads/main.zip) *If you are logged into your OCI tenancy, the button will take you directly to OCI Resource Manager where you can proceed to deploy. If you are not logged, the button takes you to Oracle Cloud initial page where you must enter your tenancy name and login to OCI.* +
+
+  Check our [Live Lab](https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3662) for key use cases and hands on deployment experience! +
+
# CIS OCI Landing Zone Quick Start Template ![Landing_Zone_Logo](images/landing%20zone_300.png) ## Table of Contents diff --git a/config/iam_groups.tf b/config/iam_groups.tf index a4f6b5bb..81cb8b59 100644 --- a/config/iam_groups.tf +++ b/config/iam_groups.tf @@ -258,7 +258,7 @@ locals { announcement_reader_group_name = length(trimspace(var.existing_announcement_reader_group_name)) == 0 ? module.lz_groups.groups[local.announcement_reader_group_key].name : (length(regexall("^ocid1.group.oc.*$", var.existing_announcement_reader_group_name)) > 0 ? data.oci_identity_group.existing_announcement_reader_group.name : var.existing_announcement_reader_group_name) cost_admin_group_name = length(trimspace(var.existing_cost_admin_group_name)) == 0 ? module.lz_groups.groups[local.cost_admin_group_key].name : (length(regexall("^ocid1.group.oc.*$", var.existing_cost_admin_group_name)) > 0 ? data.oci_identity_group.existing_cost_admin_group.name : var.existing_cost_admin_group_name) storage_admin_group_name = length(trimspace(var.existing_storage_admin_group_name)) == 0 ? module.lz_groups.groups[local.storage_admin_group_key].name : (length(regexall("^ocid1.group.oc.*$", var.existing_storage_admin_group_name)) > 0 ? data.oci_identity_group.existing_storage_admin_group.name : var.existing_storage_admin_group_name) - exainfra_admin_group_name = var.deploy_exainfra_cmp ? ((trimspace(var.existing_exainfra_admin_group_name)) == 0 ? module.lz_groups.groups[local.exainfra_admin_group_key].name : (length(regexall("^ocid1.group.oc.*$", var.existing_exainfra_admin_group_name)) > 0 ? data.oci_identity_group.existing_exainfra_admin_group.name : var.existing_exainfra_admin_group_name)) : var.existing_exainfra_admin_group_name + exainfra_admin_group_name = var.deploy_exainfra_cmp ? (length(trimspace(var.existing_exainfra_admin_group_name)) == 0 ? module.lz_groups.groups[local.exainfra_admin_group_key].name : (length(regexall("^ocid1.group.oc.*$", var.existing_exainfra_admin_group_name)) > 0 ? data.oci_identity_group.existing_exainfra_admin_group.name : var.existing_exainfra_admin_group_name)) : var.existing_exainfra_admin_group_name /* iam_admin_group_name = length(trimspace(var.existing_iam_admin_group_name)) == 0 ? local.provided_iam_admin_group_name : (length(regexall("^ocid1.group.oc.*$", var.existing_iam_admin_group_name)) > 0 ? data.oci_identity_group.existing_iam_admin_group.name : var.existing_iam_admin_group_name) cred_admin_group_name = length(trimspace(var.existing_cred_admin_group_name)) == 0 ? local.provided_cred_admin_group_name : (length(regexall("^ocid1.group.oc.*$", var.existing_cred_admin_group_name)) > 0 ? data.oci_identity_group.existing_cred_admin_group.name : var.existing_cred_admin_group_name) diff --git a/config/provider.tf b/config/provider.tf index 1587f18a..edd8c4ed 100644 --- a/config/provider.tf +++ b/config/provider.tf @@ -21,7 +21,7 @@ provider "oci" { } terraform { - required_version = ">= 1.2.0" + required_version = ">= 1.2.0, < 1.3.0" required_providers { oci = { diff --git a/config/schema.yml b/config/schema.yml index 85c7b1b4..faa28429 100644 --- a/config/schema.yml +++ b/config/schema.yml @@ -2,11 +2,10 @@ # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. title: "CIS (Center for Internet Security) OCI Landing Zone Quick Start" -stackDescription: "This stack deploys the CIS OCI Landing Zone Quick Start, a fully operational tenancy design that combines the recommendations of CIS Foundations Benchmark for OCI with OCI architecture best practices. For details, please see https://github.com/oracle-quickstart/oci-cis-landingzone-quickstart." -description: "This stack deploys the CIS OCI Landing Zone Quick Start, a fully operational tenancy design that combines the recommendations of CIS Foundations Benchmark for OCI with OCI architecture best practices. For details, please see CIS OCI Landing Zone Quick Start." -informationalText: "See below some of the outputs of the latest stack execution." +stackDescription: "This stack deploys the CIS OCI Landing Zone Quick Start, a fully operational tenancy that combines the recommendations of CIS Foundations Benchmark for OCI with OCI architecture best practices. For details, please see https://github.com/oracle-quickstart/oci-cis-landingzone-quickstart." +description: "This stack deploys the CIS OCI Landing Zone Quick Start, a fully operational tenancy that combines the recommendations of CIS Foundations Benchmark for OCI with OCI architecture best practices. For details, please see CIS OCI Landing Zone Quick Start." schemaVersion: 1.1.0 -version: "2.6.0" +version: "2.6.1" locale: "en" # URL of CIS Landing Zone logo icon used on Application Information tab. diff --git a/images/livelab.png b/images/livelab.png new file mode 100644 index 0000000000000000000000000000000000000000..f7ac2a4363dc8bf374151171b9954f66ae291d7f GIT binary patch literal 1655 zcmV--28j8IP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1`J6=K~zXfrB+#Q z+*B0yzKzG@v1dz~kfqHAEu|_{2qYwSfy4vq8xrsXctt#b#D9So-jF~@NL3#I2~|k6 zl%;J*leF17oqh2#9^2RE^LR3uqCUZqlexb4obR4{mhYO5*H`wj8Fj&xy zysTi?yS>iMX07Hrbh18{AR=pd^O-_vUe!dFZMn{VufsF!f}YQcQmVtyG((Pq(DB@@ zR>LPDKoy?H47O|!JtqvG%$rZ;jmdM?C^S8hfE-K2*8kx0|Ghrnx>N?iQ`ea zrfn#WVGK!H%H|}RE=%$%GAv3Q%}hBklJtEX-9%2jPG#B`WC8o(!5Gt(tahzdZ4O+_ z;B~rY9xEr%(IW+&R4&Tn$gw>V<^;hfWZfu!v$un|>w<`Kyl?f;5aR+n-U-o5UPm&9 zM(jpifPf?_C_B{qZohk{+p_&&Et|V`xOcbRe0yQJEGw_gEwnuE=jzcfwQ7CfKpD6| z08U6S9?KXy?Jg{%O)-E|zc=d#mUY1_zjtQc6veM@-~95=>z9{TvH6-|d~)H^oAZkZ z&h2)q>A65aN)V_)7)(OSe*D>|Q5@B5tLfTk7DHAVp1av;WBs{On!R9o19_vx7Y35s#h0s`Nf<;Gt7Z) zJE6Z}nCFXSYz_@WQa(6$@tu_omFM%a45Kun7fY2j-8i%@@PW(=t43+PP`pHb2D zI6e-9B%@${INJZ>@4p)U(Df4%Uea=J%`d$^zv#!&^;!)LP!UCt)EmpINf%6@(Wc*R z-9`@EVPJ=W&hj0{syjB&3zrxX&;EQg~73IgVvX9JxWza@~&W42B*2{bwij?Ael*k>3MUCw}o$7>_O-pF2S;5Hl^5BfzBK&zY` z5={_GvNF~?mN7Iy(*gPzHvqbT=Y{3GnH9x!{$B!ZQ&!5V#_{|xif}|gPe4*R@fx9k z37>Gh1irUOXsX)TVg(S>BnNAmxYgtr>HAA{m|;UenLGtN#a=U5V7{WilX3N*La~baH{CF zC<1}Nc7#XKxR}uq$%vv3dY#Q?9XoFn%SA;UMg)BQTch@Cqsq`MXd3(pdZ8)i`SQ&9 zLa`!e(C%<{t5vss|Fls!V-!-{gqu+Rb`VTH88C(a@O?TXm_jCC9L5m>jZ&Llg)Yh* z`ADwEkuqRqmP-l_UuF2%z;UJx{+pyu$SkY!!av`PD`V2>;Pe0h002ovPDHLkV1nPH B7o-3H literal 0 HcmV?d00001 diff --git a/release-notes.md b/release-notes.md index cc7b3210..0a98fdde 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,3 +1,18 @@ +# July 26, 2023 Release Notes - 2.6.1 +1. [Updates to Terraform Template](#2-6-1-tf-updates) +1. [Documentation Updates](#2-6-1-doc-updates) + +## Updates to Terraform Template +Fixes: +- Fixed a defect where missing exainfra admin group name in grants was causing policies creation to fail. + +Updates: +- Set Terraform version upper bound to *< 1.3.0* in [provider.tf](./config/provider.tf). + +## Documentation Updates +Updates: +- Added link to CIS Landing Zone Quick Start Live Lab in [README.md](./README.md). + # July 14, 2023 Release Notes - 2.6.0 1. [Updates to Terraform Template](#2-6-0-tf-updates) diff --git a/release.txt b/release.txt index 914ec967..b8d12d73 100644 --- a/release.txt +++ b/release.txt @@ -1 +1 @@ -2.6.0 \ No newline at end of file +2.6.1 \ No newline at end of file From 074e4e461d3fb1326454f1f59210ebe316f200a1 Mon Sep 17 00:00:00 2001 From: josh_hammer Date: Wed, 26 Jul 2023 15:31:02 +0000 Subject: [PATCH 08/29] doc:: Delete image-1.png --- image-1.png | Bin 4416 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 image-1.png diff --git a/image-1.png b/image-1.png deleted file mode 100644 index 36f020a7789c9c042a5acd29916eb1b6866b10fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4416 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 YlrD`oV Date: Wed, 26 Jul 2023 15:34:36 +0000 Subject: [PATCH 09/29] docs: Delete image-2.png --- image-2.png | Bin 909 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 image-2.png diff --git a/image-2.png b/image-2.png deleted file mode 100644 index 4e629dd6ef6f32f3005ff840a1a78252137fd918..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 909 zcmeAS@N?(olHy`uVBq!ia0y~yV7vlk^Kh^M$=kL*vltkdLp)s^Ln`9l&aU*%3KVhw zepW|YdW+*>w#AOW{>d-1*V=keDEHE)gGSl8J3j4ra(Ma)=AXGcIG)ejdw%cfgpKDn zF8D3GOn^}kf+V^eK145k^iYALEh^@uk^&P58R)Upsb29~n#9e`ZDwz8uP5_G4kjhS zDE{j6=gox|3zbf;T&Y=IUA@_FdGhAXoA(_!e7O03w%P2m`ucohW8-NaDmrrg(MB^( ztganD?p|GA|6S(Y+*A- zP4*7xHdR+w-}~+I<;mBT<`=edbToia&!h(Kt#RvjADQs*?c24oGBOd1FBYs!+Z-AH z|HX?F$A5Ev{q*UQnwnb7GIMkDX(v;1s;X{zEuGX~7znifeq4NfuU>g&<<093+kV#E z>+A2&&CERc^hC|E^78W9cm7-T_4NMO1?o+&^}W|@8Xg`VdxAr3rIw2W3kW4lVX2DV zS5jP3=8=`1eL7W4^wq&g%@%@M^E)Q4 z6K3R(n*BC*-t%|w&e>nTc5Tn=P)LAv9MIroxqsoDKcpK~@VIX2lmaaZq}BB+pj=l{xXms=b%Hw(kO^j=?{=+=7bSI$GX z?9EH7i;9w3oes`7t$AmE-dph1)vHsVBZW^>{>M^5vGiV+rrS4eeAw*4;$9$jiofAT zAFp+Q%h56|rsUnz`X(3$y;AVb3Rr!Ao6h5hRVAx){wtkW5%AJSuwaYXqi2$b_t?ziJGFy&&udPU6nBzUS@g61 z^vm$sQWw8UJbqML(q?tSe4!;I%^nu|arOT~zTGQ6xk6*|4u{8z$KQHi)k327A9tgE YE2rG=oBMy924*t`Pgg&ebxsLQ00XqFM*si- From 296d7d163ece0649690275200f328e3d346722bb Mon Sep 17 00:00:00 2001 From: josh_hammer Date: Wed, 26 Jul 2023 15:34:52 +0000 Subject: [PATCH 10/29] docs: Delete image.png --- image.png | Bin 4416 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 image.png diff --git a/image.png b/image.png deleted file mode 100644 index 36f020a7789c9c042a5acd29916eb1b6866b10fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4416 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 YlrD`oV Date: Wed, 26 Jul 2023 15:42:47 +0000 Subject: [PATCH 11/29] docs: Added cis_reports.py update --- release-notes.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/release-notes.md b/release-notes.md index 7317b3ef..03a333e9 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,6 +1,8 @@ # July 26, 2023 Release Notes - 2.6.1 1. [Updates to Terraform Template](#2-6-1-tf-updates) 1. [Documentation Updates](#2-6-1-doc-updates) +1. [Fixes to the CIS Compliance Script](#2-6-1-script-fixes) + ## Updates to Terraform Template Fixes: @@ -13,6 +15,11 @@ Updates: Updates: - Added link to CIS Landing Zone Quick Start Live Lab in [README.md](./README.md). +## Fixes to the CIS Compliance Script +Fixes: +-CIS check 2.8 now skips autonomous database in the UNAVAILABLE state + + # July 14, 2023 Release Notes - 2.6.0 1. [Updates to Terraform Template](#2-6-0-tf-updates) 1. [Fixes to the CIS Compliance Script](#2-6-1-script-fixes) From 4485f9a9a1577ec4270d71d188a0e9b9fb4ca6bc Mon Sep 17 00:00:00 2001 From: josh_hammer Date: Wed, 26 Jul 2023 15:43:58 +0000 Subject: [PATCH 12/29] docs: Fixed typo --- release-notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release-notes.md b/release-notes.md index 03a333e9..58d8891e 100644 --- a/release-notes.md +++ b/release-notes.md @@ -17,7 +17,7 @@ Updates: ## Fixes to the CIS Compliance Script Fixes: --CIS check 2.8 now skips autonomous database in the UNAVAILABLE state +- CIS check 2.8 now skips autonomous database in the UNAVAILABLE state # July 14, 2023 Release Notes - 2.6.0 From 7c133030618cb75f23eb64f10d07b221229c49cb Mon Sep 17 00:00:00 2001 From: Andre Correa Date: Wed, 26 Jul 2023 18:25:59 +0000 Subject: [PATCH 13/29] Update release-notes.md --- release-notes.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/release-notes.md b/release-notes.md index 58d8891e..eeb1a6e3 100644 --- a/release-notes.md +++ b/release-notes.md @@ -3,7 +3,6 @@ 1. [Documentation Updates](#2-6-1-doc-updates) 1. [Fixes to the CIS Compliance Script](#2-6-1-script-fixes) - ## Updates to Terraform Template Fixes: - Fixed a defect where missing exainfra admin group name in grants was causing policies creation to fail. @@ -22,7 +21,6 @@ Fixes: # July 14, 2023 Release Notes - 2.6.0 1. [Updates to Terraform Template](#2-6-0-tf-updates) -1. [Fixes to the CIS Compliance Script](#2-6-1-script-fixes) ## Updates to Terraform Template Updates: @@ -34,11 +32,6 @@ Updates: - Application Information tab is now enabled in OCI Resource Manager, displaying basic information about the stack and outputs of latest Terraform apply. -## Fixes to the CIS Compliance Script -Fixes: --CIS check 2.8 now skips autonomous database in the UNAVAILABLE state - - # June 29, 2023 Release Notes - 2.5.12 1. [Fixes to the CIS Compliance Script](#2-5-12-script-fixes) From 6f0082f72c86059d30b85bea90cea1581a771424 Mon Sep 17 00:00:00 2001 From: Josh Hammer Date: Thu, 27 Jul 2023 17:40:40 -0400 Subject: [PATCH 14/29] fix: Updated CIS 2.8 check for case when deployed into a subnet without NSGs attached --- scripts/cis_reports.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/cis_reports.py b/scripts/cis_reports.py index d4de0a12..62aeafd9 100644 --- a/scripts/cis_reports.py +++ b/scripts/cis_reports.py @@ -3486,7 +3486,7 @@ def __report_cis_analyze_tenancy_data(self): # Iterating through ADB Checking for null NSGs, whitelisted ip or allowed IPs 0.0.0.0/0 for autonomous_database in self.__autonomous_databases: if autonomous_database['lifecycle_state']!="UNAVAILABLE": - if not(autonomous_database['whitelisted_ips']) and not(autonomous_database['nsg_ids']): + if not(autonomous_database['whitelisted_ips']) and not(autonomous_database['subnet_id']): self.cis_foundations_benchmark_1_2['2.8']['Status'] = False self.cis_foundations_benchmark_1_2['2.8']['Findings'].append( autonomous_database) From d008576a0f3aa433bf4f710ba9b40f00a454a17b Mon Sep 17 00:00:00 2001 From: Samratha S P Date: Fri, 28 Jul 2023 18:56:39 +0000 Subject: [PATCH 15/29] script:alert to user about home region --- scripts/cis_reports.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/cis_reports.py b/scripts/cis_reports.py index d4de0a12..d5e12e9b 100644 --- a/scripts/cis_reports.py +++ b/scripts/cis_reports.py @@ -760,6 +760,9 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print if region.is_home_region: self.__home_region = region.region_name print("Home region for tenancy is " + self.__home_region) + if self.__home_region != self.__config['region']: + print_header("It is recommended to run the CIS Complaince script in your home region") + print_header("The current region is: " + self.__config['region']) self.__regions[region.region_name] = { "is_home_region": region.is_home_region, "region_key": region.region_key, From 558f077e3ee80cc0d431435c0fb06bee820a3284 Mon Sep 17 00:00:00 2001 From: Josh Hammer Date: Fri, 28 Jul 2023 15:43:48 -0400 Subject: [PATCH 16/29] docs: Added Load Balancers to the network admin documentation --- DEPLOYMENT-GUIDE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPLOYMENT-GUIDE.md b/DEPLOYMENT-GUIDE.md index c3293ddb..19d453d4 100644 --- a/DEPLOYMENT-GUIDE.md +++ b/DEPLOYMENT-GUIDE.md @@ -156,7 +156,7 @@ By default, the Landing Zone defines the following personas that account for mos - **Auditors**: entitled with read-only access across the tenancy and the ability to use cloud-shell to run the *cis_reports.py* script. - **Announcement Readers**: for reading announcements displayed in OCI Console. - **Security Administrators**: manage security services and resources including Vaults, Keys, Logging, Vulnerability Scanning, Web Application Firewall, Bastion, Service Connector Hub. -- **Network Administrators**: manage OCI network family, including VCNs, DRGs, VNICs, IP addresses. +- **Network Administrators**: manage OCI network family, including VCNs, Load Balancers, DRGs, VNICs, IP addresses. - **Application Administrators**: manage application related resources including Compute images, OCI Functions, Kubernetes clusters, Streams, Object Storage, Block Storage, File Storage. - **Database Administrators**: manage database services, including Oracle VMDB (Virtual Machine), BMDB (Bare Metal), ADB (Autonomous databases), Exadata databases, MySQL, NoSQL, etc. - **ExaCS Administrators** (only created when ExaCS compartment is created): manage Exadata infrastructure and VM clusters in the ExaCS compartment. @@ -169,7 +169,7 @@ By default, the Landing Zone defines the following personas that account for mos The Landing Zone defines four dynamic groups to satisfy common needs of workloads that are eventually deployed: - **Security Functions**: to be used by functions defined in the Security compartment. The matching rule includes all functions in the Security compartment. An example is a function for rotating secrets kept in a Vault. -- **AppDev Functions**: to be used by functions defined in the AppDev compartment. The matching rule includes all functions in the AppDev compartment. An example is a function for processing of application data and the sending to Object Storage. +- **AppDev Functions**: to be used by functions defined in the AppDev compartment. The matching rule includes all functions in the AppDev compartment. An example is a function for processing of application data and writing it to an Object Storage bucket. - **Compute Agent**: to be used by Compute's management agent in the AppDev compartment. - **Database KMS**: to be used by databases in the Database compartment to access keys in the Vault service. From 904627165c84ca816d91a21c68ad4715ac29437e Mon Sep 17 00:00:00 2001 From: Samratha S P Date: Mon, 31 Jul 2023 19:09:17 +0530 Subject: [PATCH 17/29] script:obp-adding service connector id --- scripts/cis_reports.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/cis_reports.py b/scripts/cis_reports.py index d4de0a12..9418bb17 100644 --- a/scripts/cis_reports.py +++ b/scripts/cis_reports.py @@ -3860,6 +3860,7 @@ def __obp_analyze_tenancy_data(self): log_id = log_values['log_id'] log_group_id = log_values['log_group_id'] + log_record = {"sch_id": sch_id ,"id" : subnet_id} subnet_log_group_in_sch = list(filter(lambda source: source['log_group_id'] == log_group_id, sch_values['log_sources'] )) subnet_log_in_sch = list(filter(lambda source: source['log_id'] == log_id, sch_values['log_sources'] )) @@ -3880,6 +3881,7 @@ def __obp_analyze_tenancy_data(self): log_id = log_values['log_id'] log_group_id = log_values['log_group_id'] log_region = log_values['region'] + log_record = {"sch_id": sch_id ,"id" : bucket_name} bucket_log_group_in_sch = list(filter(lambda source: source['log_group_id'] == log_group_id and sch_values['region'] == log_region, sch_values['log_sources'] )) bucket_log_in_sch = list(filter(lambda source: source['log_id'] == log_id and sch_values['region'] == log_region, sch_values['log_sources'])) @@ -3901,6 +3903,7 @@ def __obp_analyze_tenancy_data(self): log_id = log_values['log_id'] log_group_id = log_values['log_group_id'] log_region = log_values['region'] + log_record = {"sch_id": sch_id ,"id" : bucket_name} bucket_log_group_in_sch = list(filter(lambda source: source['log_group_id'] == log_group_id and sch_values['region'] == log_region, sch_values['log_sources'] )) bucket_log_in_sch = list(filter(lambda source: source['log_id'] == log_id and sch_values['region'] == log_region, sch_values['log_sources'])) From 22451a48cebbb7294c512e24e3dd7becf16e9f33 Mon Sep 17 00:00:00 2001 From: Josh Hammer Date: Mon, 31 Jul 2023 10:02:07 -0400 Subject: [PATCH 18/29] feat: Add service connector id to VCN flow logs OBP --- scripts/cis_reports.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/scripts/cis_reports.py b/scripts/cis_reports.py index 9418bb17..a11a399a 100644 --- a/scripts/cis_reports.py +++ b/scripts/cis_reports.py @@ -3867,11 +3867,11 @@ def __obp_analyze_tenancy_data(self): # Checking if the Subnets's log group in is in SCH's log sources & the log_id is empty so it covers everything in the log group if subnet_log_group_in_sch and not(subnet_log_in_sch): - self.__obp_regional_checks[sch_values['region']]['VCN']['subnets'].append(subnet_id) + self.__obp_regional_checks[sch_values['region']]['VCN']['subnets'].append(log_record) # Checking if the Subnet's log id in is in the service connector's log sources if so I will add it elif subnet_log_in_sch: - self.__obp_regional_checks[sch_values['region']]['VCN']['subnets'].append(subnet_id) + self.__obp_regional_checks[sch_values['region']]['VCN']['subnets'].append(log_record) # else: # self.__obp_regional_checks[sch_values['region']]['VCN']['findings'].append(subnet_id) @@ -3888,11 +3888,11 @@ def __obp_analyze_tenancy_data(self): # Checking if the Bucket's log group in is in SCH's log sources & the log_id is empty so it covers everything in the log group if bucket_log_group_in_sch and not(bucket_log_in_sch): - self.__obp_regional_checks[sch_values['region']]['Write_Bucket']['buckets'].append(bucket_name) + self.__obp_regional_checks[sch_values['region']]['Write_Bucket']['buckets'].append(log_record) # Checking if the Bucket's log Group in is in the service connector's log sources if so I will add it elif bucket_log_in_sch: - self.__obp_regional_checks[sch_values['region']]['Write_Bucket']['buckets'].append(bucket_name) + self.__obp_regional_checks[sch_values['region']]['Write_Bucket']['buckets'].append(log_record) # else: # self.__obp_regional_checks[sch_values['region']]['Write_Bucket']['findings'].append(bucket_name) @@ -3910,22 +3910,24 @@ def __obp_analyze_tenancy_data(self): # Checking if the Bucket's log group in is in SCH's log sources & the log_id is empty so it covers everything in the log group if bucket_log_group_in_sch and not(bucket_log_in_sch): - self.__obp_regional_checks[sch_values['region']]['Read_Bucket']['buckets'].append(bucket_name) + self.__obp_regional_checks[sch_values['region']]['Read_Bucket']['buckets'].append(log_record) # Checking if the Bucket's log id in is in the service connector's log sources if so I will add it elif bucket_log_in_sch: - self.__obp_regional_checks[sch_values['region']]['Read_Bucket']['buckets'].append(bucket_name) + self.__obp_regional_checks[sch_values['region']]['Read_Bucket']['buckets'].append(log_record) ### Consolidating regional SERVICE LOGGING findings into centralized finding report for region_key, region_values in self.__obp_regional_checks.items(): for finding in region_values['VCN']['subnets']: - logged_subnet = list(filter(lambda subnet: subnet['id'] == finding, self.__network_subnets )) + logged_subnet = list(filter(lambda subnet: subnet['id'] == finding['id'], self.__network_subnets )) # Checking that the subnet has not already been written to OBP - existing_finding = list(filter(lambda subnet: subnet['id'] == finding, self.obp_foundations_checks['SIEM_VCN_Flow_Logging']['OBP'])) + existing_finding = list(filter(lambda subnet: subnet['id'] == finding['id'], self.obp_foundations_checks['SIEM_VCN_Flow_Logging']['OBP'])) if logged_subnet and not(existing_finding): + record = logged_subnet[0] + record['sch_id'] = finding['sch_id'] self.obp_foundations_checks['SIEM_VCN_Flow_Logging']['OBP'].append(logged_subnet[0]) # else: # print("Found this subnet being logged but the subnet does not exist: " + str(finding)) From 8f7e3a1ba1068d37079fe2d28c41b417c0b40df1 Mon Sep 17 00:00:00 2001 From: Samratha S P Date: Mon, 31 Jul 2023 23:05:35 +0530 Subject: [PATCH 19/29] feat:obp:Adding serviceconnector id --- scripts/cis_reports.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/scripts/cis_reports.py b/scripts/cis_reports.py index a11a399a..11002458 100644 --- a/scripts/cis_reports.py +++ b/scripts/cis_reports.py @@ -3732,6 +3732,7 @@ def __obp_analyze_tenancy_data(self): # Only Active SCH with a target that is configured if sch_values['lifecycle_state'].upper() == "ACTIVE" and sch_values['target_kind']: for source in sch_values['log_sources']: + log_record = {"sch_id": sch_id , "id" : source['compartment_id']} try: # Checking if a the compartment being logged is the Tenancy and it has all child compartments if source['compartment_id'] == self.__tenancy.id and source['log_group_id'].upper() == "_Audit_Include_Subcompartment".upper(): @@ -3742,7 +3743,7 @@ def __obp_analyze_tenancy_data(self): elif source['log_group_id'].upper() == "_Audit_Include_Subcompartment".upper(): self.__obp_regional_checks[sch_values['region']]['Audit']['compartments'] += self.__get_children(source['compartment_id'],dict_of_compartments) elif source['log_group_id'].upper() == "_Audit".upper(): - self.__obp_regional_checks[sch_values['region']]['Audit']['compartments'].append(source['compartment_id']) + self.__obp_regional_checks[sch_values['region']]['Audit']['compartments'].append(log_record) except: # There can be empty log groups pass @@ -3933,14 +3934,18 @@ def __obp_analyze_tenancy_data(self): # print("Found this subnet being logged but the subnet does not exist: " + str(finding)) for finding in region_values['Write_Bucket']['buckets']: - logged_bucket = list(filter(lambda bucket: bucket['name'] == finding, self.__buckets )) + logged_bucket = list(filter(lambda bucket: bucket['name'] == finding['id'], self.__buckets )) if logged_bucket: + record = logged_bucket[0] + record['sch_id'] = finding['sch_id'] self.obp_foundations_checks['SIEM_Write_Bucket_Logs']['OBP'].append(logged_bucket[0]) for finding in region_values['Read_Bucket']['buckets']: - logged_bucket = list(filter(lambda bucket: bucket['name'] == finding, self.__buckets )) + logged_bucket = list(filter(lambda bucket: bucket['name'] == finding['id'], self.__buckets )) if logged_bucket: + record = logged_bucket[0] + record['sch_id'] = finding['sch_id'] self.obp_foundations_checks['SIEM_Read_Bucket_Logs']['OBP'].append(logged_bucket[0]) From 3aa0d611365a9c35da707db18304bcedf8b1fdfa Mon Sep 17 00:00:00 2001 From: Josh Hammer Date: Mon, 31 Jul 2023 18:19:38 -0400 Subject: [PATCH 20/29] feat: Added SCH ID and SCH Names to VCN and bucket related OBPs --- scripts/cis_reports.py | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/scripts/cis_reports.py b/scripts/cis_reports.py index 11002458..bac9e964 100644 --- a/scripts/cis_reports.py +++ b/scripts/cis_reports.py @@ -3732,7 +3732,7 @@ def __obp_analyze_tenancy_data(self): # Only Active SCH with a target that is configured if sch_values['lifecycle_state'].upper() == "ACTIVE" and sch_values['target_kind']: for source in sch_values['log_sources']: - log_record = {"sch_id": sch_id , "id" : source['compartment_id']} + log_record = {"sch_id": sch_id , "sch_name" : sch_values['display_name'], "id" : source['compartment_id']} try: # Checking if a the compartment being logged is the Tenancy and it has all child compartments if source['compartment_id'] == self.__tenancy.id and source['log_group_id'].upper() == "_Audit_Include_Subcompartment".upper(): @@ -3861,7 +3861,7 @@ def __obp_analyze_tenancy_data(self): log_id = log_values['log_id'] log_group_id = log_values['log_group_id'] - log_record = {"sch_id": sch_id ,"id" : subnet_id} + log_record = {"sch_id": sch_id , "sch_name" : sch_values['display_name'], "id" : subnet_id} subnet_log_group_in_sch = list(filter(lambda source: source['log_group_id'] == log_group_id, sch_values['log_sources'] )) subnet_log_in_sch = list(filter(lambda source: source['log_id'] == log_id, sch_values['log_sources'] )) @@ -3882,7 +3882,7 @@ def __obp_analyze_tenancy_data(self): log_id = log_values['log_id'] log_group_id = log_values['log_group_id'] log_region = log_values['region'] - log_record = {"sch_id": sch_id ,"id" : bucket_name} + log_record = {"sch_id": sch_id , "sch_name" : sch_values['display_name'], "id" : bucket_name} bucket_log_group_in_sch = list(filter(lambda source: source['log_group_id'] == log_group_id and sch_values['region'] == log_region, sch_values['log_sources'] )) bucket_log_in_sch = list(filter(lambda source: source['log_id'] == log_id and sch_values['region'] == log_region, sch_values['log_sources'])) @@ -3904,7 +3904,7 @@ def __obp_analyze_tenancy_data(self): log_id = log_values['log_id'] log_group_id = log_values['log_group_id'] log_region = log_values['region'] - log_record = {"sch_id": sch_id ,"id" : bucket_name} + log_record = {"sch_id": sch_id , "sch_name" : sch_values['display_name'], "id" : bucket_name} bucket_log_group_in_sch = list(filter(lambda source: source['log_group_id'] == log_group_id and sch_values['region'] == log_region, sch_values['log_sources'] )) bucket_log_in_sch = list(filter(lambda source: source['log_id'] == log_id and sch_values['region'] == log_region, sch_values['log_sources'])) @@ -3925,28 +3925,30 @@ def __obp_analyze_tenancy_data(self): logged_subnet = list(filter(lambda subnet: subnet['id'] == finding['id'], self.__network_subnets )) # Checking that the subnet has not already been written to OBP existing_finding = list(filter(lambda subnet: subnet['id'] == finding['id'], self.obp_foundations_checks['SIEM_VCN_Flow_Logging']['OBP'])) - + record = logged_subnet[0].copy() + record['sch_id'] = finding['sch_id'] + record['sch_name'] = finding['sch_name'] + if logged_subnet and not(existing_finding): - record = logged_subnet[0] - record['sch_id'] = finding['sch_id'] - self.obp_foundations_checks['SIEM_VCN_Flow_Logging']['OBP'].append(logged_subnet[0]) + self.obp_foundations_checks['SIEM_VCN_Flow_Logging']['OBP'].append(record) # else: # print("Found this subnet being logged but the subnet does not exist: " + str(finding)) for finding in region_values['Write_Bucket']['buckets']: logged_bucket = list(filter(lambda bucket: bucket['name'] == finding['id'], self.__buckets )) + record = logged_bucket[0].copy() + record['sch_id'] = finding['sch_id'] + record['sch_name'] = finding['sch_name'] if logged_bucket: - record = logged_bucket[0] - record['sch_id'] = finding['sch_id'] - self.obp_foundations_checks['SIEM_Write_Bucket_Logs']['OBP'].append(logged_bucket[0]) + self.obp_foundations_checks['SIEM_Write_Bucket_Logs']['OBP'].append(record) for finding in region_values['Read_Bucket']['buckets']: logged_bucket = list(filter(lambda bucket: bucket['name'] == finding['id'], self.__buckets )) - + record = logged_bucket[0].copy() + record['sch_id'] = finding['sch_id'] + record['sch_name'] = finding['sch_name'] if logged_bucket: - record = logged_bucket[0] - record['sch_id'] = finding['sch_id'] - self.obp_foundations_checks['SIEM_Read_Bucket_Logs']['OBP'].append(logged_bucket[0]) + self.obp_foundations_checks['SIEM_Read_Bucket_Logs']['OBP'].append(record) # Finding looking at all buckets and seeing if they meet one of the OBPs in one of the regions From 318dedd0c6e6d69a9cbd1499f5ba22e9d60fefd0 Mon Sep 17 00:00:00 2001 From: Samratha S P Date: Tue, 1 Aug 2023 19:02:35 +0530 Subject: [PATCH 21/29] feat:reverted compartment obp change for sch_id --- scripts/cis_reports.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/cis_reports.py b/scripts/cis_reports.py index bac9e964..ae89eb4f 100644 --- a/scripts/cis_reports.py +++ b/scripts/cis_reports.py @@ -3732,7 +3732,6 @@ def __obp_analyze_tenancy_data(self): # Only Active SCH with a target that is configured if sch_values['lifecycle_state'].upper() == "ACTIVE" and sch_values['target_kind']: for source in sch_values['log_sources']: - log_record = {"sch_id": sch_id , "sch_name" : sch_values['display_name'], "id" : source['compartment_id']} try: # Checking if a the compartment being logged is the Tenancy and it has all child compartments if source['compartment_id'] == self.__tenancy.id and source['log_group_id'].upper() == "_Audit_Include_Subcompartment".upper(): @@ -3743,7 +3742,7 @@ def __obp_analyze_tenancy_data(self): elif source['log_group_id'].upper() == "_Audit_Include_Subcompartment".upper(): self.__obp_regional_checks[sch_values['region']]['Audit']['compartments'] += self.__get_children(source['compartment_id'],dict_of_compartments) elif source['log_group_id'].upper() == "_Audit".upper(): - self.__obp_regional_checks[sch_values['region']]['Audit']['compartments'].append(log_record) + self.__obp_regional_checks[sch_values['region']]['Audit']['compartments'].append(source['compartment_id']) except: # There can be empty log groups pass From 0d494de4f93818eafef3fc7d6250477ce338a873 Mon Sep 17 00:00:00 2001 From: azohar Date: Mon, 7 Aug 2023 11:57:34 -0400 Subject: [PATCH 22/29] Amend script to be flake8 compliance to 2.6.2 --- scripts/cis_reports.py | 3485 ++++++++++++++++++++-------------------- 1 file changed, 1727 insertions(+), 1758 deletions(-) diff --git a/scripts/cis_reports.py b/scripts/cis_reports.py index 955f0b0a..0d655299 100644 --- a/scripts/cis_reports.py +++ b/scripts/cis_reports.py @@ -27,15 +27,16 @@ import re try: - from xlsxwriter.workbook import Workbook + from xlsxwriter.workbook import Workbook import glob OUTPUT_TO_XLSX = True -except: +except Exception: OUTPUT_TO_XLSX = False -RELEASE_VERSION = "2.6.0" +RELEASE_VERSION = "2.6.2" PYTHON_SDK_VERSION = "2.106.0" -UPDATED_DATE = "July 14, 2023" +UPDATED_DATE = "August 9, 2023" + ########################################################################## # Print header centered @@ -47,18 +48,23 @@ def print_header(name): print('#' + name.center(chars - 2, ' ') + '#') print('#' * chars) + +########################################################################## +# show_version +########################################################################## def show_version(verbose=False): script_version = f'CIS Reports - Release {RELEASE_VERSION}' - script_updated = f'Updated {UPDATED_DATE}' + script_updated = f'Version {RELEASE_VERSION} Updated on {UPDATED_DATE}' if verbose: print_header('Running ' + script_version) print(script_updated) - print(f'Tested oci-python-sdk version: {PYTHON_SDK_VERSION}') - print('Your oci-python-sdk version: ' + str(oci.__version__)) + print('Please use --help for more info') + print('\nTested oci-python-sdk version: ' + PYTHON_SDK_VERSION) + print('Installed oci-python-sdk version: ' + str(oci.__version__)) else: - print(script_version) print(script_updated) + ########################################################################## # CIS Reporting Class ########################################################################## @@ -69,11 +75,10 @@ class CIS_Report: __KMS_DAYS_OLD = 365 __home_region = [] - # Time Format __iso_time_format = "%Y-%m-%dT%H:%M:%S" - # OCI Link + # OCI Link __oci_cloud_url = "https://cloud.oracle.com" __oci_users_uri = __oci_cloud_url + "/identity/users/" __oci_policies_uri = __oci_cloud_url + "/identity/policies/" @@ -83,22 +88,22 @@ class CIS_Report: __oci_boot_volumes_uri = __oci_cloud_url + "/block-storage/boot-volumes/" __oci_block_volumes_uri = __oci_cloud_url + "/block-storage/volumes/" __oci_fss_uri = __oci_cloud_url + "/fss/file-systems/" - __oci_networking_uri = __oci_cloud_url +"/networking/vcns/" - __oci_adb_uri = __oci_cloud_url +"/db/adb/" - __oci_oicinstance_uri = __oci_cloud_url +"/oic/integration-instances/" - __oci_oacinstance_uri = __oci_cloud_url +"/analytics/instances/" - __oci_compartment_uri = __oci_cloud_url +"/identity/compartments/" - __oci_drg_uri = __oci_cloud_url +"/networking/drgs/" - __oci_cpe_uri = __oci_cloud_url +"/networking/cpes/" - __oci_ipsec_uri = __oci_cloud_url +"/networking/vpn-connections/" - __oci_events_uri = __oci_cloud_url +"/events/rules/" - __oci_loggroup_uri = __oci_cloud_url +"/logging/log-groups/" - __oci_vault_uri = __oci_cloud_url +"/security/kms/vaults/" - __oci_budget_uri = __oci_cloud_url +"/usage/budgets/" - __oci_cgtarget_uri = __oci_cloud_url +"/cloud-guard/targets/" - __oci_onssub_uri = __oci_cloud_url +"/notification/subscriptions/" - __oci_serviceconnector_uri = __oci_cloud_url +"/connector-hub/service-connectors/" - __oci_fastconnect_uri = __oci_cloud_url +"/networking/fast-connect/virtual-circuit/" + __oci_networking_uri = __oci_cloud_url + "/networking/vcns/" + __oci_adb_uri = __oci_cloud_url + "/db/adb/" + __oci_oicinstance_uri = __oci_cloud_url + "/oic/integration-instances/" + __oci_oacinstance_uri = __oci_cloud_url + "/analytics/instances/" + __oci_compartment_uri = __oci_cloud_url + "/identity/compartments/" + __oci_drg_uri = __oci_cloud_url + "/networking/drgs/" + __oci_cpe_uri = __oci_cloud_url + "/networking/cpes/" + __oci_ipsec_uri = __oci_cloud_url + "/networking/vpn-connections/" + __oci_events_uri = __oci_cloud_url + "/events/rules/" + __oci_loggroup_uri = __oci_cloud_url + "/logging/log-groups/" + __oci_vault_uri = __oci_cloud_url + "/security/kms/vaults/" + __oci_budget_uri = __oci_cloud_url + "/usage/budgets/" + __oci_cgtarget_uri = __oci_cloud_url + "/cloud-guard/targets/" + __oci_onssub_uri = __oci_cloud_url + "/notification/subscriptions/" + __oci_serviceconnector_uri = __oci_cloud_url + "/connector-hub/service-connectors/" + __oci_fastconnect_uri = __oci_cloud_url + "/networking/fast-connect/virtual-circuit/" __oci_ocid_pattern = r'ocid1\.[a-z,0-9]*\.[a-z,0-9]*\.[a-z,0-9,-]*\.[a-z,0-9,\.]{20,}' @@ -106,13 +111,14 @@ class CIS_Report: start_datetime = datetime.datetime.now().replace(tzinfo=pytz.UTC) start_time_str = str(start_datetime.strftime(__iso_time_format)) report_datetime = str(start_datetime.strftime("%Y-%m-%d_%H-%M-%S")) + # For User based key checks api_key_time_max_datetime = start_datetime - \ datetime.timedelta(days=_DAYS_OLD) str_api_key_time_max_datetime = api_key_time_max_datetime.strftime(__iso_time_format) api_key_time_max_datetime = datetime.datetime.strptime(str_api_key_time_max_datetime, __iso_time_format) - + # For KMS check kms_key_time_max_datetime = start_datetime - \ datetime.timedelta(days=__KMS_DAYS_OLD) @@ -123,407 +129,437 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print # CIS Foundation benchmark 1.2 self.cis_foundations_benchmark_1_2 = { - '1.1': {'section': 'Identity and Access Management', 'recommendation_#': '1.1', 'Title': 'Ensure service level admins are created to manage resources of particular service', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['5.4','6.7'], 'CCCS Guard Rail' : '2,3','Remediation':[]}, - '1.2': {'section': 'Identity and Access Management', 'recommendation_#': '1.2', 'Title': 'Ensure permissions on all resources are given only to the tenancy administrator group', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['3.3'], 'CCCS Guard Rail' : '1,2,3','Remediation':[]}, - '1.3': {'section': 'Identity and Access Management', 'recommendation_#': '1.3', 'Title': 'Ensure IAM administrators cannot update tenancy Administrators group', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['3.3','5.4'], 'CCCS Guard Rail' : '2,3','Remediation':[]}, - '1.4': {'section': 'Identity and Access Management', 'recommendation_#': '1.4', 'Title': 'Ensure IAM password policy requires minimum length of 14 or greater', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.1','5.2'], 'CCCS Guard Rail' : '2,3','Remediation':[]}, - '1.5': {'section': 'Identity and Access Management', 'recommendation_#': '1.5', 'Title': 'Ensure IAM password policy expires passwords within 365 days', 'Status': None, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.1','5.2'], 'CCCS Guard Rail' : '2,3','Remediation':[]}, - '1.6': {'section': 'Identity and Access Management', 'recommendation_#': '1.6', 'Title': 'Ensure IAM password policy prevents password reuse', 'Status': None, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['5.2'], 'CCCS Guard Rail' : '2,3','Remediation':[]}, - '1.7': {'section': 'Identity and Access Management', 'recommendation_#': '1.7', 'Title': 'Ensure MFA is enabled for all users with a console password', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['6.3','6.5'], 'CCCS Guard Rail' : '1,2,3,4','Remediation':[]}, - '1.8': {'section': 'Identity and Access Management', 'recommendation_#': '1.8', 'Title': 'Ensure user API keys rotate within 90 days or less', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.1','4.4'], 'CCCS Guard Rail' : '6,7','Remediation':[]}, - '1.9': {'section': 'Identity and Access Management', 'recommendation_#': '1.9', 'Title': 'Ensure user customer secret keys rotate within 90 days or less', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.1','5.2'], 'CCCS Guard Rail' : '6,7','Remediation':[]}, - '1.10': {'section': 'Identity and Access Management', 'recommendation_#': '1.10', 'Title': 'Ensure user auth tokens rotate within 90 days or less', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.1','5.2'], 'CCCS Guard Rail' : '6,7','Remediation':[]}, - '1.11': {'section': 'Identity and Access Management', 'recommendation_#': '1.11', 'Title': 'Ensure API keys are not created for tenancy administrator users', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['5.4'], 'CCCS Guard Rail' : '6,7','Remediation':[]}, - '1.12': {'section': 'Identity and Access Management', 'recommendation_#': '1.12', 'Title': 'Ensure all OCI IAM user accounts have a valid and current email address', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['5.1'], 'CCCS Guard Rail' : '1,2,3','Remediation':[]}, - '1.13': {'section': 'Identity and Access Management', 'recommendation_#': '1.13', 'Title': 'Ensure Dynamic Groups are used for OCI instances, OCI Cloud Databases and OCI Function to access OCI resources', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['6.8'], 'CCCS Guard Rail' : '6,7','Remediation':[]}, - '1.14': {'section': 'Identity and Access Management', 'recommendation_#': '1.14', 'Title': 'Ensure storage service-level admins cannot delete resources they manage', 'Status': None, 'Level': 2, 'Total': [], 'Findings': [], 'CISv8': ['5.4','6.8'], 'CCCS Guard Rail' : '2,3','Remediation':[]}, - - '2.1': {'section': 'Networking', 'recommendation_#': '2.1', 'Title': 'Ensure no security lists allow ingress from 0.0.0.0/0 to port 22.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.4','12.3'], 'CCCS Guard Rail' : '2,3,5,7,9','Remediation':[]}, - '2.2': {'section': 'Networking', 'recommendation_#': '2.2', 'Title': 'Ensure no security lists allow ingress from 0.0.0.0/0 to port 3389.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.4','12.3'], 'CCCS Guard Rail' : '2,3,5,7,9','Remediation':[]}, - '2.3': {'section': 'Networking', 'recommendation_#': '2.3', 'Title': 'Ensure no network security groups allow ingress from 0.0.0.0/0 to port 22.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.4','12.3'], 'CCCS Guard Rail' : '2,3,5,7,9','Remediation':[]}, - '2.4': {'section': 'Networking', 'recommendation_#': '2.4', 'Title': 'Ensure no network security groups allow ingress from 0.0.0.0/0 to port 3389.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.4','12.3'], 'CCCS Guard Rail' : '2,3,5,7,9','Remediation':[]}, - '2.5': {'section': 'Networking', 'recommendation_#': '2.5', 'Title': 'Ensure the default security list of every VCN restricts all traffic except ICMP.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['12.3'], 'CCCS Guard Rail' : '2,3,5,7,9','Remediation':[]}, - '2.6': {'section': 'Networking', 'recommendation_#': '2.6', 'Title': 'Ensure Oracle Integration Cloud (OIC) access is restricted to allowed sources.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.4','12.3'], 'CCCS Guard Rail' : '2,3,5,7,9','Remediation':[]}, - '2.7': {'section': 'Networking', 'recommendation_#': '2.7', 'Title': 'Ensure Oracle Analytics Cloud (OAC) access is restricted to allowed sources or deployed within a Virtual Cloud Network.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.4','12.3'], 'CCCS Guard Rail' : '2,3,5,7,9','Remediation':[]}, - '2.8': {'section': 'Networking', 'recommendation_#': '2.8', 'Title': 'Ensure Oracle Autonomous Shared Database (ADB) access is restricted or deployed within a VCN.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.4','12.3'], 'CCCS Guard Rail' : '2,3,5,7,9','Remediation':[]}, - - '3.1': {'section': 'Logging and Monitoring', 'recommendation_#': '3.1', 'Title': 'Ensure audit log retention period is set to 365 days.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['8.10'], 'CCCS Guard Rail' : '11','Remediation':[]}, - '3.2': {'section': 'Logging and Monitoring', 'recommendation_#': '3.2', 'Title': 'Ensure default tags are used on resources.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['1.1'], 'CCCS Guard Rail' : '','Remediation':[]}, - '3.3': {'section': 'Logging and Monitoring', 'recommendation_#': '3.3', 'Title': 'Create at least one notification topic and subscription to receive monitoring alerts.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['8.2','8.11'], 'CCCS Guard Rail' : '11','Remediation':[]}, - '3.4': {'section': 'Logging and Monitoring', 'recommendation_#': '3.4', 'Title': 'Ensure a notification is configured for Identity Provider changes.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.2'], 'CCCS Guard Rail' : '11','Remediation':[]}, - '3.5': {'section': 'Logging and Monitoring', 'recommendation_#': '3.5', 'Title': 'Ensure a notification is configured for IdP group mapping changes.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.2'], 'CCCS Guard Rail' : '11','Remediation':[]}, - '3.6': {'section': 'Logging and Monitoring', 'recommendation_#': '3.6', 'Title': 'Ensure a notification is configured for IAM group changes.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.2'], 'CCCS Guard Rail' : '11','Remediation':[]}, - '3.7': {'section': 'Logging and Monitoring', 'recommendation_#': '3.7', 'Title': 'Ensure a notification is configured for IAM policy changes.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.2'], 'CCCS Guard Rail' : '11','Remediation':[]}, - '3.8': {'section': 'Logging and Monitoring', 'recommendation_#': '3.8', 'Title': 'Ensure a notification is configured for user changes.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.2'], 'CCCS Guard Rail' : '11','Remediation':[]}, - '3.9': {'section': 'Logging and Monitoring', 'recommendation_#': '3.9', 'Title': 'Ensure a notification is configured for VCN changes.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.2'], 'CCCS Guard Rail' : '11','Remediation':[]}, - '3.10': {'section': 'Logging and Monitoring', 'recommendation_#': '3.10', 'Title': 'Ensure a notification is configured for changes to route tables.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.2'], 'CCCS Guard Rail' : '11','Remediation':[]}, - '3.11': {'section': 'Logging and Monitoring', 'recommendation_#': '3.11', 'Title': 'Ensure a notification is configured for security list changes.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.2'], 'CCCS Guard Rail' : '11','Remediation':[]}, - '3.12': {'section': 'Logging and Monitoring', 'recommendation_#': '3.12', 'Title': 'Ensure a notification is configured for network security group changes.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.2'], 'CCCS Guard Rail' : '11','Remediation':[]}, - '3.13': {'section': 'Logging and Monitoring', 'recommendation_#': '3.13', 'Title': 'Ensure a notification is configured for changes to network gateways.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.2'], 'CCCS Guard Rail' : '11','Remediation':[]}, - '3.14': {'section': 'Logging and Monitoring', 'recommendation_#': '3.14', 'Title': 'Ensure VCN flow logging is enabled for all subnets.', 'Status': True, 'Level': 2, 'Total': [], 'Findings': [], 'CISv8': ['8.2','8.5','13.6'], 'CCCS Guard Rail' : '','Remediation':[]}, - '3.15': {'section': 'Logging and Monitoring', 'recommendation_#': '3.15', 'Title': 'Ensure Cloud Guard is enabled in the root compartment of the tenancy.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['8.2','8.5','8.11'], 'CCCS Guard Rail' : '1,2,3','Remediation':[]}, - '3.16': {'section': 'Logging and Monitoring', 'recommendation_#': '3.16', 'Title': 'Ensure customer created Customer Managed Key (CMK) is rotated at least annually.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': [], 'CCCS Guard Rail' : '6,7','Remediation':[]}, - '3.17': {'section': 'Logging and Monitoring', 'recommendation_#': '3.17', 'Title': 'Ensure write level Object Storage logging is enabled for all buckets.', 'Status': True, 'Level': 2, 'Total': [], 'Findings': [], 'CISv8': ['8.2'], 'CCCS Guard Rail' : '','Remediation':[]}, - - '4.1.1': {'section': 'Storage - Object Storage', 'recommendation_#': '4.1.1', 'Title': 'Ensure no Object Storage buckets are publicly visible.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['3.3'], 'CCCS Guard Rail' : '','Remediation':[]}, - '4.1.2': {'section': 'Storage - Object Storage', 'recommendation_#': '4.1.2', 'Title': 'Ensure Object Storage Buckets are encrypted with a Customer-Managed Key (CMK).', 'Status': True, 'Level': 2, 'Total': [], 'Findings': [], 'CISv8': ['3.11'], 'CCCS Guard Rail' : '','Remediation':[]}, - '4.1.3': {'section': 'Storage - Object Storage', 'recommendation_#': '4.1.3', 'Title': 'Ensure Versioning is Enabled for Object Storage Buckets.', 'Status': True, 'Level': 2, 'Total': [], 'Findings': [], 'CISv8': ['3.11'], 'CCCS Guard Rail' : '','Remediation':[]}, - '4.2.1': {'section': 'Storage - Block Volumes', 'recommendation_#': '4.2.1', 'Title': 'Ensure Block Volumes are encrypted with Customer-Managed Keys.', 'Status': True, 'Level': 2, 'Total': [], 'Findings': [], 'CISv8': ['3.11'], 'CCCS Guard Rail' : ''}, - '4.2.2': {'section': 'Storage - Block Volumes', 'recommendation_#': '4.2.2', 'Title': 'Ensure Boot Volumes are encrypted with Customer-Managed Key.', 'Status': True, 'Level': 2, 'Total': [], 'Findings': [], 'CISv8': ['3.11'], 'CCCS Guard Rail' : ''}, - '4.3.1': {'section': 'Storage - File Storage Service', 'recommendation_#': '4.3.1', 'Title': 'Ensure File Storage Systems are encrypted with Customer-Managed Keys.', 'Status': True, 'Level': 2, 'Total': [], 'Findings': [], 'CISv8': ['3.11'], 'CCCS Guard Rail' : '','Remediation':[]}, - - - '5.1': {'section': 'Asset Management', 'recommendation_#': '5.1', 'Title': 'Create at least one compartment in your tenancy to store cloud resources.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['3.1'], 'CCCS Guard Rail' : '2,3,8,12','Remediation':[]}, - '5.2': {'section': 'Asset Management', 'recommendation_#': '5.2', 'Title': 'Ensure no resources are created in the root compartment.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['3.12'], 'CCCS Guard Rail' : '1,2,3','Remediation':[]} + '1.1': {'section': 'Identity and Access Management', 'recommendation_#': '1.1', 'Title': 'Ensure service level admins are created to manage resources of particular service', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['5.4', '6.7'], 'CCCS Guard Rail': '2,3', 'Remediation': []}, + '1.2': {'section': 'Identity and Access Management', 'recommendation_#': '1.2', 'Title': 'Ensure permissions on all resources are given only to the tenancy administrator group', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['3.3'], 'CCCS Guard Rail': '1,2,3', 'Remediation': []}, + '1.3': {'section': 'Identity and Access Management', 'recommendation_#': '1.3', 'Title': 'Ensure IAM administrators cannot update tenancy Administrators group', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['3.3', '5.4'], 'CCCS Guard Rail': '2,3', 'Remediation': []}, + '1.4': {'section': 'Identity and Access Management', 'recommendation_#': '1.4', 'Title': 'Ensure IAM password policy requires minimum length of 14 or greater', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.1', '5.2'], 'CCCS Guard Rail': '2,3', 'Remediation': []}, + '1.5': {'section': 'Identity and Access Management', 'recommendation_#': '1.5', 'Title': 'Ensure IAM password policy expires passwords within 365 days', 'Status': None, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.1', '5.2'], 'CCCS Guard Rail': '2,3', 'Remediation': []}, + '1.6': {'section': 'Identity and Access Management', 'recommendation_#': '1.6', 'Title': 'Ensure IAM password policy prevents password reuse', 'Status': None, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['5.2'], 'CCCS Guard Rail': '2,3', 'Remediation': []}, + '1.7': {'section': 'Identity and Access Management', 'recommendation_#': '1.7', 'Title': 'Ensure MFA is enabled for all users with a console password', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['6.3', '6.5'], 'CCCS Guard Rail': '1,2,3,4', 'Remediation': []}, + '1.8': {'section': 'Identity and Access Management', 'recommendation_#': '1.8', 'Title': 'Ensure user API keys rotate within 90 days or less', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.1', '4.4'], 'CCCS Guard Rail': '6,7', 'Remediation': []}, + '1.9': {'section': 'Identity and Access Management', 'recommendation_#': '1.9', 'Title': 'Ensure user customer secret keys rotate within 90 days or less', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.1', '5.2'], 'CCCS Guard Rail': '6,7', 'Remediation': []}, + '1.10': {'section': 'Identity and Access Management', 'recommendation_#': '1.10', 'Title': 'Ensure user auth tokens rotate within 90 days or less', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.1', '5.2'], 'CCCS Guard Rail': '6,7', 'Remediation': []}, + '1.11': {'section': 'Identity and Access Management', 'recommendation_#': '1.11', 'Title': 'Ensure API keys are not created for tenancy administrator users', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['5.4'], 'CCCS Guard Rail': '6,7', 'Remediation': []}, + '1.12': {'section': 'Identity and Access Management', 'recommendation_#': '1.12', 'Title': 'Ensure all OCI IAM user accounts have a valid and current email address', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['5.1'], 'CCCS Guard Rail': '1,2,3', 'Remediation': []}, + '1.13': {'section': 'Identity and Access Management', 'recommendation_#': '1.13', 'Title': 'Ensure Dynamic Groups are used for OCI instances, OCI Cloud Databases and OCI Function to access OCI resources', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['6.8'], 'CCCS Guard Rail': '6,7', 'Remediation': []}, + '1.14': {'section': 'Identity and Access Management', 'recommendation_#': '1.14', 'Title': 'Ensure storage service-level admins cannot delete resources they manage', 'Status': None, 'Level': 2, 'Total': [], 'Findings': [], 'CISv8': ['5.4', '6.8'], 'CCCS Guard Rail': '2,3', 'Remediation': []}, + + '2.1': {'section': 'Networking', 'recommendation_#': '2.1', 'Title': 'Ensure no security lists allow ingress from 0.0.0.0/0 to port 22.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.4', '12.3'], 'CCCS Guard Rail': '2,3,5,7,9', 'Remediation': []}, + '2.2': {'section': 'Networking', 'recommendation_#': '2.2', 'Title': 'Ensure no security lists allow ingress from 0.0.0.0/0 to port 3389.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.4', '12.3'], 'CCCS Guard Rail': '2,3,5,7,9', 'Remediation': []}, + '2.3': {'section': 'Networking', 'recommendation_#': '2.3', 'Title': 'Ensure no network security groups allow ingress from 0.0.0.0/0 to port 22.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.4', '12.3'], 'CCCS Guard Rail': '2,3,5,7,9', 'Remediation': []}, + '2.4': {'section': 'Networking', 'recommendation_#': '2.4', 'Title': 'Ensure no network security groups allow ingress from 0.0.0.0/0 to port 3389.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.4', '12.3'], 'CCCS Guard Rail': '2,3,5,7,9', 'Remediation': []}, + '2.5': {'section': 'Networking', 'recommendation_#': '2.5', 'Title': 'Ensure the default security list of every VCN restricts all traffic except ICMP.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['12.3'], 'CCCS Guard Rail': '2,3,5,7,9', 'Remediation': []}, + '2.6': {'section': 'Networking', 'recommendation_#': '2.6', 'Title': 'Ensure Oracle Integration Cloud (OIC) access is restricted to allowed sources.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.4', '12.3'], 'CCCS Guard Rail': '2,3,5,7,9', 'Remediation': []}, + '2.7': {'section': 'Networking', 'recommendation_#': '2.7', 'Title': 'Ensure Oracle Analytics Cloud (OAC) access is restricted to allowed sources or deployed within a Virtual Cloud Network.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.4', '12.3'], 'CCCS Guard Rail': '2,3,5,7,9', 'Remediation': []}, + '2.8': {'section': 'Networking', 'recommendation_#': '2.8', 'Title': 'Ensure Oracle Autonomous Shared Database (ADB) access is restricted or deployed within a VCN.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.4', '12.3'], 'CCCS Guard Rail': '2,3,5,7,9', 'Remediation': []}, + + '3.1': {'section': 'Logging and Monitoring', 'recommendation_#': '3.1', 'Title': 'Ensure audit log retention period is set to 365 days.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['8.10'], 'CCCS Guard Rail': '11', 'Remediation': []}, + '3.2': {'section': 'Logging and Monitoring', 'recommendation_#': '3.2', 'Title': 'Ensure default tags are used on resources.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['1.1'], 'CCCS Guard Rail': '', 'Remediation': []}, + '3.3': {'section': 'Logging and Monitoring', 'recommendation_#': '3.3', 'Title': 'Create at least one notification topic and subscription to receive monitoring alerts.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['8.2', '8.11'], 'CCCS Guard Rail': '11', 'Remediation': []}, + '3.4': {'section': 'Logging and Monitoring', 'recommendation_#': '3.4', 'Title': 'Ensure a notification is configured for Identity Provider changes.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.2'], 'CCCS Guard Rail': '11', 'Remediation': []}, + '3.5': {'section': 'Logging and Monitoring', 'recommendation_#': '3.5', 'Title': 'Ensure a notification is configured for IdP group mapping changes.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.2'], 'CCCS Guard Rail': '11', 'Remediation': []}, + '3.6': {'section': 'Logging and Monitoring', 'recommendation_#': '3.6', 'Title': 'Ensure a notification is configured for IAM group changes.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.2'], 'CCCS Guard Rail': '11', 'Remediation': []}, + '3.7': {'section': 'Logging and Monitoring', 'recommendation_#': '3.7', 'Title': 'Ensure a notification is configured for IAM policy changes.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.2'], 'CCCS Guard Rail': '11', 'Remediation': []}, + '3.8': {'section': 'Logging and Monitoring', 'recommendation_#': '3.8', 'Title': 'Ensure a notification is configured for user changes.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.2'], 'CCCS Guard Rail': '11', 'Remediation': []}, + '3.9': {'section': 'Logging and Monitoring', 'recommendation_#': '3.9', 'Title': 'Ensure a notification is configured for VCN changes.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.2'], 'CCCS Guard Rail': '11', 'Remediation': []}, + '3.10': {'section': 'Logging and Monitoring', 'recommendation_#': '3.10', 'Title': 'Ensure a notification is configured for changes to route tables.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.2'], 'CCCS Guard Rail': '11', 'Remediation': []}, + '3.11': {'section': 'Logging and Monitoring', 'recommendation_#': '3.11', 'Title': 'Ensure a notification is configured for security list changes.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.2'], 'CCCS Guard Rail': '11', 'Remediation': []}, + '3.12': {'section': 'Logging and Monitoring', 'recommendation_#': '3.12', 'Title': 'Ensure a notification is configured for network security group changes.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.2'], 'CCCS Guard Rail': '11', 'Remediation': []}, + '3.13': {'section': 'Logging and Monitoring', 'recommendation_#': '3.13', 'Title': 'Ensure a notification is configured for changes to network gateways.', 'Status': False, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['4.2'], 'CCCS Guard Rail': '11', 'Remediation': []}, + '3.14': {'section': 'Logging and Monitoring', 'recommendation_#': '3.14', 'Title': 'Ensure VCN flow logging is enabled for all subnets.', 'Status': True, 'Level': 2, 'Total': [], 'Findings': [], 'CISv8': ['8.2', '8.5', '13.6'], 'CCCS Guard Rail': '', 'Remediation': []}, + '3.15': {'section': 'Logging and Monitoring', 'recommendation_#': '3.15', 'Title': 'Ensure Cloud Guard is enabled in the root compartment of the tenancy.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['8.2', '8.5', '8.11'], 'CCCS Guard Rail': '1,2,3', 'Remediation': []}, + '3.16': {'section': 'Logging and Monitoring', 'recommendation_#': '3.16', 'Title': 'Ensure customer created Customer Managed Key (CMK) is rotated at least annually.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': [], 'CCCS Guard Rail': '6,7', 'Remediation': []}, + '3.17': {'section': 'Logging and Monitoring', 'recommendation_#': '3.17', 'Title': 'Ensure write level Object Storage logging is enabled for all buckets.', 'Status': True, 'Level': 2, 'Total': [], 'Findings': [], 'CISv8': ['8.2'], 'CCCS Guard Rail': '', 'Remediation': []}, + + '4.1.1': {'section': 'Storage - Object Storage', 'recommendation_#': '4.1.1', 'Title': 'Ensure no Object Storage buckets are publicly visible.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['3.3'], 'CCCS Guard Rail': '', 'Remediation': []}, + '4.1.2': {'section': 'Storage - Object Storage', 'recommendation_#': '4.1.2', 'Title': 'Ensure Object Storage Buckets are encrypted with a Customer-Managed Key (CMK).', 'Status': True, 'Level': 2, 'Total': [], 'Findings': [], 'CISv8': ['3.11'], 'CCCS Guard Rail': '', 'Remediation': []}, + '4.1.3': {'section': 'Storage - Object Storage', 'recommendation_#': '4.1.3', 'Title': 'Ensure Versioning is Enabled for Object Storage Buckets.', 'Status': True, 'Level': 2, 'Total': [], 'Findings': [], 'CISv8': ['3.11'], 'CCCS Guard Rail': '', 'Remediation': []}, + '4.2.1': {'section': 'Storage - Block Volumes', 'recommendation_#': '4.2.1', 'Title': 'Ensure Block Volumes are encrypted with Customer-Managed Keys.', 'Status': True, 'Level': 2, 'Total': [], 'Findings': [], 'CISv8': ['3.11'], 'CCCS Guard Rail': ''}, + '4.2.2': {'section': 'Storage - Block Volumes', 'recommendation_#': '4.2.2', 'Title': 'Ensure Boot Volumes are encrypted with Customer-Managed Key.', 'Status': True, 'Level': 2, 'Total': [], 'Findings': [], 'CISv8': ['3.11'], 'CCCS Guard Rail': ''}, + '4.3.1': {'section': 'Storage - File Storage Service', 'recommendation_#': '4.3.1', 'Title': 'Ensure File Storage Systems are encrypted with Customer-Managed Keys.', 'Status': True, 'Level': 2, 'Total': [], 'Findings': [], 'CISv8': ['3.11'], 'CCCS Guard Rail': '', 'Remediation': []}, + + + '5.1': {'section': 'Asset Management', 'recommendation_#': '5.1', 'Title': 'Create at least one compartment in your tenancy to store cloud resources.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['3.1'], 'CCCS Guard Rail': '2,3,8,12', 'Remediation': []}, + '5.2': {'section': 'Asset Management', 'recommendation_#': '5.2', 'Title': 'Ensure no resources are created in the root compartment.', 'Status': True, 'Level': 1, 'Total': [], 'Findings': [], 'CISv8': ['3.12'], 'CCCS Guard Rail': '1,2,3', 'Remediation': []} } # Remediation Report self.cis_report_data = { - "1.1":{ "Description":"To apply least-privilege security principle, one can create service-level administrators in corresponding groups and assigning specific users to each service-level administrative group in a tenancy. This limits administrative access in a tenancy.

It means service-level administrators can only manage resources of a specific service.

Example policies for global/tenant level service-administrators\n
\nAllow group VolumeAdmins to manage volume-family in tenancy\nAllow group ComputeAdmins to manage instance-family in tenancy\nAllow group NetworkAdmins to manage virtual-network-family in tenancy\n
\nOrganizations have various ways of defining service-administrators. Some may prefer creating service administrators at a tenant level and some per department or per project or even per application environment (dev/test/production etc.). Either approach works so long as the policies are written to limit access given to the service-administrators.

Example policies for compartment level service-administrators

Allow group NonProdComputeAdmins to manage instance-family in compartment dev\nAllow group ProdComputeAdmins to manage instance-family in compartment production\nAllow group A-Admins to manage instance-family in compartment Project-A\nAllow group A-Admins to manage volume-family in compartment Project-A\n
", - "Rationale":"Creating service-level administrators helps in tightly controlling access to Oracle Cloud Infrastructure (OCI) services to implement the least-privileged security principle.", - "Impact":"", - "Remediation":"Refer to the policy syntax document and create new policies if the audit results indicate that the required policies are missing.", - "Recommendation":"", - "Observation": "custom IAM policy that grants tenancy administrative access." - }, - "1.2":{ "Description":"There is a built-in OCI IAM policy enabling the Administrators group to perform any action within a tenancy. In the OCI IAM console, this policy reads:

\nAllow group Administrators to manage all-resources in tenancy\n


Administrators create more users, groups, and policies to provide appropriate access to other groups.

Administrators should not allow any-other-group full access to the tenancy by writing a policy like this:

\nAllow group any-other-group to manage all-resources in tenancy\n


The access should be narrowed down to ensure the least-privileged principle is applied.", - "Rationale":"Permission to manage all resources in a tenancy should be limited to a small number of users in the 'Administrators' group for break-glass situations and to set up users/groups/policies when a tenancy is created.

No group other than 'Administrators' in a tenancy should need access to all resources in a tenancy, as this violates the enforcement of the least privilege principle.", - "Impact":"", - "Remediation":"Remove any policy statement that allows any group other than Administrators or any service access to manage all resources in the tenancy.", - "Recommendation":"Evaluate if tenancy-wide administrative access is needed for the identified policy and update it to be more restrictive.", - "Observation":"custom IAM policy that grants tenancy administrative access." - }, - "1.3":{ "Description":"Tenancy administrators can create more users, groups, and policies to provide other service administrators access to OCI resources.

For example, an IAM administrator will need to have access to manage\n resources like compartments, users, groups, dynamic-groups, policies, identity-providers, tenancy tag-namespaces, tag-definitions in the tenancy.

The policy that gives IAM-Administrators or any other group full access to 'groups' resources should not allow access to the tenancy 'Administrators' group.

The policy statements would look like:

\nAllow group IAMAdmins to inspect users in tenancy\nAllow group IAMAdmins to use users in tenancy where target.group.name != 'Administrators'\nAllow group IAMAdmins to inspect groups in tenancy\nAllow group IAMAdmins to use groups in tenancy where target.group.name != 'Administrators'\n


Note: You must include separate statements for 'inspect' access, because the target.group.name variable is not used by the ListUsers and ListGroups operations", - "Rationale":"These policy statements ensure that no other group can manage tenancy administrator users or the membership to the 'Administrators' group thereby gain or remove tenancy administrator access.", - "Impact":"", - "Remediation":"Verify the results to ensure that the policy statements that grant access to use or manage users or groups in the tenancy have a condition that excludes access to Administrators group or to users in the Administrators group.", - "Recommendation":"Evaluate if tenancy-wide administrative access is needed for the identified policy and update it to be more restrictive.", - "Observation":"custom IAM policy that grants tenancy administrative access." - }, - "1.4":{ "Description":"Password policies are used to enforce password complexity requirements. IAM password policies can be used to ensure password are at least a certain length and are composed of certain characters.

It is recommended the password policy require a minimum password length 14 characters and contain 1 non-alphabetic\ncharacter (Number or 'Special Character').", - "Rationale":"In keeping with the overall goal of having users create a password that is not overly weak, an eight-character minimum password length is recommended for an MFA account, and 14 characters for a password only account. In addition, maximum password length should be made as long as possible based on system/software capabilities and not restricted by policy.

In general, it is true that longer passwords are better (harder to crack), but it is also true that forced password length requirements can cause user behavior that is predictable and undesirable. For example, requiring users to have a minimum 16-character password may cause them to choose repeating patterns like fourfourfourfour or passwordpassword that meet the requirement but aren't hard to guess. Additionally, length requirements increase the chances that users will adopt other insecure practices, like writing them down, re-using them or storing them unencrypted in their documents.

Password composition requirements are a poor defense against guessing attacks. Forcing users to choose some combination of upper-case, lower-case, numbers, and special characters has a negative impact. It places an extra burden on users and many\nwill use predictable patterns (for example, a capital letter in the first position, followed by lowercase letters, then one or two numbers, and a “special character” at the end). Attackers know this, so dictionary attacks will often contain these common patterns and use the most common substitutions like, $ for s, @ for a, 1 for l, 0 for o.

Passwords that are too complex in nature make it harder for users to remember, leading to bad practices. In addition, composition requirements provide no defense against common attack types such as social engineering or insecure storage of passwords.", - "Impact":"", - "Remediation":"Update the password policy such as minimum length to 14, password must contain expected special characters and numeric characters.", - "Recommendation":"It is recommended the password policy require a minimum password length 14 characters and contain 1 non-alphabetic character (Number or 'Special Character').", - "Observation":"password policy/policies that do not enforce sufficient password complexity requirements." - }, - "1.5":{ "Description":"IAM password policies can require passwords to be rotated or expired after a given number of days. It is recommended that the password policy expire passwords after 365 and are changed immediately based on events.", - "Rationale":"Excessive password expiration requirements do more harm than good, because these requirements make users select predictable passwords, composed of sequential words and numbers that are closely related to each other.10 In these cases, the next password can be predicted based on the previous one (incrementing a number used in the password for example). Also, password expiration requirements offer no containment benefits because attackers will often use credentials as soon as they compromise them. Instead, immediate password changes should be based on key events including, but not\nlimited to:

1. Indication of compromise\n1. Change of user roles\n1. When a user leaves the organization.

Not only does changing passwords every few weeks or months frustrate the user, it's been suggested that it does more harm than good, because it could lead to bad practices by the user such as adding a character to the end of their existing password.

In addition, we also recommend a yearly password change. This is primarily because for all their good intentions users will share credentials across accounts. Therefore, even if a breach is publicly identified, the user may not see this notification, or forget they have an account on that site. This could leave a shared credential vulnerable indefinitely. Having an organizational policy of a 1-year (annual) password expiration is a reasonable compromise to mitigate this with minimal user burden.", - "Impact":"", - "Remediation":"Update the password policy by setting number of days configured in Expires after to 365.", - "Recommendation":"Evaluate password rotation policies are inline with your organizational standard.", - "Observation":"password policy/policies that do not require rotation." - }, - "1.6":{ "Description":"IAM password policies can prevent the reuse of a given password by the same user. It is recommended the password policy prevent the reuse of passwords.", - "Rationale":"Enforcing password history ensures that passwords are not reused in for a certain period of time by the same user. If a user is not allowed to use last 24 passwords, that window of time is greater. This helps maintain the effectiveness of password security.", - "Impact":"", - "Remediation":"Update the number of remembered passwords in previous passwords remembered setting to 24 in the password policy.", - "Recommendation":"Evaluate password reuse policies are inline with your organizational standard.", - "Observation":"password policy/policies that do not prevent reuse." - }, - "1.7":{ "Description":"Multi-factor authentication is a method of authentication that requires the use of more than one factor to verify a user's identity.

With MFA enabled in the IAM service, when a user signs in to Oracle Cloud Infrastructure, they are prompted for their user name and password, which is the first factor (something that they know). The user is then prompted to provide a second verification code from a registered MFA device, which is the second factor (something that they have). The two factors work together, requiring an extra layer of security to verify the user's identity and complete the sign-in process.

OCI IAM supports two-factor authentication using a password (first factor) and a device that can generate a time-based one-time password (TOTP) (second factor).

See [OCI documentation](https://docs.cloud.oracle.com/en-us/iaas/Content/Identity/Tasks/usingmfa.htm) for more details.", - "Rationale":"Multi factor authentication adds an extra layer of security during the login process and makes it harder for unauthorized users to gain access to OCI resources.", - "Impact":"", - "Remediation":"Each user must enable MFA for themselves using a device they will have access to every time they sign in. An administrator cannot enable MFA for another user but can enforce MFA by identifying the list of non-complaint users, notifying them or disabling access by resetting password for non-complaint accounts.", - "Recommendation":"Evaluate if local users are required. For Break Glass accounts ensure MFA is in place.", - "Observation":"users with Password access but not MFA." + "1.1": { + "Description": "To apply least-privilege security principle, one can create service-level administrators in corresponding groups and assigning specific users to each service-level administrative group in a tenancy. This limits administrative access in a tenancy.

It means service-level administrators can only manage resources of a specific service.

Example policies for global/tenant level service-administrators\n
\nAllow group VolumeAdmins to manage volume-family in tenancy\nAllow group ComputeAdmins to manage instance-family in tenancy\nAllow group NetworkAdmins to manage virtual-network-family in tenancy\n
\nOrganizations have various ways of defining service-administrators. Some may prefer creating service administrators at a tenant level and some per department or per project or even per application environment (dev/test/production etc.). Either approach works so long as the policies are written to limit access given to the service-administrators.

Example policies for compartment level service-administrators

Allow group NonProdComputeAdmins to manage instance-family in compartment dev\nAllow group ProdComputeAdmins to manage instance-family in compartment production\nAllow group A-Admins to manage instance-family in compartment Project-A\nAllow group A-Admins to manage volume-family in compartment Project-A\n
", + "Rationale": "Creating service-level administrators helps in tightly controlling access to Oracle Cloud Infrastructure (OCI) services to implement the least-privileged security principle.", + "Impact": "", + "Remediation": "Refer to the policy syntax document and create new policies if the audit results indicate that the required policies are missing.", + "Recommendation": "", + "Observation": "custom IAM policy that grants tenancy administrative access."}, + "1.2": { + "Description": "There is a built-in OCI IAM policy enabling the Administrators group to perform any action within a tenancy. In the OCI IAM console, this policy reads:

\nAllow group Administrators to manage all-resources in tenancy\n


Administrators create more users, groups, and policies to provide appropriate access to other groups.

Administrators should not allow any-other-group full access to the tenancy by writing a policy like this:

\nAllow group any-other-group to manage all-resources in tenancy\n


The access should be narrowed down to ensure the least-privileged principle is applied.", + "Rationale": "Permission to manage all resources in a tenancy should be limited to a small number of users in the 'Administrators' group for break-glass situations and to set up users/groups/policies when a tenancy is created.

No group other than 'Administrators' in a tenancy should need access to all resources in a tenancy, as this violates the enforcement of the least privilege principle.", + "Impact": "", + "Remediation": "Remove any policy statement that allows any group other than Administrators or any service access to manage all resources in the tenancy.", + "Recommendation": "Evaluate if tenancy-wide administrative access is needed for the identified policy and update it to be more restrictive.", + "Observation": "custom IAM policy that grants tenancy administrative access."}, + "1.3": { + "Description": "Tenancy administrators can create more users, groups, and policies to provide other service administrators access to OCI resources.

For example, an IAM administrator will need to have access to manage\n resources like compartments, users, groups, dynamic-groups, policies, identity-providers, tenancy tag-namespaces, tag-definitions in the tenancy.

The policy that gives IAM-Administrators or any other group full access to 'groups' resources should not allow access to the tenancy 'Administrators' group.

The policy statements would look like:

\nAllow group IAMAdmins to inspect users in tenancy\nAllow group IAMAdmins to use users in tenancy where target.group.name != 'Administrators'\nAllow group IAMAdmins to inspect groups in tenancy\nAllow group IAMAdmins to use groups in tenancy where target.group.name != 'Administrators'\n


Note: You must include separate statements for 'inspect' access, because the target.group.name variable is not used by the ListUsers and ListGroups operations", + "Rationale": "These policy statements ensure that no other group can manage tenancy administrator users or the membership to the 'Administrators' group thereby gain or remove tenancy administrator access.", + "Impact": "", + "Remediation": "Verify the results to ensure that the policy statements that grant access to use or manage users or groups in the tenancy have a condition that excludes access to Administrators group or to users in the Administrators group.", + "Recommendation": "Evaluate if tenancy-wide administrative access is needed for the identified policy and update it to be more restrictive.", + "Observation": "custom IAM policy that grants tenancy administrative access."}, + "1.4": { + "Description": "Password policies are used to enforce password complexity requirements. IAM password policies can be used to ensure password are at least a certain length and are composed of certain characters.

It is recommended the password policy require a minimum password length 14 characters and contain 1 non-alphabetic\ncharacter (Number or 'Special Character').", + "Rationale": "In keeping with the overall goal of having users create a password that is not overly weak, an eight-character minimum password length is recommended for an MFA account, and 14 characters for a password only account. In addition, maximum password length should be made as long as possible based on system/software capabilities and not restricted by policy.

In general, it is true that longer passwords are better (harder to crack), but it is also true that forced password length requirements can cause user behavior that is predictable and undesirable. For example, requiring users to have a minimum 16-character password may cause them to choose repeating patterns like fourfourfourfour or passwordpassword that meet the requirement but aren't hard to guess. Additionally, length requirements increase the chances that users will adopt other insecure practices, like writing them down, re-using them or storing them unencrypted in their documents.

Password composition requirements are a poor defense against guessing attacks. Forcing users to choose some combination of upper-case, lower-case, numbers, and special characters has a negative impact. It places an extra burden on users and many\nwill use predictable patterns (for example, a capital letter in the first position, followed by lowercase letters, then one or two numbers, and a “special character” at the end). Attackers know this, so dictionary attacks will often contain these common patterns and use the most common substitutions like, $ for s, @ for a, 1 for l, 0 for o.

Passwords that are too complex in nature make it harder for users to remember, leading to bad practices. In addition, composition requirements provide no defense against common attack types such as social engineering or insecure storage of passwords.", + "Impact": "", + "Remediation": "Update the password policy such as minimum length to 14, password must contain expected special characters and numeric characters.", + "Recommendation": "It is recommended the password policy require a minimum password length 14 characters and contain 1 non-alphabetic character (Number or 'Special Character').", + "Observation": "password policy/policies that do not enforce sufficient password complexity requirements."}, + "1.5": { + "Description": "IAM password policies can require passwords to be rotated or expired after a given number of days. It is recommended that the password policy expire passwords after 365 and are changed immediately based on events.", + "Rationale": "Excessive password expiration requirements do more harm than good, because these requirements make users select predictable passwords, composed of sequential words and numbers that are closely related to each other.10 In these cases, the next password can be predicted based on the previous one (incrementing a number used in the password for example). Also, password expiration requirements offer no containment benefits because attackers will often use credentials as soon as they compromise them. Instead, immediate password changes should be based on key events including, but not\nlimited to:

1. Indication of compromise\n1. Change of user roles\n1. When a user leaves the organization.

Not only does changing passwords every few weeks or months frustrate the user, it's been suggested that it does more harm than good, because it could lead to bad practices by the user such as adding a character to the end of their existing password.

In addition, we also recommend a yearly password change. This is primarily because for all their good intentions users will share credentials across accounts. Therefore, even if a breach is publicly identified, the user may not see this notification, or forget they have an account on that site. This could leave a shared credential vulnerable indefinitely. Having an organizational policy of a 1-year (annual) password expiration is a reasonable compromise to mitigate this with minimal user burden.", + "Impact": "", + "Remediation": "Update the password policy by setting number of days configured in Expires after to 365.", + "Recommendation": "Evaluate password rotation policies are inline with your organizational standard.", + "Observation": "password policy/policies that do not require rotation."}, + "1.6": { + "Description": "IAM password policies can prevent the reuse of a given password by the same user. It is recommended the password policy prevent the reuse of passwords.", + "Rationale": "Enforcing password history ensures that passwords are not reused in for a certain period of time by the same user. If a user is not allowed to use last 24 passwords, that window of time is greater. This helps maintain the effectiveness of password security.", + "Impact": "", + "Remediation": "Update the number of remembered passwords in previous passwords remembered setting to 24 in the password policy.", + "Recommendation": "Evaluate password reuse policies are inline with your organizational standard.", + "Observation": "password policy/policies that do not prevent reuse."}, + "1.7": { + "Description": "Multi-factor authentication is a method of authentication that requires the use of more than one factor to verify a user's identity.

With MFA enabled in the IAM service, when a user signs in to Oracle Cloud Infrastructure, they are prompted for their user name and password, which is the first factor (something that they know). The user is then prompted to provide a second verification code from a registered MFA device, which is the second factor (something that they have). The two factors work together, requiring an extra layer of security to verify the user's identity and complete the sign-in process.

OCI IAM supports two-factor authentication using a password (first factor) and a device that can generate a time-based one-time password (TOTP) (second factor).

See [OCI documentation](https://docs.cloud.oracle.com/en-us/iaas/Content/Identity/Tasks/usingmfa.htm) for more details.", + "Rationale": "Multi factor authentication adds an extra layer of security during the login process and makes it harder for unauthorized users to gain access to OCI resources.", + "Impact": "", + "Remediation": "Each user must enable MFA for themselves using a device they will have access to every time they sign in. An administrator cannot enable MFA for another user but can enforce MFA by identifying the list of non-complaint users, notifying them or disabling access by resetting password for non-complaint accounts.", + "Recommendation": "Evaluate if local users are required. For Break Glass accounts ensure MFA is in place.", + "Observation": "users with Password access but not MFA."}, + "1.8": { + "Description": "API keys are used by administrators, developers, services and scripts for accessing OCI APIs directly or via SDKs/OCI CLI to search, create, update or delete OCI resources.

The API key is an RSA key pair. The private key is used for signing the API requests and the public key is associated with a local or synchronized user's profile.", + "Rationale": "It is important to secure and rotate an API key every 90 days or less as it provides the same level of access that a user it is associated with has.

In addition to a security engineering best practice, this is also a compliance requirement. For example, PCI-DSS Section 3.6.4 states, \"Verify that key-management procedures include a defined cryptoperiod for each key type in use and define a process for key changes at the end of the defined crypto period(s).\"", + "Impact": "", + "Remediation": "Delete any API Keys with a date of 90 days or older under the Created column of the API Key table.", + "Recommendation": "Evaluate if APIs Keys are still used/required and rotate API Keys It is important to secure and rotate an API key every 90 days or less as it provides the same level of access that a user it is associated with has.", + "Observation": "user(s) with APIs that have not been rotated with 90 days."}, + "1.9": { + "Description": "Object Storage provides an API to enable interoperability with Amazon S3. To use this Amazon S3 Compatibility API, you need to generate the signing key required to authenticate with Amazon S3.

This special signing key is an Access Key/Secret Key pair. Oracle generates the Customer Secret key to pair with the Access Key.", + "Rationale": "It is important to secure and rotate an customer secret key every 90 days or less as it provides the same level of object storage access that a user is associated with has.", + "Impact": "", + "Remediation": "Delete any Access Keys with a date of 90 days or older under the Created column of the Customer Secret Keys.", + "Recommendation": "Evaluate if Customer Secret Keys are still used/required and rotate the Keys accordingly.", + "Observation": "users with Customer Secret Keys that have not been rotated with 90 days."}, + "1.10": { + "Description": "Auth tokens are authentication tokens generated by Oracle. You use auth tokens to authenticate with APIs that do not support the Oracle Cloud Infrastructure signature-based authentication. If the service requires an auth token, the service-specific documentation instructs you to generate one and how to use it.", + "Rationale": "It is important to secure and rotate an auth token every 90 days or less as it provides the same level of access to APIs that do not support the OCI signature-based authentication as the user associated to it.", + "Impact": "", + "Remediation": "Delete any auth token with a date of 90 days or older under the Created column of the Auth Tokens.", + "Recommendation": "Evaluate if Auth Tokens are still used/required and rotate Auth tokens.", + "Observation": "user(s) with auth tokens that have not been rotated in 90 days."}, + "1.11": { + "Description": "Tenancy administrator users have full access to the organization's OCI tenancy. API keys associated with user accounts are used for invoking the OCI APIs via custom programs or clients like CLI/SDKs. The clients are typically used for performing day-to-day operations and should never require full tenancy access. Service-level administrative users with API keys should be used instead.", + "Rationale": "For performing day-to-day operations tenancy administrator access is not needed.\nService-level administrative users with API keys should be used to apply privileged security principle.", + "Impact": "", + "Remediation": "For each tenancy administrator user who has an API key,select API Keys from the menu and delete any associated keys from the API Keys table.", + "Recommendation": "Evaluate if a user with API Keys requires Administrator access and use a least privilege approach.", + "Observation": "users with Administrator access and API Keys."}, + "1.12": { + "Description": "All OCI IAM local user accounts have an email address field associated with the account. It is recommended to specify an email address that is valid and current.

If you have an email address in your user profile, you can use the Forgot Password link on the sign on page to have a temporary password sent to you.", + "Rationale": "Having a valid and current email address associated with an OCI IAM local user account allows you to tie the account to identity in your organization. It also allows that user to reset their password if it is forgotten or lost.", + "Impact": "", + "Remediation": "Update the current email address in the email text box on exch non compliant user.", + "Recommendation": "Add emails to users to allow them to use the 'Forgot Password' feature and uniquely identify the user. For service accounts it could be a mail alias.", + "Observation": "without an email."}, + "1.13": { + "Description": "OCI instances, OCI database and OCI functions can access other OCI resources either via an OCI API key associated to a user or by being including in a Dynamic Group that has an IAM policy granting it the required access. Access to OCI Resources refers to making API calls to another OCI resource like Object Storage, OCI Vaults, etc.", + "Rationale": "Dynamic Groups reduces the risks related to hard coded credentials. Hard coded API keys can be shared and require rotation which can open them up to being compromised. Compromised credentials could allow access to OCI services outside of the expected radius.", + "Impact": "For an OCI instance that contains embedded credential audit the scripts and environment variables to ensure that none of them contain OCI API Keys or credentials.", + "Remediation": "Create Dynamic group and Enter Matching Rules to that includes the instances accessing your OCI resources. Refer:\"https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/managingdynamicgroups.htm\".", + "Recommendation": "Evaluate how your instances, functions, and autonomous database interact with other OCI services.", + "Observation": "Dynamic Groups reduces the risks related to hard coded credentials. Hard coded API keys can be shared and require rotation which can open them up to being compromised. Compromised credentials could allow access to OCI services outside of the expected radius."}, + "1.14": { + "Description": "To apply the separation of duties security principle, one can restrict service-level administrators from being able to delete resources they are managing. It means service-level administrators can only manage resources of a specific service but not delete resources for that specific service.

Example policies for global/tenant level for block volume service-administrators:\n
\nAllow group VolumeUsers to manage volumes in tenancy where request.permission!='VOLUME_DELETE'\nAllow group VolumeUsers to manage volume-backups in tenancy where request.permission!='VOLUME_BACKUP_DELETE'\n

Example policies for global/tenant level for file storage system service-administrators:
\nAllow group FileUsers to manage file-systems in tenancy where request.permission!='FILE_SYSTEM_DELETE'\nAllow group FileUsers to manage mount-targets in tenancy where request.permission!='MOUNT_TARGET_DELETE'\nAllow group FileUsers to manage export-sets in tenancy where request.permission!='EXPORT_SET_DELETE'\n


Example policies for global/tenant level for object storage system service-administrators:
\nAllow group BucketUsers to manage objects in tenancy where request.permission!='OBJECT_DELETE'\nAllow group BucketUsers to manage buckets in tenancy where request.permission!='BUCKET_DELETE'\n
", + "Rationale": "Creating service-level administrators without the ability to delete the resource they are managing helps in tightly controlling access to Oracle Cloud Infrastructure (OCI) services by implementing the separation of duties security principle.", "Impact": "", + "Remediation": "Add the appropriate where condition to any policy statement that allows the storage service-level to manage the storage service.", + "Recommendation": "To apply a separation of duties security principle, it is recommended to restrict service-level administrators from being able to delete resources they are managing.", + "Observation": "IAM Policies that give service administrator the ability to delete service resources."}, + "2.1": { + "Description": "Security lists provide stateful or stateless filtering of ingress/egress network traffic to OCI resources on a subnet level. It is recommended that no security group allows unrestricted ingress access to port 22.", + "Rationale": "Removing unfettered connectivity to remote console services, such as Secure Shell (SSH), reduces a server's exposure to risk.", + "Impact": "For updating an existing environment, care should be taken to ensure that administrators currently relying on an existing ingress from 0.0.0.0/0 have access to ports 22 and/or 3389 through another network security group or security list.", + "Remediation": "For each security list in the returned results, click the security list name. Either edit the ingress rule to be more restrictive, delete the ingress rule or click on the VCN and terminate the security list as appropriate.", + "Recommendation": "Review the security lists. If they are not used(attached to a subnet) they should be deleted if possible or empty. For attached security lists it is recommended to restrict the CIDR block to only allow access to Port 22 from known networks.", + "Observation": "Security lists that allow internet access to port 22. (Note this does not necessarily mean external traffic can reach a compute instance)."}, + "2.2": { + "Description": "Security lists provide stateful or stateless filtering of ingress/egress network traffic to OCI resources on a subnet level. It is recommended that no security group allows unrestricted ingress access to port 3389.", + "Rationale": "Removing unfettered connectivity to remote console services, such as Remote Desktop Protocol (RDP), reduces a server's exposure to risk.", + "Impact": "For updating an existing environment, care should be taken to ensure that administrators currently relying on an existing ingress from 0.0.0.0/0 have access to ports 22 and/or 3389 through another network security group or security list.", + "Remediation": "For each security list in the returned results, click the security list name. Either edit the ingress rule to be more restrictive, delete the ingress rule or click on the VCN and terminate the security list as appropriate.", + "Recommendation": "Review the security lists. If they are not used(attached to a subnet) they should be deleted if possible or empty. For attached security lists it is recommended to restrict the CIDR block to only allow access to Port 3389 from known networks.", + "Observation": "Security lists that allow internet access to port 3389. (Note this does not necessarily mean external traffic can reach a compute instance)." }, - "1.8":{ "Description":"API keys are used by administrators, developers, services and scripts for accessing OCI APIs directly or via SDKs/OCI CLI to search, create, update or delete OCI resources.

The API key is an RSA key pair. The private key is used for signing the API requests and the public key is associated with a local or synchronized user's profile.", - "Rationale":"It is important to secure and rotate an API key every 90 days or less as it provides the same level of access that a user it is associated with has.

In addition to a security engineering best practice, this is also a compliance requirement. For example, PCI-DSS Section 3.6.4 states, \"Verify that key-management procedures include a defined cryptoperiod for each key type in use and define a process for key changes at the end of the defined crypto period(s).\"", - "Impact":"", - "Remediation":"Delete any API Keys with a date of 90 days or older under the Created column of the API Key table.", - "Recommendation":"Evaluate if APIs Keys are still used/required and rotate API Keys It is important to secure and rotate an API key every 90 days or less as it provides the same level of access that a user it is associated with has.", - "Observation":"user(s) with APIs that have not been rotated with 90 days." + "2.3": { + "Description": "Network security groups provide stateful filtering of ingress/egress network traffic to OCI resources. It is recommended that no security group allows unrestricted ingress access to port 22.", + "Rationale": "Removing unfettered connectivity to remote console services, such as Secure Shell (SSH), reduces a server's exposure to risk.", + "Impact": "For updating an existing environment, care should be taken to ensure that administrators currently relying on an existing ingress from 0.0.0.0/0 have access to ports 22 and/or 3389 through another network security group or security list.", + "Remediation": "Using the details returned from the audit procedure either Remove the security rules or Update the security rules.", + "Recommendation": "Review the network security groups. If they are not used(attached to a subnet) they should be deleted if possible or empty. For attached security lists it is recommended to restrict the CIDR block to only allow access to Port 3389 from known networks.", + "Observation": "Network security groups that allow internet access to port 22. (Note this does not necessarily mean external traffic can reach a compute instance)." }, - "1.9":{ "Description":"Object Storage provides an API to enable interoperability with Amazon S3. To use this Amazon S3 Compatibility API, you need to generate the signing key required to authenticate with Amazon S3.

This special signing key is an Access Key/Secret Key pair. Oracle generates the Customer Secret key to pair with the Access Key.", - "Rationale":"It is important to secure and rotate an customer secret key every 90 days or less as it provides the same level of object storage access that a user is associated with has.", - "Impact":"", - "Remediation":"Delete any Access Keys with a date of 90 days or older under the Created column of the Customer Secret Keys.", - "Recommendation":"Evaluate if Customer Secret Keys are still used/required and rotate the Keys accordingly.", - "Observation":"users with Customer Secret Keys that have not been rotated with 90 days." + "2.4": { + "Description": "Network security groups provide stateful filtering of ingress/egress network traffic to OCI resources. It is recommended that no security group allows unrestricted ingress access to port 3389.", + "Rationale": "Removing unfettered connectivity to remote console services, such as Remote Desktop Protocol (RDP), reduces a server's exposure to risk.", + "Impact": "For updating an existing environment, care should be taken to ensure that administrators currently relying on an existing ingress from 0.0.0.0/0 have access to ports 22 and/or 3389 through another network security group or security list.", + "Remediation": "Using the details returned from the audit procedure either Remove the security rules or Update the security rules.", + "Recommendation": "Review the network security groups. If they are not used(attached to a subnet) they should be deleted if possible or empty. For attached network security groups it is recommended to restrict the CIDR block to only allow access to Port 3389 from known networks.", + "Observation": "Network security groups that allow internet access to port 3389. (Note this does not necessarily mean external traffic can reach a compute instance)." }, - "1.10":{ "Description":"Auth tokens are authentication tokens generated by Oracle. You use auth tokens to authenticate with APIs that do not support the Oracle Cloud Infrastructure signature-based authentication. If the service requires an auth token, the service-specific documentation instructs you to generate one and how to use it.", - "Rationale":"It is important to secure and rotate an auth token every 90 days or less as it provides the same level of access to APIs that do not support the OCI signature-based authentication as the user associated to it.", - "Impact":"", - "Remediation":"Delete any auth token with a date of 90 days or older under the Created column of the Auth Tokens.", - "Recommendation":"Evaluate if Auth Tokens are still used/required and rotate Auth tokens.", - "Observation":"user(s) with auth tokens that have not been rotated in 90 days." + "2.5": { + "Description": "A default security list is created when a Virtual Cloud Network (VCN) is created. Security lists provide stateful filtering of ingress and egress network traffic to OCI resources. It is recommended no security list allows unrestricted ingress access to Secure Shell (SSH) via port 22.", + "Rationale": "Removing unfettered connectivity to remote console services, such as SSH on port 22, reduces a server's exposure to unauthorized access.", + "Impact": "For updating an existing environment, care should be taken to ensure that administrators currently relying on an existing ingress from 0.0.0.0/0 have access to ports 22 and/or 3389 through another security group.", + "Remediation": "Select Default Security List for and Remove the Ingress Rule with Source 0.0.0.0/0, IP Protocol 22 and Destination Port Range 22.", + "Recommendation": "Create specific custom security lists with workload specific rules and attach to subnets.", + "Observation": "Default Security lists that allow more traffic then ICMP." }, - "1.11":{ "Description":"Tenancy administrator users have full access to the organization's OCI tenancy. API keys associated with user accounts are used for invoking the OCI APIs via custom programs or clients like CLI/SDKs. The clients are typically used for performing day-to-day operations and should never require full tenancy access. Service-level administrative users with API keys should be used instead.", - "Rationale":"For performing day-to-day operations tenancy administrator access is not needed.\nService-level administrative users with API keys should be used to apply privileged security principle.", - "Impact":"", - "Remediation":"For each tenancy administrator user who has an API key,select API Keys from the menu and delete any associated keys from the API Keys table.", - "Recommendation":"Evaluate if a user with API Keys requires Administrator access and use a least privilege approach.", - "Observation":"users with Administrator access and API Keys." + "2.6": { + "Description": "Oracle Integration (OIC) is a complete, secure, but lightweight integration solution that enables you to connect your applications in the cloud. It simplifies connectivity between your applications and connects both your applications that live in the cloud and your applications that still live on premises. Oracle Integration provides secure, enterprise-grade connectivity regardless of the applications you are connecting or where they reside. OIC instances are created within an Oracle managed secure private network with each having a public endpoint. The capability to configure ingress filtering of network traffic to protect your OIC instances from unauthorized network access is included. It is recommended that network access to your OIC instances be restricted to your approved corporate IP Addresses or Virtual Cloud Networks (VCN)s.", + "Rationale": "Restricting connectivity to OIC Instances reduces an OIC instance's exposure to risk.", + "Impact": "When updating ingress filters for an existing environment, care should be taken to ensure that IP addresses and VCNs currently used by administrators, users, and services to access your OIC instances are included in the updated filters.", + "Remediation": "For each OIC instance in the returned results, select the OIC Instance name,edit the Network Access to be more restrictive.", + "Recommendation": "It is recommended that OIC Network Access is restricted to your corporate IP Addresses or VCNs for OIC Instances.", + "Observation": "OIC Instances that allow unfiltered public ingress traffic (Authentication and authorization is still required)." }, - "1.12":{ "Description":"All OCI IAM local user accounts have an email address field associated with the account. It is recommended to specify an email address that is valid and current.

If you have an email address in your user profile, you can use the Forgot Password link on the sign on page to have a temporary password sent to you.", - "Rationale":"Having a valid and current email address associated with an OCI IAM local user account allows you to tie the account to identity in your organization. It also allows that user to reset their password if it is forgotten or lost.", - "Impact":"", - "Remediation":"Update the current email address in the email text box on exch non compliant user.", - "Recommendation":"Add emails to users to allow them to use the 'Forgot Password' feature and uniquely identify the user. For service accounts it could be a mail alias.", - "Observation":"without an email." + "2.7": { + "Description": "Oracle Analytics Cloud (OAC) is a scalable and secure public cloud service that provides a full set of capabilities to explore and perform collaborative analytics for you, your workgroup, and your enterprise. OAC instances provide ingress filtering of network traffic or can be deployed with in an existing Virtual Cloud Network VCN. It is recommended that all new OAC instances be deployed within a VCN and that the Access Control Rules are restricted to your corporate IP Addresses or VCNs for existing OAC instances.", + "Rationale": "Restricting connectivity to Oracle Analytics Cloud instances reduces an OAC instance's exposure to risk.", + "Impact": "When updating ingress filters for an existing environment, care should be taken to ensure that IP addresses and VCNs currently used by administrators, users, and services to access your OAC instances are included in the updated filters. Also, these changes will temporarily bring the OAC instance offline.", + "Remediation": "For each OAC instance in the returned results, select the OAC Instance name edit the Access Control Rules by clicking +Another Rule and add rules as required.", + "Recommendation": "It is recommended that all new OAC instances be deployed within a VCN and that the Access Control Rules are restricted to your corporate IP Addresses or VCNs for existing OAC instances.", + "Observation": "OAC Instances that allow unfiltered public ingress traffic (Authentication and authorization is still required)." }, - "1.13":{ "Description":"OCI instances, OCI database and OCI functions can access other OCI resources either via an OCI API key associated to a user or by being including in a Dynamic Group that has an IAM policy granting it the required access. Access to OCI Resources refers to making API calls to another OCI resource like Object Storage, OCI Vaults, etc.", - "Rationale":"Dynamic Groups reduces the risks related to hard coded credentials. Hard coded API keys can be shared and require rotation which can open them up to being compromised. Compromised credentials could allow access to OCI services outside of the expected radius.", - "Impact":"For an OCI instance that contains embedded credential audit the scripts and environment variables to ensure that none of them contain OCI API Keys or credentials.", - "Remediation":"Create Dynamic group and Enter Matching Rules to that includes the instances accessing your OCI resources. Refer:\"https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/managingdynamicgroups.htm\".", - "Recommendation":"Evaluate how your instances, functions, and autonomous database interact with other OCI services.", - "Observation":"Dynamic Groups reduces the risks related to hard coded credentials. Hard coded API keys can be shared and require rotation which can open them up to being compromised. Compromised credentials could allow access to OCI services outside of the expected radius." + "2.8": { + "Description": "Oracle Autonomous Database Shared (ADB-S) automates database tuning, security, backups, updates, and other routine management tasks traditionally performed by DBAs. ADB-S provide ingress filtering of network traffic or can be deployed within an existing Virtual Cloud Network (VCN). It is recommended that all new ADB-S databases be deployed within a VCN and that the Access Control Rules are restricted to your corporate IP Addresses or VCNs for existing ADB-S databases.", + "Rationale": "Restricting connectivity to ADB-S Databases reduces an ADB-S database's exposure to risk.", + "Impact": "When updating ingress filters for an existing environment, care should be taken to ensure that IP addresses and VCNs currently used by administrators, users, and services to access your ADB-S instances are included in the updated filters.", + "Remediation": "For each ADB-S database in the returned results, select the ADB-S database name edit the Access Control Rules by clicking +Another Rule and add rules as required.", + "Recommendation": "It is recommended that all new ADB-S databases be deployed within a VCN and that the Access Control Rules are restricted to your corporate IP Addresses or VCNs for existing ADB-S databases.", + "Observation": "ADB-S Instances that allow unfiltered public ingress traffic (Authentication and authorization is still required)." }, - "1.14":{ "Description":"To apply the separation of duties security principle, one can restrict service-level administrators from being able to delete resources they are managing. It means service-level administrators can only manage resources of a specific service but not delete resources for that specific service.

Example policies for global/tenant level for block volume service-administrators:\n
\nAllow group VolumeUsers to manage volumes in tenancy where request.permission!='VOLUME_DELETE'\nAllow group VolumeUsers to manage volume-backups in tenancy where request.permission!='VOLUME_BACKUP_DELETE'\n

Example policies for global/tenant level for file storage system service-administrators:
\nAllow group FileUsers to manage file-systems in tenancy where request.permission!='FILE_SYSTEM_DELETE'\nAllow group FileUsers to manage mount-targets in tenancy where request.permission!='MOUNT_TARGET_DELETE'\nAllow group FileUsers to manage export-sets in tenancy where request.permission!='EXPORT_SET_DELETE'\n


Example policies for global/tenant level for object storage system service-administrators:
\nAllow group BucketUsers to manage objects in tenancy where request.permission!='OBJECT_DELETE'\nAllow group BucketUsers to manage buckets in tenancy where request.permission!='BUCKET_DELETE'\n
", - "Rationale":"Creating service-level administrators without the ability to delete the resource they are managing helps in tightly controlling access to Oracle Cloud Infrastructure (OCI) services by implementing the separation of duties security principle.", - "Impact":"", - "Remediation":"Add the appropriate where condition to any policy statement that allows the storage service-level to manage the storage service.", - "Recommendation":"To apply a separation of duties security principle, it is recommended to restrict service-level administrators from being able to delete resources they are managing.", - "Observation":"IAM Policies that give service administrator the ability to delete service resources." + "3.1": { + "Description": "Ensuring audit logs are kept for 365 days.", + "Rationale": "Log retention controls how long activity logs should be retained. Studies have shown that The Mean Time to Detect (MTTD) a cyber breach is anywhere from 30 days in some sectors to up to 206 days in others. Retaining logs for at least 365 days or more will provide the ability to respond to incidents.", + "Impact": "There is no performance impact when enabling the above described features but additional audit data will be retained.", + "Remediation": "Go to the Tenancy Details page and edit Audit Retention Policy by setting AUDIT RETENTION PERIOD to 365.", + "Recommendation": "", + "Observation": "" }, - "2.1":{ "Description":"Security lists provide stateful or stateless filtering of ingress/egress network traffic to OCI resources on a subnet level. It is recommended that no security group allows unrestricted ingress access to port 22.", - "Rationale":"Removing unfettered connectivity to remote console services, such as Secure Shell (SSH), reduces a server's exposure to risk.", - "Impact":"For updating an existing environment, care should be taken to ensure that administrators currently relying on an existing ingress from 0.0.0.0/0 have access to ports 22 and/or 3389 through another network security group or security list.", - "Remediation":"For each security list in the returned results, click the security list name. Either edit the ingress rule to be more restrictive, delete the ingress rule or click on the VCN and terminate the security list as appropriate.", - "Recommendation":"Review the security lists. If they are not used(attached to a subnet) they should be deleted if possible or empty. For attached security lists it is recommended to restrict the CIDR block to only allow access to Port 22 from known networks.", - "Observation":"Security lists that allow internet access to port 22. (Note this does not necessarily mean external traffic can reach a compute instance)." + "3.2": { + "Description": "Using default tags is a way to ensure all resources that support tags are tagged during creation. Tags can be based on static values or based on computed values. It is recommended to setup default tags early on to ensure all created resources will get tagged.\nTags are scoped to Compartments and are inherited by Child Compartments. The recommendation is to create default tags like “CreatedBy” at the Root Compartment level to ensure all resources get tagged.\nWhen using Tags it is important to ensure that Tag Namespaces are protected by IAM Policies otherwise this will allow users to change tags or tag values.\nDepending on the age of the OCI Tenancy there may already be Tag defaults setup at the Root Level and no need for further action to implement this action.", + "Rationale": "In the case of an incident having default tags like “CreatedBy” applied will provide info on who created the resource without having to search the Audit logs.", + "Impact": "There is no performance impact when enabling the above described features", + "Remediation": "Update the root compartments tag default link.In the Tag Defaults table verify that there is a Tag with a value of \"${iam.principal.names}\" and a Tag Key Status of Active. Also cretae a Tag key definition by providing a Tag Key, Description and selecting 'Static Value' for Tag Value Type.", + "Recommendation": "", + "Observation": "" }, - "2.2":{ "Description":"Security lists provide stateful or stateless filtering of ingress/egress network traffic to OCI resources on a subnet level. It is recommended that no security group allows unrestricted ingress access to port 3389.", - "Rationale":"Removing unfettered connectivity to remote console services, such as Remote Desktop Protocol (RDP), reduces a server's exposure to risk.", - "Impact":"For updating an existing environment, care should be taken to ensure that administrators currently relying on an existing ingress from 0.0.0.0/0 have access to ports 22 and/or 3389 through another network security group or security list.", - "Remediation":"For each security list in the returned results, click the security list name. Either edit the ingress rule to be more restrictive, delete the ingress rule or click on the VCN and terminate the security list as appropriate.", - "Recommendation":"Review the security lists. If they are not used(attached to a subnet) they should be deleted if possible or empty. For attached security lists it is recommended to restrict the CIDR block to only allow access to Port 3389 from known networks.", - "Observation":"Security lists that allow internet access to port 3389. (Note this does not necessarily mean external traffic can reach a compute instance)." + "3.3": { + "Description": "Notifications provide a multi-channel messaging service that allow users and applications to be notified of events of interest occurring within OCI. Messages can be sent via eMail, HTTPs, PagerDuty, Slack or the OCI Function service. Some channels, such as eMail require confirmation of the subscription before it becomes active.", + "Rationale": "Creating one or more notification topics allow administrators to be notified of relevant changes made to OCI infrastructure.", + "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", + "Remediation": "Create a Topic in the notifications service under the appropriate compartment and add the subscriptions with current email address and correct protocol.", + "Recommendation": "", + "Observation": "" }, - "2.3":{ "Description":"Network security groups provide stateful filtering of ingress/egress network traffic to OCI resources. It is recommended that no security group allows unrestricted ingress access to port 22.", - "Rationale":"Removing unfettered connectivity to remote console services, such as Secure Shell (SSH), reduces a server's exposure to risk.", - "Impact":"For updating an existing environment, care should be taken to ensure that administrators currently relying on an existing ingress from 0.0.0.0/0 have access to ports 22 and/or 3389 through another network security group or security list.", - "Remediation":"Using the details returned from the audit procedure either Remove the security rules or Update the security rules.", - "Recommendation":"Review the network security groups. If they are not used(attached to a subnet) they should be deleted if possible or empty. For attached security lists it is recommended to restrict the CIDR block to only allow access to Port 3389 from known networks.", - "Observation":"Network security groups that allow internet access to port 22. (Note this does not necessarily mean external traffic can reach a compute instance)." + "3.4": { + "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when Identity Providers are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments. It is recommended to create the Event rule at the root compartment level.", + "Rationale": "OCI Identity Providers allow management of User ID / passwords in external systems and use of those credentials to access OCI resources. Identity Providers allow users to single sign-on to OCI console and have other OCI credentials like API Keys.\nMonitoring and alerting on changes to Identity Providers will help in identifying changes to the security posture.", + "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", + "Remediation": "Create a Rule Condition in the Events services by selecting Identity in the Service Name Drop-down and selecting Identity Provider – Create, Identity Provider - Delete and Identity Provider – Update. In the Actions section select Notifications as Action Type and selct the compartment and topic to be used.", + "Recommendation": "", + "Observation": "" }, - "2.4":{ "Description":"Network security groups provide stateful filtering of ingress/egress network traffic to OCI resources. It is recommended that no security group allows unrestricted ingress access to port 3389.", - "Rationale":"Removing unfettered connectivity to remote console services, such as Remote Desktop Protocol (RDP), reduces a server's exposure to risk.", - "Impact":"For updating an existing environment, care should be taken to ensure that administrators currently relying on an existing ingress from 0.0.0.0/0 have access to ports 22 and/or 3389 through another network security group or security list.", - "Remediation":"Using the details returned from the audit procedure either Remove the security rules or Update the security rules.", - "Recommendation":"Review the network security groups. If they are not used(attached to a subnet) they should be deleted if possible or empty. For attached network security groups it is recommended to restrict the CIDR block to only allow access to Port 3389 from known networks.", - "Observation":"Network security groups that allow internet access to port 3389. (Note this does not necessarily mean external traffic can reach a compute instance)." + "3.5": { + "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when Identity Provider Group Mappings are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments. It is recommended to create the Event rule at the root compartment level", + "Rationale": "IAM Policies govern access to all resources within an OCI Tenancy. IAM Policies use OCI Groups for assigning the privileges. Identity Provider Groups could be mapped to OCI Groups to assign privileges to federated users in OCI. Monitoring and alerting on changes to Identity Provider Group mappings will help in identifying changes to the security posture.", + "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", + "Remediation": "Find and click the Rule that handles Idp Group Mapping Changes. Click the Edit Rule button and verify that the RuleConditions section contains a condition for the Service Identity and Event Types: Idp Group Mapping – Create, Idp Group Mapping – Delete, and Idp Group Mapping – Update and confirm Action Type contains: Notifications and that a valid Topic is referenced.", + "Recommendation": "", + "Observation": "" }, - "2.5":{ "Description":"A default security list is created when a Virtual Cloud Network (VCN) is created. Security lists provide stateful filtering of ingress and egress network traffic to OCI resources. It is recommended no security list allows unrestricted ingress access to Secure Shell (SSH) via port 22.", - "Rationale":"Removing unfettered connectivity to remote console services, such as SSH on port 22, reduces a server's exposure to unauthorized access.", - "Impact":"For updating an existing environment, care should be taken to ensure that administrators currently relying on an existing ingress from 0.0.0.0/0 have access to ports 22 and/or 3389 through another security group.", - "Remediation":"Select Default Security List for and Remove the Ingress Rule with Source 0.0.0.0/0, IP Protocol 22 and Destination Port Range 22.", - "Recommendation":"Create specific custom security lists with workload specific rules and attach to subnets.", - "Observation":"Default Security lists that allow more traffic then ICMP." + "3.6": { + "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when IAM Groups are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", + "Rationale": "IAM Groups control access to all resources within an OCI Tenancy.\n Monitoring and alerting on changes to IAM Groups will help in identifying changes to satisfy least privilege principle.", + "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", + "Remediation": "Create a Rule Condition by selecting Identity in the Service Name Drop-down and selecting Group – Create, Group – Delete and Group – Update. In the Actions section select Notifications as Action Type and selct the compartment and topic to be used.", + "Recommendation": "", + "Observation": "" }, - "2.6":{ "Description":"Oracle Integration (OIC) is a complete, secure, but lightweight integration solution that enables you to connect your applications in the cloud. It simplifies connectivity between your applications and connects both your applications that live in the cloud and your applications that still live on premises. Oracle Integration provides secure, enterprise-grade connectivity regardless of the applications you are connecting or where they reside. OIC instances are created within an Oracle managed secure private network with each having a public endpoint. The capability to configure ingress filtering of network traffic to protect your OIC instances from unauthorized network access is included. It is recommended that network access to your OIC instances be restricted to your approved corporate IP Addresses or Virtual Cloud Networks (VCN)s.", - "Rationale":"Restricting connectivity to OIC Instances reduces an OIC instance's exposure to risk.", - "Impact":"When updating ingress filters for an existing environment, care should be taken to ensure that IP addresses and VCNs currently used by administrators, users, and services to access your OIC instances are included in the updated filters.", - "Remediation":"For each OIC instance in the returned results, select the OIC Instance name,edit the Network Access to be more restrictive.", - "Recommendation":"It is recommended that OIC Network Access is restricted to your corporate IP Addresses or VCNs for OIC Instances.", - "Observation":"OIC Instances that allow unfiltered public ingress traffic (Authentication and authorization is still required)." + "3.7": { + "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when IAM Policies are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", + "Rationale": "IAM Policies govern access to all resources within an OCI Tenancy.\n Monitoring and alerting on changes to IAM policies will help in identifying changes to the security posture.", + "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", + "Remediation": "Create a Rule Condition by selecting Identity in the Service Name Drop-down and selecting Policy – Change Compartment, Policy – Create, Policy - Delete and Policy – Update. In the Actions section select Notifications as Action Type and selct the compartment and topic to be used.", + "Recommendation": "", + "Observation": "" }, - "2.7":{ "Description":"Oracle Analytics Cloud (OAC) is a scalable and secure public cloud service that provides a full set of capabilities to explore and perform collaborative analytics for you, your workgroup, and your enterprise. OAC instances provide ingress filtering of network traffic or can be deployed with in an existing Virtual Cloud Network VCN. It is recommended that all new OAC instances be deployed within a VCN and that the Access Control Rules are restricted to your corporate IP Addresses or VCNs for existing OAC instances.", - "Rationale":"Restricting connectivity to Oracle Analytics Cloud instances reduces an OAC instance's exposure to risk.", - "Impact":"When updating ingress filters for an existing environment, care should be taken to ensure that IP addresses and VCNs currently used by administrators, users, and services to access your OAC instances are included in the updated filters. Also, these changes will temporarily bring the OAC instance offline.", - "Remediation":"For each OAC instance in the returned results, select the OAC Instance name edit the Access Control Rules by clicking +Another Rule and add rules as required.", - "Recommendation":"It is recommended that all new OAC instances be deployed within a VCN and that the Access Control Rules are restricted to your corporate IP Addresses or VCNs for existing OAC instances.", - "Observation":"OAC Instances that allow unfiltered public ingress traffic (Authentication and authorization is still required)." + "3.8": { + "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when IAM Users are created, updated, deleted, capabilities updated, or state updated. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", + "Rationale": "Users use or manage Oracle Cloud Infrastructure resources.\n Monitoring and alerting on changes to Users will help in identifying changes to the security posture.", + "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", + "Remediation": "Edit Rule that handles IAM User Changes and verify that the Rule Conditions section contains a condition for the Service Identity and Event Types: User – Create, User – Delete, User – Update, User Capabilities – Update, User State – Update.", + "Recommendation": "", + "Observation": "" }, - "2.8":{ "Description":"Oracle Autonomous Database Shared (ADB-S) automates database tuning, security, backups, updates, and other routine management tasks traditionally performed by DBAs. ADB-S provide ingress filtering of network traffic or can be deployed within an existing Virtual Cloud Network (VCN). It is recommended that all new ADB-S databases be deployed within a VCN and that the Access Control Rules are restricted to your corporate IP Addresses or VCNs for existing ADB-S databases.", - "Rationale":"Restricting connectivity to ADB-S Databases reduces an ADB-S database's exposure to risk.", - "Impact":"When updating ingress filters for an existing environment, care should be taken to ensure that IP addresses and VCNs currently used by administrators, users, and services to access your ADB-S instances are included in the updated filters.", - "Remediation":"For each ADB-S database in the returned results, select the ADB-S database name edit the Access Control Rules by clicking +Another Rule and add rules as required.", - "Recommendation":"It is recommended that all new ADB-S databases be deployed within a VCN and that the Access Control Rules are restricted to your corporate IP Addresses or VCNs for existing ADB-S databases.", - "Observation":"ADB-S Instances that allow unfiltered public ingress traffic (Authentication and authorization is still required)." + "3.9": { + "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when Virtual Cloud Networks are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", + "Rationale": "Virtual Cloud Networks (VCNs) closely resembles a traditional network.\n Monitoring and alerting on changes to VCNs will help in identifying changes to the security posture.", + "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", + "Remediation": "Edit Rule that handles VCN Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: VCN – Create, VCN - Delete, and VCN – Update.", + "Recommendation": "", + "Observation": "" }, - "3.1":{ "Description":"Ensuring audit logs are kept for 365 days.", - "Rationale":"Log retention controls how long activity logs should be retained. Studies have shown that The Mean Time to Detect (MTTD) a cyber breach is anywhere from 30 days in some sectors to up to 206 days in others. Retaining logs for at least 365 days or more will provide the ability to respond to incidents.", - "Impact":"There is no performance impact when enabling the above described features but additional audit data will be retained.", - "Remediation":"Go to the Tenancy Details page and edit Audit Retention Policy by setting AUDIT RETENTION PERIOD to 365.", - "Recommendation":"", - "Observation":"" + "3.10": { + "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when route tables are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", + "Rationale": "Route tables control traffic flowing to or from Virtual Cloud Networks and Subnets.\n Monitoring and alerting on changes to route tables will help in identifying changes these traffic flows.", + "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", + "Remediation": "Edit Rule that handles Route Table Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: Route Table – Change Compartment, Route Table – Create, Route Table - Delete, and Route Table – Update.", + "Recommendation": "", + "Observation": "" }, - "3.2":{ "Description":"Using default tags is a way to ensure all resources that support tags are tagged during creation. Tags can be based on static values or based on computed values. It is recommended to setup default tags early on to ensure all created resources will get tagged.\nTags are scoped to Compartments and are inherited by Child Compartments. The recommendation is to create default tags like “CreatedBy” at the Root Compartment level to ensure all resources get tagged.\nWhen using Tags it is important to ensure that Tag Namespaces are protected by IAM Policies otherwise this will allow users to change tags or tag values.\nDepending on the age of the OCI Tenancy there may already be Tag defaults setup at the Root Level and no need for further action to implement this action.", - "Rationale":"In the case of an incident having default tags like “CreatedBy” applied will provide info on who created the resource without having to search the Audit logs.", - "Impact":"There is no performance impact when enabling the above described features", - "Remediation":"Update the root compartments tag default link.In the Tag Defaults table verify that there is a Tag with a value of \"${iam.principal.names}\" and a Tag Key Status of Active. Also cretae a Tag key definition by providing a Tag Key, Description and selecting 'Static Value' for Tag Value Type.", - "Recommendation":"", - "Observation":"" + "3.11": { + "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when security lists are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", + "Rationale": "Security Lists control traffic flowing into and out of Subnets within a Virtual Cloud Network.\n Monitoring and alerting on changes to Security Lists will help in identifying changes to these security controls.", + "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", + "Remediation": "Edit Rule that handles Security List Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: Security List – Change Compartment, Security List – Create, Security List - Delete, and Security List – Update.", + "Recommendation": "", + "Observation": "" }, - "3.3":{ "Description":"Notifications provide a multi-channel messaging service that allow users and applications to be notified of events of interest occurring within OCI. Messages can be sent via eMail, HTTPs, PagerDuty, Slack or the OCI Function service. Some channels, such as eMail require confirmation of the subscription before it becomes active.", - "Rationale":"Creating one or more notification topics allow administrators to be notified of relevant changes made to OCI infrastructure.", - "Impact":"There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", - "Remediation":"Create a Topic in the notifications service under the appropriate compartment and add the subscriptions with current email address and correct protocol.", - "Recommendation":"", - "Observation":"" + "3.12": { + "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when network security groups are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", + "Rationale": "Network Security Groups control traffic flowing between Virtual Network Cards attached to Compute instances.\n Monitoring and alerting on changes to Network Security Groups will help in identifying changes these security controls.", + "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", + "Remediation": "Edit Rule that handles Network Security Group Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: Network Security Group – Change Compartment, Network Security Group – Create, Network Security Group - Delete, and Network Security Group – Update.", + "Recommendation": "", + "Observation": "" }, - "3.4":{ "Description":"It is recommended to setup an Event Rule and Notification that gets triggered when Identity Providers are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments. It is recommended to create the Event rule at the root compartment level.", - "Rationale":"OCI Identity Providers allow management of User ID / passwords in external systems and use of those credentials to access OCI resources. Identity Providers allow users to single sign-on to OCI console and have other OCI credentials like API Keys.\nMonitoring and alerting on changes to Identity Providers will help in identifying changes to the security posture.", - "Impact":"There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", - "Remediation":"Create a Rule Condition in the Events services by selecting Identity in the Service Name Drop-down and selecting Identity Provider – Create, Identity Provider - Delete and Identity Provider – Update. In the Actions section select Notifications as Action Type and selct the compartment and topic to be used.", - "Recommendation":"", - "Observation":"" + "3.13": { + "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when Network Gateways are created, updated, deleted, attached, detached, or moved. This recommendation includes Internet Gateways, Dynamic Routing Gateways, Service Gateways, Local Peering Gateways, and NAT Gateways. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", + "Rationale": "Network Gateways act as routers between VCNs and the Internet, Oracle Services Networks, other VCNS, and on-premise networks.\n Monitoring and alerting on changes to Network Gateways will help in identifying changes to the security posture.", + "Impact": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", + "Remediation": "Edit Rule that handles Network Gateways Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: DRG – Create, DRG - Delete, DRG - Update, DRG Attachment – Create, DRG Attachment – Delete, DRG Attachment - Update, Internet Gateway – Create, Internet Gateway – Delete, Internet Gateway - Update, Internet Gateway – Change Compartment, Local Peering Gateway – Create, Local Peering Gateway – Delete, Local Peering Gateway - Update, Local Peering Gateway – Change Compartment, NAT Gateway – Create, NAT Gateway – Delete, NAT Gateway - Update, NAT Gateway – Change Compartment.", + "Recommendation": "", + "Observation": "" }, - "3.5":{ "Description":"It is recommended to setup an Event Rule and Notification that gets triggered when Identity Provider Group Mappings are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments. It is recommended to create the Event rule at the root compartment level", - "Rationale":"IAM Policies govern access to all resources within an OCI Tenancy. IAM Policies use OCI Groups for assigning the privileges. Identity Provider Groups could be mapped to OCI Groups to assign privileges to federated users in OCI. Monitoring and alerting on changes to Identity Provider Group mappings will help in identifying changes to the security posture.", - "Impact":"There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", - "Remediation":"Find and click the Rule that handles Idp Group Mapping Changes. Click the Edit Rule button and verify that the RuleConditions section contains a condition for the Service Identity and Event Types: Idp Group Mapping – Create, Idp Group Mapping – Delete, and Idp Group Mapping – Update and confirm Action Type contains: Notifications and that a valid Topic is referenced.", - "Recommendation":"", - "Observation":"" + "3.14": { + "Description": "VCN flow logs record details about traffic that has been accepted or rejected based on the security list rule.", + "Rationale": "Enabling VCN flow logs enables you to monitor traffic flowing within your virtual network and can be used to detect anomalous traffic.", + "Impact": "Enabling VCN flow logs will not affect the performance of your virtual network but it will generate additional use of object storage that should be controlled via object lifecycle management.

By default, VCN flow logs are stored for 30 days in object storage. Users can specify a longer retention period.", + "Remediation": "Enable Flow Logs (all records) on Virtual Cloud Networks (subnets) under the relevant resource compartment. Before hand create Log group if not exist in the Log services.", + "Recommendation": "", + "Observation": "" }, - "3.6":{ "Description":"It is recommended to setup an Event Rule and Notification that gets triggered when IAM Groups are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", - "Rationale":"IAM Groups control access to all resources within an OCI Tenancy.\n Monitoring and alerting on changes to IAM Groups will help in identifying changes to satisfy least privilege principle.", - "Impact":"There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", - "Remediation":"Create a Rule Condition by selecting Identity in the Service Name Drop-down and selecting Group – Create, Group – Delete and Group – Update. In the Actions section select Notifications as Action Type and selct the compartment and topic to be used.", - "Recommendation":"", - "Observation":"" + "3.15": { + "Description": "Cloud Guard detects misconfigured resources and insecure activity within a tenancy and provides security administrators with the visibility to resolve these issues. Upon detection, Cloud Guard can suggest, assist, or take corrective actions to mitigate these issues. Cloud Guard should be enabled in the root compartment of your tenancy with the default configuration, activity detectors and responders.", + "Rationale": "Cloud Guard provides an automated means to monitor a tenancy for resources that are configured in an insecure manner as well as risky network activity from these resources.", + "Impact": "There is no performance impact when enabling the above described features, but additional IAM policies will be required.", + "Remediation": "Enable the cloud guard by selecting the services in the menu and provide appropriate reporting region and other configurations.", + "Recommendation": "", + "Observation": "" }, - "3.7":{ "Description":"It is recommended to setup an Event Rule and Notification that gets triggered when IAM Policies are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", - "Rationale":"IAM Policies govern access to all resources within an OCI Tenancy.\n Monitoring and alerting on changes to IAM policies will help in identifying changes to the security posture.", - "Impact":"There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", - "Remediation":"Create a Rule Condition by selecting Identity in the Service Name Drop-down and selecting Policy – Change Compartment, Policy – Create, Policy - Delete and Policy – Update. In the Actions section select Notifications as Action Type and selct the compartment and topic to be used.", - "Recommendation":"", - "Observation":"" + "3.16": { + "Description": "Oracle Cloud Infrastructure Vault securely stores master encryption keys that protect your encrypted data. You can use the Vault service to rotate keys to generate new cryptographic material. Periodically rotating keys limits the amount of data encrypted by one key version.", + "Rationale": "Rotating keys annually limits the data encrypted under one key version. Key rotation thereby reduces the risk in case a key is ever compromised.", + "Impact": "", + "Remediation": "Select the security service and select vault. Ensure the date of each Master Encryption Key under the Created column of the Master Encryption key is no more than 365 days old.", + "Recommendation": "", + "Observation": "" }, - "3.8":{ "Description":"It is recommended to setup an Event Rule and Notification that gets triggered when IAM Users are created, updated, deleted, capabilities updated, or state updated. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", - "Rationale":"Users use or manage Oracle Cloud Infrastructure resources.\n Monitoring and alerting on changes to Users will help in identifying changes to the security posture.", - "Impact":"There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", - "Remediation":"Edit Rule that handles IAM User Changes and verify that the Rule Conditions section contains a condition for the Service Identity and Event Types: User – Create, User – Delete, User – Update, User Capabilities – Update, User State – Update.", - "Recommendation":"", - "Observation":"" + "3.17": { + "Description": "Object Storage write logs will log all write requests made to objects in a bucket.", + "Rationale": "Enabling an Object Storage write log, the 'requestAction' property would contain values of 'PUT', 'POST', or 'DELETE'. This will provide you more visibility into changes to objects in your buckets.", + "Impact": "There is no performance impact when enabling the above described features, but will generate additional use of object storage that should be controlled via object lifecycle management.

By default, Object Storage logs are stored for 30 days in object storage. Users can specify a longer retention period.", + "Remediation": "To the relevant bucket enable log by providing Write Access Events from the Log Category. Beforehand create log group if required.", + "Recommendation": "", + "Observation": "" }, - "3.9":{ "Description":"It is recommended to setup an Event Rule and Notification that gets triggered when Virtual Cloud Networks are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", - "Rationale":"Virtual Cloud Networks (VCNs) closely resembles a traditional network.\n Monitoring and alerting on changes to VCNs will help in identifying changes to the security posture.", - "Impact":"There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", - "Remediation":"Edit Rule that handles VCN Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: VCN – Create, VCN - Delete, and VCN – Update.", - "Recommendation":"", - "Observation":"" + "4.1.1": { + "Description": "A bucket is a logical container for storing objects. It is associated with a single compartment that has policies that determine what action a user can perform on a bucket and on all the objects in the bucket. It is recommended that no bucket be publicly accessible.", + "Rationale": "Removing unfettered reading of objects in a bucket reduces an organization's exposure to data loss.", + "Impact": "For updating an existing bucket, care should be taken to ensure objects in the bucket can be accessed through either IAM policies or pre-authenticated requests.", + "Remediation": "Edit the visibility into 'private' for each Bucket.", + "Recommendation": "", + "Observation": "" }, - "3.10":{ "Description":"It is recommended to setup an Event Rule and Notification that gets triggered when route tables are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", - "Rationale":"Route tables control traffic flowing to or from Virtual Cloud Networks and Subnets.\n Monitoring and alerting on changes to route tables will help in identifying changes these traffic flows.", - "Impact":"There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", - "Remediation":"Edit Rule that handles Route Table Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: Route Table – Change Compartment, Route Table – Create, Route Table - Delete, and Route Table – Update.", - "Recommendation":"", - "Observation":"" + "4.1.2": { + "Description": "Oracle Object Storage buckets support encryption with a Customer Managed Key (CMK). By default, Object Storage buckets are encrypted with an Oracle managed key.", + "Rationale": "Encryption of Object Storage buckets with a Customer Managed Key (CMK) provides an additional level of security on your data by allowing you to manage your own encryption key lifecycle management for the bucket.", + "Impact": "Encrypting with a Customer Managed Keys requires a Vault and a Customer Master Key. In addition, you must authorize Object Storage service to use keys on your behalf.

Required Policy:\n
\nAllow service objectstorage-<region_name>, to use keys in compartment <compartment-id> where target.key.id = '<key_OCID>'

", + "Remediation": "Assign Master encryption key to Encryption key in every Object storage under Bucket name by clicking assign and select vault.", + "Recommendation": "", + "Observation": "" }, - "3.11":{ "Description":"It is recommended to setup an Event Rule and Notification that gets triggered when security lists are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", - "Rationale":"Security Lists control traffic flowing into and out of Subnets within a Virtual Cloud Network.\n Monitoring and alerting on changes to Security Lists will help in identifying changes to these security controls.", - "Impact":"There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", - "Remediation":"Edit Rule that handles Security List Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: Security List – Change Compartment, Security List – Create, Security List - Delete, and Security List – Update.", - "Recommendation":"", - "Observation":"" + "4.1.3": { + "Description": "A bucket is a logical container for storing objects. Object versioning is enabled at the bucket level and is disabled by default upon creation. Versioning directs Object Storage to automatically create an object version each time a new object is uploaded, an existing object is overwritten, or when an object is deleted. You can enable object versioning at bucket creation time or later.", + "Rationale": "Versioning object storage buckets provides for additional integrity of your data. Management of data integrity is critical to protecting and accessing protected data. Some customers want to identify object storage buckets without versioning in order to apply their own data lifecycle protection and management policy.", + "Impact": "", + "Remediation": "Enable Versioning by clicking on every bucket by editing the bucket configuration.", + "Recommendation": "", + "Observation": "" }, - "3.12":{ "Description":"It is recommended to setup an Event Rule and Notification that gets triggered when network security groups are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", - "Rationale":"Network Security Groups control traffic flowing between Virtual Network Cards attached to Compute instances.\n Monitoring and alerting on changes to Network Security Groups will help in identifying changes these security controls.", - "Impact":"There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", - "Remediation":"Edit Rule that handles Network Security Group Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: Network Security Group – Change Compartment, Network Security Group – Create, Network Security Group - Delete, and Network Security Group – Update.", - "Recommendation":"", - "Observation":"" + "4.2.1": { + "Description": "Oracle Cloud Infrastructure Block Volume service lets you dynamically provision and manage block storage volumes. By default, the Oracle service manages the keys that encrypt this block volume. Block Volumes can also be encrypted using a customer managed key.", + "Rationale": "Encryption of block volumes provides an additional level of security for your data. Management of encryption keys is critical to protecting and accessing protected data. Customers should identify block volumes encrypted with Oracle service managed keys in order to determine if they want to manage the keys for certain volumes and then apply their own key lifecycle management to the selected block volumes.", + "Impact": "Encrypting with a Customer Managed Keys requires a Vault and a Customer Master Key. In addition, you must authorize the Block Volume service to use the keys you create.\nRequired IAM Policy:\n
\nAllow service blockstorage to use keys in compartment <compartment-id> where target.key.id = '<key_OCID>'\n
", + "Remediation": "For each block volumes from the result, assign the encryption key by Selecting the Vault Compartment and Vault, select the Master Encryption Key Compartment and Master Encryption key, click Assign.", + "Recommendation": "", + "Observation": "" }, - "3.13":{ "Description":"It is recommended to setup an Event Rule and Notification that gets triggered when Network Gateways are created, updated, deleted, attached, detached, or moved. This recommendation includes Internet Gateways, Dynamic Routing Gateways, Service Gateways, Local Peering Gateways, and NAT Gateways. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.", - "Rationale":"Network Gateways act as routers between VCNs and the Internet, Oracle Services Networks, other VCNS, and on-premise networks.\n Monitoring and alerting on changes to Network Gateways will help in identifying changes to the security posture.", - "Impact":"There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.", - "Remediation":"Edit Rule that handles Network Gateways Changes and verify that the RuleConditions section contains a condition for the Service Networking and Event Types: DRG – Create, DRG - Delete, DRG - Update, DRG Attachment – Create, DRG Attachment – Delete, DRG Attachment - Update, Internet Gateway – Create, Internet Gateway – Delete, Internet Gateway - Update, Internet Gateway – Change Compartment, Local Peering Gateway – Create, Local Peering Gateway – Delete, Local Peering Gateway - Update, Local Peering Gateway – Change Compartment, NAT Gateway – Create, NAT Gateway – Delete, NAT Gateway - Update, NAT Gateway – Change Compartment.", - "Recommendation":"", - "Observation":"" + "4.2.2": { + "Description": "When you launch a virtual machine (VM) or bare metal instance based on a platform image or custom image, a new boot volume for the instance is created in the same compartment. That boot volume is associated with that instance until you terminate the instance. By default, the Oracle service manages the keys that encrypt this boot volume. Boot Volumes can also be encrypted using a customer managed key.", + "Rationale": "Encryption of boot volumes provides an additional level of security for your data. Management of encryption keys is critical to protecting and accessing protected data. Customers should identify boot volumes encrypted with Oracle service managed keys in order to determine if they want to manage the keys for certain boot volumes and then apply their own key lifecycle management to the selected boot volumes.", + "Impact": "Encrypting with a Customer Managed Keys requires a Vault and a Customer Master Key. In addition, you must authorize the Boot Volume service to use the keys you create.\nRequired IAM Policy:\n
\nAllow service Bootstorage to use keys in compartment <compartment-id> where target.key.id = '<key_OCID>'\n
", + "Remediation": "For each boot volumes from the result, assign the encryption key by Selecting the Vault Compartment and Vault, select the Master Encryption Key Compartment and Master Encryption key, click Assign.", + "Recommendation": "", + "Observation": "" }, - "3.14":{ "Description":"VCN flow logs record details about traffic that has been accepted or rejected based on the security list rule.", - "Rationale":"Enabling VCN flow logs enables you to monitor traffic flowing within your virtual network and can be used to detect anomalous traffic.", - "Impact":"Enabling VCN flow logs will not affect the performance of your virtual network but it will generate additional use of object storage that should be controlled via object lifecycle management.

By default, VCN flow logs are stored for 30 days in object storage. Users can specify a longer retention period.", - "Remediation":"Enable Flow Logs (all records) on Virtual Cloud Networks (subnets) under the relevant resource compartment. Before hand create Log group if not exist in the Log services.", - "Recommendation":"", - "Observation":"" + "4.3.1": { + "Description": "Oracle Cloud Infrastructure File Storage service (FSS) provides a durable, scalable, secure, enterprise-grade network file system. By default, the Oracle service manages the keys that encrypt FSS file systems. FSS file systems can also be encrypted using a customer managed key.", + "Rationale": "Encryption of FSS systems provides an additional level of security for your data. Management of encryption keys is critical to protecting and accessing protected data. Customers should identify FSS file systems that are encrypted with Oracle service managed keys in order to determine if they want to manage the keys for certain FSS file systems and then apply their own key lifecycle management to the selected FSS file systems.", + "Impact": "Encrypting with a Customer Managed Keys requires a Vault and a Customer Master Key. In addition, you must authorize the File Storage service to use the keys you create.\nRequired IAM Policy:\n
\nAllow service FssOc1Prod to use keys in compartment <compartment-id> where target.key.id = '<key_OCID>'\n
", + "Remediation": "For each file storage system from the result, assign the encryption key by Selecting the Vault Compartment and Vault, select the Master Encryption Key Compartment and Master Encryption key, click Assign.", + "Recommendation": "", + "Observation": "" }, - "3.15":{ "Description":"Cloud Guard detects misconfigured resources and insecure activity within a tenancy and provides security administrators with the visibility to resolve these issues. Upon detection, Cloud Guard can suggest, assist, or take corrective actions to mitigate these issues. Cloud Guard should be enabled in the root compartment of your tenancy with the default configuration, activity detectors and responders.", - "Rationale":"Cloud Guard provides an automated means to monitor a tenancy for resources that are configured in an insecure manner as well as risky network activity from these resources.", - "Impact":"There is no performance impact when enabling the above described features, but additional IAM policies will be required.", - "Remediation":"Enable the cloud guard by selecting the services in the menu and provide appropriate reporting region and other configurations.", - "Recommendation":"", - "Observation":"" + "5.1": { + "Description": "When you sign up for Oracle Cloud Infrastructure, Oracle creates your tenancy, which is the root compartment that holds all your cloud resources. You then create additional compartments within the tenancy (root compartment) and corresponding policies to control access to the resources in each compartment.

Compartments allow you to organize and control access to your cloud resources. A compartment is a collection of related resources (such as instances, databases, virtual cloud networks, block volumes) that can be accessed only by certain groups that have been given permission by an administrator.", + "Rationale": "Compartments are a logical group that adds an extra layer of isolation, organization and authorization making it harder for unauthorized users to gain access to OCI resources.", + "Impact": "Once the compartment is created an OCI IAM policy must be created to allow a group to resources in the compartment otherwise only group with tenancy access will have access.", + "Remediation": "Create the new compartment under the root compartment.", + "Recommendation": "", + "Observation": "" }, - "3.16":{ "Description":"Oracle Cloud Infrastructure Vault securely stores master encryption keys that protect your encrypted data. You can use the Vault service to rotate keys to generate new cryptographic material. Periodically rotating keys limits the amount of data encrypted by one key version.", - "Rationale":"Rotating keys annually limits the data encrypted under one key version. Key rotation thereby reduces the risk in case a key is ever compromised.", - "Impact":"", - "Remediation":"Select the security service and select vault. Ensure the date of each Master Encryption Key under the Created column of the Master Encryption key is no more than 365 days old.", - "Recommendation":"", - "Observation":"" - }, - "3.17":{ "Description":"Object Storage write logs will log all write requests made to objects in a bucket.", - "Rationale":"Enabling an Object Storage write log, the 'requestAction' property would contain values of 'PUT', 'POST', or 'DELETE'. This will provide you more visibility into changes to objects in your buckets.", - "Impact":"There is no performance impact when enabling the above described features, but will generate additional use of object storage that should be controlled via object lifecycle management.

By default, Object Storage logs are stored for 30 days in object storage. Users can specify a longer retention period.", - "Remediation":"To the relevant bucket enable log by providing Write Access Events from the Log Category. Beforehand create log group if required.", - "Recommendation":"", - "Observation":"" - }, - "4.1.1":{ "Description":"A bucket is a logical container for storing objects. It is associated with a single compartment that has policies that determine what action a user can perform on a bucket and on all the objects in the bucket. It is recommended that no bucket be publicly accessible.", - "Rationale":"Removing unfettered reading of objects in a bucket reduces an organization's exposure to data loss.", - "Impact":"For updating an existing bucket, care should be taken to ensure objects in the bucket can be accessed through either IAM policies or pre-authenticated requests.", - "Remediation":"Edit the visibility into 'private' for each Bucket.", - "Recommendation":"", - "Observation":"" - }, - "4.1.2":{ "Description":"Oracle Object Storage buckets support encryption with a Customer Managed Key (CMK). By default, Object Storage buckets are encrypted with an Oracle managed key.", - "Rationale":"Encryption of Object Storage buckets with a Customer Managed Key (CMK) provides an additional level of security on your data by allowing you to manage your own encryption key lifecycle management for the bucket.", - "Impact":"Encrypting with a Customer Managed Keys requires a Vault and a Customer Master Key. In addition, you must authorize Object Storage service to use keys on your behalf.

Required Policy:\n
\nAllow service objectstorage-<region_name>, to use keys in compartment <compartment-id> where target.key.id = '<key_OCID>'

", - "Remediation":"Assign Master encryption key to Encryption key in every Object storage under Bucket name by clicking assign and select vault.", - "Recommendation":"", - "Observation":"" - }, - "4.1.3":{ "Description":"A bucket is a logical container for storing objects. Object versioning is enabled at the bucket level and is disabled by default upon creation. Versioning directs Object Storage to automatically create an object version each time a new object is uploaded, an existing object is overwritten, or when an object is deleted. You can enable object versioning at bucket creation time or later.", - "Rationale":"Versioning object storage buckets provides for additional integrity of your data. Management of data integrity is critical to protecting and accessing protected data. Some customers want to identify object storage buckets without versioning in order to apply their own data lifecycle protection and management policy.", - "Impact":"", - "Remediation":"Enable Versioning by clicking on every bucket by editing the bucket configuration.", - "Recommendation":"", - "Observation":"" - }, - "4.2.1":{ "Description":"Oracle Cloud Infrastructure Block Volume service lets you dynamically provision and manage block storage volumes. By default, the Oracle service manages the keys that encrypt this block volume. Block Volumes can also be encrypted using a customer managed key.", - "Rationale":"Encryption of block volumes provides an additional level of security for your data. Management of encryption keys is critical to protecting and accessing protected data. Customers should identify block volumes encrypted with Oracle service managed keys in order to determine if they want to manage the keys for certain volumes and then apply their own key lifecycle management to the selected block volumes.", - "Impact":"Encrypting with a Customer Managed Keys requires a Vault and a Customer Master Key. In addition, you must authorize the Block Volume service to use the keys you create.\nRequired IAM Policy:\n
\nAllow service blockstorage to use keys in compartment <compartment-id> where target.key.id = '<key_OCID>'\n
", - "Remediation":"For each block volumes from the result, assign the encryption key by Selecting the Vault Compartment and Vault, select the Master Encryption Key Compartment and Master Encryption key, click Assign.", - "Recommendation":"", - "Observation":"" - }, - "4.2.2":{ "Description":"When you launch a virtual machine (VM) or bare metal instance based on a platform image or custom image, a new boot volume for the instance is created in the same compartment. That boot volume is associated with that instance until you terminate the instance. By default, the Oracle service manages the keys that encrypt this boot volume. Boot Volumes can also be encrypted using a customer managed key.", - "Rationale":"Encryption of boot volumes provides an additional level of security for your data. Management of encryption keys is critical to protecting and accessing protected data. Customers should identify boot volumes encrypted with Oracle service managed keys in order to determine if they want to manage the keys for certain boot volumes and then apply their own key lifecycle management to the selected boot volumes.", - "Impact":"Encrypting with a Customer Managed Keys requires a Vault and a Customer Master Key. In addition, you must authorize the Boot Volume service to use the keys you create.\nRequired IAM Policy:\n
\nAllow service Bootstorage to use keys in compartment <compartment-id> where target.key.id = '<key_OCID>'\n
", - "Remediation":"For each boot volumes from the result, assign the encryption key by Selecting the Vault Compartment and Vault, select the Master Encryption Key Compartment and Master Encryption key, click Assign.", - "Recommendation":"", - "Observation":"" - }, - "4.3.1":{ "Description":"Oracle Cloud Infrastructure File Storage service (FSS) provides a durable, scalable, secure, enterprise-grade network file system. By default, the Oracle service manages the keys that encrypt FSS file systems. FSS file systems can also be encrypted using a customer managed key.", - "Rationale":"Encryption of FSS systems provides an additional level of security for your data. Management of encryption keys is critical to protecting and accessing protected data. Customers should identify FSS file systems that are encrypted with Oracle service managed keys in order to determine if they want to manage the keys for certain FSS file systems and then apply their own key lifecycle management to the selected FSS file systems.", - "Impact":"Encrypting with a Customer Managed Keys requires a Vault and a Customer Master Key. In addition, you must authorize the File Storage service to use the keys you create.\nRequired IAM Policy:\n
\nAllow service FssOc1Prod to use keys in compartment <compartment-id> where target.key.id = '<key_OCID>'\n
", - "Remediation":"For each file storage system from the result, assign the encryption key by Selecting the Vault Compartment and Vault, select the Master Encryption Key Compartment and Master Encryption key, click Assign.", - "Recommendation":"", - "Observation":"" - }, - "5.1":{ "Description":"When you sign up for Oracle Cloud Infrastructure, Oracle creates your tenancy, which is the root compartment that holds all your cloud resources. You then create additional compartments within the tenancy (root compartment) and corresponding policies to control access to the resources in each compartment.

Compartments allow you to organize and control access to your cloud resources. A compartment is a collection of related resources (such as instances, databases, virtual cloud networks, block volumes) that can be accessed only by certain groups that have been given permission by an administrator.", - "Rationale":"Compartments are a logical group that adds an extra layer of isolation, organization and authorization making it harder for unauthorized users to gain access to OCI resources.", - "Impact":"Once the compartment is created an OCI IAM policy must be created to allow a group to resources in the compartment otherwise only group with tenancy access will have access.", - "Remediation":"Create the new compartment under the root compartment.", - "Recommendation":"", - "Observation":"" - }, - "5.2":{ "Description":"When you create a cloud resource such as an instance, block volume, or cloud network, you must specify to which compartment you want the resource to belong. Placing resources in the root compartment makes it difficult to organize and isolate those resources.", - "Rationale":"Placing resources into a compartment will allow you to organize and have more granular access controls to your cloud resources.", - "Impact":"Placing a resource in a compartment will impact how you write policies to manage access and organize that resource.", - "Remediation":"For each item in the returned results,select Move Resource or More Actions then Move Resource and select compartment except root and choose new then move resources.", - "Recommendation":"", - "Observation":"" + "5.2": { + "Description": "When you create a cloud resource such as an instance, block volume, or cloud network, you must specify to which compartment you want the resource to belong. Placing resources in the root compartment makes it difficult to organize and isolate those resources.", + "Rationale": "Placing resources into a compartment will allow you to organize and have more granular access controls to your cloud resources.", + "Impact": "Placing a resource in a compartment will impact how you write policies to manage access and organize that resource.", + "Remediation": "For each item in the returned results,select Move Resource or More Actions then Move Resource and select compartment except root and choose new then move resources.", + "Recommendation": "", + "Observation": "" } } # MAP Checks self.obp_foundations_checks = { - 'Cost_Tracking_Budgets' : {'Status' : False, 'Findings' : [], 'OBP' : [], "Documentation" : "https://docs.oracle.com/en-us/iaas/Content/Billing/Concepts/budgetsoverview.htm#Budgets_Overview"}, - 'SIEM_Audit_Log_All_Comps' : {'Status' : True, 'Findings' : [], 'OBP' : [], "Documentation" : "https://docs.oracle.com/en/solutions/oci-aggregate-logs-siem/index.html"}, # Assuming True - 'SIEM_Audit_Incl_Sub_Comp' : {'Status' : True,'Findings' : [], 'OBP' : [], "Documentation" : "https://docs.oracle.com/en/solutions/oci-aggregate-logs-siem/index.html" }, # Assuming True - 'SIEM_VCN_Flow_Logging' : {'Status' : None, 'Findings' : [], 'OBP' : [], "Documentation" : "https://docs.oracle.com/en/solutions/oci-aggregate-logs-siem/index.html"}, - 'SIEM_Write_Bucket_Logs' : {'Status' : None, 'Findings' : [], 'OBP' : [], "Documentation" : "https://docs.oracle.com/en/solutions/oci-aggregate-logs-siem/index.html"}, - 'SIEM_Read_Bucket_Logs' : {'Status' : None, 'Findings' : [], 'OBP' : [], "Documentation" : "https://docs.oracle.com/en/solutions/oci-aggregate-logs-siem/index.html"}, - 'Networking_Connectivity' : {'Status' : True, 'Findings' : [], 'OBP' : [], "Documentation" : "https://docs.oracle.com/en-us/iaas/Content/Network/Troubleshoot/drgredundancy.htm" }, - 'Cloud_Guard_Config' : {'Status' : None, 'Findings' : [], 'OBP' : [], "Documentation" : "" }, + 'Cost_Tracking_Budgets': {'Status': False, 'Findings': [], 'OBP': [], "Documentation": "https://docs.oracle.com/en-us/iaas/Content/Billing/Concepts/budgetsoverview.htm#Budgets_Overview"}, + 'SIEM_Audit_Log_All_Comps': {'Status': True, 'Findings': [], 'OBP': [], "Documentation": "https://docs.oracle.com/en/solutions/oci-aggregate-logs-siem/index.html"}, # Assuming True + 'SIEM_Audit_Incl_Sub_Comp': {'Status': True, 'Findings': [], 'OBP': [], "Documentation": "https://docs.oracle.com/en/solutions/oci-aggregate-logs-siem/index.html"}, # Assuming True + 'SIEM_VCN_Flow_Logging': {'Status': None, 'Findings': [], 'OBP': [], "Documentation": "https://docs.oracle.com/en/solutions/oci-aggregate-logs-siem/index.html"}, + 'SIEM_Write_Bucket_Logs': {'Status': None, 'Findings': [], 'OBP': [], "Documentation": "https://docs.oracle.com/en/solutions/oci-aggregate-logs-siem/index.html"}, + 'SIEM_Read_Bucket_Logs': {'Status': None, 'Findings': [], 'OBP': [], "Documentation": "https://docs.oracle.com/en/solutions/oci-aggregate-logs-siem/index.html"}, + 'Networking_Connectivity': {'Status': True, 'Findings': [], 'OBP': [], "Documentation": "https://docs.oracle.com/en-us/iaas/Content/Network/Troubleshoot/drgredundancy.htm"}, + 'Cloud_Guard_Config': {'Status': None, 'Findings': [], 'OBP': [], "Documentation": ""}, } # MAP Regional Data self.__obp_regional_checks = {} - # CIS monitoring notifications check self.cis_monitoring_checks = { "3.4": [ @@ -604,32 +640,37 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print ] } - + # CIS IAM check self.cis_iam_checks = { "1.3": {"targets": ["target.group.name!=Administrators"]}, "1.13": {"resources": ["fnfunc", "instance", "autonomousdatabase", "resource.compartment.id"]}, - "1.14": {"all-resources": ["request.permission!=BUCKET_DELETE", "request.permission!=OBJECT_DELETE", "request.permission!=EXPORT_SET_DELETE", - "request.permission!=MOUNT_TARGET_DELETE", "request.permission!=FILE_SYSTEM_DELETE", "request.permission!=VOLUME_BACKUP_DELETE", - "request.permission!=VOLUME_DELETE", "request.permission!=FILE_SYSTEM_DELETE_SNAPSHOT"], - "file-family": ["request.permission!=EXPORT_SET_DELETE", "request.permission!=MOUNT_TARGET_DELETE", - "request.permission!=FILE_SYSTEM_DELETE", "request.permission!=FILE_SYSTEM_DELETE_SNAPSHOT"], - "file-systems" : ["request.permission!=FILE_SYSTEM_DELETE", "request.permission!=FILE_SYSTEM_DELETE_SNAPSHOT"], - "mount-targets": ["request.permission!=MOUNT_TARGET_DELETE"], - "object-family": ["request.permission!=BUCKET_DELETE", "request.permission!=OBJECT_DELETE"], - "buckets": ["request.permission!=BUCKET_DELETE"], - "objects": ["request.permission!=OBJECT_DELETE"], - "volume-family": ["request.permission!=VOLUME_BACKUP_DELETE", "request.permission!=VOLUME_DELETE", "request.permission!=BOOT_VOLUME_BACKUP_DELETE"], - "volumes": ["request.permission!=VOLUME_DELETE"], - "volume-backups": ["request.permission!=VOLUME_BACKUP_DELETE"], - "boot-volume-backups": ["request.permission!=BOOT_VOLUME_BACKUP_DELETE"]}} + "1.14": { + "all-resources": [ + "request.permission!=BUCKET_DELETE", "request.permission!=OBJECT_DELETE", "request.permission!=EXPORT_SET_DELETE", + "request.permission!=MOUNT_TARGET_DELETE", "request.permission!=FILE_SYSTEM_DELETE", "request.permission!=VOLUME_BACKUP_DELETE", + "request.permission!=VOLUME_DELETE", "request.permission!=FILE_SYSTEM_DELETE_SNAPSHOT" + ], + "file-family": [ + "request.permission!=EXPORT_SET_DELETE", "request.permission!=MOUNT_TARGET_DELETE", + "request.permission!=FILE_SYSTEM_DELETE", "request.permission!=FILE_SYSTEM_DELETE_SNAPSHOT" + ], + "file-systems": ["request.permission!=FILE_SYSTEM_DELETE", "request.permission!=FILE_SYSTEM_DELETE_SNAPSHOT"], + "mount-targets": ["request.permission!=MOUNT_TARGET_DELETE"], + "object-family": ["request.permission!=BUCKET_DELETE", "request.permission!=OBJECT_DELETE"], + "buckets": ["request.permission!=BUCKET_DELETE"], + "objects": ["request.permission!=OBJECT_DELETE"], + "volume-family": ["request.permission!=VOLUME_BACKUP_DELETE", "request.permission!=VOLUME_DELETE", "request.permission!=BOOT_VOLUME_BACKUP_DELETE"], + "volumes": ["request.permission!=VOLUME_DELETE"], + "volume-backups": ["request.permission!=VOLUME_BACKUP_DELETE"], + "boot-volume-backups": ["request.permission!=BOOT_VOLUME_BACKUP_DELETE"]}} # Tenancy Data self.__tenancy = None self.__cloud_guard_config = None self.__cloud_guard_config_status = None self.__os_namespace = None - + # For IAM Checks self.__tenancy_password_policy = None self.__compartments = [] @@ -644,13 +685,13 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print self.__network_security_groups = [] self.__network_security_lists = [] self.__network_subnets = [] - self.__network_fastconnects = {} # Indexed by DRG ID - self.__network_drgs = {} # Indexed by DRG ID + self.__network_fastconnects = {} # Indexed by DRG ID + self.__network_drgs = {} # Indexed by DRG ID self.__raw_network_drgs = [] - self.__network_cpes = [] - self.__network_ipsec_connections = {} # Indexed by DRG ID - self.__network_drg_attachments = {} # Indexed by DRG ID + self.__network_cpes = [] + self.__network_ipsec_connections = {} # Indexed by DRG ID + self.__network_drg_attachments = {} # Indexed by DRG ID # For Autonomous Database Checks self.__autonomous_databases = [] @@ -675,7 +716,6 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print # Cloud Guard checks self.__cloud_guard_targets = {} - # For Storage Checks self.__buckets = [] self.__boot_volumes = [] @@ -706,7 +746,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print # Start print time info show_version(verbose=True) - print("Starts at " + self.start_time_str) + print("\nStarts at " + self.start_time_str) self.__config = config self.__signer = signer @@ -725,13 +765,13 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print # If no regions are passed I will run them in all self.__regions_to_run_in = regions_to_run_in self.__run_in_all_regions = True - print("Regions to run in: " + ("all regions" if self.__run_in_all_regions else str(self.__regions_to_run_in))) + print("\nRegions to run in: " + ("all regions" if self.__run_in_all_regions else str(self.__regions_to_run_in))) - except Exception as e: + except Exception: raise RuntimeError("Invalid input regions must be comma separated with no : 'us-ashburn-1,us-phoenix-1'") try: - + self.__identity = oci.identity.IdentityClient( self.__config, signer=self.__signer) if proxy: @@ -744,8 +784,7 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print self.__tenancy.id).data except Exception as e: - raise RuntimeError("Failed to get identity information." + str(e.args)) - + raise RuntimeError("Failed to get identity information." + str(e.args)) try: self.__budget_client = oci.budget.BudgetClient( @@ -763,48 +802,48 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print if self.__home_region != self.__config['region']: print_header("It is recommended to run the CIS Complaince script in your home region") print_header("The current region is: " + self.__config['region']) - self.__regions[region.region_name] = { + + self.__regions[region.region_name] = { "is_home_region": region.is_home_region, "region_key": region.region_key, "region_name": region.region_name, "status": region.status, - "identity_client" : self.__identity, - "budget_client" : self.__budget_client + "identity_client": self.__identity, + "budget_client": self.__budget_client } - elif region.region_name in self.__regions_to_run_in or self.__run_in_all_regions: + elif region.region_name in self.__regions_to_run_in or self.__run_in_all_regions: self.__regions[region.region_name] = { "is_home_region": region.is_home_region, "region_key": region.region_key, "region_name": region.region_name, "status": region.status, - } + } record = { - "is_home_region": region.is_home_region, - "region_key": region.region_key, - "region_name": region.region_name, - "status": region.status, - } - self.__raw_regions.append(record) + "is_home_region": region.is_home_region, + "region_key": region.region_key, + "region_name": region.region_name, + "status": region.status, + } + self.__raw_regions.append(record) - # By Default it is today's date if report_directory: self.__report_directory = report_directory + "/" else: self.__report_directory = self.__tenancy.name + "-" + self.report_datetime - # Creating signers and config for all regions + # Creating signers and config for all regions self.__create_regional_signers(proxy) # Setting os_namespace based on home region try: - if not(self.__os_namespace): - self.__os_namespace =self.__regions[self.__home_region]['os_client'].get_namespace().data + if not (self.__os_namespace): + self.__os_namespace = self.__regions[self.__home_region]['os_client'].get_namespace().data except Exception as e: raise RuntimeError( "Failed to get tenancy namespace." + str(e.args)) - + # Determining if a need a object storage client for output self.__output_bucket = output_bucket if self.__output_bucket: @@ -819,7 +858,6 @@ def __init__(self, config, signer, proxy, output_bucket, report_directory, print # Determining if CSV report OCIDs will be redacted self.__redact_output = redact_output - ########################################################################## # Create regional config, signers adds appends them to self.__regions object ########################################################################## @@ -832,103 +870,86 @@ def __create_regional_signers(self, proxy): region_config = self.__config region_config['region'] = region_key - try: - identity = oci.identity.IdentityClient( - region_config, signer=region_signer) + identity = oci.identity.IdentityClient(region_config, signer=region_signer) if proxy: identity.base_client.session.proxies = {'https': proxy} - region_values['identity_client'] = identity + region_values['identity_client'] = identity - audit = oci.audit.AuditClient( - region_config, signer=region_signer) + audit = oci.audit.AuditClient(region_config, signer=region_signer) if proxy: audit.base_client.session.proxies = {'https': proxy} - region_values['audit_client'] = audit - - cloud_guard = oci.cloud_guard.CloudGuardClient( - region_config, signer=region_signer) + region_values['audit_client'] = audit + + cloud_guard = oci.cloud_guard.CloudGuardClient(region_config, signer=region_signer) if proxy: cloud_guard.base_client.session.proxies = {'https': proxy} - region_values['cloud_guard_client'] = cloud_guard - - search = oci.resource_search.ResourceSearchClient( - region_config, signer=region_signer) + region_values['cloud_guard_client'] = cloud_guard + + search = oci.resource_search.ResourceSearchClient(region_config, signer=region_signer) if proxy: search.base_client.session.proxies = {'https': proxy} region_values['search_client'] = search - network = oci.core.VirtualNetworkClient( - region_config, signer=region_signer) + network = oci.core.VirtualNetworkClient(region_config, signer=region_signer) if proxy: network.base_client.session.proxies = {'https': proxy} region_values['network_client'] = network - events = oci.events.EventsClient( - region_config, signer=region_signer) + events = oci.events.EventsClient(region_config, signer=region_signer) if proxy: events.base_client.session.proxies = {'https': proxy} region_values['events_client'] = events - logging = oci.logging.LoggingManagementClient( - region_config, signer=region_signer) + logging = oci.logging.LoggingManagementClient(region_config, signer=region_signer) if proxy: logging.base_client.session.proxies = {'https': proxy} region_values['logging_client'] = logging - os_client = oci.object_storage.ObjectStorageClient( - region_config, signer=region_signer) + os_client = oci.object_storage.ObjectStorageClient(region_config, signer=region_signer) if proxy: os_client.base_client.session.proxies = {'https': proxy} region_values['os_client'] = os_client - vault = oci.key_management.KmsVaultClient( - region_config, signer=region_signer) + vault = oci.key_management.KmsVaultClient(region_config, signer=region_signer) if proxy: vault.session.proxies = {'https': proxy} region_values['vault_client'] = vault - ons_subs = oci.ons.NotificationDataPlaneClient( - region_config, signer=region_signer) + ons_subs = oci.ons.NotificationDataPlaneClient(region_config, signer=region_signer) if proxy: ons_subs.session.proxies = {'https': proxy} region_values['ons_subs_client'] = ons_subs - adb = oci.database.DatabaseClient( - region_config, signer=region_signer) + adb = oci.database.DatabaseClient(region_config, signer=region_signer) if proxy: adb.base_client.session.proxies = {'https': proxy} region_values['adb_client'] = adb - oac = oci.analytics.AnalyticsClient( - region_config, signer=region_signer) + oac = oci.analytics.AnalyticsClient(region_config, signer=region_signer) if proxy: oac.base_client.session.proxies = {'https': proxy} region_values['oac_client'] = oac - oic = oci.integration.IntegrationInstanceClient( - region_config, signer=region_signer) + oic = oci.integration.IntegrationInstanceClient(region_config, signer=region_signer) if proxy: oic.base_client.session.proxies = {'https': proxy} region_values['oic_client'] = oic - bv = oci.core.BlockstorageClient( - region_config, signer=region_signer) + bv = oci.core.BlockstorageClient(region_config, signer=region_signer) if proxy: bv.base_client.session.proxies = {'https': proxy} region_values['bv_client'] = bv - fss = oci.file_storage.FileStorageClient( - region_config, signer=region_signer) + fss = oci.file_storage.FileStorageClient(region_config, signer=region_signer) if proxy: fss.base_client.session.proxies = {'https': proxy} region_values['fss_client'] = fss - sch = oci.sch.ServiceConnectorClient( - region_config, signer=region_signer) + sch = oci.sch.ServiceConnectorClient(region_config, signer=region_signer) if proxy: sch.base_client.session.proxies = {'https': proxy} - region_values['sch_client'] = sch + region_values['sch_client'] = sch except Exception as e: raise RuntimeError("Failed to create regional clients for data collection: " + str(e)) @@ -937,7 +958,7 @@ def __create_regional_signers(self, proxy): # Check for Managed PaaS Compartment ########################################################################## def __if_not_managed_paas_compartment(self, name): - return name != "ManagedCompartmentForPaaS" + return name != "ManagedCompartmentForPaaS" ########################################################################## # Set ManagementCompartment ID @@ -952,20 +973,21 @@ def __set_managed_paas_compartment(self): # Load compartments ########################################################################## def __identity_read_compartments(self): - print("Processing Compartments...") + print("\nProcessing Compartments...") try: self.__compartments = oci.pagination.list_call_get_all_results( self.__regions[self.__home_region]['identity_client'].list_compartments, - compartment_id = self.__tenancy.id, + compartment_id=self.__tenancy.id, compartment_id_in_subtree=True, - lifecycle_state = "ACTIVE" + lifecycle_state="ACTIVE" ).data + # Need to convert for raw output for compartment in self.__compartments: deep_link = self.__oci_compartment_uri + compartment.id record = { 'id': compartment.id, - 'name' : compartment.name, + 'name': compartment.name, "deep_link": self.__generate_csv_hyperlink(deep_link, compartment.name), 'compartment_id': compartment.compartment_id, 'defined_tags': compartment.defined_tags, @@ -975,17 +997,17 @@ def __identity_read_compartments(self): "is_accessible": compartment.is_accessible, "lifecycle_state": compartment.lifecycle_state, "time_created": compartment.time_created.strftime(self.__iso_time_format), - "region" : "" - } + "region": "" + } self.__raw_compartment.append(record) self.cis_foundations_benchmark_1_2['5.1']['Total'].append(compartment) - + # Add root compartment which is not part of the list_compartments self.__compartments.append(self.__tenancy) deep_link = self.__oci_compartment_uri + compartment.id root_compartment = { - "id" : self.__tenancy.id, - "name" : self.__tenancy.name, + "id": self.__tenancy.id, + "name": self.__tenancy.name, "deep_link": self.__generate_csv_hyperlink(deep_link, self.__tenancy.name), "compartment_id": "(root)", "defined_tags": self.__tenancy.defined_tags, @@ -995,14 +1017,14 @@ def __identity_read_compartments(self): "is_accessible": "", "lifecycle_state": "", "time_created": "", - "region" : "" + "region": "" } self.__raw_compartment.append(root_compartment) self.__set_managed_paas_compartment() - print("\tProcessed " + str(len(self.__compartments)) + " Compartments") + print("\tProcessed " + str(len(self.__compartments)) + " Compartments") return self.__compartments except Exception as e: @@ -1017,15 +1039,15 @@ def __identity_read_groups_and_membership(self): # Getting all Groups in the Tenancy groups_data = oci.pagination.list_call_get_all_results( self.__regions[self.__home_region]['identity_client'].list_groups, - compartment_id = self.__tenancy.id + compartment_id=self.__tenancy.id ).data # For each group in the tenacy getting the group's membership for grp in groups_data: membership = oci.pagination.list_call_get_all_results( self.__regions[self.__home_region]['identity_client'].list_user_group_memberships, - compartment_id = self.__tenancy.id, - group_id=grp.id - ).data + compartment_id=self.__tenancy.id, + group_id=grp.id).data + for member in membership: grp_deep_link = self.__oci_groups_uri + grp.id user_deep_link = self.__oci_users_uri + member.user_id @@ -1037,7 +1059,7 @@ def __identity_read_groups_and_membership(self): "lifecycle_state": grp.lifecycle_state, "time_created": grp.time_created.strftime(self.__iso_time_format), "user_id": member.user_id, - "user_id_link": self.__generate_csv_hyperlink(user_deep_link,member.user_id) + "user_id_link": self.__generate_csv_hyperlink(user_deep_link, member.user_id) } # Adding a record per user to group self.__groups_to_users.append(group_record) @@ -1054,8 +1076,9 @@ def __identity_read_users(self): # Getting all users in the Tenancy users_data = oci.pagination.list_call_get_all_results( self.__regions[self.__home_region]['identity_client'].list_users, - compartment_id = self.__tenancy.id + compartment_id=self.__tenancy.id ).data + # Adding record to the users for user in users_data: deep_link = self.__oci_users_uri + user.id @@ -1108,7 +1131,7 @@ def __identity_read_user_api_key(self, user_ocid): try: user_api_keys_data = oci.pagination.list_call_get_all_results( self.__regions[self.__home_region]['identity_client'].list_api_keys, - user_id = user_ocid + user_id=user_ocid ).data for api_key in user_api_keys_data: @@ -1137,7 +1160,7 @@ def __identity_read_user_auth_token(self, user_ocid): try: auth_tokens_data = oci.pagination.list_call_get_all_results( self.__regions[self.__home_region]['identity_client'].list_auth_tokens, - user_id = user_ocid + user_id=user_ocid ).data for token in auth_tokens_data: @@ -1162,7 +1185,6 @@ def __identity_read_user_auth_token(self, user_ocid): raise RuntimeError( "Error in identity_read_user_auth_token: " + str(e.args)) - ########################################################################## # Load user customer secret key ########################################################################## @@ -1171,7 +1193,7 @@ def __identity_read_user_customer_secret_key(self, user_ocid): try: customer_secret_key_data = oci.pagination.list_call_get_all_results( self.__regions[self.__home_region]['identity_client'].list_customer_secret_keys, - user_id = user_ocid + user_id=user_ocid ).data for key in customer_secret_key_data: @@ -1200,10 +1222,10 @@ def __identity_read_user_customer_secret_key(self, user_ocid): def __identity_read_tenancy_policies(self): try: policies_data = oci.pagination.list_call_get_all_results( - self.__regions[self.__home_region]['search_client'].search_resources, + self.__regions[self.__home_region]['search_client'].search_resources, search_details=oci.resource_search.models.StructuredSearchDetails( - query="query Policy resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") - ).data + query="query Policy resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") + ).data for policy in policies_data: deep_link = self.__oci_policies_uri + policy.identifier @@ -1216,10 +1238,10 @@ def __identity_read_tenancy_policies(self): "lifecycle_state": policy.lifecycle_state, "statements": policy.additional_details['statements'] } - self.__policies.append(record) - print("\tProcessed " + str(len(self.__policies)) + " IAM Policies") + self.__policies.append(record) + print("\tProcessed " + str(len(self.__policies)) + " IAM Policies") return self.__policies - + except Exception as e: raise RuntimeError("Error in __identity_read_tenancy_policies: " + str(e.args)) @@ -1230,8 +1252,7 @@ def __identity_read_dynamic_groups(self): try: dynamic_groups_data = oci.pagination.list_call_get_all_results( self.__regions[self.__home_region]['identity_client'].list_dynamic_groups, - compartment_id = self.__tenancy.id - ).data + compartment_id=self.__tenancy.id).data for dynamic_group in dynamic_groups_data: deep_link = self.__oci_dynamic_groups_uri + dynamic_group.id # try: @@ -1265,13 +1286,13 @@ def __identity_read_dynamic_groups(self): # "notes": str(e) # } self.__dynamic_groups.append(record) - - print("\tProcessed " + str(len(self.__dynamic_groups)) + " Dynamic Groups") + + print("\tProcessed " + str(len(self.__dynamic_groups)) + " Dynamic Groups") return self.__dynamic_groups except Exception as e: raise RuntimeError("Error in __identity_read_dynamic_groups: " + str(e.args)) pass - + ############################################ # Load Availlability Domains ############################################ @@ -1280,39 +1301,38 @@ def __identity_read_availability_domains(self): for region_key, region_values in self.__regions.items(): region_values['availability_domains'] = oci.pagination.list_call_get_all_results( region_values['identity_client'].list_availability_domains, - compartment_id = self.__tenancy.id + compartment_id=self.__tenancy.id ).data - print("\tProcessed " + str(len(region_values['availability_domains'])) + " Availability Domains in " + region_key) + print("\tProcessed " + str(len(region_values['availability_domains'])) + " Availability Domains in " + region_key) except Exception as e: raise RuntimeError( "Error in __identity_read_availability_domains: " + str(e.args)) - + ########################################################################## # Get Objects Store Buckets ########################################################################## def __os_read_buckets(self): - - # Getting OS Namespace + + # Getting OS Namespace try: # looping through regions for region_key, region_values in self.__regions.items(): buckets_data = oci.pagination.list_call_get_all_results( - region_values['search_client'].search_resources, + region_values['search_client'].search_resources, search_details=oci.resource_search.models.StructuredSearchDetails( - query="query Bucket resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") - ).data + query="query Bucket resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") + ).data # Getting Bucket Info for bucket in buckets_data: try: bucket_info = region_values['os_client'].get_bucket( bucket.additional_details['namespace'], bucket.display_name).data - deep_link = self.__oci_buckets_uri + bucket_info.namespace + \ - "/" + bucket_info.name + "/objects?region=" + region_key + deep_link = self.__oci_buckets_uri + bucket_info.namespace + "/" + bucket_info.name + "/objects?region=" + region_key record = { "id": bucket_info.id, "name": bucket_info.name, - "deep_link": self.__generate_csv_hyperlink(deep_link, bucket_info.name), + "deep_link": self.__generate_csv_hyperlink(deep_link, bucket_info.name), "kms_key_id": bucket_info.kms_key_id, "namespace": bucket_info.namespace, "compartment_id": bucket_info.compartment_id, @@ -1323,16 +1343,16 @@ def __os_read_buckets(self): "storage_tier": bucket_info.storage_tier, "time_created": bucket_info.time_created.strftime(self.__iso_time_format), "versioning": bucket_info.versioning, - "defined_tags" : bucket_info.defined_tags, - "freeform_tags" : bucket_info.freeform_tags, - "region" : region_key, + "defined_tags": bucket_info.defined_tags, + "freeform_tags": bucket_info.freeform_tags, + "region": region_key, "notes": "" } self.__buckets.append(record) except Exception as e: record = { "id": "", - "name": bucket.display_name, + "name": bucket.display_name, "deep_link": "", "kms_key_id": "", "namespace": bucket.additional_details['namespace'], @@ -1344,14 +1364,14 @@ def __os_read_buckets(self): "storage_tier": "", "time_created": bucket.time_created.strftime(self.__iso_time_format), "versioning": "", - "defined_tags" : bucket.defined_tags, - "freeform_tags" : "", - "region" : region_key, + "defined_tags": bucket.defined_tags, + "freeform_tags": "", + "region": region_key, "notes": str(e) } self.__buckets.append(record) # Returning Buckets - print("\tProcessed " + str(len(self.__buckets)) + " Buckets") + print("\tProcessed " + str(len(self.__buckets)) + " Buckets") return self.__buckets except Exception as e: raise RuntimeError("Error in __os_read_buckets " + str(e.args)) @@ -1363,10 +1383,10 @@ def __block_volume_read_block_volumes(self): try: for region_key, region_values in self.__regions.items(): volumes_data = oci.pagination.list_call_get_all_results( - region_values['search_client'].search_resources, + region_values['search_client'].search_resources, search_details=oci.resource_search.models.StructuredSearchDetails( - query="query Volume resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") - ).data + query="query Volume resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") + ).data # Getting Block Volume inf for volume in volumes_data: @@ -1381,19 +1401,19 @@ def __block_volume_read_block_volumes(self): "compartment_id": volume.compartment_id, "size_in_gbs": volume.additional_details['sizeInGBs'], "size_in_mbs": volume.additional_details['sizeInMBs'], - #"source_details": volume.source_details, + # "source_details": volume.source_details, "time_created": volume.time_created.strftime(self.__iso_time_format), - #"volume_group_id": volume.volume_group_id, - #"vpus_per_gb": volume.vpus_per_gb, - #"auto_tuned_vpus_per_gb": volume.auto_tuned_vpus_per_gb, - "availability_domain" : volume.availability_domain, - #"block_volume_replicas": volume.block_volume_replicas, - #"is_auto_tune_enabled": volume.is_auto_tune_enabled, - #"is_hydrated": volume.is_hydrated, + # "volume_group_id": volume.volume_group_id, + # "vpus_per_gb": volume.vpus_per_gb, + # "auto_tuned_vpus_per_gb": volume.auto_tuned_vpus_per_gb, + "availability_domain": volume.availability_domain, + # "block_volume_replicas": volume.block_volume_replicas, + # "is_auto_tune_enabled": volume.is_auto_tune_enabled, + # "is_hydrated": volume.is_hydrated, "defined_tags": volume.defined_tags, "freeform_tags": volume.freeform_tags, "system_tags": volume.system_tags, - "region" : region_key, + "region": region_key, "notes": "" } except Exception as e: @@ -1406,26 +1426,26 @@ def __block_volume_read_block_volumes(self): "compartment_id": "", "size_in_gbs": "", "size_in_mbs": "", - #"source_details": "", - "time_created":"", - #"volume_group_id": "", - #"vpus_per_gb": "", - #"auto_tuned_vpus_per_gb": "", - "availability_domain" : "", - #"block_volume_replicas": "", - #"is_auto_tune_enabled": "", - #"is_hydrated": "", + # "source_details": "", + "time_created": "", + # "volume_group_id": "", + # "vpus_per_gb": "", + # "auto_tuned_vpus_per_gb": "", + "availability_domain": "", + # "block_volume_replicas": "", + # "is_auto_tune_enabled": "", + # "is_hydrated": "", "defined_tags": "", "freeform_tags": "", "system_tags": "", - "region" : region_key, + "region": region_key, "notes": str(e) - } + } self.__block_volumes.append(record) print("\tProcessed " + str(len(self.__block_volumes)) + " Block Volumes") return self.__block_volumes except Exception as e: - raise RuntimeError("Error in __block_volume_read_block_volumes " + str(e.args)) + raise RuntimeError("Error in __block_volume_read_block_volumes " + str(e.args)) ############################################ # Load Boot Volumes @@ -1434,10 +1454,10 @@ def __boot_volume_read_boot_volumes(self): try: for region_key, region_values in self.__regions.items(): boot_volumes_data = oci.pagination.list_call_get_all_results( - region_values['search_client'].search_resources, - search_details=oci.resource_search.models.StructuredSearchDetails( + region_values['search_client'].search_resources, + search_details=oci.resource_search.models.StructuredSearchDetails( query="query BootVolume resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") - ).data + ).data for boot_volume in boot_volumes_data: deep_link = self.__oci_boot_volumes_uri + boot_volume.identifier + '?region=' + region_key @@ -1446,7 +1466,7 @@ def __boot_volume_read_boot_volumes(self): "id": boot_volume.identifier, "display_name": boot_volume.display_name, "deep_link": self.__generate_csv_hyperlink(deep_link, boot_volume.display_name), - #"image_id": boot_volume.image_id, + # "image_id": boot_volume.image_id, "kms_key_id": boot_volume.additional_details['kmsKeyId'], "lifecycle_state": boot_volume.lifecycle_state, "size_in_gbs": boot_volume.additional_details['sizeInGBs'], @@ -1454,16 +1474,16 @@ def __boot_volume_read_boot_volumes(self): "availability_domain": boot_volume.availability_domain, "time_created": boot_volume.time_created.strftime(self.__iso_time_format), "compartment_id": boot_volume.compartment_id, - #"auto_tuned_vpus_per_gb": boot_volume.auto_tuned_vpus_per_gb, - #"boot_volume_replicas": boot_volume.boot_volume_replicas, - #"is_auto_tune_enabled": boot_volume.is_auto_tune_enabled, - #"is_hydrated": boot_volume.is_hydrated, - #"source_details": boot_volume.source_details, - #"vpus_per_gb": boot_volume.vpus_per_gb, + # "auto_tuned_vpus_per_gb": boot_volume.auto_tuned_vpus_per_gb, + # "boot_volume_replicas": boot_volume.boot_volume_replicas, + # "is_auto_tune_enabled": boot_volume.is_auto_tune_enabled, + # "is_hydrated": boot_volume.is_hydrated, + # "source_details": boot_volume.source_details, + # "vpus_per_gb": boot_volume.vpus_per_gb, "system_tags": boot_volume.system_tags, "defined_tags": boot_volume.defined_tags, "freeform_tags": boot_volume.freeform_tags, - "region" : region_key, + "region": region_key, "notes": "" } except Exception as e: @@ -1471,7 +1491,7 @@ def __boot_volume_read_boot_volumes(self): "id": boot_volume.identifier, "display_name": boot_volume.display_name, "deep_link": self.__generate_csv_hyperlink(deep_link, boot_volume.display_name), - #"image_id": "", + # "image_id": "", "kms_key_id": "", "lifecycle_state": "", "size_in_gbs": "", @@ -1479,23 +1499,23 @@ def __boot_volume_read_boot_volumes(self): "availability_domain": "", "time_created": "", "compartment_id": "", - #"auto_tuned_vpus_per_gb": "", - #"boot_volume_replicas": "", - #"is_auto_tune_enabled": "", - #"is_hydrated": "", - #"source_details": "", - #"vpus_per_gb": "", + # "auto_tuned_vpus_per_gb": "", + # "boot_volume_replicas": "", + # "is_auto_tune_enabled": "", + # "is_hydrated": "", + # "source_details": "", + # "vpus_per_gb": "", "system_tags": "", "defined_tags": "", "freeform_tags": "", - "region" : region_key, + "region": region_key, "notes": str(e) } self.__boot_volumes.append(record) print("\tProcessed " + str(len(self.__boot_volumes)) + " Boot Volumes") - return(self.__boot_volumes) + return (self.__boot_volumes) except Exception as e: - raise RuntimeError("Error in __boot_volume_read_boot_volumes " + str(e.args)) + raise RuntimeError("Error in __boot_volume_read_boot_volumes " + str(e.args)) ############################################ # Load FSS @@ -1504,10 +1524,10 @@ def __fss_read_fsss(self): try: for region_key, region_values in self.__regions.items(): fss_data = oci.pagination.list_call_get_all_results( - region_values['search_client'].search_resources, - search_details=oci.resource_search.models.StructuredSearchDetails( + region_values['search_client'].search_resources, + search_details=oci.resource_search.models.StructuredSearchDetails( query="query FileSystem resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") - ).data + ).data for fss in fss_data: deep_link = self.__oci_fss_uri + fss.identifier + '?region=' + region_key @@ -1518,17 +1538,17 @@ def __fss_read_fsss(self): "deep_link": self.__generate_csv_hyperlink(deep_link, fss.display_name), "kms_key_id": fss.additional_details['kmsKeyId'], "lifecycle_state": fss.lifecycle_state, - #"lifecycle_details": fss.lifecycle_details, + # "lifecycle_details": fss.lifecycle_details, "availability_domain": fss.availability_domain, "time_created": fss.time_created.strftime(self.__iso_time_format), "compartment_id": fss.compartment_id, - #"is_clone_parent": fss.is_clone_parent, - #"is_hydrated": fss.is_hydrated, - #"metered_bytes": fss.metered_bytes, + # "is_clone_parent": fss.is_clone_parent, + # "is_hydrated": fss.is_hydrated, + # "metered_bytes": fss.metered_bytes, "source_details": fss.additional_details['sourceDetails'], "defined_tags": fss.defined_tags, "freeform_tags": fss.freeform_tags, - "region" : region_key, + "region": region_key, "notes": "" } except Exception as e: @@ -1538,25 +1558,24 @@ def __fss_read_fsss(self): "deep_link": self.__generate_csv_hyperlink(deep_link, fss.display_name), "kms_key_id": "", "lifecycle_state": "", - #"lifecycle_details": "", + # "lifecycle_details": "", "availability_domain": "", "time_created": "", "compartment_id": "", - #"is_clone_parent": "", - #"is_hydrated": "", - #"metered_bytes": "", + # "is_clone_parent": "", + # "is_hydrated": "", + # "metered_bytes": "", "source_details": "", "defined_tags": "", "freeform_tags": "", - "region" : region_key, + "region": region_key, "notes": str(e) } self.__file_storage_system.append(record) print("\tProcessed " + str(len(self.__file_storage_system)) + " File Storage service") - return(self.__file_storage_system) + return (self.__file_storage_system) except Exception as e: - raise RuntimeError("Error in __fss_read_fsss " + str(e.args)) - + raise RuntimeError("Error in __fss_read_fsss " + str(e.args)) ########################################################################## # Network Security Groups @@ -1567,15 +1586,14 @@ def __network_read_network_security_groups_rules(self): try: for region_key, region_values in self.__regions.items(): nsgs_data = oci.pagination.list_call_get_all_results( - region_values['search_client'].search_resources, + region_values['search_client'].search_resources, search_details=oci.resource_search.models.StructuredSearchDetails( - query="query NetworkSecurityGroup resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") - ).data - + query="query NetworkSecurityGroup resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") + ).data + # Looping through NSGs to to get for nsg in nsgs_data: - deep_link = self.__oci_networking_uri + nsg.additional_details['vcnId'] + \ - "/network-security-groups/" + nsg.identifier + '?region=' + region_key + deep_link = self.__oci_networking_uri + nsg.additional_details['vcnId'] + "/network-security-groups/" + nsg.identifier + '?region=' + region_key record = { "id": nsg.identifier, "compartment_id": nsg.compartment_id, @@ -1584,20 +1602,19 @@ def __network_read_network_security_groups_rules(self): "lifecycle_state": nsg.lifecycle_state, "time_created": nsg.time_created.strftime(self.__iso_time_format), "vcn_id": nsg.additional_details['vcnId'], - "freeform_tags" : nsg.freeform_tags, - "defined_tags" : nsg.defined_tags, - "region" : region_key, + "freeform_tags": nsg.freeform_tags, + "defined_tags": nsg.defined_tags, + "region": region_key, "rules": [] } nsg_rules = oci.pagination.list_call_get_all_results( region_values['network_client'].list_network_security_group_security_rules, - network_security_group_id = nsg.identifier + network_security_group_id=nsg.identifier ).data for rule in nsg_rules: - deep_link = self.__oci_networking_uri + nsg.additional_details['vcnId'] + \ - "/network-security-groups/" + nsg.identifier + "/nsg-rules" + '?region=' + region_key + deep_link = self.__oci_networking_uri + nsg.additional_details['vcnId'] + "/network-security-groups/" + nsg.identifier + "/nsg-rules" + '?region=' + region_key rule_record = { "id": rule.id, "deep_link": self.__generate_csv_hyperlink(deep_link, rule.id), @@ -1632,62 +1649,62 @@ def __network_read_network_security_lists(self): # Looping Through Compartments Except Managed try: for region_key, region_values in self.__regions.items(): - security_lists_data = oci.pagination.list_call_get_all_results( - region_values['search_client'].search_resources, - search_details=oci.resource_search.models.StructuredSearchDetails( - query="query SecurityList resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") - ).data + security_lists_data = oci.pagination.list_call_get_all_results( + region_values['search_client'].search_resources, + search_details=oci.resource_search.models.StructuredSearchDetails( + query="query SecurityList resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") + ).data - # Looping through Security Lists to to get - for security_list in security_lists_data: - deep_link = self.__oci_networking_uri + security_list.additional_details['vcnId'] + \ - "/security-lists/" + security_list.identifier + '?region=' + region_key - record = { - "id": security_list.identifier, - "compartment_id": security_list.compartment_id, - "display_name": security_list.display_name, - "deep_link": self.__generate_csv_hyperlink(deep_link, security_list.display_name), - "lifecycle_state": security_list.lifecycle_state, - "time_created": security_list.time_created.strftime(self.__iso_time_format), - "vcn_id": security_list.additional_details['vcnId'], - "region" : region_key, - "freeform_tags" : security_list.freeform_tags, - "defined_tags" : security_list.defined_tags, - "ingress_security_rules": [], - "egress_security_rules": [] + # Looping through Security Lists to to get + for security_list in security_lists_data: + deep_link = self.__oci_networking_uri + security_list.additional_details['vcnId'] + \ + "/security-lists/" + security_list.identifier + '?region=' + region_key + record = { + "id": security_list.identifier, + "compartment_id": security_list.compartment_id, + "display_name": security_list.display_name, + "deep_link": self.__generate_csv_hyperlink(deep_link, security_list.display_name), + "lifecycle_state": security_list.lifecycle_state, + "time_created": security_list.time_created.strftime(self.__iso_time_format), + "vcn_id": security_list.additional_details['vcnId'], + "region": region_key, + "freeform_tags": security_list.freeform_tags, + "defined_tags": security_list.defined_tags, + "ingress_security_rules": [], + "egress_security_rules": [] + } + + if security_list.additional_details['egressSecurityRules'] is not None: + for i in range(len(security_list.additional_details['egressSecurityRules'])): + erule = { + # "description": egress_rule.description, + "destination": security_list.additional_details['egressSecurityRules'][i]['destination'], + # "destination_type": egress_rule.destination_type, + "icmp_options": security_list.additional_details['egressSecurityRules'][i]['icmpOptions'], + "is_stateless": security_list.additional_details['egressSecurityRules'][i]['isStateless'], + "protocol": security_list.additional_details['egressSecurityRules'][i]['protocol'], + "tcp_options": security_list.additional_details['egressSecurityRules'][i]['tcpOptions'], + "udp_options": security_list.additional_details['egressSecurityRules'][i]['udpOptions'] + } + record['egress_security_rules'].append(erule) + if security_list.additional_details['ingressSecurityRules'] is not None: + for i in range(len(security_list.additional_details['ingressSecurityRules'])): + irule = { + # "description": ingress_rule.description, + "source": security_list.additional_details['ingressSecurityRules'][i]['source'], + # "source_type": ingress_rule.source_type, + "icmp_options": security_list.additional_details['ingressSecurityRules'][i]['icmpOptions'], + "is_stateless": security_list.additional_details['ingressSecurityRules'][i]['isStateless'], + "protocol": security_list.additional_details['ingressSecurityRules'][i]['protocol'], + "tcp_options": security_list.additional_details['ingressSecurityRules'][i]['tcpOptions'], + "udp_options": security_list.additional_details['ingressSecurityRules'][i]['udpOptions'] } + record['ingress_security_rules'].append(irule) + + # Append Security List to list of NSGs + self.__network_security_lists.append(record) - if security_list.additional_details['egressSecurityRules'] is not None: - for i in range(len(security_list.additional_details['egressSecurityRules'])): - erule = { - #"description": egress_rule.description, - "destination": security_list.additional_details['egressSecurityRules'][i]['destination'], - #"destination_type": egress_rule.destination_type, - "icmp_options": security_list.additional_details['egressSecurityRules'][i]['icmpOptions'], - "is_stateless": security_list.additional_details['egressSecurityRules'][i]['isStateless'], - "protocol": security_list.additional_details['egressSecurityRules'][i]['protocol'], - "tcp_options": security_list.additional_details['egressSecurityRules'][i]['tcpOptions'], - "udp_options": security_list.additional_details['egressSecurityRules'][i]['udpOptions'] - } - record['egress_security_rules'].append(erule) - if security_list.additional_details['ingressSecurityRules'] is not None: - for i in range(len(security_list.additional_details['ingressSecurityRules'])): - irule = { - #"description": ingress_rule.description, - "source": security_list.additional_details['ingressSecurityRules'][i]['source'], - #"source_type": ingress_rule.source_type, - "icmp_options": security_list.additional_details['ingressSecurityRules'][i]['icmpOptions'], - "is_stateless": security_list.additional_details['ingressSecurityRules'][i]['isStateless'], - "protocol": security_list.additional_details['ingressSecurityRules'][i]['protocol'], - "tcp_options": security_list.additional_details['ingressSecurityRules'][i]['tcpOptions'], - "udp_options": security_list.additional_details['ingressSecurityRules'][i]['udpOptions'] - } - record['ingress_security_rules'].append(irule) - - # Append Security List to list of NSGs - self.__network_security_lists.append(record) - - print("\tProcessed " + str(len(self.__network_security_lists)) + " Security Lists") + print("\tProcessed " + str(len(self.__network_security_lists)) + " Security Lists") return self.__network_security_lists except Exception as e: raise RuntimeError( @@ -1700,15 +1717,14 @@ def __network_read_network_subnets(self): try: for region_key, region_values in self.__regions.items(): subnets_data = oci.pagination.list_call_get_all_results( - region_values['search_client'].search_resources, + region_values['search_client'].search_resources, search_details=oci.resource_search.models.StructuredSearchDetails( - query="query Subnet resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") + query="query Subnet resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") ).data try: for subnet in subnets_data: - deep_link = self.__oci_networking_uri + subnet.additional_details['vcnId'] + \ - "/subnets/" + subnet.identifier + '?region=' + region_key + deep_link = self.__oci_networking_uri + subnet.additional_details['vcnId'] + "/subnets/" + subnet.identifier + '?region=' + region_key record = { "id": subnet.identifier, "availability_domain": subnet.availability_domain, @@ -1729,17 +1745,16 @@ def __network_read_network_subnets(self): "vcn_id": subnet.additional_details['vcnId'], "virtual_router_ip": subnet.additional_details['virtualRouterIp'], "virtual_router_mac": subnet.additional_details['virtualRouterMac'], - "freeform_tags" : subnet.freeform_tags, - "define_tags" : subnet.defined_tags, - "region" : region_key, - "notes":"" + "freeform_tags": subnet.freeform_tags, + "define_tags": subnet.defined_tags, + "region": region_key, + "notes": "" } # Adding subnet to subnet list self.__network_subnets.append(record) except Exception as e: - deep_link = self.__oci_networking_uri + subnet.additional_details['vcnId'] + \ - "/subnet/" + subnet.identifier + '?region=' + region_key + deep_link = self.__oci_networking_uri + subnet.additional_details['vcnId'] + "/subnet/" + subnet.identifier + '?region=' + region_key record = { "id": subnet.identifier, "availability_domain": subnet.availability_domain, @@ -1760,20 +1775,18 @@ def __network_read_network_subnets(self): "vcn_id": subnet.additional_details['vcnId'], "virtual_router_ip": subnet.additional_details['virtualRouterIp'], "virtual_router_mac": subnet.additional_details['virtualRouterMac'], - "region" : region_key, + "region": region_key, "notes": str(e) } self.__network_subnets.append(record) - print("\tProcessed " + str(len(self.__network_subnets)) + " Network Subnets") - + print("\tProcessed " + str(len(self.__network_subnets)) + " Network Subnets") return self.__network_subnets except Exception as e: raise RuntimeError( "Error in __network_read_network_subnets " + str(e.args)) - ########################################################################## # Load DRG Attachments ########################################################################## @@ -1783,16 +1796,16 @@ def __network_read_drg_attachments(self): for region_key, region_values in self.__regions.items(): # Looping through compartments in tenancy drg_resources = oci.pagination.list_call_get_all_results( - region_values['search_client'].search_resources, + region_values['search_client'].search_resources, search_details=oci.resource_search.models.StructuredSearchDetails( - query="query DrgAttachment resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") + query="query DrgAttachment resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") ).data compartments = set() for drg in drg_resources: compartments.add(drg.compartment_id) - + for compartment in compartments: drg_attachment_data = oci.pagination.list_call_get_all_results( region_values['network_client'].list_drg_attachments, @@ -1806,73 +1819,71 @@ def __network_read_drg_attachments(self): deep_link = self.__oci_drg_uri + drg_attachment.drg_id + "/drg-attachment/" + drg_attachment.id + '?region=' + region_key try: record = { - "id": drg_attachment.id, - "display_name" : drg_attachment.display_name, - "deep_link": self.__generate_csv_hyperlink(deep_link, drg_attachment.display_name), - "drg_id" : drg_attachment.drg_id, - "vcn_id" : drg_attachment.vcn_id, - "drg_route_table_id" : str(drg_attachment.drg_route_table_id), - "export_drg_route_distribution_id" : str(drg_attachment.export_drg_route_distribution_id), - "is_cross_tenancy" : drg_attachment.is_cross_tenancy, - "lifecycle_state" : drg_attachment.lifecycle_state, - "network_details" : drg_attachment.network_details, - "network_id" : drg_attachment.network_details.id, - "network_type" : drg_attachment.network_details.type, - "freeform_tags" : drg_attachment.freeform_tags, - "define_tags" : drg_attachment.defined_tags, - "time_created" : drg_attachment.time_created.strftime(self.__iso_time_format), - "region" : region_key, - "notes":"" - - } - except: + "id": drg_attachment.id, + "display_name": drg_attachment.display_name, + "deep_link": self.__generate_csv_hyperlink(deep_link, drg_attachment.display_name), + "drg_id": drg_attachment.drg_id, + "vcn_id": drg_attachment.vcn_id, + "drg_route_table_id": str(drg_attachment.drg_route_table_id), + "export_drg_route_distribution_id": str(drg_attachment.export_drg_route_distribution_id), + "is_cross_tenancy": drg_attachment.is_cross_tenancy, + "lifecycle_state": drg_attachment.lifecycle_state, + "network_details": drg_attachment.network_details, + "network_id": drg_attachment.network_details.id, + "network_type": drg_attachment.network_details.type, + "freeform_tags": drg_attachment.freeform_tags, + "define_tags": drg_attachment.defined_tags, + "time_created": drg_attachment.time_created.strftime(self.__iso_time_format), + "region": region_key, + "notes": "" + } + except Exception: record = { - "id": drg_attachment.id, - "display_name" : drg_attachment.display_name, - "deep_link": self.__generate_csv_hyperlink(deep_link, drg_attachment.display_name), - "drg_id" : drg_attachment.drg_id, - "vcn_id" : drg_attachment.vcn_id, - "drg_route_table_id" : str(drg_attachment.drg_route_table_id), - "export_drg_route_distribution_id" : str(drg_attachment.export_drg_route_distribution_id), - "is_cross_tenancy" : drg_attachment.is_cross_tenancy, - "lifecycle_state" : drg_attachment.lifecycle_state, - "network_details" : drg_attachment.network_details, - "network_id" : "", - "network_type" : "", - "freeform_tags" : drg_attachment.freeform_tags, - "define_tags" : drg_attachment.defined_tags, - "time_created" : drg_attachment.time_created.strftime(self.__iso_time_format), - "region" : region_key, - "notes":"" + "id": drg_attachment.id, + "display_name": drg_attachment.display_name, + "deep_link": self.__generate_csv_hyperlink(deep_link, drg_attachment.display_name), + "drg_id": drg_attachment.drg_id, + "vcn_id": drg_attachment.vcn_id, + "drg_route_table_id": str(drg_attachment.drg_route_table_id), + "export_drg_route_distribution_id": str(drg_attachment.export_drg_route_distribution_id), + "is_cross_tenancy": drg_attachment.is_cross_tenancy, + "lifecycle_state": drg_attachment.lifecycle_state, + "network_details": drg_attachment.network_details, + "network_id": "", + "network_type": "", + "freeform_tags": drg_attachment.freeform_tags, + "define_tags": drg_attachment.defined_tags, + "time_created": drg_attachment.time_created.strftime(self.__iso_time_format), + "region": region_key, + "notes": "" } # Adding DRG Attachment to DRG Attachments list try: self.__network_drg_attachments[drg_attachment.drg_id].append(record) - except: + except Exception: self.__network_drg_attachments[drg_attachment.drg_id] = [] self.__network_drg_attachments[drg_attachment.drg_id].append(record) # Counter - count_of_drg_attachments +=1 + count_of_drg_attachments += 1 - - print("\tProcessed " + str(count_of_drg_attachments) + " DRG Attachments") + print("\tProcessed " + str(count_of_drg_attachments) + " DRG Attachments") return self.__network_drg_attachments except Exception as e: raise RuntimeError( "Error in __network_read_drg_attachments " + str(e.args)) ########################################################################## - # Load DRGs + # Load DRGs ########################################################################## def __network_read_drgs(self): try: for region_key, region_values in self.__regions.items(): # Looping through compartments in tenancy drg_resources = oci.pagination.list_call_get_all_results( - region_values['search_client'].search_resources, + region_values['search_client'].search_resources, search_details=oci.resource_search.models.StructuredSearchDetails( - query="query Drg resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") + query="query Drg resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") ).data compartments = set() @@ -1888,50 +1899,50 @@ def __network_read_drgs(self): # Looping through DRGs in a compartment for drg in drg_data: deep_link = self.__oci_drg_uri + drg.id + '?region=' + region_key - #Fetch DRG Upgrade status + # Fetch DRG Upgrade status try: upgrade_status = region_values['network_client'].get_upgrade_status(drg.id).data.status - except: + except Exception: upgrade_status = "Not Available" - + try: record = { "id": drg.id, - "display_name" : drg.display_name, + "display_name": drg.display_name, "deep_link": self.__generate_csv_hyperlink(deep_link, drg.display_name), - "default_drg_route_tables" : drg.default_drg_route_tables, - "default_ipsec_tunnel_route_table" : drg.default_drg_route_tables.ipsec_tunnel, - "default_remote_peering_connection_route_table" : drg.default_drg_route_tables.remote_peering_connection, - "default_vcn_table" : drg.default_drg_route_tables.vcn, - "default_virtual_circuit_route_table" : drg.default_drg_route_tables.virtual_circuit, - "default_export_drg_route_distribution_id" : drg.default_export_drg_route_distribution_id, - "compartment_id" : drg.compartment_id, - "lifecycle_state" : drg.lifecycle_state, - "upgrade_status" : upgrade_status, - "time_created" : drg.time_created.strftime(self.__iso_time_format), - "freeform_tags" : drg.freeform_tags, - "define_tags" : drg.defined_tags, - "region" : region_key, - "notes":"" + "default_drg_route_tables": drg.default_drg_route_tables, + "default_ipsec_tunnel_route_table": drg.default_drg_route_tables.ipsec_tunnel, + "default_remote_peering_connection_route_table": drg.default_drg_route_tables.remote_peering_connection, + "default_vcn_table": drg.default_drg_route_tables.vcn, + "default_virtual_circuit_route_table": drg.default_drg_route_tables.virtual_circuit, + "default_export_drg_route_distribution_id": drg.default_export_drg_route_distribution_id, + "compartment_id": drg.compartment_id, + "lifecycle_state": drg.lifecycle_state, + "upgrade_status": upgrade_status, + "time_created": drg.time_created.strftime(self.__iso_time_format), + "freeform_tags": drg.freeform_tags, + "define_tags": drg.defined_tags, + "region": region_key, + "notes": "" } except Exception as e: record = { "id": drg.id, - "display_name" : drg.display_name, + "display_name": drg.display_name, "deep_link": self.__generate_csv_hyperlink(deep_link, drg.display_name), - "default_drg_route_tables" : drg.default_drg_route_tables, - "default_ipsec_tunnel_route_table" : "", - "default_remote_peering_connection_route_table" : "", - "default_vcn_table" : "", - "default_virtual_circuit_route_table" : "", - "default_export_drg_route_distribution_id" : drg.default_export_drg_route_distribution_id, - "compartment_id" : drg.compartment_id, - "lifecycle_state" : drg.lifecycle_state, - "upgrade_status" : upgrade_status, - "time_created" : drg.time_created.strftime(self.__iso_time_format), - "freeform_tags" : drg.freeform_tags, - "define_tags" : drg.defined_tags, - "region" : region_key, + "default_drg_route_tables": drg.default_drg_route_tables, + "default_ipsec_tunnel_route_table": "", + "default_remote_peering_connection_route_table": "", + "default_vcn_table": "", + "default_virtual_circuit_route_table": "", + "default_export_drg_route_distribution_id": drg.default_export_drg_route_distribution_id, + "compartment_id": drg.compartment_id, + "lifecycle_state": drg.lifecycle_state, + "upgrade_status": upgrade_status, + "time_created": drg.time_created.strftime(self.__iso_time_format), + "freeform_tags": drg.freeform_tags, + "define_tags": drg.defined_tags, + "region": region_key, "notes": str(e) } @@ -1940,25 +1951,23 @@ def __network_read_drgs(self): # For Checks data self.__network_drgs[drg.id] = record - - - print("\tProcessed " + str(len(self.__network_drgs)) + " Dynamic Routing Gateways") + print("\tProcessed " + str(len(self.__network_drgs)) + " Dynamic Routing Gateways") return self.__network_drgs except Exception as e: raise RuntimeError( "Error in __network_read_drgs " + str(e.args)) ########################################################################## - # Load Network FastConnect + # Load Network FastConnect ########################################################################## def __network_read_fastonnects(self): try: for region_key, region_values in self.__regions.items(): # Looping through compartments in tenancy fastconnects = oci.pagination.list_call_get_all_results( - region_values['search_client'].search_resources, + region_values['search_client'].search_resources, search_details=oci.resource_search.models.StructuredSearchDetails( - query="query VirtualCircuit resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") + query="query VirtualCircuit resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") ).data compartments = set() @@ -1976,96 +1985,93 @@ def __network_read_fastonnects(self): for fastconnect in fastconnect_data: deep_link = self.__oci_fastconnect_uri + fastconnect.id + '?region=' + region_key try: - record = { - "id": fastconnect.id, - "display_name" : fastconnect.display_name, - "deep_link": self.__generate_csv_hyperlink(deep_link, fastconnect.display_name), - "bandwidth_shape_name" : fastconnect.bandwidth_shape_name, - "bgp_admin_state" : fastconnect.bgp_admin_state, - "bgp_ipv6_session_state" : fastconnect.bgp_ipv6_session_state, - "bgp_management" : fastconnect.bgp_management, - "bgp_session_state" : fastconnect.bgp_session_state, - "compartment_id" : fastconnect.compartment_id, - "cross_connect_mappings" : fastconnect.cross_connect_mappings, - "customer_asn" : fastconnect.customer_asn, - "customer_bgp_asn" : fastconnect.customer_bgp_asn, - "gateway_id" : fastconnect.gateway_id, - "ip_mtu" : fastconnect.ip_mtu, - "is_bfd_enabled" : fastconnect.is_bfd_enabled, - "lifecycle_state" : fastconnect.lifecycle_state, - "oracle_bgp_asn" : fastconnect.oracle_bgp_asn, - "provider_name" : fastconnect.provider_name, - "provider_service_id" : fastconnect.provider_service_id, - "provider_service_key_name" : fastconnect.provider_service_id, - "provider_service_name" : fastconnect.provider_service_name, - "provider_state" : fastconnect.provider_state, - "public_prefixes" : fastconnect.public_prefixes, - "reference_comment" : fastconnect.reference_comment, - "fastconnect_region" : fastconnect.region, - "routing_policy" : fastconnect.routing_policy, - "service_type" : fastconnect.service_type, - "time_created" : fastconnect.time_created.strftime(self.__iso_time_format), - "type" : fastconnect.type, - "freeform_tags" : fastconnect.freeform_tags, - "define_tags" : fastconnect.defined_tags, - "region" : region_key, - "notes":"" - - } - # Adding fastconnect to fastconnect dict - + record = { + "id": fastconnect.id, + "display_name": fastconnect.display_name, + "deep_link": self.__generate_csv_hyperlink(deep_link, fastconnect.display_name), + "bandwidth_shape_name": fastconnect.bandwidth_shape_name, + "bgp_admin_state": fastconnect.bgp_admin_state, + "bgp_ipv6_session_state": fastconnect.bgp_ipv6_session_state, + "bgp_management": fastconnect.bgp_management, + "bgp_session_state": fastconnect.bgp_session_state, + "compartment_id": fastconnect.compartment_id, + "cross_connect_mappings": fastconnect.cross_connect_mappings, + "customer_asn": fastconnect.customer_asn, + "customer_bgp_asn": fastconnect.customer_bgp_asn, + "gateway_id": fastconnect.gateway_id, + "ip_mtu": fastconnect.ip_mtu, + "is_bfd_enabled": fastconnect.is_bfd_enabled, + "lifecycle_state": fastconnect.lifecycle_state, + "oracle_bgp_asn": fastconnect.oracle_bgp_asn, + "provider_name": fastconnect.provider_name, + "provider_service_id": fastconnect.provider_service_id, + "provider_service_key_name": fastconnect.provider_service_id, + "provider_service_name": fastconnect.provider_service_name, + "provider_state": fastconnect.provider_state, + "public_prefixes": fastconnect.public_prefixes, + "reference_comment": fastconnect.reference_comment, + "fastconnect_region": fastconnect.region, + "routing_policy": fastconnect.routing_policy, + "service_type": fastconnect.service_type, + "time_created": fastconnect.time_created.strftime(self.__iso_time_format), + "type": fastconnect.type, + "freeform_tags": fastconnect.freeform_tags, + "define_tags": fastconnect.defined_tags, + "region": region_key, + "notes": "" + } + # Adding fastconnect to fastconnect dict except Exception as e: record = { - "id": fastconnect.id, - "display_name" : fastconnect.display_name, - "deep_link": self.__generate_csv_hyperlink(deep_link, fastconnect.display_name), - "bandwidth_shape_name" : "", - "bgp_admin_state" : "", - "bgp_ipv6_session_state" : "", - "bgp_management" : "", - "bgp_session_state" : "", - "compartment_id" : fastconnect.compartment_id, - "cross_connect_mappings" : "", - "customer_asn" : "", - "customer_bgp_asn" : "", - "gateway_id" : "", - "ip_mtu" : "", - "is_bfd_enabled" : "", - "lifecycle_state" : "", - "oracle_bgp_asn" : "", - "provider_name" : "", - "provider_service_id" : "", - "provider_service_key_name" : "", - "provider_service_name" : "", - "provider_state" : "", - "public_prefixes" : "", - "reference_comment" : "", - "fastconnect_region" : "", - "routing_policy" : "", - "service_type" : "", - "time_created" : "", - "type" : "", - "freeform_tags" : "", - "define_tags" : "", - "region" : region_key, - "notes": str(e) + "id": fastconnect.id, + "display_name": fastconnect.display_name, + "deep_link": self.__generate_csv_hyperlink(deep_link, fastconnect.display_name), + "bandwidth_shape_name": "", + "bgp_admin_state": "", + "bgp_ipv6_session_state": "", + "bgp_management": "", + "bgp_session_state": "", + "compartment_id": fastconnect.compartment_id, + "cross_connect_mappings": "", + "customer_asn": "", + "customer_bgp_asn": "", + "gateway_id": "", + "ip_mtu": "", + "is_bfd_enabled": "", + "lifecycle_state": "", + "oracle_bgp_asn": "", + "provider_name": "", + "provider_service_id": "", + "provider_service_key_name": "", + "provider_service_name": "", + "provider_state": "", + "public_prefixes": "", + "reference_comment": "", + "fastconnect_region": "", + "routing_policy": "", + "service_type": "", + "time_created": "", + "type": "", + "freeform_tags": "", + "define_tags": "", + "region": region_key, + "notes": str(e) + } - } - # Adding fastconnect to fastconnect dict try: self.__network_fastconnects[fastconnect.gateway_id].append(record) - except: + except Exception: self.__network_fastconnects[fastconnect.gateway_id] = [] self.__network_fastconnects[fastconnect.gateway_id].append(record) - print("\tProcessed " + str(len((list(itertools.chain.from_iterable(self.__network_fastconnects.values()))))) + " FastConnects") + + print("\tProcessed " + str(len((list(itertools.chain.from_iterable(self.__network_fastconnects.values()))))) + " FastConnects") return self.__network_fastconnects except Exception as e: raise RuntimeError( "Error in __network_read_fastonnects " + str(e.args)) - ########################################################################## # Load IP Sec Connections ########################################################################## @@ -2073,31 +2079,31 @@ def __network_read_ip_sec_connections(self): try: for region_key, region_values in self.__regions.items(): ip_sec_connections_data = oci.pagination.list_call_get_all_results( - region_values['search_client'].search_resources, + region_values['search_client'].search_resources, search_details=oci.resource_search.models.StructuredSearchDetails( - query="query IPSecConnection resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") + query="query IPSecConnection resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") ).data - + for ip_sec in ip_sec_connections_data: try: deep_link = self.__oci_ipsec_uri + ip_sec.identifier + '?region=' + region_key record = { "id": ip_sec.identifier, - "display_name" : ip_sec.display_name, + "display_name": ip_sec.display_name, "deep_link": self.__generate_csv_hyperlink(deep_link, ip_sec.display_name), - "cpe_id" : ip_sec.additional_details['cpeId'], - "drg_id" : ip_sec.additional_details['drgId'], - "compartment_id" : ip_sec.compartment_id, - #"cpe_local_identifier" : ip_sec.cpe_local_identifier, - #"cpe_local_identifier_type" : ip_sec.cpe_local_identifier_type, - "lifecycle_state" : ip_sec.lifecycle_state, - "freeform_tags" : ip_sec.freeform_tags, - "define_tags" : ip_sec.defined_tags, - "region" : region_key, - "tunnels" : [], - "number_tunnels_up" : 0, - "tunnels_up" : True, # It is true unless I find out otherwise - "notes":"" + "cpe_id": ip_sec.additional_details['cpeId'], + "drg_id": ip_sec.additional_details['drgId'], + "compartment_id": ip_sec.compartment_id, + # "cpe_local_identifier": ip_sec.cpe_local_identifier, + # "cpe_local_identifier_type": ip_sec.cpe_local_identifier_type, + "lifecycle_state": ip_sec.lifecycle_state, + "freeform_tags": ip_sec.freeform_tags, + "define_tags": ip_sec.defined_tags, + "region": region_key, + "tunnels": [], + "number_tunnels_up": 0, + "tunnels_up": True, # It is true unless I find out otherwise + "notes": "" } # Getting Tunnel Data try: @@ -2108,81 +2114,78 @@ def __network_read_ip_sec_connections(self): for tunnel in ip_sec_tunnels_data: deep_link = self.__oci_ipsec_uri + ip_sec.identifier + "/tunnels/" + tunnel.id + '?region=' + region_key tunnel_record = { - "id" : tunnel.id, - "cpe_ip" : tunnel.cpe_ip, - "display_name" : tunnel.display_name, - "deep_link": self.__generate_csv_hyperlink(deep_link, tunnel.display_name), - "vpn_ip" : tunnel.vpn_ip, - "ike_version" : tunnel.ike_version, - "encryption_domain_config" : tunnel.encryption_domain_config, - "lifecycle_state" : tunnel.lifecycle_state, - "nat_translation_enabled" : tunnel.nat_translation_enabled, - "bgp_session_info" : tunnel.bgp_session_info, - "oracle_can_initiate" : tunnel.oracle_can_initiate, - "routing" : tunnel.routing, - "status" : tunnel.status, - "compartment_id" : tunnel.compartment_id, - "dpd_mode" : tunnel.dpd_mode, - "dpd_timeout_in_sec" : tunnel.dpd_timeout_in_sec, - "time_created" : tunnel.time_created.strftime(self.__iso_time_format), - "time_status_updated" : str(tunnel.time_status_updated), - "notes" : "" - } + "id": tunnel.id, + "cpe_ip": tunnel.cpe_ip, + "display_name": tunnel.display_name, + "deep_link": self.__generate_csv_hyperlink(deep_link, tunnel.display_name), + "vpn_ip": tunnel.vpn_ip, + "ike_version": tunnel.ike_version, + "encryption_domain_config": tunnel.encryption_domain_config, + "lifecycle_state": tunnel.lifecycle_state, + "nat_translation_enabled": tunnel.nat_translation_enabled, + "bgp_session_info": tunnel.bgp_session_info, + "oracle_can_initiate": tunnel.oracle_can_initiate, + "routing": tunnel.routing, + "status": tunnel.status, + "compartment_id": tunnel.compartment_id, + "dpd_mode": tunnel.dpd_mode, + "dpd_timeout_in_sec": tunnel.dpd_timeout_in_sec, + "time_created": tunnel.time_created.strftime(self.__iso_time_format), + "time_status_updated": str(tunnel.time_status_updated), + "notes": "" + } if tunnel_record['status'].upper() == "UP": record['number_tunnels_up'] += 1 else: record['tunnels_up'] = False record["tunnels"].append(tunnel_record) - except: + except Exception: print("\t Unable to tunnels for ip_sec_connection: " + ip_sec.display_name + " id: " + ip_sec.identifier) record['tunnels_up'] = False - - except: + except Exception: record = { "id": ip_sec.identifier, - "display_name" : ip_sec.display_name, + "display_name": ip_sec.display_name, "deep_link": self.__generate_csv_hyperlink(deep_link, ip_sec.display_name), - "cpe_id" : "", - "drg_id" : "", - "compartment_id" : ip_sec.compartment_id, - "cpe_local_identifier" : "", - "cpe_local_identifier_type" : "", - "lifecycle_state" : "", - "freeform_tags" : "", - "define_tags" : "", - "region" : region_key, - "tunnels" : [], - "number_tunnels_up" : 0, - "tunnels_up" : False, - "notes":"" + "cpe_id": "", + "drg_id": "", + "compartment_id": ip_sec.compartment_id, + "cpe_local_identifier": "", + "cpe_local_identifier_type": "", + "lifecycle_state": "", + "freeform_tags": "", + "define_tags": "", + "region": region_key, + "tunnels": [], + "number_tunnels_up": 0, + "tunnels_up": False, + "notes": "" } - + try: self.__network_ipsec_connections[ip_sec.additional_details['drgId']].append(record) - except: + except Exception: self.__network_ipsec_connections[ip_sec.additional_details['drgId']] = [] self.__network_ipsec_connections[ip_sec.additional_details['drgId']].append(record) - print("\tProcessed " + str(len((list(itertools.chain.from_iterable(self.__network_ipsec_connections.values()))))) + " IP SEC Conenctions") + print("\tProcessed " + str(len((list(itertools.chain.from_iterable(self.__network_ipsec_connections.values()))))) + " IP SEC Conenctions") return self.__network_ipsec_connections except Exception as e: raise RuntimeError( "Error in __network_read_ip_sec_connections " + str(e.args)) - ############################################ - # Load Autonomous Databases - ############################################ + ############################################ + # Load Autonomous Databases + ############################################ def __adb_read_adbs(self): try: for region_key, region_values in self.__regions.items(): - ##UPDATED JB - - + # UPDATED JB adb_query_resources = oci.pagination.list_call_get_all_results( - region_values['search_client'].search_resources, + region_values['search_client'].search_resources, search_details=oci.resource_search.models.StructuredSearchDetails( - query="query AutonomousDatabase resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") + query="query AutonomousDatabase resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") ).data compartments = set() @@ -2190,275 +2193,273 @@ def __adb_read_adbs(self): for adb in adb_query_resources: compartments.add(adb.compartment_id) - for compartment in compartments: + for compartment in compartments: autonomous_databases = oci.pagination.list_call_get_all_results( - region_values['adb_client'].list_autonomous_databases, - compartment_id = compartment - ).data + region_values['adb_client'].list_autonomous_databases, + compartment_id=compartment + ).data for adb in autonomous_databases: - try: + try: deep_link = self.__oci_adb_uri + adb.id + '?region=' + region_key - if (adb.lifecycle_state != oci.database.models.AutonomousDatabaseSummary.LIFECYCLE_STATE_TERMINATED or - adb.lifecycle_state != oci.database.models.AutonomousDatabaseSummary.LIFECYCLE_STATE_TERMINATING): + if (adb.lifecycle_state != oci.database.models.AutonomousDatabaseSummary.LIFECYCLE_STATE_TERMINATED or adb.lifecycle_state != oci.database.models.AutonomousDatabaseSummary.LIFECYCLE_STATE_TERMINATING): record = { - "id": adb.id, - "display_name": adb.display_name, - "deep_link": self.__generate_csv_hyperlink(deep_link, adb.display_name), - "apex_details": adb.apex_details, - "are_primary_whitelisted_ips_used": adb.are_primary_whitelisted_ips_used, - "autonomous_container_database_id": adb.autonomous_container_database_id, - "autonomous_maintenance_schedule_type": adb.autonomous_maintenance_schedule_type, - "available_upgrade_versions": adb.available_upgrade_versions, - "backup_config": adb.backup_config, - "compartment_id": adb.compartment_id, - "connection_strings": adb.connection_strings, - "connection_urls": adb.connection_urls, - "cpu_core_count": adb.cpu_core_count, - "customer_contacts": adb.cpu_core_count, - "data_safe_status": adb.data_safe_status, - "data_storage_size_in_gbs": adb.data_storage_size_in_gbs, - "data_storage_size_in_tbs": adb.data_storage_size_in_tbs, - "database_management_status": adb.database_management_status, - "dataguard_region_type": adb.dataguard_region_type, - "db_name": adb.db_name, - "db_version": adb.db_version, - "db_workload": adb.db_workload, - "defined_tags": adb.defined_tags, - "failed_data_recovery_in_seconds": adb.failed_data_recovery_in_seconds, - "freeform_tags": adb.freeform_tags, - "infrastructure_type": adb.infrastructure_type, - "is_access_control_enabled": adb.is_access_control_enabled, - "is_auto_scaling_enabled": adb.is_auto_scaling_enabled, - "is_data_guard_enabled": adb.is_data_guard_enabled, - "is_dedicated": adb.is_dedicated, - "is_free_tier": adb.is_free_tier, - "is_mtls_connection_required": adb.is_mtls_connection_required, - "is_preview": adb.is_preview, - "is_reconnect_clone_enabled": adb.is_reconnect_clone_enabled, - "is_refreshable_clone": adb.is_refreshable_clone, - "key_history_entry": adb.key_history_entry, - "key_store_id": adb.key_store_id, - "key_store_wallet_name": adb.key_store_wallet_name, - "kms_key_id": adb.kms_key_id, - "kms_key_lifecycle_details": adb.kms_key_lifecycle_details, - "kms_key_version_id": adb.kms_key_version_id, - "license_model": adb.license_model, - "lifecycle_details": adb.lifecycle_details, - "lifecycle_state": adb.lifecycle_state, - "nsg_ids": adb.nsg_ids, - "ocpu_count": adb.ocpu_count, - "open_mode": adb.open_mode, - "operations_insights_status": adb.operations_insights_status, - "peer_db_ids": adb.peer_db_ids, - "permission_level": adb.permission_level, - "private_endpoint": adb.private_endpoint, - "private_endpoint_ip": adb.private_endpoint_ip, - "private_endpoint_label": adb.private_endpoint_label, - "refreshable_mode": adb.refreshable_mode, - "refreshable_status": adb.refreshable_status, - "role": adb.role, - "scheduled_operations": adb.scheduled_operations, - "service_console_url": adb.service_console_url, - "source_id": adb.source_id, - "standby_whitelisted_ips": adb.standby_whitelisted_ips, - "subnet_id": adb.subnet_id, - "supported_regions_to_clone_to": adb.supported_regions_to_clone_to, - "system_tags": adb.system_tags, - "time_created": adb.time_created.strftime(self.__iso_time_format), - "time_data_guard_role_changed": str(adb.time_data_guard_role_changed), - "time_deletion_of_free_autonomous_database": str(adb.time_deletion_of_free_autonomous_database), - "time_local_data_guard_enabled": str(adb.time_local_data_guard_enabled), - "time_maintenance_begin": str(adb.time_maintenance_begin), - "time_maintenance_end": str(adb.time_maintenance_end), - "time_of_last_failover": str(adb.time_of_last_failover), - "time_of_last_refresh": str(adb.time_of_last_refresh), - "time_of_last_refresh_point": str(adb.time_of_last_refresh_point), - "time_of_last_switchover": str(adb.time_of_last_switchover), - "time_of_next_refresh": str(adb.time_of_next_refresh), - "time_reclamation_of_free_autonomous_database": str(adb.time_reclamation_of_free_autonomous_database), - "time_until_reconnect_clone_enabled": str(adb.time_until_reconnect_clone_enabled), - "used_data_storage_size_in_tbs": str(adb.used_data_storage_size_in_tbs), - "vault_id": adb.vault_id, - "whitelisted_ips": adb.whitelisted_ips, - "region" : region_key, - "notes" : "" - } + "id": adb.id, + "display_name": adb.display_name, + "deep_link": self.__generate_csv_hyperlink(deep_link, adb.display_name), + "apex_details": adb.apex_details, + "are_primary_whitelisted_ips_used": adb.are_primary_whitelisted_ips_used, + "autonomous_container_database_id": adb.autonomous_container_database_id, + "autonomous_maintenance_schedule_type": adb.autonomous_maintenance_schedule_type, + "available_upgrade_versions": adb.available_upgrade_versions, + "backup_config": adb.backup_config, + "compartment_id": adb.compartment_id, + "connection_strings": adb.connection_strings, + "connection_urls": adb.connection_urls, + "cpu_core_count": adb.cpu_core_count, + "customer_contacts": adb.cpu_core_count, + "data_safe_status": adb.data_safe_status, + "data_storage_size_in_gbs": adb.data_storage_size_in_gbs, + "data_storage_size_in_tbs": adb.data_storage_size_in_tbs, + "database_management_status": adb.database_management_status, + "dataguard_region_type": adb.dataguard_region_type, + "db_name": adb.db_name, + "db_version": adb.db_version, + "db_workload": adb.db_workload, + "defined_tags": adb.defined_tags, + "failed_data_recovery_in_seconds": adb.failed_data_recovery_in_seconds, + "freeform_tags": adb.freeform_tags, + "infrastructure_type": adb.infrastructure_type, + "is_access_control_enabled": adb.is_access_control_enabled, + "is_auto_scaling_enabled": adb.is_auto_scaling_enabled, + "is_data_guard_enabled": adb.is_data_guard_enabled, + "is_dedicated": adb.is_dedicated, + "is_free_tier": adb.is_free_tier, + "is_mtls_connection_required": adb.is_mtls_connection_required, + "is_preview": adb.is_preview, + "is_reconnect_clone_enabled": adb.is_reconnect_clone_enabled, + "is_refreshable_clone": adb.is_refreshable_clone, + "key_history_entry": adb.key_history_entry, + "key_store_id": adb.key_store_id, + "key_store_wallet_name": adb.key_store_wallet_name, + "kms_key_id": adb.kms_key_id, + "kms_key_lifecycle_details": adb.kms_key_lifecycle_details, + "kms_key_version_id": adb.kms_key_version_id, + "license_model": adb.license_model, + "lifecycle_details": adb.lifecycle_details, + "lifecycle_state": adb.lifecycle_state, + "nsg_ids": adb.nsg_ids, + "ocpu_count": adb.ocpu_count, + "open_mode": adb.open_mode, + "operations_insights_status": adb.operations_insights_status, + "peer_db_ids": adb.peer_db_ids, + "permission_level": adb.permission_level, + "private_endpoint": adb.private_endpoint, + "private_endpoint_ip": adb.private_endpoint_ip, + "private_endpoint_label": adb.private_endpoint_label, + "refreshable_mode": adb.refreshable_mode, + "refreshable_status": adb.refreshable_status, + "role": adb.role, + "scheduled_operations": adb.scheduled_operations, + "service_console_url": adb.service_console_url, + "source_id": adb.source_id, + "standby_whitelisted_ips": adb.standby_whitelisted_ips, + "subnet_id": adb.subnet_id, + "supported_regions_to_clone_to": adb.supported_regions_to_clone_to, + "system_tags": adb.system_tags, + "time_created": adb.time_created.strftime(self.__iso_time_format), + "time_data_guard_role_changed": str(adb.time_data_guard_role_changed), + "time_deletion_of_free_autonomous_database": str(adb.time_deletion_of_free_autonomous_database), + "time_local_data_guard_enabled": str(adb.time_local_data_guard_enabled), + "time_maintenance_begin": str(adb.time_maintenance_begin), + "time_maintenance_end": str(adb.time_maintenance_end), + "time_of_last_failover": str(adb.time_of_last_failover), + "time_of_last_refresh": str(adb.time_of_last_refresh), + "time_of_last_refresh_point": str(adb.time_of_last_refresh_point), + "time_of_last_switchover": str(adb.time_of_last_switchover), + "time_of_next_refresh": str(adb.time_of_next_refresh), + "time_reclamation_of_free_autonomous_database": str(adb.time_reclamation_of_free_autonomous_database), + "time_until_reconnect_clone_enabled": str(adb.time_until_reconnect_clone_enabled), + "used_data_storage_size_in_tbs": str(adb.used_data_storage_size_in_tbs), + "vault_id": adb.vault_id, + "whitelisted_ips": adb.whitelisted_ips, + "region": region_key, + "notes": "" + } else: record = { - "id": adb.id, - "display_name": adb.display_name, - "deep_link": self.__generate_csv_hyperlink(deep_link, adb.display_name), - "apex_details": "", - "are_primary_whitelisted_ips_used": "", - "autonomous_container_database_id": "", - "autonomous_maintenance_schedule_type": "", - "available_upgrade_versions": "", - "backup_config": "", - "compartment_id": adb.compartment_id, - "connection_strings": "", - "connection_urls": "", - "cpu_core_count": "", - "customer_contacts": "", - "data_safe_status": "", - "data_storage_size_in_gbs": "", - "data_storage_size_in_tbs": "", - "database_management_status": "", - "dataguard_region_type": "", - "db_name": "", - "db_version": "", - "db_workload": "", - "defined_tags": "", - "failed_data_recovery_in_seconds": "", - "freeform_tags": "", - "infrastructure_type": "", - "is_access_control_enabled": "", - "is_auto_scaling_enabled": "", - "is_data_guard_enabled": "", - "is_dedicated": "", - "is_free_tier": "", - "is_mtls_connection_required": "", - "is_preview": "", - "is_reconnect_clone_enabled": "", - "is_refreshable_clone": "", - "key_history_entry": "", - "key_store_id": "", - "key_store_wallet_name": "", - "kms_key_id": "", - "kms_key_lifecycle_details": "", - "kms_key_version_id": "", - "license_model": "", - "lifecycle_details": "", - "lifecycle_state": adb.lifecycle_state, - "nsg_ids": "", - "ocpu_count": "", - "open_mode": "", - "operations_insights_status": "", - "peer_db_ids": "", - "permission_level": "", - "private_endpoint": "", - "private_endpoint_ip":"", - "private_endpoint_label": "", - "refreshable_mode": "", - "refreshable_status": "", - "role": "", - "scheduled_operations": "", - "service_console_url": "", - "source_id": "", - "standby_whitelisted_ips": "", - "subnet_id": "", - "supported_regions_to_clone_to": "", - "system_tags": "", - "time_created": "", - "time_data_guard_role_changed": "", - "time_deletion_of_free_autonomous_database": "", - "time_local_data_guard_enabled": "", - "time_maintenance_begin": "", - "time_maintenance_end": "", - "time_of_last_failover": "", - "time_of_last_refresh": "", - "time_of_last_refresh_point": "", - "time_of_last_switchover": "", - "time_of_next_refresh": "", - "time_reclamation_of_free_autonomous_database": "", - "time_until_reconnect_clone_enabled": "", - "used_data_storage_size_in_tbs": "", - "vault_id": "", - "whitelisted_ips": "", - "region" : region_key, - "notes": "" - } + "id": adb.id, + "display_name": adb.display_name, + "deep_link": self.__generate_csv_hyperlink(deep_link, adb.display_name), + "apex_details": "", + "are_primary_whitelisted_ips_used": "", + "autonomous_container_database_id": "", + "autonomous_maintenance_schedule_type": "", + "available_upgrade_versions": "", + "backup_config": "", + "compartment_id": adb.compartment_id, + "connection_strings": "", + "connection_urls": "", + "cpu_core_count": "", + "customer_contacts": "", + "data_safe_status": "", + "data_storage_size_in_gbs": "", + "data_storage_size_in_tbs": "", + "database_management_status": "", + "dataguard_region_type": "", + "db_name": "", + "db_version": "", + "db_workload": "", + "defined_tags": "", + "failed_data_recovery_in_seconds": "", + "freeform_tags": "", + "infrastructure_type": "", + "is_access_control_enabled": "", + "is_auto_scaling_enabled": "", + "is_data_guard_enabled": "", + "is_dedicated": "", + "is_free_tier": "", + "is_mtls_connection_required": "", + "is_preview": "", + "is_reconnect_clone_enabled": "", + "is_refreshable_clone": "", + "key_history_entry": "", + "key_store_id": "", + "key_store_wallet_name": "", + "kms_key_id": "", + "kms_key_lifecycle_details": "", + "kms_key_version_id": "", + "license_model": "", + "lifecycle_details": "", + "lifecycle_state": adb.lifecycle_state, + "nsg_ids": "", + "ocpu_count": "", + "open_mode": "", + "operations_insights_status": "", + "peer_db_ids": "", + "permission_level": "", + "private_endpoint": "", + "private_endpoint_ip": "", + "private_endpoint_label": "", + "refreshable_mode": "", + "refreshable_status": "", + "role": "", + "scheduled_operations": "", + "service_console_url": "", + "source_id": "", + "standby_whitelisted_ips": "", + "subnet_id": "", + "supported_regions_to_clone_to": "", + "system_tags": "", + "time_created": "", + "time_data_guard_role_changed": "", + "time_deletion_of_free_autonomous_database": "", + "time_local_data_guard_enabled": "", + "time_maintenance_begin": "", + "time_maintenance_end": "", + "time_of_last_failover": "", + "time_of_last_refresh": "", + "time_of_last_refresh_point": "", + "time_of_last_switchover": "", + "time_of_next_refresh": "", + "time_reclamation_of_free_autonomous_database": "", + "time_until_reconnect_clone_enabled": "", + "used_data_storage_size_in_tbs": "", + "vault_id": "", + "whitelisted_ips": "", + "region": region_key, + "notes": "" + } except Exception as e: record = { - "id":"", - "display_name": "", - "deep_link": "", - "apex_details": "", - "are_primary_whitelisted_ips_used": "", - "autonomous_container_database_id": "", - "autonomous_maintenance_schedule_type": "", - "available_upgrade_versions": "", - "backup_config": "", - "compartment_id": "", - "connection_strings": "", - "connection_urls": "", - "cpu_core_count": "", - "customer_contacts": "", - "data_safe_status": "", - "data_storage_size_in_gbs": "", - "data_storage_size_in_tbs": "", - "database_management_status": "", - "dataguard_region_type": "", - "db_name": "", - "db_version": "", - "db_workload": "", - "defined_tags": "", - "failed_data_recovery_in_seconds": "", - "freeform_tags": "", - "infrastructure_type": "", - "is_access_control_enabled": "", - "is_auto_scaling_enabled": "", - "is_data_guard_enabled": "", - "is_dedicated": "", - "is_free_tier": "", - "is_mtls_connection_required": "", - "is_preview": "", - "is_reconnect_clone_enabled": "", - "is_refreshable_clone": "", - "key_history_entry": "", - "key_store_id": "", - "key_store_wallet_name": "", - "kms_key_id": "", - "kms_key_lifecycle_details": "", - "kms_key_version_id": "", - "license_model": "", - "lifecycle_details": "", - "lifecycle_state": "", - "nsg_ids": "", - "ocpu_count": "", - "open_mode": "", - "operations_insights_status": "", - "peer_db_ids": "", - "permission_level": "", - "private_endpoint": "", - "private_endpoint_ip":"", - "private_endpoint_label": "", - "refreshable_mode": "", - "refreshable_status": "", - "role": "", - "scheduled_operations": "", - "service_console_url": "", - "source_id": "", - "standby_whitelisted_ips": "", - "subnet_id": "", - "supported_regions_to_clone_to": "", - "system_tags": "", - "time_created": "", - "time_data_guard_role_changed": "", - "time_deletion_of_free_autonomous_database": "", - "time_local_data_guard_enabled": "", - "time_maintenance_begin": "", - "time_maintenance_end": "", - "time_of_last_failover": "", - "time_of_last_refresh": "", - "time_of_last_refresh_point": "", - "time_of_last_switchover": "", - "time_of_next_refresh": "", - "time_reclamation_of_free_autonomous_database": "", - "time_until_reconnect_clone_enabled": "", - "used_data_storage_size_in_tbs": "", - "vault_id": "", - "whitelisted_ips": "", - "region" : region_key, - "notes": str(e) + "id": "", + "display_name": "", + "deep_link": "", + "apex_details": "", + "are_primary_whitelisted_ips_used": "", + "autonomous_container_database_id": "", + "autonomous_maintenance_schedule_type": "", + "available_upgrade_versions": "", + "backup_config": "", + "compartment_id": "", + "connection_strings": "", + "connection_urls": "", + "cpu_core_count": "", + "customer_contacts": "", + "data_safe_status": "", + "data_storage_size_in_gbs": "", + "data_storage_size_in_tbs": "", + "database_management_status": "", + "dataguard_region_type": "", + "db_name": "", + "db_version": "", + "db_workload": "", + "defined_tags": "", + "failed_data_recovery_in_seconds": "", + "freeform_tags": "", + "infrastructure_type": "", + "is_access_control_enabled": "", + "is_auto_scaling_enabled": "", + "is_data_guard_enabled": "", + "is_dedicated": "", + "is_free_tier": "", + "is_mtls_connection_required": "", + "is_preview": "", + "is_reconnect_clone_enabled": "", + "is_refreshable_clone": "", + "key_history_entry": "", + "key_store_id": "", + "key_store_wallet_name": "", + "kms_key_id": "", + "kms_key_lifecycle_details": "", + "kms_key_version_id": "", + "license_model": "", + "lifecycle_details": "", + "lifecycle_state": "", + "nsg_ids": "", + "ocpu_count": "", + "open_mode": "", + "operations_insights_status": "", + "peer_db_ids": "", + "permission_level": "", + "private_endpoint": "", + "private_endpoint_ip": "", + "private_endpoint_label": "", + "refreshable_mode": "", + "refreshable_status": "", + "role": "", + "scheduled_operations": "", + "service_console_url": "", + "source_id": "", + "standby_whitelisted_ips": "", + "subnet_id": "", + "supported_regions_to_clone_to": "", + "system_tags": "", + "time_created": "", + "time_data_guard_role_changed": "", + "time_deletion_of_free_autonomous_database": "", + "time_local_data_guard_enabled": "", + "time_maintenance_begin": "", + "time_maintenance_end": "", + "time_of_last_failover": "", + "time_of_last_refresh": "", + "time_of_last_refresh_point": "", + "time_of_last_switchover": "", + "time_of_next_refresh": "", + "time_reclamation_of_free_autonomous_database": "", + "time_until_reconnect_clone_enabled": "", + "used_data_storage_size_in_tbs": "", + "vault_id": "", + "whitelisted_ips": "", + "region": region_key, + "notes": str(e) } self.__autonomous_databases.append(record) - - print("\tProcessed " + str(len(self.__autonomous_databases)) + " Autonomous Databases") + + print("\tProcessed " + str(len(self.__autonomous_databases)) + " Autonomous Databases") return self.__autonomous_databases except Exception as e: - raise RuntimeError ( - "Error in __adb_read_adbs " + str(e.args)) - + raise RuntimeError("Error in __adb_read_adbs " + str(e.args)) + ############################################ # Load Oracle Integration Cloud ############################################ @@ -2466,9 +2467,9 @@ def __oic_read_oics(self): try: for region_key, region_values in self.__regions.items(): oic_resources = oci.pagination.list_call_get_all_results( - region_values['search_client'].search_resources, + region_values['search_client'].search_resources, search_details=oci.resource_search.models.StructuredSearchDetails( - query="query IntegrationInstance resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") + query="query IntegrationInstance resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") ).data compartments = set() @@ -2479,11 +2480,11 @@ def __oic_read_oics(self): for compartment in compartments: oic_instances = oci.pagination.list_call_get_all_results( region_values['oic_client'].list_integration_instances, - compartment_id = compartment + compartment_id=compartment ).data for oic_instance in oic_instances: - if oic_instance.lifecycle_state == 'ACTIVE' or oic_instance.LIFECYCLE_STATE_INACTIVE == "INACTIVE": - deep_link = self.__oci_oicinstance_uri+ oic_instance.id + '?region=' + region_key + if oic_instance.lifecycle_state == 'ACTIVE' or oic_instance.LIFECYCLE_STATE_INACTIVE == "INACTIVE": + deep_link = self.__oci_oicinstance_uri + oic_instance.id + '?region=' + region_key try: record = { "id": oic_instance.id, @@ -2504,7 +2505,7 @@ def __oic_read_oics(self): "state_message": oic_instance.state_message, "time_created": oic_instance.time_created.strftime(self.__iso_time_format), "time_updated": str(oic_instance.time_updated), - "region" : region_key, + "region": region_key, "notes": "" } except Exception as e: @@ -2525,17 +2526,17 @@ def __oic_read_oics(self): "lifecycle_state": "", "message_packs": "", "state_message": "", - "time_created":"", - "time_updated":"", - "region" : region_key, + "time_created": "", + "time_updated": "", + "region": region_key, "notes": str(e) } self.__integration_instances.append(record) - print("\tProcessed " + str(len(self.__integration_instances)) + " Integration Instance") + print("\tProcessed " + str(len(self.__integration_instances)) + " Integration Instance") return self.__integration_instances except Exception as e: raise RuntimeError("Error in __oic_read_oics " + str(e.args)) - + ############################################ # Load Oracle Analytics Cloud ############################################ @@ -2543,23 +2544,23 @@ def __oac_read_oacs(self): try: for region_key, region_values in self.__regions.items(): oac_resources = oci.pagination.list_call_get_all_results( - region_values['search_client'].search_resources, + region_values['search_client'].search_resources, search_details=oci.resource_search.models.StructuredSearchDetails( - query="query AnalyticsInstance resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") + query="query AnalyticsInstance resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") ).data - compartments=set() + compartments = set() for resource in oac_resources: compartments.add(resource.compartment_id) for compartment in compartments: oac_instances = oci.pagination.list_call_get_all_results( - region_values['oac_client'].list_analytics_instances, - compartment_id=compartment - ).data + region_values['oac_client'].list_analytics_instances, + compartment_id=compartment + ).data for oac_instance in oac_instances: - deep_link = self.__oci_oacinstance_uri+ oac_instance.id + '?region=' + region_key + deep_link = self.__oci_oacinstance_uri + oac_instance.id + '?region=' + region_key try: record = { "id": oac_instance.id, @@ -2577,8 +2578,8 @@ def __oac_read_oacs(self): "license_type": oac_instance.license_type, "time_created": oac_instance.time_created.strftime(self.__iso_time_format), "time_updated": str(oac_instance.time_updated), - "region" : region_key, - "notes":"" + "region": region_key, + "notes": "" } except Exception as e: record = { @@ -2595,29 +2596,29 @@ def __oac_read_oacs(self): "license_type": "", "time_created": "", "time_updated": "", - "region" : region_key, - "notes":str(e) + "region": region_key, + "notes": str(e) } self.__analytics_instances.append(record) - - print("\tProcessed " + str(len(self.__analytics_instances)) + " Analytics Instances") + + print("\tProcessed " + str(len(self.__analytics_instances)) + " Analytics Instances") return self.__analytics_instances except Exception as e: raise RuntimeError("Error in __oac_read_oacs " + str(e.args)) - + ########################################################################## # Events ########################################################################## def __events_read_event_rules(self): - + try: for region_key, region_values in self.__regions.items(): events_rules_data = oci.pagination.list_call_get_all_results( - region_values['search_client'].search_resources, + region_values['search_client'].search_resources, search_details=oci.resource_search.models.StructuredSearchDetails( - query="query EventRule resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") + query="query EventRule resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") ).data - + for event_rule in events_rules_data: deep_link = self.__oci_events_uri + event_rule.identifier + '?region=' + region_key record = { @@ -2627,15 +2628,14 @@ def __events_read_event_rules(self): "display_name": event_rule.display_name, "deep_link": self.__generate_csv_hyperlink(deep_link, event_rule.display_name), "id": event_rule.identifier, - #"is_enabled": event_rule.is_enabled, + # "is_enabled": event_rule.is_enabled, "lifecycle_state": event_rule.lifecycle_state, "time_created": event_rule.time_created.strftime(self.__iso_time_format), - "region" : region_key + "region": region_key } self.__event_rules.append(record) - - print("\tProcessed " + str(len(self.__event_rules)) + " Event Rules") + print("\tProcessed " + str(len(self.__event_rules)) + " Event Rules") return self.__event_rules except Exception as e: raise RuntimeError("Error in events_read_rules " + str(e.args)) @@ -2644,93 +2644,93 @@ def __events_read_event_rules(self): # Logging - Log Groups and Logs ########################################################################## def __logging_read_log_groups_and_logs(self): - + try: for region_key, region_values in self.__regions.items(): - log_groups = oci.pagination.list_call_get_all_results( - region_values['search_client'].search_resources, - search_details=oci.resource_search.models.StructuredSearchDetails( - query="query LogGroup resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") - ).data + log_groups = oci.pagination.list_call_get_all_results( + region_values['search_client'].search_resources, + search_details=oci.resource_search.models.StructuredSearchDetails( + query="query LogGroup resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") + ).data - # Looping through log groups to get logs - for log_group in log_groups: - deep_link = self.__oci_loggroup_uri + log_group.identifier + '?region=' + region_key - record = { - "compartment_id": log_group.compartment_id, - "description": log_group.additional_details['description'], - "display_name": log_group.display_name, - "deep_link": self.__generate_csv_hyperlink(deep_link, log_group.display_name), - "id": log_group.identifier, - "time_created": log_group.time_created.strftime(self.__iso_time_format), - #"time_last_modified": str(log_group.time_last_modified), - "defined_tags" : log_group.defined_tags, - "freeform_tags" : log_group.freeform_tags, - "region" : region_key, - "logs": [] - } + # Looping through log groups to get logs + for log_group in log_groups: + deep_link = self.__oci_loggroup_uri + log_group.identifier + '?region=' + region_key + record = { + "compartment_id": log_group.compartment_id, + "description": log_group.additional_details['description'], + "display_name": log_group.display_name, + "deep_link": self.__generate_csv_hyperlink(deep_link, log_group.display_name), + "id": log_group.identifier, + "time_created": log_group.time_created.strftime(self.__iso_time_format), + # "time_last_modified": str(log_group.time_last_modified), + "defined_tags": log_group.defined_tags, + "freeform_tags": log_group.freeform_tags, + "region": region_key, + "logs": [] + } - logs = oci.pagination.list_call_get_all_results( - region_values['logging_client'].list_logs, - log_group_id=log_group.identifier - ).data - for log in logs: - deep_link = self.__oci_loggroup_uri + log_group.identifier + "/logs/" + log.id + '?region=' + region_key - log_record = { - "compartment_id": log.compartment_id, - "display_name": log.display_name, - "deep_link": self.__generate_csv_hyperlink(deep_link, log.display_name), - "id": log.id, - "is_enabled": log.is_enabled, - "lifecycle_state": log.lifecycle_state, - "log_group_id": log.log_group_id, - "log_type": log.log_type, - "retention_duration": log.retention_duration, - "time_created": log.time_created.strftime(self.__iso_time_format), - "time_last_modified": str(log.time_last_modified), - "defined_tags" : log.defined_tags, - "freeform_tags" : log.freeform_tags - } - try: - if log.configuration: - log_record["configuration_compartment_id"] = log.configuration.compartment_id, - log_record["source_category"] = log.configuration.source.category, - log_record["source_parameters"] = log.configuration.source.parameters, - log_record["source_resource"] = log.configuration.source.resource, - log_record["source_service"] = log.configuration.source.service, - log_record["source_source_type"] = log.configuration.source.source_type - log_record["archiving_enabled"] = log.configuration.archiving.is_enabled - - if log.configuration.source.service == 'flowlogs': - self.__subnet_logs[log.configuration.source.resource] = {"log_group_id" : log.log_group_id, "log_id": log.id} - - elif log.configuration.source.service == 'objectstorage' and 'write' in log.configuration.source.category: - # Only write logs - self.__write_bucket_logs[log.configuration.source.resource] = {"log_group_id" : log.log_group_id, "log_id": log.id, "region" : region_key} - - elif log.configuration.source.service == 'objectstorage' and 'read' in log.configuration.source.category: - # Only read logs - self.__read_bucket_logs[log.configuration.source.resource] = {"log_group_id" : log.log_group_id, "log_id": log.id, "region" : region_key} - - elif log.configuration.source.service == 'loadbalancer' and 'error' in log.configuration.source.category: - self.__load_balancer_error_logs.append( - log.configuration.source.resource) - elif log.configuration.source.service == 'loadbalancer' and 'access' in log.configuration.source.category: - self.__load_balancer_access_logs.append( - log.configuration.source.resource) - elif log.configuration.source.service == 'apigateway' and 'access' in log.configuration.source.category: - self.__api_gateway_access_logs.append( - log.configuration.source.resource) - elif log.configuration.source.service == 'apigateway' and 'error' in log.configuration.source.category: - self.__api_gateway_error_logs.append( - log.configuration.source.resource) - except: - pass - # Append Log to log List - record['logs'].append(log_record) - self.__logging_list.append(record) - - print("\tProcessed " + str(len(self.__logging_list)) + " Log Group Logs") + logs = oci.pagination.list_call_get_all_results( + region_values['logging_client'].list_logs, + log_group_id=log_group.identifier + ).data + for log in logs: + deep_link = self.__oci_loggroup_uri + log_group.identifier + "/logs/" + log.id + '?region=' + region_key + log_record = { + "compartment_id": log.compartment_id, + "display_name": log.display_name, + "deep_link": self.__generate_csv_hyperlink(deep_link, log.display_name), + "id": log.id, + "is_enabled": log.is_enabled, + "lifecycle_state": log.lifecycle_state, + "log_group_id": log.log_group_id, + "log_type": log.log_type, + "retention_duration": log.retention_duration, + "time_created": log.time_created.strftime(self.__iso_time_format), + "time_last_modified": str(log.time_last_modified), + "defined_tags": log.defined_tags, + "freeform_tags": log.freeform_tags + } + try: + if log.configuration: + log_record["configuration_compartment_id"] = log.configuration.compartment_id, + log_record["source_category"] = log.configuration.source.category, + log_record["source_parameters"] = log.configuration.source.parameters, + log_record["source_resource"] = log.configuration.source.resource, + log_record["source_service"] = log.configuration.source.service, + log_record["source_source_type"] = log.configuration.source.source_type + log_record["archiving_enabled"] = log.configuration.archiving.is_enabled + + if log.configuration.source.service == 'flowlogs': + self.__subnet_logs[log.configuration.source.resource] = {"log_group_id": log.log_group_id, "log_id": log.id} + + elif log.configuration.source.service == 'objectstorage' and 'write' in log.configuration.source.category: + # Only write logs + self.__write_bucket_logs[log.configuration.source.resource] = {"log_group_id": log.log_group_id, "log_id": log.id, "region": region_key} + + elif log.configuration.source.service == 'objectstorage' and 'read' in log.configuration.source.category: + # Only read logs + self.__read_bucket_logs[log.configuration.source.resource] = {"log_group_id": log.log_group_id, "log_id": log.id, "region": region_key} + + elif log.configuration.source.service == 'loadbalancer' and 'error' in log.configuration.source.category: + self.__load_balancer_error_logs.append( + log.configuration.source.resource) + elif log.configuration.source.service == 'loadbalancer' and 'access' in log.configuration.source.category: + self.__load_balancer_access_logs.append( + log.configuration.source.resource) + elif log.configuration.source.service == 'apigateway' and 'access' in log.configuration.source.category: + self.__api_gateway_access_logs.append( + log.configuration.source.resource) + elif log.configuration.source.service == 'apigateway' and 'error' in log.configuration.source.category: + self.__api_gateway_error_logs.append( + log.configuration.source.resource) + except Exception: + pass + # Append Log to log List + record['logs'].append(log_record) + self.__logging_list.append(record) + + print("\tProcessed " + str(len(self.__logging_list)) + " Log Group Logs") return self.__logging_list except Exception as e: raise RuntimeError( @@ -2744,15 +2744,15 @@ def __vault_read_vaults(self): try: for region_key, region_values in self.__regions.items(): keys_data = oci.pagination.list_call_get_all_results( - region_values['search_client'].search_resources, + region_values['search_client'].search_resources, search_details=oci.resource_search.models.StructuredSearchDetails( - query="query Key resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") + query="query Key resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") ).data vaults_data = oci.pagination.list_call_get_all_results( - region_values['search_client'].search_resources, + region_values['search_client'].search_resources, search_details=oci.resource_search.models.StructuredSearchDetails( - query="query Vault resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") + query="query Vault resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") ).data # Get all Vaults in a compartment @@ -2760,17 +2760,17 @@ def __vault_read_vaults(self): deep_link = self.__oci_vault_uri + vlt.identifier + '?region=' + region_key vault_record = { "compartment_id": vlt.compartment_id, - #"crypto_endpoint": vlt.crypto_endpoint, + # "crypto_endpoint": vlt.crypto_endpoint, "display_name": vlt.display_name, "deep_link": self.__generate_csv_hyperlink(deep_link, vlt.display_name), "id": vlt.identifier, "lifecycle_state": vlt.lifecycle_state, - #"management_endpoint": vlt.management_endpoint, + # "management_endpoint": vlt.management_endpoint, "time_created": vlt.time_created.strftime(self.__iso_time_format), "vault_type": vlt.additional_details['vaultType'], "freeform_tags": vlt.freeform_tags, "defined_tags": vlt.defined_tags, - "region" : region_key, + "region": region_key, "keys": [] } for key in keys_data: @@ -2788,11 +2788,11 @@ def __vault_read_vaults(self): self.__vaults.append(vault_record) - print("\tProcessed " + str(len(self.__vaults)) + " Vaults") + print("\tProcessed " + str(len(self.__vaults)) + " Vaults") return self.__vaults except Exception as e: raise RuntimeError( - "Error in __vault_read_vaults " + str(e.args)) + "Error in __vault_read_vaults " + str(e.args)) ########################################################################## # OCI Budgets @@ -2809,34 +2809,35 @@ def __budget_read_budgets(self): for budget in budgets_data: try: alerts_data = oci.pagination.list_call_get_all_results( - self.__regions[self.__home_region]['budget_client'].list_alert_rules, - budget_id=budget.id, - ).data - except Exception as e: + self.__regions[self.__home_region]['budget_client'].list_alert_rules, + budget_id=budget.id, + ).data + except Exception: print("\tFailed to get Budget Data for Budget Name: " + budget.display_name + " id: " + budget.id) alerts_data = [] + deep_link = self.__oci_budget_uri + budget.id record = { - "actual_spend" : budget.actual_spend, - "alert_rule_count" : budget.alert_rule_count, - "amount" : budget.amount, - "budget_processing_period_start_offset" : budget.budget_processing_period_start_offset, + "actual_spend": budget.actual_spend, + "alert_rule_count": budget.alert_rule_count, + "amount": budget.amount, + "budget_processing_period_start_offset": budget.budget_processing_period_start_offset, "compartment_id": budget.compartment_id, - "description" : budget.description, + "description": budget.description, "display_name": budget.display_name, "deep_link": self.__generate_csv_hyperlink(deep_link, budget.display_name), "id": budget.id, - "lifecycle_state" : budget.lifecycle_state, - "processing_period_type" : budget.processing_period_type, - "reset_period" : budget.reset_period, - "target_compartment_id" : budget.target_compartment_id, - "target_type" : budget.target_type, - "tagerts" : budget.targets, + "lifecycle_state": budget.lifecycle_state, + "processing_period_type": budget.processing_period_type, + "reset_period": budget.reset_period, + "target_compartment_id": budget.target_compartment_id, + "target_type": budget.target_type, + "tagerts": budget.targets, "time_created": budget.time_created.strftime(self.__iso_time_format), "time_spend_computed": str(budget.time_spend_computed), - "alerts" : [] + "alerts": [] } - + for alert in alerts_data: record['alerts'].append(alert) @@ -2849,7 +2850,6 @@ def __budget_read_budgets(self): raise RuntimeError( "Error in __budget_read_budgets " + str(e.args)) - ########################################################################## # Audit Configuration ########################################################################## @@ -2864,7 +2864,7 @@ def __audit_read_tenancy_audit_configuration(self): print("\t*** Access to audit retention requires the user to be part of the Administrator group ***") else: raise RuntimeError("Error in __audit_read_tenancy_audit_configuration " + str(e.args)) - + print("\tProcessed Audit Configuration.") return self.__audit_retention_period @@ -2876,14 +2876,14 @@ def __cloud_guard_read_cloud_guard_configuration(self): self.__cloud_guard_config = self.__regions[self.__home_region]['cloud_guard_client'].get_configuration( self.__tenancy.id).data self.__cloud_guard_config_status = self.__cloud_guard_config.status - + print("\tProcessed Cloud Guard Configuration.") return self.__cloud_guard_config_status - except Exception as e: + + except Exception: self.__cloud_guard_config_status = 'DISABLED' print("*** Cloud Guard service requires a PayGo account ***") - ########################################################################## # Cloud Guard Configuration ########################################################################## @@ -2898,11 +2898,13 @@ def __cloud_guard_read_cloud_guard_targets(self): # Looping throufh targets to get target data for target in cg_targets: try: - # Getting Target data like recipes + # Getting Target data like recipes try: target_data = self.__regions[self.__cloud_guard_config.reporting_region]['cloud_guard_client'].get_target( - target_id=target.id).data - except Exception as e: + target_id=target.id + ).data + + except Exception: target_data = None deep_link = self.__oci_cgtarget_uri + target.id record = { @@ -2915,28 +2917,30 @@ def __cloud_guard_read_cloud_guard_targets(self): "lifecycle_state": target.lifecycle_state, "lifecyle_details": target.lifecyle_details, "system_tags": target.system_tags, - "recipe_count" : target.recipe_count, + "recipe_count": target.recipe_count, "target_resource_id": target.target_resource_id, "target_resource_type": target.target_resource_type, "time_created": target.time_created.strftime(self.__iso_time_format), "time_updated": str(target.time_updated), - "inherited_by_compartments" : target_data.inherited_by_compartments if target_data else "", - "description" : target_data.description if target_data else "", - "target_details" : target_data.target_details if target_data else "", - "target_detector_recipes" : target_data.target_detector_recipes if target_data else "", - "target_responder_recipes" : target_data.target_responder_recipes if target_data else "" + "inherited_by_compartments": target_data.inherited_by_compartments if target_data else "", + "description": target_data.description if target_data else "", + "target_details": target_data.target_details if target_data else "", + "target_detector_recipes": target_data.target_detector_recipes if target_data else "", + "target_responder_recipes": target_data.target_responder_recipes if target_data else "" } # Indexing by compartment_id self.__cloud_guard_targets[compartment.id] = record cloud_guard_targets += 1 - except Exception as e: + + except Exception: print("\t Failed to Cloud Guard Target Data for: " + target.display_name + " id: " + target.id) - print("\tProcessed " + str(cloud_guard_targets) + " Cloud Guard Targets") + print("\tProcessed " + str(cloud_guard_targets) + " Cloud Guard Targets") return self.__cloud_guard_targets - except Exception as e: + + except Exception: print("*** Cloud Guard service requires a PayGo account ***") ########################################################################## @@ -2945,8 +2949,9 @@ def __cloud_guard_read_cloud_guard_targets(self): def __identity_read_tenancy_password_policy(self): try: self.__tenancy_password_policy = self.__regions[self.__home_region]['identity_client'].get_authentication_policy( - self.__tenancy.id).data - + self.__tenancy.id + ).data + print("\tProcessed Tenancy Password Policy...") return self.__tenancy_password_policy except Exception as e: @@ -2954,8 +2959,7 @@ def __identity_read_tenancy_password_policy(self): self.__tenancy_password_policy = None print("\t*** Access to password policies in this tenancy requires elevated permissions. ***") else: - raise RuntimeError( - "Error in __identity_read_tenancy_password_policy " + str(e.args)) + raise RuntimeError("Error in __identity_read_tenancy_password_policy " + str(e.args)) ########################################################################## # Oracle Notifications Services for Subscriptions @@ -2965,18 +2969,18 @@ def __ons_read_subscriptions(self): for region_key, region_values in self.__regions.items(): # Iterate through compartments to get all subscriptions subs_data = oci.pagination.list_call_get_all_results( - region_values['search_client'].search_resources, + region_values['search_client'].search_resources, search_details=oci.resource_search.models.StructuredSearchDetails( - query="query OnsSubscription resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") + query="query OnsSubscription resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") ).data for sub in subs_data: - deep_link = self.__oci_onssub_uri +sub.identifier + '?region=' + region_key + deep_link = self.__oci_onssub_uri + sub.identifier + '?region=' + region_key record = { - "id":sub.identifier, - "deep_link": self.__generate_csv_hyperlink(deep_link,sub.identifier), + "id": sub.identifier, + "deep_link": self.__generate_csv_hyperlink(deep_link, sub.identifier), "compartment_id": sub.compartment_id, - #"created_time": sub.created_time, # this is an INT + # "created_time": sub.created_time, # this is an INT "created_time": sub.time_created, "endpoint": sub.additional_details['endpoint'], "protocol": sub.additional_details['protocol'], @@ -2984,13 +2988,12 @@ def __ons_read_subscriptions(self): "lifecycle_state": sub.lifecycle_state, "defined_tags": sub.defined_tags, "freeform_tags": sub.freeform_tags, - "region" : region_key + "region": region_key } self.__subscriptions.append(record) - - print("\tProcessed " + str(len(self.__subscriptions)) + " Subscriptions") + print("\tProcessed " + str(len(self.__subscriptions)) + " Subscriptions") return self.__subscriptions except Exception as e: @@ -3021,8 +3024,8 @@ def __identity_read_tag_defaults(self): } self.__tag_defaults.append(record) - - print("\tProcessed " + str(len(self.__tag_defaults)) + " Tag Defaults") + + print("\tProcessed " + str(len(self.__tag_defaults)) + " Tag Defaults") return self.__tag_defaults except Exception as e: @@ -3033,15 +3036,15 @@ def __identity_read_tag_defaults(self): # Get Service Connectors ########################################################################## def __sch_read_service_connectors(self): - + try: # looping through regions for region_key, region_values in self.__regions.items(): # Collecting Service Connectors from each compartment service_connectors_data = oci.pagination.list_call_get_all_results( - region_values['search_client'].search_resources, + region_values['search_client'].search_resources, search_details=oci.resource_search.models.StructuredSearchDetails( - query="query ServiceConnector resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") + query="query ServiceConnector resources return allAdditionalFields where compartmentId != '" + self.__managed_paas_compartment_id + "'") ).data # Getting Bucket Info @@ -3050,31 +3053,30 @@ def __sch_read_service_connectors(self): try: service_connector = region_values['sch_client'].get_service_connector( service_connector_id=connector.identifier - ).data + ).data record = { "id": service_connector.id, "display_name": service_connector.display_name, "deep_link": self.__generate_csv_hyperlink(deep_link, service_connector.display_name), "description": service_connector.description, "freeform_tags": service_connector.freeform_tags, - "defined_tags" : service_connector.defined_tags, - "lifecycle_state" : service_connector.lifecycle_state, - #"lifecycle_details": service_connector.lifecyle_details, + "defined_tags": service_connector.defined_tags, + "lifecycle_state": service_connector.lifecycle_state, + # "lifecycle_details": service_connector.lifecyle_details, "system_tags": service_connector.system_tags, "time_created": service_connector.time_created.strftime(self.__iso_time_format), - #"time_updated": str(service_connector.time_updated), - "target_kind" : service_connector.target.kind, - "log_sources" : [], - "region" : region_key, + # "time_updated": str(service_connector.time_updated), + "target_kind": service_connector.target.kind, + "log_sources": [], + "region": region_key, "notes": "" } for log_source in service_connector.source.log_sources: record['log_sources'].append({ - 'compartment_id' : log_source.compartment_id, - 'log_group_id' : log_source.log_group_id, - 'log_id' : log_source.log_id - } - ) + 'compartment_id': log_source.compartment_id, + 'log_group_id': log_source.log_group_id, + 'log_id': log_source.log_id + }) self.__service_connectors[service_connector.id] = record except Exception as e: record = { @@ -3083,15 +3085,15 @@ def __sch_read_service_connectors(self): "deep_link": self.__generate_csv_hyperlink(deep_link, connector.display_name), "description": connector.additional_details['description'], "freeform_tags": connector.freeform_tags, - "defined_tags" : connector.defined_tags, - "lifecycle_state" : connector.lifecycle_state, - #"lifecycle_details": connector.lifecycle_details, + "defined_tags": connector.defined_tags, + "lifecycle_state": connector.lifecycle_state, + # "lifecycle_details": connector.lifecycle_details, "system_tags": "", "time_created": connector.time_created.strftime(self.__iso_time_format), - #"time_updated": str(connector.time_updated), - "target_kind" : "", - "log_sources" : [], - "region" : region_key, + # "time_updated": str(connector.time_updated), + "target_kind": "", + "log_sources": [], + "region": region_key, "notes": str(e) } self.__service_connectors[connector.identifier] = record @@ -3105,7 +3107,7 @@ def __sch_read_service_connectors(self): # Resources in root compartment ########################################################################## def __search_resources_in_root_compartment(self): - + # query = [] # resources_in_root_data = [] # record = [] @@ -3115,18 +3117,18 @@ def __search_resources_in_root_compartment(self): for region_key, region_values in self.__regions.items(): try: - #Searching for non compliant resources in root compartment + # Searching for non compliant resources in root compartment structured_search_query = oci.resource_search.models.StructuredSearchDetails(query=query_non_compliant) search_results = oci.pagination.list_call_get_all_results( region_values['search_client'].search_resources, search_details=structured_search_query - ).data - + ).data + for item in search_results: record = { "display_name": item.display_name, "id": item.identifier, - "region" : region_key + "region": region_key } self.__resources_in_root_compartment.append(record) @@ -3136,44 +3138,44 @@ def __search_resources_in_root_compartment(self): region_values['search_client'].search_resources, search_details=structured_search_all_query ).data - + for item in structured_search_all_resources: # ignoring global resources like IAM if item.identifier.split('.')[3]: record = { "display_name": item.display_name, "id": item.identifier, - "region" : region_key + "region": region_key } self.cis_foundations_benchmark_1_2['5.2']['Total'].append(item) except Exception as e: raise RuntimeError( "Error in __search_resources_in_root_compartment " + str(e.args)) - - print("\tProcessed " + str(len(self.__resources_in_root_compartment)) + " resources in the root compartment") + + print("\tProcessed " + str(len(self.__resources_in_root_compartment)) + " resources in the root compartment") return self.__resources_in_root_compartment ########################################################################## # Analyzes Tenancy Data for CIS Report ########################################################################## def __report_cis_analyze_tenancy_data(self): - + # 1.1 Check - Checking for policy statements that are not restricted to a service - - for policy in self.__policies: + + for policy in self.__policies: for statement in policy['statements']: if "allow group".upper() in statement.upper() \ and ("to manage all-resources".upper() in statement.upper()) \ and policy['name'].upper() != "Tenant Admin Policy".upper(): # If there are more than manage all-resources in you don't meet this rule - self.cis_foundations_benchmark_1_2['1.1']['Status'] = False + self.cis_foundations_benchmark_1_2['1.1']['Status'] = False self.cis_foundations_benchmark_1_2['1.1']['Findings'].append(policy) break - + # 1.2 Check - - for policy in self.__policies: + + for policy in self.__policies: for statement in policy['statements']: if "allow group".upper() in statement.upper() \ and "to manage all-resources in tenancy".upper() in statement.upper() \ @@ -3182,20 +3184,18 @@ def __report_cis_analyze_tenancy_data(self): self.cis_foundations_benchmark_1_2['1.2']['Status'] = False self.cis_foundations_benchmark_1_2['1.2']['Findings'].append( policy) - + # 1.3 Check - May want to add a service check for policy in self.__policies: - if policy['name'].upper() != "Tenant Admin Policy".upper() and policy['name'].upper() != "PSM-root-policy": + if policy['name'].upper() != "Tenant Admin Policy".upper() and policy['name'].upper() != "PSM-root-policy": for statement in policy['statements']: - if ("allow group".upper() in statement.upper() and "tenancy".upper() in statement.upper() and \ - ("to manage ".upper() in statement.upper() or "to use".upper() in statement.upper()) and \ - ("all-resources".upper() in statement.upper() or (" groups ".upper() in statement.upper() and " users ".upper() in statement.upper()))): + if ("allow group".upper() in statement.upper() and "tenancy".upper() in statement.upper() and ("to manage ".upper() in statement.upper() or "to use".upper() in statement.upper()) and ("all-resources".upper() in statement.upper() or (" groups ".upper() in statement.upper() and " users ".upper() in statement.upper()))): split_statement = statement.split("where") # Checking if there is a where clause if len(split_statement) == 2: # If there is a where clause remove whitespace and quotes clean_where_clause = split_statement[1].upper().replace(" ", "").replace("'", "") - if all(permission.upper() in clean_where_clause for permission in self.cis_iam_checks['1.3']["targets"]): + if all(permission.upper() in clean_where_clause for permission in self.cis_iam_checks['1.3']["targets"]): pass else: self.cis_foundations_benchmark_1_2['1.3']['Findings'].append(policy) @@ -3210,7 +3210,6 @@ def __report_cis_analyze_tenancy_data(self): self.cis_foundations_benchmark_1_2['1.2']['Total'] = self.__policies self.cis_foundations_benchmark_1_2['1.3']['Total'] = self.__policies - # 1.4 Check - Password Policy - Only in home region if self.__tenancy_password_policy: if self.__tenancy_password_policy.password_policy.is_lowercase_characters_required: @@ -3220,15 +3219,14 @@ def __report_cis_analyze_tenancy_data(self): # 1.7 Check - Local Users w/o MFA for user in self.__users: - if user['identity_provider_id'] is None and user['can_use_console_password'] and not(user['is_mfa_activated']) and user['lifecycle_state'] == 'ACTIVE': + if user['identity_provider_id'] is None and user['can_use_console_password'] and not (user['is_mfa_activated']) and user['lifecycle_state'] == 'ACTIVE': self.cis_foundations_benchmark_1_2['1.7']['Status'] = False self.cis_foundations_benchmark_1_2['1.7']['Findings'].append( user) - + # CIS Total 1.7 Adding - All Users to CIS Total self.cis_foundations_benchmark_1_2['1.7']['Total'] = self.__users - # 1.8 Check - API Keys over 90 for user in self.__users: if user['api_keys']: @@ -3247,7 +3245,7 @@ def __report_cis_analyze_tenancy_data(self): self.cis_foundations_benchmark_1_2['1.8']['Findings'].append( finding) - + # CIS Total 1.8 Adding - Customer Secrets to CIS Total self.cis_foundations_benchmark_1_2['1.8']['Total'].append(key) @@ -3271,7 +3269,7 @@ def __report_cis_analyze_tenancy_data(self): self.cis_foundations_benchmark_1_2['1.9']['Findings'].append( finding) - + # CIS Total 1.9 Adding - Customer Secrets to CIS Total self.cis_foundations_benchmark_1_2['1.9']['Total'].append(key) @@ -3296,7 +3294,7 @@ def __report_cis_analyze_tenancy_data(self): self.cis_foundations_benchmark_1_2['1.10']['Findings'].append( finding) - + # CIS Total 1.10 Adding - Keys to CIS Total self.cis_foundations_benchmark_1_2['1.10']['Total'].append( key) @@ -3307,25 +3305,23 @@ def __report_cis_analyze_tenancy_data(self): if 'Administrators' in user['groups'] and user['api_keys'] and user['lifecycle_state'] == 'ACTIVE': self.cis_foundations_benchmark_1_2['1.11']['Status'] = False self.cis_foundations_benchmark_1_2['1.11']['Findings'].append( - user) - + user) + # CIS Total 1.12 Adding - All IAM Users in Administrator group to CIS Total if 'Administrators' in user['groups'] and user['lifecycle_state'] == 'ACTIVE': self.cis_foundations_benchmark_1_2['1.11']['Total'].append(user) - # CIS 1.12 Check - This check is complete uses email verification # Iterating through all users to see if they have API Keys and if they are active users for user in self.__users: - if user['external_identifier'] is None and user['lifecycle_state'] == 'ACTIVE' and not(user['email_verified']): + if user['external_identifier'] is None and user['lifecycle_state'] == 'ACTIVE' and not (user['email_verified']): self.cis_foundations_benchmark_1_2['1.12']['Status'] = False self.cis_foundations_benchmark_1_2['1.12']['Findings'].append( user) - + # CIS Total 1.12 Adding - All IAM Users for to CIS Total self.cis_foundations_benchmark_1_2['1.12']['Total'] = self.__users - # CIS 1.13 Check - Ensure Dynamic Groups are used for OCI instances, OCI Cloud Databases and OCI Function to access OCI resources # Iterating through all dynamic groups ensure there are some for fnfunc, instance or autonomous. Using reverse logic so starts as a false for dynamic_group in self.__dynamic_groups: @@ -3341,14 +3337,13 @@ def __report_cis_analyze_tenancy_data(self): # CIS Total 1.13 Adding - All Dynamic Groups for to CIS Total self.cis_foundations_benchmark_1_2['1.13']['Total'] = self.__dynamic_groups - - # CIS 1.14 Check - Ensure storage service-level admins cannot delete resources they manage. + # CIS 1.14 Check - Ensure storage service-level admins cannot delete resources they manage. # Iterating through all policies for policy in self.__policies: if policy['name'].upper() != "Tenant Admin Policy".upper() and policy['name'].upper() != "PSM-root-policy": for statement in policy['statements']: for resource in self.cis_iam_checks['1.14']: - if "allow group".upper() in statement.upper() and "manage".upper() in statement.upper() and resource.upper() in statement.upper(): + if "allow group".upper() in statement.upper() and "manage".upper() in statement.upper() and resource.upper() in statement.upper(): split_statement = statement.split("where") if len(split_statement) == 2: clean_where_clause = split_statement[1].upper().replace(" ", "").replace("'", "") @@ -3358,7 +3353,7 @@ def __report_cis_analyze_tenancy_data(self): self.cis_foundations_benchmark_1_2['1.14']['Findings'].append(policy) else: self.cis_foundations_benchmark_1_2['1.14']['Findings'].append(policy) - + if self.cis_foundations_benchmark_1_2['1.14']['Findings']: self.cis_foundations_benchmark_1_2['1.14']['Status'] = False else: @@ -3374,8 +3369,8 @@ def __report_cis_analyze_tenancy_data(self): if irule['tcp_options'] and irule['tcp_options']['destinationPortRange']: port_min = irule['tcp_options']['destinationPortRange']['min'] port_max = irule['tcp_options']['destinationPortRange']['max'] - ports_range = range(port_min, port_max +1) - if 22 in ports_range: + ports_range = range(port_min, port_max + 1) + if 22 in ports_range: self.cis_foundations_benchmark_1_2['2.1']['Status'] = False self.cis_foundations_benchmark_1_2['2.1']['Findings'].append(sl) if 3389 in ports_range: @@ -3396,13 +3391,11 @@ def __report_cis_analyze_tenancy_data(self): self.cis_foundations_benchmark_1_2['2.2']['Status'] = False self.cis_foundations_benchmark_1_2['2.2']['Findings'].append(sl) break - + # CIS Total 2.1, 2.2 Adding - All SLs for to CIS Total self.cis_foundations_benchmark_1_2['2.1']['Total'] = self.__network_security_lists self.cis_foundations_benchmark_1_2['2.2']['Total'] = self.__network_security_lists - - # CIS 2.5 Check - any rule with 0.0.0.0 where protocol not 1 (ICMP) # CIS Total 2.5 Adding - All Default Security List for to CIS Total for sl in self.__network_security_lists: @@ -3422,7 +3415,7 @@ def __report_cis_analyze_tenancy_data(self): if rule['tcp_options'] and rule['tcp_options'].destination_port_range: port_min = rule['tcp_options'].destination_port_range.min port_max = rule['tcp_options'].destination_port_range.max - ports_range = range(port_min,port_max+1) + ports_range = range(port_min, port_max + 1) if 22 in ports_range: self.cis_foundations_benchmark_1_2['2.3']['Status'] = False self.cis_foundations_benchmark_1_2['2.3']['Findings'].append( @@ -3445,16 +3438,15 @@ def __report_cis_analyze_tenancy_data(self): self.cis_foundations_benchmark_1_2['2.4']['Status'] = False self.cis_foundations_benchmark_1_2['2.4']['Findings'].append(nsg) break - + # CIS Total 2.2 & 2.4 Adding - All NSGs Instances to CIS Total self.cis_foundations_benchmark_1_2['2.3']['Total'] = self.__network_security_groups self.cis_foundations_benchmark_1_2['2.4']['Total'] = self.__network_security_groups - # CIS 2.6 - Ensure Oracle Integration Cloud (OIC) access is restricted to allowed sources # Iterating through OIC instance have network access rules and ensure 0.0.0.0/0 is not in the list for integration_instance in self.__integration_instances: - if not(integration_instance['network_endpoint_details']): + if not (integration_instance['network_endpoint_details']): self.cis_foundations_benchmark_1_2['2.6']['Status'] = False self.cis_foundations_benchmark_1_2['2.6']['Findings'].append( integration_instance) @@ -3462,34 +3454,31 @@ def __report_cis_analyze_tenancy_data(self): if "0.0.0.0/0" in str(integration_instance['network_endpoint_details']): self.cis_foundations_benchmark_1_2['2.6']['Status'] = False self.cis_foundations_benchmark_1_2['2.6']['Findings'].append( - integration_instance) + integration_instance) # CIS Total 2.6 Adding - All OIC Instances to CIS Total self.cis_foundations_benchmark_1_2['2.6']['Total'] = self.__integration_instances - # CIS 2.7 - Ensure Oracle Analytics Cloud (OAC) access is restricted to allowed sources or deployed within a VCN for analytics_instance in self.__analytics_instances: if analytics_instance['network_endpoint_type'].upper() == 'PUBLIC': - if not(analytics_instance['network_endpoint_details'].whitelisted_ips): + if not (analytics_instance['network_endpoint_details'].whitelisted_ips): self.cis_foundations_benchmark_1_2['2.7']['Status'] = False - self.cis_foundations_benchmark_1_2['2.7']['Findings'].append( - analytics_instance) + self.cis_foundations_benchmark_1_2['2.7']['Findings'].append(analytics_instance) elif "0.0.0.0/0" in analytics_instance['network_endpoint_details'].whitelisted_ips: self.cis_foundations_benchmark_1_2['2.7']['Status'] = False self.cis_foundations_benchmark_1_2['2.7']['Findings'].append( - analytics_instance) + analytics_instance) # CIS Total 2.7 Adding - All OAC Instances to CIS Total self.cis_foundations_benchmark_1_2['2.7']['Total'] = self.__analytics_instances - # CIS 2.8 Check - Ensure Oracle Autonomous Shared Databases (ADB) access is restricted to allowed sources or deployed within a VCN - # Iterating through ADB Checking for null NSGs, whitelisted ip or allowed IPs 0.0.0.0/0 + # Iterating through ADB Checking for null NSGs, whitelisted ip or allowed IPs 0.0.0.0/0 for autonomous_database in self.__autonomous_databases: - if autonomous_database['lifecycle_state']!="UNAVAILABLE": - if not(autonomous_database['whitelisted_ips']) and not(autonomous_database['subnet_id']): + if autonomous_database['lifecycle_state'] != "UNAVAILABLE": + if not (autonomous_database['whitelisted_ips']) and not (autonomous_database['subnet_id']): self.cis_foundations_benchmark_1_2['2.8']['Status'] = False self.cis_foundations_benchmark_1_2['2.8']['Findings'].append( autonomous_database) @@ -3503,7 +3492,6 @@ def __report_cis_analyze_tenancy_data(self): # CIS Total 2.8 Adding - All ADBs to CIS Total self.cis_foundations_benchmark_1_2['2.8']['Total'] = self.__autonomous_databases - # CIS 3.1 Check - Ensure Audit log retention == 365 - Only checking in home region if self.__audit_retention_period >= 365: self.cis_foundations_benchmark_1_2['3.1']['Status'] = True @@ -3517,7 +3505,6 @@ def __report_cis_analyze_tenancy_data(self): # CIS Total 3.2 Adding - All Tag Defaults to CIS Total self.cis_foundations_benchmark_1_2['3.2']['Total'] = self.__tag_defaults - # CIS Check 3.3 - Check for Active Notification and Subscription if len(self.__subscriptions) > 0: self.cis_foundations_benchmark_1_2['3.3']['Status'] = True @@ -3525,7 +3512,6 @@ def __report_cis_analyze_tenancy_data(self): # CIS Check 3.2 Total - All Subscriptions to CIS Total self.cis_foundations_benchmark_1_2['3.3']['Total'] = self.__subscriptions - # CIS Checks 3.4 - 3.13 # Iterate through all event rules for event in self.__event_rules: @@ -3533,7 +3519,7 @@ def __report_cis_analyze_tenancy_data(self): jsonable_str = event['condition'].lower().replace("'", "\"") try: event_dict = json.loads(jsonable_str) - except: + except Exception: print("*** Invalid Event Condition for event (not in JSON format): " + event['display_name'] + " ***") event_dict = {} # Issue 256: 'eventtpye' not in event_dict (i.e. missing in event condition) @@ -3541,22 +3527,21 @@ def __report_cis_analyze_tenancy_data(self): for key, changes in self.cis_monitoring_checks.items(): # Checking if all cis change list is a subset of event condition try: - if(all(x in event_dict['eventtype'] for x in changes)): + if (all(x in event_dict['eventtype'] for x in changes)): self.cis_foundations_benchmark_1_2[key]['Status'] = True - except Exception as e: + except Exception: print("*** Invalid Event Data for event: " + event['display_name'] + " ***") - + # CIS Check 3.14 - VCN FlowLog enable # Generate list of subnets IDs for subnet in self.__network_subnets: - if not(subnet['id'] in self.__subnet_logs): + if not (subnet['id'] in self.__subnet_logs): self.cis_foundations_benchmark_1_2['3.14']['Status'] = False self.cis_foundations_benchmark_1_2['3.14']['Findings'].append( subnet) # CIS Check 3.14 Total - Adding All Subnets to total - self.cis_foundations_benchmark_1_2['3.14']['Total'] = self.__network_subnets - + self.cis_foundations_benchmark_1_2['3.14']['Total'] = self.__network_subnets # CIS Check 3.15 - Cloud Guard enabled if self.__cloud_guard_config_status == 'ENABLED': @@ -3568,28 +3553,26 @@ def __report_cis_analyze_tenancy_data(self): # Generating list of keys for vault in self.__vaults: for key in vault['keys']: - if self.kms_key_time_max_datetime >= datetime.datetime.strptime(key['time_created'], self.__iso_time_format): + if self.kms_key_time_max_datetime >= datetime.datetime.strptime(key['time_created'], self.__iso_time_format): self.cis_foundations_benchmark_1_2['3.16']['Status'] = False self.cis_foundations_benchmark_1_2['3.16']['Findings'].append( key) - + # CIS Check 3.16 Total - Adding Key to total self.cis_foundations_benchmark_1_2['3.16']['Total'].append(key) - # CIS Check 3.17 - Object Storage with Logs # Generating list of buckets names - - for bucket in self.__buckets: - if not(bucket['name'] in self.__write_bucket_logs): + + for bucket in self.__buckets: + if not (bucket['name'] in self.__write_bucket_logs): self.cis_foundations_benchmark_1_2['3.17']['Status'] = False self.cis_foundations_benchmark_1_2['3.17']['Findings'].append( bucket) - + # CIS Check 3.17 Total - Adding All Buckets to total self.cis_foundations_benchmark_1_2['3.17']['Total'] = self.__buckets - # CIS Section 4.1 Bucket Checks # Generating list of buckets names for bucket in self.__buckets: @@ -3600,11 +3583,11 @@ def __report_cis_analyze_tenancy_data(self): bucket) if 'kms_key_id' in bucket: - if not(bucket['kms_key_id']): + if not (bucket['kms_key_id']): self.cis_foundations_benchmark_1_2['4.1.2']['Findings'].append( bucket) self.cis_foundations_benchmark_1_2['4.1.2']['Status'] = False - + if 'versioning' in bucket: if bucket['versioning'] != "Enabled": self.cis_foundations_benchmark_1_2['4.1.3']['Findings'].append( @@ -3613,28 +3596,26 @@ def __report_cis_analyze_tenancy_data(self): # CIS Check 4.1.1,4.1.2,4.1.3 Total - Adding All Buckets to total self.cis_foundations_benchmark_1_2['4.1.1']['Total'] = self.__buckets - self.cis_foundations_benchmark_1_2['4.1.2']['Total'] = self.__buckets - self.cis_foundations_benchmark_1_2['4.1.3']['Total'] = self.__buckets - + self.cis_foundations_benchmark_1_2['4.1.2']['Total'] = self.__buckets + self.cis_foundations_benchmark_1_2['4.1.3']['Total'] = self.__buckets # CIS Section 4.2.1 Block Volume Checks # Generating list of block volumes names for volume in self.__block_volumes: if 'kms_key_id' in volume: - if not(volume['kms_key_id']): + if not (volume['kms_key_id']): self.cis_foundations_benchmark_1_2['4.2.1']['Findings'].append( volume) self.cis_foundations_benchmark_1_2['4.2.1']['Status'] = False - + # CIS Check 4.2.1 Total - Adding All Block Volumes to total self.cis_foundations_benchmark_1_2['4.2.1']['Total'] = self.__block_volumes - # CIS Section 4.2.2 Boot Volume Checks # Generating list of boot names for boot_volume in self.__boot_volumes: if 'kms_key_id' in boot_volume: - if not(boot_volume['kms_key_id']): + if not (boot_volume['kms_key_id']): self.cis_foundations_benchmark_1_2['4.2.2']['Findings'].append( boot_volume) self.cis_foundations_benchmark_1_2['4.2.2']['Status'] = False @@ -3642,17 +3623,15 @@ def __report_cis_analyze_tenancy_data(self): # CIS Check 4.2.2 Total - Adding All Block Volumes to total self.cis_foundations_benchmark_1_2['4.2.2']['Total'] = self.__boot_volumes - # CIS Section 4.3.1 FSS Checks # Generating list of FSS names for file_system in self.__file_storage_system: if 'kms_key_id' in file_system: - if not(file_system['kms_key_id']): + if not (file_system['kms_key_id']): self.cis_foundations_benchmark_1_2['4.3.1']['Findings'].append( file_system) self.cis_foundations_benchmark_1_2['4.3.1']['Status'] = False - # CIS Check 4.3.1 Total - Adding All Block Volumes to total self.cis_foundations_benchmark_1_2['4.3.1']['Total'] = self.__file_storage_system @@ -3669,12 +3648,12 @@ def __report_cis_analyze_tenancy_data(self): ########################################################################## # Recursive function the gets the child compartments of a compartment - ########################################################################## - + ########################################################################## + def __get_children(self, parent, compartments): try: kids = compartments[parent] - except: + except Exception: kids = [] if kids: @@ -3687,50 +3666,69 @@ def __get_children(self, parent, compartments): # Analyzes Tenancy Data for Oracle Best Practices Report ########################################################################## def __obp_analyze_tenancy_data(self): - + ####################################### - ### Budget Checks + # Budget Checks ####################################### - ## Determines if a Budget Exists with an alert rule + # Determines if a Budget Exists with an alert rule if len(self.__budgets) > 0: for budget in self.__budgets: - if budget['alert_rule_count'] >0 and budget['target_compartment_id'] == self.__tenancy.id: + if budget['alert_rule_count'] > 0 and budget['target_compartment_id'] == self.__tenancy.id: self.obp_foundations_checks['Cost_Tracking_Budgets']['Status'] = True self.obp_foundations_checks['Cost_Tracking_Budgets']['OBP'].append(budget) else: self.obp_foundations_checks['Cost_Tracking_Budgets']['Findings'].append(budget) - # Stores Regional Checks + # Stores Regional Checks for region_key, region_values in self.__regions.items(): - self.__obp_regional_checks[region_key] = {"Audit" : {"tenancy_level_audit" : False, "tenancy_level_include_sub_comps" : False, "compartments" : [], "findings" : []}, - "VCN" : {"subnets" : [], "findings" : []}, - "Write_Bucket" : {"buckets" : [], "findings" : []}, - "Read_Bucket" : {"buckets" : [], "findings" : []}, - "Network_Connectivity" : {"drgs" : [], "findings" : [], "status" : False}, - } + self.__obp_regional_checks[region_key] = { + "Audit": { + "tenancy_level_audit": False, + "tenancy_level_include_sub_comps": False, + "compartments": [], + "findings": [] + }, + "VCN": { + "subnets": [], + "findings": [] + }, + "Write_Bucket": { + "buckets": [], + "findings": [] + }, + "Read_Bucket": { + "buckets": [], + "findings": [] + }, + "Network_Connectivity": { + "drgs": [], + "findings": [], + "status": False + }, + } ####################################### - ### OCI Audit Log Compartments Checks + # OCI Audit Log Compartments Checks ####################################### list_of_all_compartments = [] dict_of_compartments = {} for compartment in self.__compartments: list_of_all_compartments.append(compartment.id) - + # Building a Hash Table of Parent Child Hieracrchy for Audit dict_of_compartments = {} for compartment in self.__compartments: if "tenancy" not in compartment.id: try: dict_of_compartments[compartment.compartment_id].append(compartment.id) - except: + except Exception: dict_of_compartments[compartment.compartment_id] = [] dict_of_compartments[compartment.compartment_id].append(compartment.id) - + # This is used for comparing compartments that are audit to the full list of compartments set_of_all_compartments = set(list_of_all_compartments) - ## Collecting Servie Connectors Logs related to compartments + # Collecting Servie Connectors Logs related to compartments for sch_id, sch_values in self.__service_connectors.items(): # Only Active SCH with a target that is configured if sch_values['lifecycle_state'].upper() == "ACTIVE" and sch_values['target_kind']: @@ -3743,17 +3741,17 @@ def __obp_analyze_tenancy_data(self): # Since it is not the Tenancy we should add the compartment to the list and check if sub compartment are included elif source['log_group_id'].upper() == "_Audit_Include_Subcompartment".upper(): - self.__obp_regional_checks[sch_values['region']]['Audit']['compartments'] += self.__get_children(source['compartment_id'],dict_of_compartments) + self.__obp_regional_checks[sch_values['region']]['Audit']['compartments'] += self.__get_children(source['compartment_id'], dict_of_compartments) elif source['log_group_id'].upper() == "_Audit".upper(): self.__obp_regional_checks[sch_values['region']]['Audit']['compartments'].append(source['compartment_id']) - except: + except Exception: # There can be empty log groups pass - ## Analyzing Service Connector Audit Logs to see if each region has all compartments + # Analyzing Service Connector Audit Logs to see if each region has all compartments for region_key, region_values in self.__obp_regional_checks.items(): # Checking if I already found the tenancy ocid with all child compartments included if not region_values['Audit']['tenancy_level_audit']: - audit_findings = set_of_all_compartments - set(region_values['Audit']['compartments']) + audit_findings = set_of_all_compartments - set(region_values['Audit']['compartments']) # If there are items in the then it is not auditing everything in the tenancy if audit_findings: region_values['Audit']['findings'] += list(audit_findings) @@ -3761,28 +3759,26 @@ def __obp_analyze_tenancy_data(self): region_values['Audit']['tenancy_level_audit'] = True region_values['Audit']['findings'] = [] - - - ## Consolidating Audit findings into the OBP Checks + # Consolidating Audit findings into the OBP Checks for region_key, region_values in self.__obp_regional_checks.items(): # If this flag is set all compartments are not logged in region if not region_values['Audit']['tenancy_level_audit']: self.obp_foundations_checks['SIEM_Audit_Log_All_Comps']['Status'] = False - + # If this flag is set the region has the tenancy logging and all sub compartments flag checked if not region_values['Audit']['tenancy_level_include_sub_comps']: self.obp_foundations_checks['SIEM_Audit_Incl_Sub_Comp']['Status'] = False - self.obp_foundations_checks['SIEM_Audit_Incl_Sub_Comp']['Findings'].append({"region_name" : region_key}) + self.obp_foundations_checks['SIEM_Audit_Incl_Sub_Comp']['Findings'].append({"region_name": region_key}) else: - self.obp_foundations_checks['SIEM_Audit_Incl_Sub_Comp']['OBP'].append({"region_name" : region_key}) + self.obp_foundations_checks['SIEM_Audit_Incl_Sub_Comp']['OBP'].append({"region_name": region_key}) # Compartment Logs that are missed in the region for compartment in region_values['Audit']['findings']: try: - finding = list(filter(lambda source: source['id']== compartment, self.__raw_compartment ))[0] - record = { - "id" : finding['id'], - "name" : finding['name'], + finding = list(filter(lambda source: source['id'] == compartment, self.__raw_compartment))[0] + record = { + "id": finding['id'], + "name": finding['name'], "deep_link": finding['deep_link'], "compartment_id": finding['compartment_id'], "defined_tags": finding['defined_tags'], @@ -3792,12 +3788,12 @@ def __obp_analyze_tenancy_data(self): "is_accessible": finding['is_accessible'], "lifecycle_state": finding['lifecycle_state'], "time_created": finding['time_created'], - "region" : region_key + "region": region_key } except Exception as e: - record = { - "id" : compartment, - "name" : "Compartment No Longer Exists", + record = { + "id": compartment, + "name": "Compartment No Longer Exists", "deep_link": "", "compartment_id": "", "defined_tags": "", @@ -3807,20 +3803,20 @@ def __obp_analyze_tenancy_data(self): "is_accessible": "", "lifecycle_state": "", "time_created": "", - "region" : region_key + "region": region_key } # Need to check for duplicates before adding the record - exists_already = list(filter(lambda source: source['id']== record['id'] and source['region']== record['region'], self.obp_foundations_checks['SIEM_Audit_Log_All_Comps']['Findings'] )) + exists_already = list(filter(lambda source: source['id'] == record['id'] and source['region'] == record['region'], self.obp_foundations_checks['SIEM_Audit_Log_All_Comps']['Findings'])) if not exists_already: self.obp_foundations_checks['SIEM_Audit_Log_All_Comps']['Findings'].append(record) - + # Compartment logs that are not missed in the region for compartment in region_values['Audit']['compartments']: try: - finding = list(filter(lambda source: source['id']== compartment, self.__raw_compartment ))[0] - record = { - "id" : finding['id'], - "name" : finding['name'], + finding = list(filter(lambda source: source['id'] == compartment, self.__raw_compartment))[0] + record = { + "id": finding['id'], + "name": finding['name'], "deep_link": finding['deep_link'], "compartment_id": finding['compartment_id'], "defined_tags": finding['defined_tags'], @@ -3830,12 +3826,12 @@ def __obp_analyze_tenancy_data(self): "is_accessible": finding['is_accessible'], "lifecycle_state": finding['lifecycle_state'], "time_created": finding['time_created'], - "region" : region_key + "region": region_key } except Exception as e: - record = { - "id" : compartment, - "name" : "Compartment No Longer Exists", + record = { + "id": compartment, + "name": "Compartment No Longer Exists", "deep_link": "", "compartment_id": "", "defined_tags": "", @@ -3845,129 +3841,130 @@ def __obp_analyze_tenancy_data(self): "is_accessible": "", "lifecycle_state": "", "time_created": "", - "region" : region_key + "region": region_key } # Need to check for duplicates before adding the record - exists_already = list(filter(lambda source: source['id'] == record['id'] and source['region'] == record['region'], self.obp_foundations_checks['SIEM_Audit_Log_All_Comps']['OBP'] )) + exists_already = list(filter(lambda source: source['id'] == record['id'] and source['region'] == record['region'], self.obp_foundations_checks['SIEM_Audit_Log_All_Comps']['OBP'])) if not exists_already: self.obp_foundations_checks['SIEM_Audit_Log_All_Comps']['OBP'].append(record) - + ####################################### - ### Subnet and Bucket Log Checks + # Subnet and Bucket Log Checks ####################################### for sch_id, sch_values in self.__service_connectors.items(): # Only Active SCH with a target that is configured if sch_values['lifecycle_state'].upper() == "ACTIVE" and sch_values['target_kind']: - ### Subnet Logs Checks + # Subnet Logs Checks for subnet_id, log_values in self.__subnet_logs.items(): - + log_id = log_values['log_id'] log_group_id = log_values['log_group_id'] - log_record = {"sch_id": sch_id , "sch_name" : sch_values['display_name'], "id" : subnet_id} - - subnet_log_group_in_sch = list(filter(lambda source: source['log_group_id'] == log_group_id, sch_values['log_sources'] )) - subnet_log_in_sch = list(filter(lambda source: source['log_id'] == log_id, sch_values['log_sources'] )) + log_record = {"sch_id": sch_id, "sch_name": sch_values['display_name'], "id": subnet_id} - # Checking if the Subnets's log group in is in SCH's log sources & the log_id is empty so it covers everything in the log group - if subnet_log_group_in_sch and not(subnet_log_in_sch): + subnet_log_group_in_sch = list(filter(lambda source: source['log_group_id'] == log_group_id, sch_values['log_sources'])) + subnet_log_in_sch = list(filter(lambda source: source['log_id'] == log_id, sch_values['log_sources'])) + + # Checking if the Subnets's log group in is in SCH's log sources & the log_id is empty so it covers everything in the log group + if subnet_log_group_in_sch and not (subnet_log_in_sch): self.__obp_regional_checks[sch_values['region']]['VCN']['subnets'].append(log_record) # Checking if the Subnet's log id in is in the service connector's log sources if so I will add it elif subnet_log_in_sch: self.__obp_regional_checks[sch_values['region']]['VCN']['subnets'].append(log_record) - + # else: # self.__obp_regional_checks[sch_values['region']]['VCN']['findings'].append(subnet_id) - ### Bucket Write Logs Checks + # Bucket Write Logs Checks for bucket_name, log_values in self.__write_bucket_logs.items(): log_id = log_values['log_id'] log_group_id = log_values['log_group_id'] + log_record = {"sch_id": sch_id, "sch_name": sch_values['display_name'], "id": bucket_name} log_region = log_values['region'] - log_record = {"sch_id": sch_id , "sch_name" : sch_values['display_name'], "id" : bucket_name} - bucket_log_group_in_sch = list(filter(lambda source: source['log_group_id'] == log_group_id and sch_values['region'] == log_region, sch_values['log_sources'] )) - bucket_log_in_sch = list(filter(lambda source: source['log_id'] == log_id and sch_values['region'] == log_region, sch_values['log_sources'])) + bucket_log_group_in_sch = list(filter(lambda source: source['log_group_id'] == log_group_id and sch_values['region'] == log_region, sch_values['log_sources'])) + bucket_log_in_sch = list(filter(lambda source: source['log_id'] == log_id and sch_values['region'] == log_region, sch_values['log_sources'])) - # Checking if the Bucket's log group in is in SCH's log sources & the log_id is empty so it covers everything in the log group - if bucket_log_group_in_sch and not(bucket_log_in_sch): + # Checking if the Bucket's log group in is in SCH's log sources & the log_id is empty so it covers everything in the log group + if bucket_log_group_in_sch and not (bucket_log_in_sch): self.__obp_regional_checks[sch_values['region']]['Write_Bucket']['buckets'].append(log_record) - + # Checking if the Bucket's log Group in is in the service connector's log sources if so I will add it elif bucket_log_in_sch: self.__obp_regional_checks[sch_values['region']]['Write_Bucket']['buckets'].append(log_record) # else: # self.__obp_regional_checks[sch_values['region']]['Write_Bucket']['findings'].append(bucket_name) - - ### Bucket Read Log Checks + + # Bucket Read Log Checks for bucket_name, log_values in self.__read_bucket_logs.items(): log_id = log_values['log_id'] log_group_id = log_values['log_group_id'] + log_record = {"sch_id": sch_id, "sch_name": sch_values['display_name'], "id": bucket_name} + log_region = log_values['region'] - log_record = {"sch_id": sch_id , "sch_name" : sch_values['display_name'], "id" : bucket_name} - bucket_log_group_in_sch = list(filter(lambda source: source['log_group_id'] == log_group_id and sch_values['region'] == log_region, sch_values['log_sources'] )) - bucket_log_in_sch = list(filter(lambda source: source['log_id'] == log_id and sch_values['region'] == log_region, sch_values['log_sources'])) + bucket_log_group_in_sch = list(filter(lambda source: source['log_group_id'] == log_group_id and sch_values['region'] == log_region, sch_values['log_sources'])) + bucket_log_in_sch = list(filter(lambda source: source['log_id'] == log_id and sch_values['region'] == log_region, sch_values['log_sources'])) - # Checking if the Bucket's log group in is in SCH's log sources & the log_id is empty so it covers everything in the log group - if bucket_log_group_in_sch and not(bucket_log_in_sch): + # Checking if the Bucket's log group in is in SCH's log sources & the log_id is empty so it covers everything in the log group + if bucket_log_group_in_sch and not (bucket_log_in_sch): self.__obp_regional_checks[sch_values['region']]['Read_Bucket']['buckets'].append(log_record) # Checking if the Bucket's log id in is in the service connector's log sources if so I will add it elif bucket_log_in_sch: self.__obp_regional_checks[sch_values['region']]['Read_Bucket']['buckets'].append(log_record) - - ### Consolidating regional SERVICE LOGGING findings into centralized finding report + # Consolidating regional SERVICE LOGGING findings into centralized finding report for region_key, region_values in self.__obp_regional_checks.items(): - + for finding in region_values['VCN']['subnets']: - logged_subnet = list(filter(lambda subnet: subnet['id'] == finding['id'], self.__network_subnets )) - # Checking that the subnet has not already been written to OBP + logged_subnet = list(filter(lambda subnet: subnet['id'] == finding['id'], self.__network_subnets)) + # Checking that the subnet has not already been written to OBP existing_finding = list(filter(lambda subnet: subnet['id'] == finding['id'], self.obp_foundations_checks['SIEM_VCN_Flow_Logging']['OBP'])) record = logged_subnet[0].copy() record['sch_id'] = finding['sch_id'] record['sch_name'] = finding['sch_name'] - - if logged_subnet and not(existing_finding): + + if logged_subnet and not (existing_finding): self.obp_foundations_checks['SIEM_VCN_Flow_Logging']['OBP'].append(record) # else: # print("Found this subnet being logged but the subnet does not exist: " + str(finding)) for finding in region_values['Write_Bucket']['buckets']: - logged_bucket = list(filter(lambda bucket: bucket['name'] == finding['id'], self.__buckets )) + logged_bucket = list(filter(lambda bucket: bucket['name'] == finding['id'], self.__buckets)) record = logged_bucket[0].copy() record['sch_id'] = finding['sch_id'] record['sch_name'] = finding['sch_name'] + if logged_bucket: self.obp_foundations_checks['SIEM_Write_Bucket_Logs']['OBP'].append(record) for finding in region_values['Read_Bucket']['buckets']: - logged_bucket = list(filter(lambda bucket: bucket['name'] == finding['id'], self.__buckets )) + logged_bucket = list(filter(lambda bucket: bucket['name'] == finding['id'], self.__buckets)) record = logged_bucket[0].copy() record['sch_id'] = finding['sch_id'] record['sch_name'] = finding['sch_name'] + if logged_bucket: self.obp_foundations_checks['SIEM_Read_Bucket_Logs']['OBP'].append(record) - # Finding looking at all buckets and seeing if they meet one of the OBPs in one of the regions for finding in self.__buckets: read_logged_bucket = list(filter(lambda bucket: bucket['name'] == finding['name'] and bucket['region'] == finding['region'], self.obp_foundations_checks['SIEM_Read_Bucket_Logs']['OBP'])) - if not(read_logged_bucket): + if not (read_logged_bucket): self.obp_foundations_checks['SIEM_Read_Bucket_Logs']['Findings'].append(finding) - + write_logged_bucket = list(filter(lambda bucket: bucket['name'] == finding['name'] and bucket['region'] == finding['region'], self.obp_foundations_checks['SIEM_Write_Bucket_Logs']['OBP'])) - if not(write_logged_bucket): + if not (write_logged_bucket): self.obp_foundations_checks['SIEM_Write_Bucket_Logs']['Findings'].append(finding) # Finding looking at all subnet and seeing if they meet one of the OBPs in one of the regions for finding in self.__network_subnets: logged_subnet = list(filter(lambda subnet: subnet['id'] == finding['id'], self.obp_foundations_checks['SIEM_VCN_Flow_Logging']['OBP'])) - if not(logged_subnet): - self.obp_foundations_checks['SIEM_VCN_Flow_Logging']['Findings'].append(finding) + if not (logged_subnet): + self.obp_foundations_checks['SIEM_VCN_Flow_Logging']['Findings'].append(finding) # Setting VCN Flow Logs Findings if self.obp_foundations_checks['SIEM_VCN_Flow_Logging']['Findings']: @@ -3976,7 +3973,7 @@ def __obp_analyze_tenancy_data(self): else: self.obp_foundations_checks['SIEM_VCN_Flow_Logging']['Status'] = True - ## Setting Write Bucket Findings + # Setting Write Bucket Findings if self.obp_foundations_checks['SIEM_Write_Bucket_Logs']['Findings']: self.obp_foundations_checks['SIEM_Write_Bucket_Logs']['Status'] = False @@ -3988,11 +3985,10 @@ def __obp_analyze_tenancy_data(self): else: self.obp_foundations_checks['SIEM_Write_Bucket_Logs']['Status'] = True - ## Setting Read Bucket Findings + # Setting Read Bucket Findings if self.obp_foundations_checks['SIEM_Read_Bucket_Logs']['Findings']: self.obp_foundations_checks['SIEM_Read_Bucket_Logs']['Status'] = False - elif not self.__service_connectors: # If there are no service connectors then by default all buckets are not logged self.obp_foundations_checks['SIEM_Read_Bucket_Logs']['Status'] = False @@ -4000,39 +3996,36 @@ def __obp_analyze_tenancy_data(self): else: self.obp_foundations_checks['SIEM_Read_Bucket_Logs']['Status'] = True - ####################################### - ### OBP Networking Checks + # OBP Networking Checks ####################################### - ### Fast Connect Connections + # Fast Connect Connections for drg_id, drg_values in self.__network_drg_attachments.items(): number_of_valid_connected_vcns = 0 number_of_valid_fast_connect_circuits = 0 number_of_valid_site_to_site_connection = 0 - + fast_connect_providers = set() customer_premises_equipment = set() - for attachment in drg_values: if attachment['network_type'].upper() == 'VCN': # Checking if DRG has a valid VCN attached to it - number_of_valid_connected_vcns += 1 + number_of_valid_connected_vcns += 1 elif attachment['network_type'].upper() == 'IPSEC_TUNNEL': # Checking if the IPSec Connection has both tunnels up for ipsec_connection in self.__network_ipsec_connections[drg_id]: if ipsec_connection['tunnels_up']: - # Good IP Sec Connection increment valid site to site and track CPEs + # Good IP Sec Connection increment valid site to site and track CPEs customer_premises_equipment.add(ipsec_connection['cpe_id']) - number_of_valid_site_to_site_connection +=1 - + number_of_valid_site_to_site_connection += 1 elif attachment['network_type'].upper() == 'VIRTUAL_CIRCUIT': - - # Checking for Provision and BGP enabled Virtual Circuits and that it is associated + + # Checking for Provision and BGP enabled Virtual Circuits and that it is associated for virtual_circuit in self.__network_fastconnects[attachment['drg_id']]: if attachment['network_id'] == virtual_circuit['id']: if virtual_circuit['lifecycle_state'].upper() == 'PROVISIONED' and virtual_circuit['bgp_session_state'].upper() == "UP": @@ -4042,29 +4035,29 @@ def __obp_analyze_tenancy_data(self): try: record = { - "drg_id" : drg_id, - "drg_display_name" : self.__network_drgs[drg_id]['display_name'], - "region" : self.__network_drgs[drg_id]['region'], - "number_of_connected_vcns" : number_of_valid_connected_vcns, - "number_of_customer_premises_equipment" : len(customer_premises_equipment), - "number_of_connected_ipsec_connections" : number_of_valid_site_to_site_connection, - "number_of_fastconnects_cicruits" : number_of_valid_fast_connect_circuits, - "number_of_fastconnect_providers" : len(fast_connect_providers), + "drg_id": drg_id, + "drg_display_name": self.__network_drgs[drg_id]['display_name'], + "region": self.__network_drgs[drg_id]['region'], + "number_of_connected_vcns": number_of_valid_connected_vcns, + "number_of_customer_premises_equipment": len(customer_premises_equipment), + "number_of_connected_ipsec_connections": number_of_valid_site_to_site_connection, + "number_of_fastconnects_cicruits": number_of_valid_fast_connect_circuits, + "number_of_fastconnect_providers": len(fast_connect_providers), } - except: + except Exception: record = { - "drg_id" : drg_id, - "drg_display_name" : "Deleted with an active attachement", - "region" : attachment['region'], - "number_of_connected_vcns" : 0, - "number_of_customer_premises_equipment" : 0, - "number_of_connected_ipsec_connections" : 0, - "number_of_fastconnects_cicruits" : 0, - "number_of_fastconnect_providers" : 0, + "drg_id": drg_id, + "drg_display_name": "Deleted with an active attachement", + "region": attachment['region'], + "number_of_connected_vcns": 0, + "number_of_customer_premises_equipment": 0, + "number_of_connected_ipsec_connections": 0, + "number_of_fastconnects_cicruits": 0, + "number_of_fastconnect_providers": 0, } print(f"This DRG: {drg_id} is deleted with an active attachement: {attachment['display_name']}") - #Checking if the DRG and connected resourcs are aligned with best practices + # Checking if the DRG and connected resourcs are aligned with best practices # One attached VCN, One VPN connection and one fast connect if number_of_valid_connected_vcns and number_of_valid_site_to_site_connection and number_of_valid_fast_connect_circuits: self.__obp_regional_checks[record['region']]["Network_Connectivity"]["drgs"].append(record) @@ -4080,40 +4073,38 @@ def __obp_analyze_tenancy_data(self): else: self.__obp_regional_checks[record['region']]["Network_Connectivity"]["findings"].append(record) + # Consolidating Regional - ### Consolidating Regional - for region_key, region_values in self.__obp_regional_checks.items(): # I assume you are well connected in all regions if find one region that is not it fails if not region_values["Network_Connectivity"]["status"]: self.obp_foundations_checks['Networking_Connectivity']['Status'] = False - + self.obp_foundations_checks["Networking_Connectivity"]["Findings"] += region_values["Network_Connectivity"]["findings"] self.obp_foundations_checks["Networking_Connectivity"]["OBP"] += region_values["Network_Connectivity"]["drgs"] ####################################### - ### Cloud Guard Checks - ####################################### + # Cloud Guard Checks + ####################################### cloud_guard_record = { - "cloud_guard_endable" : True if self.__cloud_guard_config_status == 'ENABLED' else False, - "target_at_root" : False, - "targert_configuration_detector" : False, - "targert_configuration_detector_customer_owned" : False, - "target_activity_detector" : False, - "target_activity_detector_customer_owned" : False, - "target_threat_detector" : False, - "target_threat_detector_customer_owned" : False, - "target_responder_recipes" : False, - "target_responder_recipes_customer_owned" : False, - "target_responder_event_rule" : False, + "cloud_guard_endable": True if self.__cloud_guard_config_status == 'ENABLED' else False, + "target_at_root": False, + "targert_configuration_detector": False, + "targert_configuration_detector_customer_owned": False, + "target_activity_detector": False, + "target_activity_detector_customer_owned": False, + "target_threat_detector": False, + "target_threat_detector_customer_owned": False, + "target_responder_recipes": False, + "target_responder_recipes_customer_owned": False, + "target_responder_event_rule": False, } - + try: # Cloud Guard Target attached to the root compartment with activity, config, and threat detector plus a responder if self.__cloud_guard_targets[self.__tenancy.id]: - - cloud_guard_record['target_at_root'] = True + cloud_guard_record['target_at_root'] = True if self.__cloud_guard_targets[self.__tenancy.id]: if self.__cloud_guard_targets[self.__tenancy.id]['target_detector_recipes']: @@ -4123,7 +4114,6 @@ def __obp_analyze_tenancy_data(self): if recipe.owner.upper() == "CUSTOMER": cloud_guard_record['targert_configuration_detector_customer_owned'] = True - elif recipe.detector.upper() == 'IAAS_ACTIVITY_DETECTOR': cloud_guard_record['target_activity_detector'] = True if recipe.owner.upper() == "CUSTOMER": @@ -4134,7 +4124,6 @@ def __obp_analyze_tenancy_data(self): if recipe.owner.upper() == "CUSTOMER": cloud_guard_record['target_threat_detector_customer_owned'] = True - if self.__cloud_guard_targets[self.__tenancy.id]['target_responder_recipes']: cloud_guard_record['target_responder_recipes'] = True for recipe in self.__cloud_guard_targets[self.__tenancy.id]['target_responder_recipes']: @@ -4145,28 +4134,26 @@ def __obp_analyze_tenancy_data(self): if rule.responder_rule_id.upper() == 'EVENT' and rule.details.is_enabled: cloud_guard_record['target_responder_event_rule'] = True - cloud_guard_record['target_id'] = self.__cloud_guard_targets[self.__tenancy.id]['id'] - cloud_guard_record['target_name'] = self.__cloud_guard_targets[self.__tenancy.id]['display_name'] - - except: + cloud_guard_record['target_id'] = self.__cloud_guard_targets[self.__tenancy.id]['id'] + cloud_guard_record['target_name'] = self.__cloud_guard_targets[self.__tenancy.id]['display_name'] + + except Exception: pass all_cloud_guard_checks = True - for key,value in cloud_guard_record.items(): - if not(value): + for key, value in cloud_guard_record.items(): + if not (value): all_cloud_guard_checks = False - + self.obp_foundations_checks['Cloud_Guard_Config']['Status'] = all_cloud_guard_checks if all_cloud_guard_checks: self.obp_foundations_checks['Cloud_Guard_Config']['OBP'].append(cloud_guard_record) else: self.obp_foundations_checks['Cloud_Guard_Config']['Findings'].append(cloud_guard_record) - ########################################################################## # Orchestrates data collection and CIS report generation ########################################################################## - def __report_generate_cis_report(self, level): # This function reports generates CSV reportsffo @@ -4174,8 +4161,8 @@ def __report_generate_cis_report(self, level): summary_report = [] for key, recommendation in self.cis_foundations_benchmark_1_2.items(): if recommendation['Level'] <= level: - report_filename = "cis" + " "+ recommendation['section'] + "_" + recommendation['recommendation_#'] - report_filename = report_filename.replace(" ", "_").replace(".", "-").replace("_-_","_") + ".csv" + report_filename = "cis" + " " + recommendation['section'] + "_" + recommendation['recommendation_#'] + report_filename = report_filename.replace(" ", "_").replace(".", "-").replace("_-_", "_") + ".csv" if recommendation['Status']: compliant_output = "Yes" elif recommendation['Status'] is None: @@ -4183,35 +4170,35 @@ def __report_generate_cis_report(self, level): else: compliant_output = "No" record = { - "Recommendation #": f"'{key}'", + "Recommendation #": f"'{key}'", "Section": recommendation['section'], "Level": str(recommendation['Level']), "Compliant": compliant_output if compliant_output != "Not Applicable" else "N/A", "Findings": (str(len(recommendation['Findings'])) if len(recommendation['Findings']) > 0 else " "), - "Compliant Items" : str(len(recommendation['Total']) - len(recommendation['Findings'])), + "Compliant Items": str(len(recommendation['Total']) - len(recommendation['Findings'])), "Total": (str(len(recommendation['Total'])) if len(recommendation['Total']) > 0 else " "), "Title": recommendation['Title'], "CIS v8": recommendation['CISv8'], "CCCS Guard Rail": recommendation['CCCS Guard Rail'], - "Filename" : report_filename if len(recommendation['Findings']) > 0 else " ", - "Remediation" : self.cis_report_data[key]['Remediation'] + "Filename": report_filename if len(recommendation['Findings']) > 0 else " ", + "Remediation": self.cis_report_data[key]['Remediation'] } # Add record to summary report for CSV output summary_report.append(record) - + # Generate Findings report - # self.__print_to_csv_file("cis", recommendation['section'] + "_" + recommendation['recommendation_#'], recommendation['Findings'] ) + # self.__print_to_csv_file("cis", recommendation['section'] + "_" + recommendation['recommendation_#'], recommendation['Findings']) # Screen output for CIS Summary Report print_header("CIS Foundations Benchmark 1.2 Summary Report") print('Num' + "\t" + "Level " + - "\t" "Compliant" + "\t" + "Findings " + "\t" + "Total " + "\t\t" + 'Title') + "\t" "Compliant" + "\t" + "Findings " + "\t" + "Total " + "\t\t" + 'Title') print('#' * 90) for finding in summary_report: # If print_to_screen is False it will only print non-compliant findings - if not(self.__print_to_screen) and finding['Compliant'] == 'No': + if not (self.__print_to_screen) and finding['Compliant'] == 'No': print(finding['Recommendation #'] + "\t" + - finding['Level'] + "\t" + finding['Compliant'] + "\t\t" + finding['Findings'] + "\t\t" + + finding['Level'] + "\t" + finding['Compliant'] + "\t\t" + finding['Findings'] + "\t\t" + finding['Total'] + "\t\t" + finding['Title']) elif self.__print_to_screen: print(finding['Recommendation #'] + "\t" + @@ -4222,15 +4209,15 @@ def __report_generate_cis_report(self, level): print_header("Writing CIS reports to CSV") summary_file_name = self.__print_to_csv_file( self.__report_directory, "cis", "summary_report", summary_report) - + self.__report_generate_html_summary_report( self.__report_directory, "cis", "html_summary_report", summary_report) - + # Outputting to a bucket if I have one if summary_file_name and self.__output_bucket: self.__os_copy_report_to_object_storage( self.__output_bucket, summary_file_name) - + for key, recommendation in self.cis_foundations_benchmark_1_2.items(): if recommendation['Level'] <= level: report_file_name = self.__print_to_csv_file( @@ -4239,7 +4226,6 @@ def __report_generate_cis_report(self, level): self.__os_copy_report_to_object_storage( self.__output_bucket, report_file_name) - ########################################################################## # Generates an HTML report ########################################################################## @@ -4257,19 +4243,17 @@ def __report_generate_html_summary_report(self, report_directory, header, file_s # if no data if len(data) == 0: return None - + # get the file name of the CSV - + file_name = header + "_" + file_subject - file_name = (file_name.replace(" ", "_") - ).replace(".", "-").replace("_-_","_") + ".html" + file_name = (file_name.replace(" ", "_")).replace(".", "-").replace("_-_", "_") + ".html" file_path = os.path.join(report_directory, file_name) # add report_datetimeto each dictionary result = [dict(item, extract_date=self.start_time_str) for item in data] - # If this flag is set all OCIDs are Hashed to redact them if self.__redact_output: redacted_result = [] @@ -4277,16 +4261,15 @@ def __report_generate_html_summary_report(self, report_directory, header, file_s record = {} for key in item.keys(): str_item = str(item[key]) - items_to_redact = re.findall(self.__oci_ocid_pattern,str_item) + items_to_redact = re.findall(self.__oci_ocid_pattern, str_item) for redact_me in items_to_redact: - str_item = str_item.replace(redact_me,hashlib.sha256(str.encode(redact_me)).hexdigest() ) - + str_item = str_item.replace(redact_me, hashlib.sha256(str.encode(redact_me)).hexdigest()) + record[key] = str_item redacted_result.append(record) # Overriding result with redacted result result = redacted_result - # generate fields fields = ['Recommendation #', 'Compliant', 'Section', 'Details'] @@ -4314,7 +4297,7 @@ def __report_generate_html_summary_report(self, report_directory, header, file_s