diff --git a/ibm_catalog.json b/ibm_catalog.json index fcac0469..5f5bd752 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -55,6 +55,10 @@ { "title": "Observability", "description": "This solution can leverage [Cloud automation for Observability](https://cloud.ibm.com/catalog/7a4d68b4-cf8b-40cd-a3d1-f49aff526eb3/architecture/deploy-arch-ibm-observability-a3137d28-79e0-479d-8a24-758ebd5a0eab-global) that supports configuring resources for logging, monitoring and activity tracker event routing (optional)." + }, + { + "title": "Kube Audit", + "description": "Deploys the Kube Audit solution to monitor and log Kubernetes API server activity. It captures events such as user actions, configuration changes, and access attempts, helping meet security and compliance requirements through centralized [audit logging](https://cloud.ibm.com/docs/containers?topic=containers-health-audit#audit-api-server)." } ], "support_details": "This product is in the community registry, as such support is handled through the originated repo. If you experience issues, please open an issue in the repository [here](https://github.com/terraform-ibm-modules/terraform-ibm-base-ocp-vpc/issues). Please note this product is not supported via the IBM Cloud Support Center.", @@ -770,6 +774,34 @@ } ], "hidden": true + }, + { + "key":"enable_kube_audit" + }, + { + "key": "audit_deployment_name" + }, + { + "key": "audit_log_policy", + "options": [ + { + "displayname": "Default", + "value": "default" + }, + { + "displayname": "Write Request Bodies", + "value": "WriteRequestBodies" + } + ] + }, + { + "key": "audit_namespace" + }, + { + "key": "audit_webhook_listener_image" + }, + { + "key": "audit_webhook_listener_image_tag_digest" } ], "dependencies": [ diff --git a/modules/kube-audit/README.md b/modules/kube-audit/README.md index c7a543c2..da3dbc4d 100644 --- a/modules/kube-audit/README.md +++ b/modules/kube-audit/README.md @@ -84,7 +84,7 @@ No modules. | [audit\_log\_policy](#input\_audit\_log\_policy) | Specify the amount of information that is logged to the API server audit logs by choosing the audit log policy profile to use. Supported values are `default` and `WriteRequestBodies`. | `string` | `"default"` | no | | [audit\_namespace](#input\_audit\_namespace) | The name of the namespace where log collection service and a deployment will be created. | `string` | `"ibm-kube-audit"` | no | | [audit\_webhook\_listener\_image](#input\_audit\_webhook\_listener\_image) | The audit webhook listener image reference in the format of `[registry-url]/[namespace]/[image]`.The sub-module uses the `icr.io/ibm/ibmcloud-kube-audit-to-ibm-cloud-logs` image to forward logs to IBM Cloud Logs. This image is for demonstration purposes only. For a production solution, configure and maintain your own log forwarding image. | `string` | `"icr.io/ibm/ibmcloud-kube-audit-to-ibm-cloud-logs"` | no | -| [audit\_webhook\_listener\_image\_version](#input\_audit\_webhook\_listener\_image\_version) | The tag or digest for the audit webhook listener image to deploy. If changing the value, ensure it is compatible with `audit_webhook_listener_image`. | `string` | `"deaabcb8225e800385413ba420cf3f819d3b0671@sha256:acf123f4dba63534cbc104c6886abedff9d25a22a34ab7b549ede988ed6e7144"` | no | +| [audit\_webhook\_listener\_image\_tag\_digest](#input\_audit\_webhook\_listener\_image\_tag\_digest) | The tag or digest for the audit webhook listener image to deploy. If changing the value, ensure it is compatible with `audit_webhook_listener_image`. | `string` | `"deaabcb8225e800385413ba420cf3f819d3b0671@sha256:acf123f4dba63534cbc104c6886abedff9d25a22a34ab7b549ede988ed6e7144"` | no | | [cluster\_config\_endpoint\_type](#input\_cluster\_config\_endpoint\_type) | Specify which type of endpoint to use for for cluster config access: 'default', 'private', 'vpe', 'link'. 'default' value will use the default endpoint of the cluster. | `string` | `"default"` | no | | [cluster\_id](#input\_cluster\_id) | The ID of the cluster to deploy the log collection service in. | `string` | n/a | yes | | [cluster\_resource\_group\_id](#input\_cluster\_resource\_group\_id) | The resource group ID of the cluster. | `string` | n/a | yes | diff --git a/modules/kube-audit/main.tf b/modules/kube-audit/main.tf index ba79caf9..ae0d7757 100644 --- a/modules/kube-audit/main.tf +++ b/modules/kube-audit/main.tf @@ -68,7 +68,7 @@ resource "helm_release" "kube_audit" { set { name = "image.tag" type = "string" - value = var.audit_webhook_listener_image_version + value = var.audit_webhook_listener_image_tag_digest } provisioner "local-exec" { diff --git a/modules/kube-audit/variables.tf b/modules/kube-audit/variables.tf index 3173fdd5..a9e5a7f1 100644 --- a/modules/kube-audit/variables.tf +++ b/modules/kube-audit/variables.tf @@ -91,13 +91,14 @@ variable "audit_webhook_listener_image" { default = "icr.io/ibm/ibmcloud-kube-audit-to-ibm-cloud-logs" } -variable "audit_webhook_listener_image_version" { +variable "audit_webhook_listener_image_tag_digest" { type = string description = "The tag or digest for the audit webhook listener image to deploy. If changing the value, ensure it is compatible with `audit_webhook_listener_image`." nullable = false - default = "deaabcb8225e800385413ba420cf3f819d3b0671@sha256:acf123f4dba63534cbc104c6886abedff9d25a22a34ab7b549ede988ed6e7144" # See, https://github.ibm.com/GoldenEye/issues/issues/13371 + default = "deaabcb8225e800385413ba420cf3f819d3b0671@sha256:acf123f4dba63534cbc104c6886abedff9d25a22a34ab7b549ede988ed6e7144" + validation { - condition = can(regex("^[a-f0-9]{40}@sha256:[a-f0-9]{64}$", var.audit_webhook_listener_image_version)) + condition = can(regex("^[a-f0-9]{40}@sha256:[a-f0-9]{64}$", var.audit_webhook_listener_image_tag_digest)) error_message = "The value of the audit webhook listener image version must match the tag and sha256 image digest format" } } diff --git a/solutions/fully-configurable/kubeconfig/.gitignore b/solutions/fully-configurable/kubeconfig/.gitignore new file mode 100644 index 00000000..632a28fb --- /dev/null +++ b/solutions/fully-configurable/kubeconfig/.gitignore @@ -0,0 +1,6 @@ +# Ignore everything +* + +# But not these files... +!.gitignore +!README.md diff --git a/solutions/fully-configurable/kubeconfig/README.md b/solutions/fully-configurable/kubeconfig/README.md new file mode 100644 index 00000000..e85afee8 --- /dev/null +++ b/solutions/fully-configurable/kubeconfig/README.md @@ -0,0 +1,2 @@ +This directory must exist in source control so the `ibm_container_cluster_config` data lookup can use it to place the +config.yml used to connect to a kubernetes cluster. diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index b46ef2b7..ede84ff1 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -284,3 +284,28 @@ module "secret_group" { secret_group_description = "Secret group for storing ingress certificates for cluster ${var.cluster_name} with id: ${module.ocp_base.cluster_id}" endpoint_type = var.secrets_manager_endpoint_type } + +data "ibm_container_cluster_config" "cluster_config" { + count = var.enable_kube_audit ? 1 : 0 + cluster_name_id = module.ocp_base.cluster_id + config_dir = "${path.module}/kubeconfig" + admin = true + resource_group_id = module.ocp_base.resource_group_id + endpoint_type = var.cluster_config_endpoint_type != "default" ? var.cluster_config_endpoint_type : null +} + +module "kube_audit" { + count = var.enable_kube_audit ? 1 : 0 + ibmcloud_api_key = var.ibmcloud_api_key + source = "../../modules/kube-audit" + cluster_id = module.ocp_base.cluster_id + cluster_resource_group_id = module.ocp_base.resource_group_id + region = module.ocp_base.region + use_private_endpoint = var.use_private_endpoint + cluster_config_endpoint_type = var.cluster_config_endpoint_type + audit_log_policy = var.audit_log_policy + audit_namespace = var.audit_namespace + audit_deployment_name = var.audit_deployment_name + audit_webhook_listener_image = var.audit_webhook_listener_image + audit_webhook_listener_image_tag_digest = var.audit_webhook_listener_image_tag_digest +} diff --git a/solutions/fully-configurable/provider.tf b/solutions/fully-configurable/provider.tf index a476e329..3ff173c3 100644 --- a/solutions/fully-configurable/provider.tf +++ b/solutions/fully-configurable/provider.tf @@ -24,3 +24,17 @@ provider "ibm" { visibility = var.provider_visibility private_endpoint_type = (var.provider_visibility == "private" && local.vpc_region == "ca-mon") ? "vpe" : null } + +provider "helm" { + kubernetes { + host = data.ibm_container_cluster_config.cluster_config[0].host + token = data.ibm_container_cluster_config.cluster_config[0].token + cluster_ca_certificate = data.ibm_container_cluster_config.cluster_config[0].ca_certificate + } +} + +provider "kubernetes" { + host = data.ibm_container_cluster_config.cluster_config[0].host + token = data.ibm_container_cluster_config.cluster_config[0].token + cluster_ca_certificate = data.ibm_container_cluster_config.cluster_config[0].ca_certificate +} diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index 165ee823..09052890 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -556,3 +556,53 @@ variable "skip_ocp_secrets_manager_iam_auth_policy" { description = "To skip creating auth policy that allows OCP cluster 'Manager' role access in the existing Secrets Manager instance for managing ingress certificates." default = false } + +############################################################## +# Kube Audit +############################################################## + +variable "enable_kube_audit" { + type = bool + description = "Kubernetes audit logging provides a chronological record of operations performed on the cluster, including by users, administrators, and system components. It is useful for compliance, and security monitoring. Set true to enable kube audit by default. [Learn more](https://cloud.ibm.com/docs/containers?topic=containers-health-audit#audit-api-server)" + default = true +} + +variable "audit_log_policy" { + type = string + description = "Specify the amount of information that is logged to the API server audit logs by choosing the audit log policy profile to use. Supported values are `default` and `WriteRequestBodies`." + default = "default" + + validation { + error_message = "Invalid Audit log policy Type! Valid values are 'default' or 'WriteRequestBodies'" + condition = contains(["default", "WriteRequestBodies"], var.audit_log_policy) + } +} + +variable "audit_namespace" { + type = string + description = "The name of the namespace where log collection service and a deployment will be created." + default = "ibm-kube-audit" +} + +variable "audit_deployment_name" { + type = string + description = "The name of log collection deployement and service." + default = "ibmcloud-kube-audit" +} + +variable "audit_webhook_listener_image" { + type = string + description = "The audit webhook listener image reference in the format of `[registry-url]/[namespace]/[image]`. This solution uses the `icr.io/ibm/ibmcloud-kube-audit-to-ibm-cloud-logs` image to forward logs to IBM Cloud Logs. This image is for demonstration purposes only. For a production solution, configure and maintain your own log forwarding image." + default = "icr.io/ibm/ibmcloud-kube-audit-to-ibm-cloud-logs" +} + +variable "audit_webhook_listener_image_tag_digest" { + type = string + description = "The tag or digest for the audit webhook listener image to deploy. If changing the value, ensure it is compatible with `audit_webhook_listener_image`." + default = "deaabcb8225e800385413ba420cf3f819d3b0671@sha256:acf123f4dba63534cbc104c6886abedff9d25a22a34ab7b549ede988ed6e7144" + + validation { + condition = can(regex("^[a-f0-9]{40}@sha256:[a-f0-9]{64}$", var.audit_webhook_listener_image_tag_digest)) + error_message = "The value of the audit webhook listener image version must match the tag and sha256 image digest format" + } +} diff --git a/solutions/fully-configurable/version.tf b/solutions/fully-configurable/version.tf index b68e98b6..b8ef8b38 100644 --- a/solutions/fully-configurable/version.tf +++ b/solutions/fully-configurable/version.tf @@ -7,5 +7,13 @@ terraform { source = "IBM-Cloud/ibm" version = "1.80.4" } + helm = { + source = "hashicorp/helm" + version = "2.17.0" + } + kubernetes = { + source = "hashicorp/kubernetes" + version = "2.37.1" + } } } diff --git a/tests/pr_test.go b/tests/pr_test.go index 6a82bd11..e547dd32 100644 --- a/tests/pr_test.go +++ b/tests/pr_test.go @@ -105,7 +105,7 @@ func TestRunFullyConfigurableInSchematics(t *testing.T) { options := testschematic.TestSchematicOptionsDefault(&testschematic.TestSchematicOptions{ Testing: t, Prefix: "ocp-fc", - TarIncludePatterns: []string{"*.tf", fullyConfigurableTerraformDir + "/*.*", fullyConfigurableTerraformDir + "/scripts/*.*", "scripts/*.sh", "kubeconfig/README.md"}, + TarIncludePatterns: []string{"*.tf", fullyConfigurableTerraformDir + "/*.*", fullyConfigurableTerraformDir + "/scripts/*.*", "scripts/*.sh", "kubeconfig/README.md", "modules/kube-audit/*.*", "modules/kube-audit/kubeconfig/README.md", "modules/kube-audit/scripts/*.sh", fullyConfigurableTerraformDir + "/kubeconfig/README.md", "modules/kube-audit/helm-charts/kube-audit/*.*", "modules/kube-audit/helm-charts/kube-audit/templates/*.*"}, TemplateFolder: fullyConfigurableTerraformDir, Tags: []string{"test-schematic"}, DeleteWorkspaceOnFail: false, @@ -141,7 +141,7 @@ func TestRunUpgradeFullyConfigurable(t *testing.T) { options := testschematic.TestSchematicOptionsDefault(&testschematic.TestSchematicOptions{ Testing: t, Prefix: "fc-upg", - TarIncludePatterns: []string{"*.tf", "scripts/*.sh", "kubeconfig/README.md", fullyConfigurableTerraformDir + "/*.*", fullyConfigurableTerraformDir + "/scripts/*.*"}, + TarIncludePatterns: []string{"*.tf", fullyConfigurableTerraformDir + "/*.*", fullyConfigurableTerraformDir + "/scripts/*.*", "scripts/*.sh", "kubeconfig/README.md", "modules/kube-audit/*.*", "modules/kube-audit/kubeconfig/README.md", "modules/kube-audit/scripts/*.sh", fullyConfigurableTerraformDir + "/kubeconfig/README.md", "modules/kube-audit/helm-charts/kube-audit/*.*", "modules/kube-audit/helm-charts/kube-audit/templates/*.*"}, TemplateFolder: fullyConfigurableTerraformDir, Tags: []string{"test-schematic"}, DeleteWorkspaceOnFail: false,