From 5862307f93ffbb50d897aac80e7fbf7e4d9e30d4 Mon Sep 17 00:00:00 2001 From: Jose Pablo Camacho Date: Thu, 5 Sep 2024 14:45:56 -0600 Subject: [PATCH 01/34] feat(modular): add modular support for cdr/ciem --- .../integrations/webhook-datasource/README.md | 101 +++++++ .../integrations/webhook-datasource/main.tf | 264 ++++++++++++++++++ .../webhook-datasource/organizational.tf | 86 ++++++ .../webhook-datasource/outputs.tf | 5 + .../webhook-datasource/variables.tf | 115 ++++++++ .../webhook-datasource/versions.tf | 17 ++ .../webhook_datasource.tf | 119 ++++++++ .../webhook_datasource.tf | 93 ++++++ 8 files changed, 800 insertions(+) create mode 100644 modules/integrations/webhook-datasource/README.md create mode 100644 modules/integrations/webhook-datasource/main.tf create mode 100644 modules/integrations/webhook-datasource/organizational.tf create mode 100644 modules/integrations/webhook-datasource/outputs.tf create mode 100644 modules/integrations/webhook-datasource/variables.tf create mode 100644 modules/integrations/webhook-datasource/versions.tf create mode 100644 test/examples/organization_cdr_test/webhook_datasource.tf create mode 100644 test/examples/single_account_cdr_test/webhook_datasource.tf diff --git a/modules/integrations/webhook-datasource/README.md b/modules/integrations/webhook-datasource/README.md new file mode 100644 index 0000000..8307a80 --- /dev/null +++ b/modules/integrations/webhook-datasource/README.md @@ -0,0 +1,101 @@ +# GCP Webhook Datasource Module + +This Module creates the resources required to send AuditLogs logs to Sysdig via GCP Pub Subscription. These resources enable Threat Detection in the given GCP project or organization. +Before applying the changes defined in this module, the following operations need to be performed on the target GCP environment: + +- Enable the following APIs in the target environment (https://support.google.com/googleapi/answer/6158841?hl=en) + - Cloud Pub/Sub API + - Identity and Access Management (IAM) API + - IAM Service Account Credentials API + - Cloud Resource Manager API + +- The following resources will be created in each instrumented project: + - A `PubSub Topic` to send the AuditLogs from the project + - A `Logging Sink` that export AuditLogs to the PubSub topic + - A `PubSub Topic IAM member` to assign a role to the PubSub topic + - A `PubSub Subscription` to allows receiving messages from the PubSub topic, including its `Service Account` + - An `IAM Workload Identity Pool` that enables identities from external systems(AWS) tp access GCP resources through IAM + - An `IAM role and member` that provides the required permissions for Sysdig Backend to read cloud resources created for data ingestion + +When run in organizational mode, this module is similar however the main difference is that an organizational sink is used +instead of a project-specific one, as well as enabling AuditLogs for all the projects that fall within the organization. + +This module will also deploy a Webhook Datasource Component in Sysdig Backend for onboarded Sysdig Cloud Account. + + +## Requirements + +| Name | Version | +|---------------------------------------------------------------------------|-----------| +| [terraform](#requirement\_terraform) | >= 1.0.0 | +| [google](#requirement\_google) | >= 4.21.0 | +| [sysdig](#requirement\_sysdig) | | + +## Providers + +| Name | Version | +|------------------------------------------------------------------|-----------| +| [google](#provider\_google) | >= 4.21.0 | +| [random](#requirement\_random) | >= 3.1 | +| [sysdig](#requirement\_sysdig) | + + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------| +| [random_id.suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource | +| [google_project_iam_audit_config.audit_config](https://registry.terraform.io/providers/hashicorp/google/3.0.0-beta.1/docs/resources/google_project_iam#google_project_iam_audit_config) | resource | +| [google_pubsub_topic.ingestion_topic](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/pubsub_topic.html) | resource | +| [google_pubsub_topic.deadletter_topic](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/pubsub_topic.html) | resource | +| [google_logging_project_sink.ingestion_sink](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/logging_project_sink) | resource | +| [google_pubsub_topic_iam_member.publisher_iam_member](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/pubsub_topic_iam#google_pubsub_topic_iam_member) | resource | +| [google_service_account.push_auth](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_service_account) | resource | +| [google_service_account_iam_binding.push_auth_binding](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_service_account_iam#google_service_account_iam_binding) | resource | +| [google_pubsub_subscription.ingestion_topic_push_subscription](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/pubsub_subscription.html) | resource | +| [google_iam_workload_identity_pool.ingestion_auth_pool](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/iam_workload_identity_pool) | resource | +| [google_iam_workload_identity_pool_provider.ingestion_auth_pool_provider](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/iam_workload_identity_pool_provider) | resource | +| [google_project_iam_custom_role.custom_ingestion_auth_role](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_iam_custom_role) | resource | +| [google_project_iam_member.custom](https://registry.terraform.io/providers/hashicorp/google/3.22.0/docs/resources/google_project_iam#google_project_iam_member) | resource | +| [google_service_account_iam_member.custom_auth](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_service_account_iam#google_service_account_iam_member) | resource | +| [sysdig_secure_trusted_cloud_identity.trusted_identity](https://registry.terraform.io/providers/sysdiglabs/sysdig/latest/docs/data-sources/secure_trusted_cloud_identity) | data source | +| [google_project.project](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/project) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [ack\_deadline\_seconds](#input\_ack\_deadline\_seconds) | (Optional) Maximum time in seconds after Sysdig's subscriber receives a message before the subscriber should acknowledge the message | `number` | `60` | no | +| [is\_organizational](#input\_is\_organizational) | (Optional) Set this field to 'true' to deploy secure-for-cloud to a GCP Organization. | `bool` | `false` | no | +| [labels](#input\_labels) | (Optional) Labels to be associated with Sysdig-originated resources | `map(string)` |
{
"originator": "sysdig"
}
| no | +| [max\_delivery\_attempts](#input\_max\_delivery\_attempts) | (Optional) Number of attempts redelivering missed messages from the deadletter topic to the main one | `number` | `5` | no | +| [maximum\_backoff](#input\_maximum\_backoff) | (Optional) Maximum backoff time for exponential backoff of the push subscription retry policy | `string` | `"600s"` | no | +| [message\_retention\_duration](#input\_message\_retention\_duration) | (Optional) How long unacknowledged messages are retained in Sysdig's subscription backlog, from the moment a message is published | `string` | `"604800s"` | no | +| [minimum\_backoff](#input\_minimum\_backoff) | (Optional) Minimum backoff time for exponential backoff of the push subscription retry policy | `string` | `"10s"` | no | +| [organization\_domain](#input\_organization\_domain) | Organization domain. e.g. sysdig.com | `string` | `""` | no | +| [project\_id](#input\_project\_id) | (Required) Target Project identifier provided by the customer | `string` | n/a | yes | +| [role\_name](#input\_role\_name) | (Optional) Role name for custom role binding to the service account, with read permissions for data ingestion resources | `string` | `"SysdigIngestionAuthRole"` | no | +| [suffix](#input\_suffix) | (Optional) Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated | `string` | `null` | no | +| [audit\_log\_config](#input\_audit\_log\_config) | List of services and their audit log configurations to be ingested. Default is to ingest all logs. |
list(object({
service = string,
log_config = list(object({
log_type = string,
exempted_members = optional(list(string))
}))
}))
|
[
{
"log_config": [
{
"log_type": "ADMIN_READ"
},
{
"log_type": "DATA_READ"
},
{
"log_type": "DATA_WRITE"
}
],
"service": "allServices"
}
]
| no | +| [ingestion\_sink\_filter](#input\_ingestion\_sink\_filter) | Filter the Sink is set up with. Ingests AuditLogs by default. | `string` | `protoPayload.@type = "type.googleapis.com/google.cloud.audit.AuditLog"` | no | +| [exclude\_logs\_filter](#input\_exclude\_logs\_filter) | Filter to exclude logs from ingestion. Default is to ingest all google.cloud.audit.AuditLog logs. with no exclusions. |
list(object({
name = string,
description = optional(string),
filter = string,
disabled = optional(bool)
}))
| `[]` | no | + +## Outputs + +| Name | Description | +|---------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------| +| [webhook\_datasource\_component\_id](#webhook\_datasource\_component\_id) | Component identifier of Webhook Datasource integration created in Sysdig Backend for Log Ingestion | + + + +## Authors + +Module is maintained by [Sysdig](https://sysdig.com). + +## License + +Apache 2 Licensed. See LICENSE for full details. diff --git a/modules/integrations/webhook-datasource/main.tf b/modules/integrations/webhook-datasource/main.tf new file mode 100644 index 0000000..10c8202 --- /dev/null +++ b/modules/integrations/webhook-datasource/main.tf @@ -0,0 +1,264 @@ +#----------------------------------------------------------------------------------------------------------------------------------------- +# For Organizational installs, see organizational.tf. +# This module takes care of provisioning the necessary resources to make Sysdig's backend able to ingest data from a +# single GCP project. +# +# Note: The alternative definitions for the organizational variant of this module are contained +# in organizational.tf. The only differences w.r.t. the standalone template is in using an +# organizational sink instead of a project-specific one, as well as enabling AuditLogs for +# all the projects that fall within the organization. +#----------------------------------------------------------------------------------------------------------------------------------------- + +#----------------------------------------------------------------------------------------- +# Fetch the data sources +#----------------------------------------------------------------------------------------- +data "sysdig_secure_trusted_cloud_identity" "trusted_identity" { + cloud_provider = "gcp" +} + +data "google_project" "project" { + project_id = var.project_id +} + +data "sysdig_secure_tenant_external_id" "external_id" {} + +data "sysdig_secure_cloud_ingestion_assets" "assets" {} + +#----------------------------------------------------------------------------------------- +# These locals indicate the suffix to create unique name for resources +#----------------------------------------------------------------------------------------- +locals { + suffix = var.suffix == null ? random_id.suffix[0].hex : var.suffix +} + + +#----------------------------------------------------------------------------------------------------------------------- +# A random resource is used to generate unique Webhook Datasource name suffix for resources. +# This prevents conflicts when recreating an Webhook Datasource resources with the same name. +#----------------------------------------------------------------------------------------------------------------------- +resource "random_id" "suffix" { + count = var.suffix == null ? 1 : 0 + byte_length = 3 +} + +#----------------------------------------------------------------------------------------- +# Audit Logs +#----------------------------------------------------------------------------------------- +locals { + # Data structure will be a map for each service, that can have multiple audit_log_config + audit_log_config = { for audit in var.audit_log_config : + audit["service"] => { + log_config = audit["log_config"] + } + } +} + +resource "google_project_iam_audit_config" "audit_config" { + for_each = var.is_organizational ? {} : local.audit_log_config + project = var.project_id + service = each.key + + dynamic "audit_log_config" { + for_each = each.value.log_config + iterator = log_config + content { + log_type = log_config.value.log_type + exempted_members = log_config.value.exempted_members + } + } +} + +#----------------------------------------------------------------------------------------- +# Ingestion Topic +#----------------------------------------------------------------------------------------- +resource "google_pubsub_topic" "ingestion_topic" { + name = "ingestion_topic" + labels = var.labels + project = var.project_id + message_retention_duration = var.message_retention_duration +} + +resource "google_pubsub_topic" "deadletter_topic" { + name = "dl-${google_pubsub_topic.ingestion_topic.name}" + project = var.project_id + message_retention_duration = var.message_retention_duration +} + +#----------------------------------------------------------------------------------------- +# Sink +#----------------------------------------------------------------------------------------- +resource "google_logging_project_sink" "ingestion_sink" { + count = var.is_organizational ? 0 : 1 + name = "${google_pubsub_topic.ingestion_topic.name}_sink" + description = "Sysdig sink to direct the AuditLogs to the PubSub topic used for data gathering" + + # NOTE: The target destination is a PubSub topic + destination = "pubsub.googleapis.com/projects/${var.project_id}/topics/${google_pubsub_topic.ingestion_topic.name}" + filter = var.ingestion_sink_filter + + # Dynamic block to exclude logs from ingestion + dynamic "exclusions" { + for_each = var.exclude_logs_filter + content { + name = exclusions.value.name + description = exclusions.value.description + filter = exclusions.value.filter + disabled = exclusions.value.disabled + } + } + + # NOTE: Used to create a dedicated writer identity and not using the default one + unique_writer_identity = true +} + +resource "google_pubsub_topic_iam_member" "publisher_iam_member" { + project = google_pubsub_topic.ingestion_topic.project + topic = google_pubsub_topic.ingestion_topic.name + role = "roles/pubsub.publisher" + member = var.is_organizational ? google_logging_organization_sink.ingestion_sink[0].writer_identity : google_logging_project_sink.ingestion_sink[0].writer_identity +} + +#----------------------------------------------------------------------------------------- +# Push Subscription +#----------------------------------------------------------------------------------------- +resource "google_service_account" "push_auth" { + account_id = "sysdig-ingestion-${local.suffix}" + display_name = "Sysdig Ingestion Push Auth Service Account" + project = var.project_id +} + +resource "google_service_account_iam_binding" "push_auth_binding" { + service_account_id = google_service_account.push_auth.name + role = "roles/iam.serviceAccountTokenCreator" + + members = [ + "serviceAccount:${google_service_account.push_auth.email}", + ] +} + +resource "google_pubsub_subscription" "ingestion_topic_push_subscription" { + name = "${google_pubsub_topic.ingestion_topic.name}_push_subscription" + topic = google_pubsub_topic.ingestion_topic.name + labels = var.labels + ack_deadline_seconds = var.ack_deadline_seconds + message_retention_duration = var.message_retention_duration + project = var.project_id + + push_config { + push_endpoint = data.sysdig_secure_cloud_ingestion_assets.assets.gcp_metadata.ingestionURL + attributes = { + x-goog-version = "v1" + } + oidc_token { + service_account_email = google_service_account.push_auth.email + audience = "sysdig_secure" + } + } + + retry_policy { + minimum_backoff = var.minimum_backoff + maximum_backoff = var.maximum_backoff + } + + dead_letter_policy { + dead_letter_topic = google_pubsub_topic.deadletter_topic.id + max_delivery_attempts = var.max_delivery_attempts + } +} + +#----------------------------------------------------------------------------------------- +# Configure Workload Identity Federation for auth +# See https://cloud.google.com/iam/docs/access-resources-aws +# ----------------------------------------------------------------------------------------- + +resource "google_iam_workload_identity_pool" "ingestion_auth_pool" { + project = var.project_id + workload_identity_pool_id = "sysdig-ingestion-${local.suffix}" +} + +resource "google_iam_workload_identity_pool_provider" "ingestion_auth_pool_provider" { + project = var.project_id + workload_identity_pool_id = google_iam_workload_identity_pool.ingestion_auth_pool.workload_identity_pool_id + workload_identity_pool_provider_id = "sysdig-ingestion-${local.suffix}" + display_name = "Sysdigcloud ingestion auth" + description = "AWS identity pool provider for Sysdig Secure Data Ingestion resources" + disabled = false + + attribute_condition = "attribute.aws_role==\"arn:aws:sts::${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id}:assumed-role/${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_role_name}/${data.sysdig_secure_tenant_external_id.external_id.external_id}\"" + + attribute_mapping = { + "google.subject" = "assertion.arn", + "attribute.aws_role" = "assertion.arn" + } + + aws { + account_id = data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id + } +} + +# creating custom role with project-level permissions to access data ingestion resources +resource "google_project_iam_custom_role" "custom_ingestion_auth_role" { + count = var.is_organizational ? 0 : 1 + + project = var.project_id + role_id = "${var.role_name}-${local.suffix}" + title = "Sysdigcloud Ingestion Auth Role" + description = "A Role providing the required permissions for Sysdig Backend to read cloud resources created for data ingestion" + permissions = [ + "pubsub.topics.get", + "pubsub.topics.list", + "pubsub.subscriptions.get", + "pubsub.subscriptions.list", + "logging.sinks.get", + "logging.sinks.list", + ] +} + +# adding custom role with project-level permissions to the service account for auth +resource "google_project_iam_member" "custom" { + count = var.is_organizational ? 0 : 1 + + project = var.project_id + role = google_project_iam_custom_role.custom_ingestion_auth_role[0].id + member = "serviceAccount:${google_service_account.push_auth.email}" +} + +# attaching WIF as a member to the service account for auth +resource "google_service_account_iam_member" "custom_auth" { + service_account_id = google_service_account.push_auth.name + role = "roles/iam.workloadIdentityUser" + member = "principalSet://iam.googleapis.com/projects/${data.google_project.project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.ingestion_auth_pool.workload_identity_pool_id}/attribute.aws_role/arn:aws:sts::${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id}:assumed-role/${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_role_name}/${data.sysdig_secure_tenant_external_id.external_id.external_id}" +} + +#----------------------------------------------------------------------------------------------------------------------------------------- +# Call Sysdig Backend to add the webhook-datasource integration to the Sysdig Cloud Account +# +# Note (optional): To ensure this gets called after all cloud resources are created, add +# explicit dependency using depends_on +#----------------------------------------------------------------------------------------------------------------------------------------- + +resource "sysdig_secure_cloud_auth_account_component" "gcp_webhook_datasource" { + account_id = var.sysdig_secure_account_id + type = "COMPONENT_WEBHOOK_DATASOURCE" + instance = "secure-runtime" + version = "v0.1.0" + webhook_datasource_metadata = jsonencode({ + gcp = { + webhook_datasource = { + pubsub_topic_name = google_pubsub_topic.ingestion_topic.name + sink_name = var.is_organizational ? google_logging_organization_sink.ingestion_sink[0].name : google_logging_project_sink.ingestion_sink[0].name + push_subscription_name = google_pubsub_subscription.ingestion_topic_push_subscription.name + push_endpoint = google_pubsub_subscription.ingestion_topic_push_subscription.push_config[0].push_endpoint + routing_key = "1f6d4677-84ec-4356-bd73-c79c8a96f96a" + } + service_principal = { + workload_identity_federation = { + pool_id = google_iam_workload_identity_pool.ingestion_auth_pool.workload_identity_pool_id + pool_provider_id = google_iam_workload_identity_pool_provider.ingestion_auth_pool_provider.workload_identity_pool_provider_id + project_number = data.google_project.project.number + } + email = google_service_account.push_auth.email + } + } + }) +} \ No newline at end of file diff --git a/modules/integrations/webhook-datasource/organizational.tf b/modules/integrations/webhook-datasource/organizational.tf new file mode 100644 index 0000000..0f39a3b --- /dev/null +++ b/modules/integrations/webhook-datasource/organizational.tf @@ -0,0 +1,86 @@ +#----------------------------------------------------------------------------------------- +# Fetch the data sources +#----------------------------------------------------------------------------------------- + +data "google_organization" "org" { + count = var.is_organizational ? 1 : 0 + domain = var.organization_domain +} + +#----------------------------------------------------------------------------------------- +# Audit Logs +#----------------------------------------------------------------------------------------- + +resource "google_organization_iam_audit_config" "audit_config" { + for_each = var.is_organizational ? local.audit_log_config : {} + + org_id = data.google_organization.org[0].org_id + service = each.key + + dynamic "audit_log_config" { + for_each = each.value.log_config + iterator = log_config + content { + log_type = log_config.value.log_type + exempted_members = log_config.value.exempted_members + } + } +} + +#----------------------------------------------------------------------------------------- +# Sink +#----------------------------------------------------------------------------------------- + +resource "google_logging_organization_sink" "ingestion_sink" { + count = var.is_organizational ? 1 : 0 + + name = "${google_pubsub_topic.ingestion_topic.name}_sink" + description = "Sysdig sink to direct the AuditLogs to the PubSub topic used for data gathering" + org_id = data.google_organization.org[0].org_id + + # NOTE: The target destination is a PubSub topic + destination = "pubsub.googleapis.com/projects/${var.project_id}/topics/${google_pubsub_topic.ingestion_topic.name}" + filter = var.ingestion_sink_filter + + # Dynamic block to exclude logs from ingestion + dynamic "exclusions" { + for_each = var.exclude_logs_filter + content { + name = exclusions.value.name + description = exclusions.value.description + filter = exclusions.value.filter + disabled = exclusions.value.disabled + } + } + + # NOTE: The include_children attribute is set to true in order to ingest data + # even from potential sub-organizations + include_children = true +} + +# creating custom role with organization-level permissions to access data ingestion resources +resource "google_organization_iam_custom_role" "custom_ingestion_auth_role" { + count = var.is_organizational ? 1 : 0 + + org_id = data.google_organization.org[0].org_id + role_id = "${var.role_name}-org-${local.suffix}" + title = "Sysdigcloud Ingestion Auth Role" + description = "A Role providing the required permissions for Sysdig Backend to read cloud resources created for data ingestion" + permissions = [ + "pubsub.topics.get", + "pubsub.topics.list", + "pubsub.subscriptions.get", + "pubsub.subscriptions.list", + "logging.sinks.get", + "logging.sinks.list", + ] +} + +# adding custom role with organization-level permissions to the service account for auth +resource "google_organization_iam_member" "custom" { + count = var.is_organizational ? 1 : 0 + + org_id = data.google_organization.org[0].org_id + role = google_organization_iam_custom_role.custom_ingestion_auth_role[0].id + member = "serviceAccount:${google_service_account.push_auth.email}" +} diff --git a/modules/integrations/webhook-datasource/outputs.tf b/modules/integrations/webhook-datasource/outputs.tf new file mode 100644 index 0000000..05c7cf2 --- /dev/null +++ b/modules/integrations/webhook-datasource/outputs.tf @@ -0,0 +1,5 @@ +output "webhook_datasource_component_id" { + value = "${sysdig_secure_cloud_auth_account_component.gcp_webhook_datasource.type}/${sysdig_secure_cloud_auth_account_component.gcp_webhook_datasource.instance}" + description = "Component identifier of Webhook Datasource integration created in Sysdig Backend for Log Ingestion" + depends_on = [ sysdig_secure_cloud_auth_account_component.gcp_webhook_datasource ] +} \ No newline at end of file diff --git a/modules/integrations/webhook-datasource/variables.tf b/modules/integrations/webhook-datasource/variables.tf new file mode 100644 index 0000000..79218a4 --- /dev/null +++ b/modules/integrations/webhook-datasource/variables.tf @@ -0,0 +1,115 @@ +variable "region" { + description = "Region for Google provider" + type = string + default = "us-west1" +} + +variable "project_id" { + type = string + description = "(Required) Target Project identifier provided by the customer" +} + +variable "labels" { + type = map(string) + description = "(Optional) Labels to be associated with Sysdig-originated resources" + default = { + originator = "sysdig" + } +} + +variable "ack_deadline_seconds" { + type = number + description = "(Optional) Maximum time in seconds after Sysdig's subscriber receives a message before the subscriber should acknowledge the message" + default = 60 +} + +variable "message_retention_duration" { + type = string + description = "(Optional) How long unacknowledged messages are retained in Sysdig's subscription backlog, from the moment a message is published" + default = "604800s" +} + +variable "max_delivery_attempts" { + type = number + description = "(Optional) Number of attempts redelivering missed messages from the deadletter topic to the main one" + default = 5 +} + +variable "minimum_backoff" { + type = string + description = "(Optional) Minimum backoff time for exponential backoff of the push subscription retry policy" + default = "10s" +} + +variable "maximum_backoff" { + type = string + description = "(Optional) Maximum backoff time for exponential backoff of the push subscription retry policy" + default = "600s" +} + +variable "is_organizational" { + description = "(Optional) Set this field to 'true' to deploy secure-for-cloud to a GCP Organization." + type = bool + default = false +} + +variable "organization_domain" { + type = string + description = "(Optional) Organization domain. e.g. sysdig.com" + default = "" +} + +variable "role_name" { + type = string + description = "Name for the Ingestion auth Role on the Customer infrastructure" + default = "SysdigIngestionAuthRole" +} + +variable "suffix" { + type = string + description = "Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated" + default = null +} + +variable "audit_log_config" { + description = "List of services and their audit log configurations to be ingested. Default is to ingest all logs." + type = list(object({ + service = string, + log_config = list(object({ + log_type = string, + exempted_members = optional(list(string)) + })) + })) + default = [ + { + service = "allServices" + log_config = [ + { log_type = "ADMIN_READ" }, + { log_type = "DATA_READ" }, + { log_type = "DATA_WRITE" } + ] + } + ] +} + +variable "exclude_logs_filter" { + description = "Filter to exclude logs from ingestion. Default is to ingest all google.cloud.audit.AuditLog logs. with no exclusions." + type = list(object({ + name = string, + description = optional(string), + filter = string, + disabled = optional(bool) + })) + default = [] +} + +variable "ingestion_sink_filter" { + type = string + description = "Filter the Logging Sink is set up with. Default is to ingests AuditLogs" + default = "protoPayload.@type = \"type.googleapis.com/google.cloud.audit.AuditLog\"" +} + +variable "sysdig_secure_account_id" { + type = string + description = "ID of the Sysdig Cloud Account to enable Event Bridge integration for (incase of organization, ID of the Sysdig management account)" +} \ No newline at end of file diff --git a/modules/integrations/webhook-datasource/versions.tf b/modules/integrations/webhook-datasource/versions.tf new file mode 100644 index 0000000..61980a9 --- /dev/null +++ b/modules/integrations/webhook-datasource/versions.tf @@ -0,0 +1,17 @@ +terraform { + required_version = ">= 1.0.0" + + required_providers { + google = { + source = "hashicorp/google" + version = ">= 4.21.0" + } + sysdig = { + source = "sysdiglabs/sysdig" + } + random = { + source = "hashicorp/random" + version = ">= 3.1, < 4.0" + } + } +} \ No newline at end of file diff --git a/test/examples/organization_cdr_test/webhook_datasource.tf b/test/examples/organization_cdr_test/webhook_datasource.tf new file mode 100644 index 0000000..e4d5b4d --- /dev/null +++ b/test/examples/organization_cdr_test/webhook_datasource.tf @@ -0,0 +1,119 @@ +#--------------------------------------------------------------------------------------------- +# Ensure installation flow for foundational onboarding has been completed before +# installing additional Sysdig features. +#--------------------------------------------------------------------------------------------- + +# UNCOMMENT TO TEST: FROM HERE: THIS WILL BE PART OF THE ONBOARD MODULE +# terraform { +# required_providers { +# sysdig = { +# source = "sysdiglabs/sysdig" +# version = "~> 1.34.0" +# } +# } +# } +# +# provider "sysdig" { +# sysdig_secure_url = "https://secure-staging.sysdig.com" +# sysdig_secure_api_token = "744c9bd8-f73d-4ef3-8250-32e976a5301d" +# } +# +# provider "google" { +# project = "org-child-project-1" +# region = "us-west1" +# } +# TO HERE + +module "webhook-datasource" { + source = "../../../modules/integrations/webhook-datasource" + project_id = "org-child-project-1" + # push_endpoint is no longer needed + # push_endpoint = "https://app-staging.sysdigcloud.com/api/cloudingestion/gcp/v2/84f934c6-eb2d-47d9-804b-bcfe9e6ef0b9" + is_organizational = true + organization_domain = "draios.com" + sysdig_secure_account_id = "" +} + +# UNCOMMENT TO TEST: THIS IS NOT GOING TO BE LONGER NEEDED, SINCE WILL BE PART OF FOUNDATIONAL +# module "organization-posture" { +# source = "sysdiglabs/secure/google//modules/services/service-principal" +# project_id = "org-child-project-1" +# service_account_name = "sysdig-secure-2u6g" +# is_organizational = true +# organization_domain = "draios.com" +# } +# TO HERE + +# COMMENT TO TEST: THIS WILL BE PART OF THE SNIPPET +resource "sysdig_secure_cloud_auth_account_feature" "threat_detection" { + account_id = module.onboarding.sysdig_secure_account_id + type = "FEATURE_SECURE_THREAT_DETECTION" + enabled = true + components = [ module.webhook-datasource.webhook_datasource_component_id ] + depends_on = [ module.webhook-datasource ] +} + +resource "sysdig_secure_cloud_auth_account_feature" "identity_entitlement" { + account_id = module.onboarding.sysdig_secure_account_id + type = "FEATURE_SECURE_IDENTITY_ENTITLEMENT" + enabled = true + components = [module.webhook-datasource.webhook_datasource_component_id] + depends_on = [sysdig_secure_cloud_auth_account_feature.config_posture, sysdig_secure_cloud_auth_account_feature.threat_detection] +} +# TO HERE + +# UNCOMMENT TO TEST: THIS IS NOT GOING TO BE LONGER NEEDED, SINCE WILL BE PART OF FOUNDATIONAL +# resource "sysdig_secure_cloud_auth_account" "gcp_project_org-child-project-1" { +# enabled = true +# provider_id = "org-child-project-1" +# provider_type = "PROVIDER_GCP" +# +# feature { +# +# secure_threat_detection { +# enabled = true +# components = ["COMPONENT_WEBHOOK_DATASOURCE/secure-runtime"] +# } +# } +# component { +# type = "COMPONENT_WEBHOOK_DATASOURCE" +# instance = "secure-runtime" +# webhook_datasource_metadata = jsonencode({ +# gcp = { +# webhook_datasource = { +# pubsub_topic_name = module.webhook-datasource.ingestion_pubsub_topic_name +# sink_name = module.webhook-datasource.ingestion_sink_name +# push_subscription_name = module.webhook-datasource.ingestion_push_subscription_name +# push_endpoint = module.webhook-datasource.push_endpoint +# routing_key = "84f934c6-eb2d-47d9-804b-bcfe9e6ef0b9" +# } +# service_principal = { +# workload_identity_federation = { +# pool_id = module.webhook-datasource.workload_identity_pool_id +# pool_provider_id = module.webhook-datasource.workload_identity_pool_provider_id +# project_number = module.webhook-datasource.workload_identity_project_number +# } +# email = module.webhook-datasource.service_account_email +# } +# } +# }) +# } +# +# component { +# type = "COMPONENT_SERVICE_PRINCIPAL" +# instance = "secure-onboarding" +# service_principal_metadata = jsonencode({ +# gcp = { +# key = module.organization-posture.service_account_key +# } +# }) +# } +# depends_on = [module.organization-posture, module.webhook-datasource] +# } +# +# resource "sysdig_secure_organization" "gcp_organization_org-child-project-1" { +# organizational_unit_ids = [] +# management_account_id = sysdig_secure_cloud_auth_account.gcp_project_org-child-project-1.id +# depends_on = [module.organization-posture, module.webhook-datasource] +# } +# TO HERE \ No newline at end of file diff --git a/test/examples/single_account_cdr_test/webhook_datasource.tf b/test/examples/single_account_cdr_test/webhook_datasource.tf new file mode 100644 index 0000000..c4651c6 --- /dev/null +++ b/test/examples/single_account_cdr_test/webhook_datasource.tf @@ -0,0 +1,93 @@ +#--------------------------------------------------------------------------------------------- +# Ensure installation flow for foundational onboarding has been completed before +# installing additional Sysdig features. +#--------------------------------------------------------------------------------------------- + +# UNCOMMENT TO TEST: FROM HERE: THIS WILL BE PART OF THE ONBOARD MODULE +# terraform { +# required_providers { +# sysdig = { +# source = "sysdiglabs/sysdig" +# version = "~> 1.34.0" +# } +# } +# } +# +# provider "sysdig" { +# sysdig_secure_url = "https://secure-staging.sysdig.com" +# sysdig_secure_api_token = "744c9bd8-f73d-4ef3-8250-32e976a5301d" +# } +# +# provider "google" { +# project = "org-child-project-1" +# region = "us-west1" +# } +# TO HERE + +module "webhook-datasource" { + source = "../../../modules/integrations/webhook-datasource" + project_id = "org-child-project-1" + # push_endpoint and external_id are no longer needed + # push_endpoint = "https://app-staging.sysdigcloud.com/api/cloudingestion/gcp/v2/1f6d4677-84ec-4356-bd73-c79c8a96f96a" + # external_id = "87e82bdu28323" + # This will come from the onboarding module: module.onboarding.sysdig_secure_account_id + sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id +} + +# COMMENT TO TEST: THIS WILL BE PART OF THE SNIPPET +resource "sysdig_secure_cloud_auth_account_feature" "threat_detection" { + account_id = module.onboarding.sysdig_secure_account_id + type = "FEATURE_SECURE_THREAT_DETECTION" + enabled = true + components = [ module.webhook-datasource.webhook_datasource_component_id ] + depends_on = [ module.webhook-datasource ] +} + +resource "sysdig_secure_cloud_auth_account_feature" "identity_entitlement" { + account_id = module.onboarding.sysdig_secure_account_id + type = "FEATURE_SECURE_IDENTITY_ENTITLEMENT" + enabled = true + components = [module.webhook-datasource.webhook_datasource_component_id] + depends_on = [sysdig_secure_cloud_auth_account_feature.config_posture, sysdig_secure_cloud_auth_account_feature.threat_detection] +} +# TO HERE + +# UNCOMMENT TO TEST: THIS IS NOT GOING TO BE LONGER NEEDED, SINCE WILL BE PART OF FOUNDATIONAL +# resource "sysdig_secure_cloud_auth_account" "gcp_project_org-child-project-1" { +# enabled = true +# provider_id = "org-child-project-1" +# provider_type = "PROVIDER_GCP" +# +# feature { +# +# secure_threat_detection { +# enabled = true +# components = ["COMPONENT_WEBHOOK_DATASOURCE/secure-runtime"] +# } +# } +# component { +# type = "COMPONENT_WEBHOOK_DATASOURCE" +# instance = "secure-runtime" +# webhook_datasource_metadata = jsonencode({ +# gcp = { +# webhook_datasource = { +# pubsub_topic_name = module.webhook-datasource.ingestion_pubsub_topic_name +# sink_name = module.webhook-datasource.ingestion_sink_name +# push_subscription_name = module.webhook-datasource.ingestion_push_subscription_name +# push_endpoint = module.webhook-datasource.push_endpoint +# routing_key = "1f6d4677-84ec-4356-bd73-c79c8a96f96a" +# } +# service_principal = { +# workload_identity_federation = { +# pool_id = module.webhook-datasource.workload_identity_pool_id +# pool_provider_id = module.webhook-datasource.workload_identity_pool_provider_id +# project_number = module.webhook-datasource.workload_identity_project_number +# } +# email = module.webhook-datasource.service_account_email +# } +# } +# }) +# } +# depends_on = [module.webhook-datasource] +# } +# TO HERE \ No newline at end of file From 285d3abf0f7be0bdaa398e4f1538707b2c0dcc30 Mon Sep 17 00:00:00 2001 From: Jose Pablo Camacho Date: Thu, 5 Sep 2024 15:36:38 -0600 Subject: [PATCH 02/34] feat(modular): add modular support for cdr/ciem --- test/examples/organization_cdr_test/webhook_datasource.tf | 2 +- test/examples/single_account_cdr_test/webhook_datasource.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/examples/organization_cdr_test/webhook_datasource.tf b/test/examples/organization_cdr_test/webhook_datasource.tf index e4d5b4d..2d80fbc 100644 --- a/test/examples/organization_cdr_test/webhook_datasource.tf +++ b/test/examples/organization_cdr_test/webhook_datasource.tf @@ -15,7 +15,7 @@ # # provider "sysdig" { # sysdig_secure_url = "https://secure-staging.sysdig.com" -# sysdig_secure_api_token = "744c9bd8-f73d-4ef3-8250-32e976a5301d" +# sysdig_secure_api_token = # } # # provider "google" { diff --git a/test/examples/single_account_cdr_test/webhook_datasource.tf b/test/examples/single_account_cdr_test/webhook_datasource.tf index c4651c6..babebac 100644 --- a/test/examples/single_account_cdr_test/webhook_datasource.tf +++ b/test/examples/single_account_cdr_test/webhook_datasource.tf @@ -15,7 +15,7 @@ # # provider "sysdig" { # sysdig_secure_url = "https://secure-staging.sysdig.com" -# sysdig_secure_api_token = "744c9bd8-f73d-4ef3-8250-32e976a5301d" +# sysdig_secure_api_token = # } # # provider "google" { From 86f419c1e2cc2aa32fbf86a5412d08e40579686d Mon Sep 17 00:00:00 2001 From: Jose Pablo Camacho Date: Thu, 5 Sep 2024 15:44:16 -0600 Subject: [PATCH 03/34] feat(modular): add modular support for cdr/ciem --- modules/integrations/webhook-datasource/variables.tf | 6 ------ modules/integrations/webhook-datasource/versions.tf | 1 + 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/modules/integrations/webhook-datasource/variables.tf b/modules/integrations/webhook-datasource/variables.tf index 79218a4..6541b5f 100644 --- a/modules/integrations/webhook-datasource/variables.tf +++ b/modules/integrations/webhook-datasource/variables.tf @@ -1,9 +1,3 @@ -variable "region" { - description = "Region for Google provider" - type = string - default = "us-west1" -} - variable "project_id" { type = string description = "(Required) Target Project identifier provided by the customer" diff --git a/modules/integrations/webhook-datasource/versions.tf b/modules/integrations/webhook-datasource/versions.tf index 61980a9..269cfb8 100644 --- a/modules/integrations/webhook-datasource/versions.tf +++ b/modules/integrations/webhook-datasource/versions.tf @@ -8,6 +8,7 @@ terraform { } sysdig = { source = "sysdiglabs/sysdig" + version = ">= 1.34.0" } random = { source = "hashicorp/random" From 5ff322f6aa204423498750a1c24983987007c834 Mon Sep 17 00:00:00 2001 From: Jose Pablo Camacho Date: Thu, 5 Sep 2024 15:45:09 -0600 Subject: [PATCH 04/34] feat(modular): add modular support for cdr/ciem --- .../integrations/webhook-datasource/main.tf | 18 +++++++++--------- .../webhook-datasource/organizational.tf | 2 +- .../integrations/webhook-datasource/outputs.tf | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/modules/integrations/webhook-datasource/main.tf b/modules/integrations/webhook-datasource/main.tf index 10c8202..accf57d 100644 --- a/modules/integrations/webhook-datasource/main.tf +++ b/modules/integrations/webhook-datasource/main.tf @@ -55,8 +55,8 @@ locals { resource "google_project_iam_audit_config" "audit_config" { for_each = var.is_organizational ? {} : local.audit_log_config - project = var.project_id - service = each.key + project = var.project_id + service = each.key dynamic "audit_log_config" { for_each = each.value.log_config @@ -79,7 +79,7 @@ resource "google_pubsub_topic" "ingestion_topic" { } resource "google_pubsub_topic" "deadletter_topic" { - name = "dl-${google_pubsub_topic.ingestion_topic.name}" + name = "dl-${google_pubsub_topic.ingestion_topic.name}" project = var.project_id message_retention_duration = var.message_retention_duration } @@ -88,13 +88,13 @@ resource "google_pubsub_topic" "deadletter_topic" { # Sink #----------------------------------------------------------------------------------------- resource "google_logging_project_sink" "ingestion_sink" { - count = var.is_organizational ? 0 : 1 + count = var.is_organizational ? 0 : 1 name = "${google_pubsub_topic.ingestion_topic.name}_sink" description = "Sysdig sink to direct the AuditLogs to the PubSub topic used for data gathering" # NOTE: The target destination is a PubSub topic destination = "pubsub.googleapis.com/projects/${var.project_id}/topics/${google_pubsub_topic.ingestion_topic.name}" - filter = var.ingestion_sink_filter + filter = var.ingestion_sink_filter # Dynamic block to exclude logs from ingestion dynamic "exclusions" { @@ -238,10 +238,10 @@ resource "google_service_account_iam_member" "custom_auth" { #----------------------------------------------------------------------------------------------------------------------------------------- resource "sysdig_secure_cloud_auth_account_component" "gcp_webhook_datasource" { - account_id = var.sysdig_secure_account_id - type = "COMPONENT_WEBHOOK_DATASOURCE" - instance = "secure-runtime" - version = "v0.1.0" + account_id = var.sysdig_secure_account_id + type = "COMPONENT_WEBHOOK_DATASOURCE" + instance = "secure-runtime" + version = "v0.1.0" webhook_datasource_metadata = jsonencode({ gcp = { webhook_datasource = { diff --git a/modules/integrations/webhook-datasource/organizational.tf b/modules/integrations/webhook-datasource/organizational.tf index 0f39a3b..45233bb 100644 --- a/modules/integrations/webhook-datasource/organizational.tf +++ b/modules/integrations/webhook-datasource/organizational.tf @@ -63,7 +63,7 @@ resource "google_organization_iam_custom_role" "custom_ingestion_auth_role" { count = var.is_organizational ? 1 : 0 org_id = data.google_organization.org[0].org_id - role_id = "${var.role_name}-org-${local.suffix}" + role_id = "${var.role_name}-org-${local.suffix}" title = "Sysdigcloud Ingestion Auth Role" description = "A Role providing the required permissions for Sysdig Backend to read cloud resources created for data ingestion" permissions = [ diff --git a/modules/integrations/webhook-datasource/outputs.tf b/modules/integrations/webhook-datasource/outputs.tf index 05c7cf2..f55b862 100644 --- a/modules/integrations/webhook-datasource/outputs.tf +++ b/modules/integrations/webhook-datasource/outputs.tf @@ -1,5 +1,5 @@ output "webhook_datasource_component_id" { value = "${sysdig_secure_cloud_auth_account_component.gcp_webhook_datasource.type}/${sysdig_secure_cloud_auth_account_component.gcp_webhook_datasource.instance}" description = "Component identifier of Webhook Datasource integration created in Sysdig Backend for Log Ingestion" - depends_on = [ sysdig_secure_cloud_auth_account_component.gcp_webhook_datasource ] + depends_on = [sysdig_secure_cloud_auth_account_component.gcp_webhook_datasource] } \ No newline at end of file From 519d695f422937bbdb6b24915a1f8588b6366a30 Mon Sep 17 00:00:00 2001 From: Jose Pablo Camacho Date: Thu, 5 Sep 2024 15:48:02 -0600 Subject: [PATCH 05/34] feat(modular): add modular support for cdr/ciem --- modules/integrations/webhook-datasource/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/integrations/webhook-datasource/README.md b/modules/integrations/webhook-datasource/README.md index 8307a80..1acf8e3 100644 --- a/modules/integrations/webhook-datasource/README.md +++ b/modules/integrations/webhook-datasource/README.md @@ -35,9 +35,9 @@ This module will also deploy a Webhook Datasource Component in Sysdig Backend fo | Name | Version | |------------------------------------------------------------------|-----------| -| [google](#provider\_google) | >= 4.21.0 | +| [google](#provider\_google) | >= 4.21.0 | | [random](#requirement\_random) | >= 3.1 | -| [sysdig](#requirement\_sysdig) | +| [sysdig](#requirement\_sysdig) | | ## Modules From 72b6314f50ae8ce348985e26ea5a1f0ce0a0dbb5 Mon Sep 17 00:00:00 2001 From: Jose Pablo Camacho Date: Tue, 10 Sep 2024 14:22:41 -0600 Subject: [PATCH 06/34] feat(modular): address feedback for modular support for cdr/ciem --- modules/integrations/webhook-datasource/README.md | 5 +---- modules/integrations/webhook-datasource/main.tf | 11 ++++++++++- .../integrations/webhook-datasource/organizational.tf | 9 +++++++++ modules/integrations/webhook-datasource/versions.tf | 2 +- .../organization_cdr_test/webhook_datasource.tf | 8 ++++---- 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/modules/integrations/webhook-datasource/README.md b/modules/integrations/webhook-datasource/README.md index 1acf8e3..e9cd058 100644 --- a/modules/integrations/webhook-datasource/README.md +++ b/modules/integrations/webhook-datasource/README.md @@ -3,11 +3,8 @@ This Module creates the resources required to send AuditLogs logs to Sysdig via GCP Pub Subscription. These resources enable Threat Detection in the given GCP project or organization. Before applying the changes defined in this module, the following operations need to be performed on the target GCP environment: -- Enable the following APIs in the target environment (https://support.google.com/googleapi/answer/6158841?hl=en) +- The APIs needed for the CDR/CIEM feature are listed below: - Cloud Pub/Sub API - - Identity and Access Management (IAM) API - - IAM Service Account Credentials API - - Cloud Resource Manager API - The following resources will be created in each instrumented project: - A `PubSub Topic` to send the AuditLogs from the project diff --git a/modules/integrations/webhook-datasource/main.tf b/modules/integrations/webhook-datasource/main.tf index accf57d..46cd3f7 100644 --- a/modules/integrations/webhook-datasource/main.tf +++ b/modules/integrations/webhook-datasource/main.tf @@ -129,7 +129,7 @@ resource "google_service_account" "push_auth" { resource "google_service_account_iam_binding" "push_auth_binding" { service_account_id = google_service_account.push_auth.name - role = "roles/iam.serviceAccountTokenCreator" + role = "roles/iam.workloadIdentityUser" members = [ "serviceAccount:${google_service_account.push_auth.email}", @@ -230,6 +230,15 @@ resource "google_service_account_iam_member" "custom_auth" { member = "principalSet://iam.googleapis.com/projects/${data.google_project.project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.ingestion_auth_pool.workload_identity_pool_id}/attribute.aws_role/arn:aws:sts::${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id}:assumed-role/${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_role_name}/${data.sysdig_secure_tenant_external_id.external_id.external_id}" } +# adding ciem role with permissions to the service account +resource "google_project_iam_member" "identity_mgmt" { + for_each = var.is_organizational ? [] : toset(["roles/recommender.viewer", "roles/iam.serviceAccountViewer", "roles/iam.roleViewer", "roles/container.clusterViewer", "roles/compute.viewer"]) + + project = var.project_id + role = each.key + member = "serviceAccount:${google_service_account.push_auth.email}" +} + #----------------------------------------------------------------------------------------------------------------------------------------- # Call Sysdig Backend to add the webhook-datasource integration to the Sysdig Cloud Account # diff --git a/modules/integrations/webhook-datasource/organizational.tf b/modules/integrations/webhook-datasource/organizational.tf index 45233bb..098014c 100644 --- a/modules/integrations/webhook-datasource/organizational.tf +++ b/modules/integrations/webhook-datasource/organizational.tf @@ -84,3 +84,12 @@ resource "google_organization_iam_member" "custom" { role = google_organization_iam_custom_role.custom_ingestion_auth_role[0].id member = "serviceAccount:${google_service_account.push_auth.email}" } + +# adding ciem role with permissions to the service account for org +resource "google_organization_iam_member" "identity_mgmt" { + for_each = var.is_organizational ? toset(["roles/recommender.viewer", "roles/iam.serviceAccountViewer", "roles/iam.organizationRoleViewer", "roles/container.clusterViewer", "roles/compute.viewer"]) : [] + + org_id = data.google_organization.org[0].org_id + role = each.key + member = "serviceAccount:${google_service_account.push_auth.email}" +} \ No newline at end of file diff --git a/modules/integrations/webhook-datasource/versions.tf b/modules/integrations/webhook-datasource/versions.tf index 269cfb8..adb6e1a 100644 --- a/modules/integrations/webhook-datasource/versions.tf +++ b/modules/integrations/webhook-datasource/versions.tf @@ -12,7 +12,7 @@ terraform { } random = { source = "hashicorp/random" - version = ">= 3.1, < 4.0" + version = ">= 3.1" } } } \ No newline at end of file diff --git a/test/examples/organization_cdr_test/webhook_datasource.tf b/test/examples/organization_cdr_test/webhook_datasource.tf index 2d80fbc..62c54ad 100644 --- a/test/examples/organization_cdr_test/webhook_datasource.tf +++ b/test/examples/organization_cdr_test/webhook_datasource.tf @@ -26,12 +26,12 @@ module "webhook-datasource" { source = "../../../modules/integrations/webhook-datasource" - project_id = "org-child-project-1" + project_id = module.onboarding.project_id # push_endpoint is no longer needed # push_endpoint = "https://app-staging.sysdigcloud.com/api/cloudingestion/gcp/v2/84f934c6-eb2d-47d9-804b-bcfe9e6ef0b9" - is_organizational = true - organization_domain = "draios.com" - sysdig_secure_account_id = "" + is_organizational = module.onboarding.is_organizational + organization_domain = module.onboarding.organization_domain + sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id } # UNCOMMENT TO TEST: THIS IS NOT GOING TO BE LONGER NEEDED, SINCE WILL BE PART OF FOUNDATIONAL From e51c02d5a352acfba7e224b1a84a5ed224f597cc Mon Sep 17 00:00:00 2001 From: Haresh Suresh Date: Wed, 4 Sep 2024 16:22:32 -0700 Subject: [PATCH 07/34] adding modular onboarding module --- modules/onboarding/README.md | 88 +++++++++++++++++++++++ modules/onboarding/main.tf | 100 +++++++++++++++++++++++++++ modules/onboarding/organizational.tf | 35 ++++++++++ modules/onboarding/outputs.tf | 34 +++++++++ modules/onboarding/variables.tf | 35 ++++++++++ modules/onboarding/versions.tf | 18 +++++ 6 files changed, 310 insertions(+) create mode 100644 modules/onboarding/README.md create mode 100644 modules/onboarding/main.tf create mode 100644 modules/onboarding/organizational.tf create mode 100644 modules/onboarding/outputs.tf create mode 100644 modules/onboarding/variables.tf create mode 100644 modules/onboarding/versions.tf diff --git a/modules/onboarding/README.md b/modules/onboarding/README.md new file mode 100644 index 0000000..c59db6d --- /dev/null +++ b/modules/onboarding/README.md @@ -0,0 +1,88 @@ +# GCP Onboarding Module + +This module will deploy Foundational Onboarding resources in GCP for a single project, or for a GCP Organization. +The Foundational Onboarding module serves the following functions: +- retrieving inventory for single project, or for all projects within an Organization. +- running organization scraping in the case of organizational onboarding within GCP Organization. + +If instrumenting a project, the following resources will be created: +- All the necessary `Service Accounts` and `Policies` to enable the Onboarding operation at the project level +- A `Workload Identity Pool`, `Provider` and added custom role permissions to the `Service Account`, to allow Sysdig to authenticate to GCP on your behalf to validate resources. +- A cloud account in the Sysdig Backend, associated with the GCP project and with the required component to serve the foundational functions. + +If instrumenting an Organziation, the following resources will be created: +- All the necessary `Service Accounts` and `Policies` to enable the Onboarding operation at the organization level +- A `Workload Identity Pool`, `Provider` and added custom role permissions to the `Service Account`, to allow Sysdig to authenticate to GCP on your behalf to validate resources. +- A cloud account in the Sysdig Backend, associated with the management project and with the required component to serve the foundational functions. +- A cloud organization in the Sysdig Backend, associated with the GCP Organization to fetch the organization structure to install Sysdig Secure for Cloud on. + +Note: +- The outputs from the foundational module, such as `sysdig_secure_project_id` are needed as inputs to the other features/integrations modules for subsequent modular installs. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0.0 | +| [google](#requirement\_google) | >= 4.21.0 | +| [sysdig](#requirement\_sysdig) | >= 1.23.1 | + +## Providers + +| Name | Version | +|------|---------| +| [google](#provider\_google) | 5.0.0 | +| [random](#provider\_random) | >= 3.1 | + +## Modules + +No modules. + +## Resources + +| [google_service_account.onboarding_auth](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account) | resource | +| [google_service_account_iam_binding.onboarding_auth_binding](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account_iam_binding) | resource | +| [google_organization.org](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/organization) | data source | +| [sysdig_secure_trusted_cloud_identity.trusted_identity](https://registry.terraform.io/providers/sysdiglabs/sysdig/latest/docs/data-sources/secure_trusted_cloud_identity) | data source | +| [google_project.project](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/project) | data source | +| [random_id.suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource | +| [google_iam_workload_identity_pool.onboarding_auth_pool](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/iam_workload_identity_pool) | resource | +| [google_iam_workload_identity_pool_provider.onboarding_auth_pool_provider](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/iam_workload_identity_pool_provider) | resource | +| [google_project_iam_custom_role.custom_onboarding_auth_role](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_iam_custom_role) | resource | +| [google_project_iam_member.custom](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_iam#google_project_iam_member) | resource | +| [google_service_account_iam_member.custom_auth](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_service_account_iam#google_service_account_iam_member) | resource | +| [google_organization_iam_custom_role.custom_onboarding_auth_role](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_organization_iam_custom_role) | resource | +| [google_organization_iam_member.custom](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_organization_iam#google_organization_iam_member) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [is\_organizational](#input\_is\_organizational) | (Optional) Set this field to 'true' to deploy secure-for-cloud to a GCP Organization. | `bool` | `false` | no | +| [labels](#input\_labels) | (Optional) Labels to be associated with Sysdig-originated resources | `map(string)` |
{
"originator": "sysdig"
}
| no | +| [organization\_domain](#input\_organization\_domain) | Organization domain. e.g. sysdig.com | `string` | `""` | no | +| [project\_id](#input\_project\_id) | (Required) Target Project identifier provided by the customer | `string` | n/a | yes | +| [role\_name](#input\_role\_name) | (Optional) Role name for custom role binding to the service account, with read permissions for data onboarding resources | `string` | `"SysdigOnboardingAuthRole-{random_id}"` | no | +| [external\_id](#input\_external\_id) | (Required) Random string generated unique to a customer | `string` | n/a | yes | +| [suffix](#input\_suffix) | (Optional) Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated | `string` | `null` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [workload\_identity\_pool\_id](#output\_workload\_identity\_pool\_id) | Id of Workload Identity Pool for authenticating to GCP to access data ingestion resources | +| [workload\_identity\_pool\_provider\_id](#output\_workload\_identity\_pool\_provider\_id) | Id of Workload Identity Pool Provider for authenticating to GCP to access data ingestion resources | +| [workload\_identity\_project\_number](#output\_workload\_identity\_project\_number) | GCP project number | +| [service\_account\_email](#output\_service\_account\_email) | email of the Service Account created | +| [sysdig\_secure\_project\_id](#output\_sysdig\_secure\_project\_id) | ID of the Sysdig Cloud Account created | +| [is\_organizational](#output\_is\_organizational) | Boolean value to indicate if secure-for-cloud is deployed to an entire GCP organization or not | + + +## Authors + +Module is maintained by [Sysdig](https://sysdig.com). + +## License + +Apache 2 Licensed. See LICENSE for full details. \ No newline at end of file diff --git a/modules/onboarding/main.tf b/modules/onboarding/main.tf new file mode 100644 index 0000000..bf2431e --- /dev/null +++ b/modules/onboarding/main.tf @@ -0,0 +1,100 @@ +#------------------------------------------------------------------# +# Fetch and compute required data for Workload Identity Federation # +#------------------------------------------------------------------# + +data "sysdig_secure_trusted_cloud_identity" "trusted_identity" { + cloud_provider = "gcp" +} + +data "google_project" "project" { + project_id = var.project_id +} + +// suffix to uniquely identify WIF pool and provider during multiple installs. If suffix value is not provided, this will generate a random value. +resource "random_id" "suffix" { + count = var.suffix == null ? 1 : 0 + byte_length = 3 +} + +locals { + suffix = var.suffix == null ? random_id.suffix[0].hex : var.suffix +} + +resource "google_service_account" "onboarding_auth" { + account_id = "sysdig-onboarding-${local.suffix}" + display_name = "Sysdig Onboarding Auth Service Account" + project = var.project_id +} + +resource "google_service_account_iam_binding" "onboarding_auth_binding" { + service_account_id = google_service_account.push_auth.name + role = "roles/iam.workloadIdentityUser" + + members = [ + "serviceAccount:${google_service_account.onboarding_auth.email}", + ] +} + +#------------------------------------------------------------# +# Configure Workload Identity Federation for auth # +# See https://cloud.google.com/iam/docs/access-resources-aws # +#------------------------------------------------------------# + +resource "google_iam_workload_identity_pool" "onboarding_auth_pool" { + project = var.project_id + workload_identity_pool_id = "sysdig-onboarding-${local.suffix}" +} + +resource "google_iam_workload_identity_pool_provider" "onboarding_auth_pool_provider" { + project = var.project_id + workload_identity_pool_id = google_iam_workload_identity_pool.onboarding_auth_pool.workload_identity_pool_id + workload_identity_pool_provider_id = "sysdig-onboarding-${local.suffix}" + display_name = "Sysdigcloud onboarding auth" + description = "AWS identity pool provider for Sysdig Secure Data Onboarding resources" + disabled = false + + attribute_condition = "attribute.aws_role==\"arn:aws:sts::${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id}:assumed-role/${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_role_name}/${var.external_id}\"" + + attribute_mapping = { + "google.subject" = "assertion.arn", + "attribute.aws_role" = "assertion.arn" + } + + aws { + account_id = data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id + } +} + +# creating custom role with project-level permissions to access onboarding resources +resource "google_project_iam_custom_role" "custom_onboarding_auth_role" { + count = var.is_organizational ? 0 : 1 + + project = var.project_id + role_id = var.role_name + title = "Sysdigcloud Onboarding Auth Role" + description = "A Role providing the required permissions for Sysdig Backend to read cloud resources created for onboarding" + permissions = [ + "pubsub.topics.get", + "pubsub.topics.list", + "pubsub.subscriptions.get", + "pubsub.subscriptions.list", + "logging.sinks.get", + "logging.sinks.list", + ] +} + +# adding custom role with project-level permissions to the service account for auth +resource "google_project_iam_member" "custom" { + count = var.is_organizational ? 0 : 1 + + project = var.project_id + role = google_project_iam_custom_role.custom_onboarding_auth_role[0].id + member = "serviceAccount:${google_service_account.onboarding_auth.email}" +} + +# attaching WIF as a member to the service account for auth +resource "google_service_account_iam_member" "custom_auth" { + service_account_id = google_service_account.onboarding_auth.name + role = "roles/iam.workloadIdentityUser" + member = "principalSet://iam.googleapis.com/projects/${data.google_project.project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.onboarding_auth_pool.workload_identity_pool_id}/attribute.aws_role/arn:aws:sts::${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id}:assumed-role/${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_role_name}/${var.external_id}" +} \ No newline at end of file diff --git a/modules/onboarding/organizational.tf b/modules/onboarding/organizational.tf new file mode 100644 index 0000000..a83553b --- /dev/null +++ b/modules/onboarding/organizational.tf @@ -0,0 +1,35 @@ +#--------------# +# Organization # +#--------------# + +data "google_organization" "org" { + count = var.is_organizational ? 1 : 0 + domain = var.organization_domain +} + +# creating custom role with organization-level permissions to access onboarding resources +resource "google_organization_iam_custom_role" "custom_onboarding_auth_role" { + count = var.is_organizational ? 1 : 0 + + org_id = data.google_organization.org[0].org_id + role_id = var.role_name + title = "Sysdigcloud Onboarding Auth Role" + description = "A Role providing the required permissions for Sysdig Backend to read cloud resources created for onboarding" + permissions = [ + "pubsub.topics.get", + "pubsub.topics.list", + "pubsub.subscriptions.get", + "pubsub.subscriptions.list", + "logging.sinks.get", + "logging.sinks.list", + ] +} + +# adding custom role with organization-level permissions to the service account for auth +resource "google_organization_iam_member" "custom" { + count = var.is_organizational ? 1 : 0 + + org_id = data.google_organization.org[0].org_id + role = google_organization_iam_custom_role.custom_onboarding_auth_role[0].id + member = "serviceAccount:${google_service_account.onboarding_auth.email}" +} \ No newline at end of file diff --git a/modules/onboarding/outputs.tf b/modules/onboarding/outputs.tf new file mode 100644 index 0000000..75ec94c --- /dev/null +++ b/modules/onboarding/outputs.tf @@ -0,0 +1,34 @@ +output "workload_identity_pool_id" { + value = google_iam_workload_identity_pool.onboarding_auth_pool.workload_identity_pool_id + description = "Id of Workload Identity Pool for authenticating to GCP to access data onboarding resources" +} + +output "workload_identity_pool_provider_id" { + value = google_iam_workload_identity_pool_provider.onboarding_auth_pool_provider.workload_identity_pool_provider_id + description = "Id of Workload Identity Pool Provider for authenticating to GCP to access data onboarding resources" +} + +output "workload_identity_project_number" { + value = data.google_project.project.number + description = "GCP project number" +} + +output "service_account_email" { + value = google_service_account.onboarding_auth.email + description = "email of the Service Account created" +} + +output "project_id" { + value = var.project_id + description = "Project ID in which secure-for-cloud onboarding resources are created. For organizational installs it is the Management Project ID selected during install" +} + +output "sysdig_secure_project_id" { + value = sysdig_secure_cloud_auth_account.google_account.id + description = "ID of the Sysdig Cloud Account created" +} + +output "is_organizational" { + value = var.is_organizational + description = "Boolean value to indicate if secure-for-cloud is deployed to an entire GCP organization or not" +} diff --git a/modules/onboarding/variables.tf b/modules/onboarding/variables.tf new file mode 100644 index 0000000..3da88f8 --- /dev/null +++ b/modules/onboarding/variables.tf @@ -0,0 +1,35 @@ +variable "project_id" { + type = string + description = "(Required) Target Project identifier provided by the customer" +} + +variable "labels" { + type = map(string) + description = "(Optional) Labels to be associated with Sysdig-originated resources" + default = { + originator = "sysdig" + } +} + +variable "is_organizational" { + description = "(Optional) Set this field to 'true' to deploy secure-for-cloud to a GCP Organization." + type = bool + default = false +} + +variable "organization_domain" { + type = string + description = "(Optional) Organization domain. e.g. sysdig.com" + default = "" +} + +variable "external_id" { + type = string + description = "(Required) Random string generated unique to a customer" +} + +variable "suffix" { + type = string + description = "Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated" + default = null +} \ No newline at end of file diff --git a/modules/onboarding/versions.tf b/modules/onboarding/versions.tf new file mode 100644 index 0000000..b6453f7 --- /dev/null +++ b/modules/onboarding/versions.tf @@ -0,0 +1,18 @@ +terraform { + required_version = ">= 1.0.0" + + required_providers { + google = { + source = "hashicorp/google" + version = ">= 4.21.0" + } + sysdig = { + source = "sysdiglabs/sysdig" + version = ">= 1.23.1" + } + random = { + source = "hashicorp/random" + version = ">= 3.1, < 4.0" + } + } +} \ No newline at end of file From 80b782a3c6293659be3ceec48ff61150a2bafae9 Mon Sep 17 00:00:00 2001 From: Haresh Suresh Date: Wed, 4 Sep 2024 21:03:36 -0700 Subject: [PATCH 08/34] fix var refns --- modules/onboarding/main.tf | 68 +++++++++++++++++++--------- modules/onboarding/organizational.tf | 38 ++++++++-------- modules/onboarding/variables.tf | 6 +++ modules/onboarding/versions.tf | 2 +- 4 files changed, 72 insertions(+), 42 deletions(-) diff --git a/modules/onboarding/main.tf b/modules/onboarding/main.tf index bf2431e..bc01928 100644 --- a/modules/onboarding/main.tf +++ b/modules/onboarding/main.tf @@ -27,7 +27,7 @@ resource "google_service_account" "onboarding_auth" { } resource "google_service_account_iam_binding" "onboarding_auth_binding" { - service_account_id = google_service_account.push_auth.name + service_account_id = google_service_account.onboarding_auth.name role = "roles/iam.workloadIdentityUser" members = [ @@ -65,30 +65,14 @@ resource "google_iam_workload_identity_pool_provider" "onboarding_auth_pool_prov } } -# creating custom role with project-level permissions to access onboarding resources -resource "google_project_iam_custom_role" "custom_onboarding_auth_role" { - count = var.is_organizational ? 0 : 1 - - project = var.project_id - role_id = var.role_name - title = "Sysdigcloud Onboarding Auth Role" - description = "A Role providing the required permissions for Sysdig Backend to read cloud resources created for onboarding" - permissions = [ - "pubsub.topics.get", - "pubsub.topics.list", - "pubsub.subscriptions.get", - "pubsub.subscriptions.list", - "logging.sinks.get", - "logging.sinks.list", - ] -} - -# adding custom role with project-level permissions to the service account for auth -resource "google_project_iam_member" "custom" { +#--------------------------------- +# role permissions for onboarding +#--------------------------------- +resource "google_project_iam_member" "browser" { count = var.is_organizational ? 0 : 1 project = var.project_id - role = google_project_iam_custom_role.custom_onboarding_auth_role[0].id + role = "roles/browser" member = "serviceAccount:${google_service_account.onboarding_auth.email}" } @@ -97,4 +81,44 @@ resource "google_service_account_iam_member" "custom_auth" { service_account_id = google_service_account.onboarding_auth.name role = "roles/iam.workloadIdentityUser" member = "principalSet://iam.googleapis.com/projects/${data.google_project.project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.onboarding_auth_pool.workload_identity_pool_id}/attribute.aws_role/arn:aws:sts::${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id}:assumed-role/${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_role_name}/${var.external_id}" +} + +#--------------------------------------------------------------------------------------------- +# Call Sysdig Backend to create account with foundational onboarding +# (ensure it is called after all above cloud resources are created using explicit depends_on) +#--------------------------------------------------------------------------------------------- + +resource "sysdig_secure_cloud_auth_account" "google_account" { + enabled = true + provider_id = var.project_id + provider_type = "PROVIDER_GCP" + provider_alias = data.google_project.project.name + provider_tenant_id = var.organization_domain + + component { + type = "COMPONENT_SERVICE_PRINCIPAL" + instance = "secure-onboarding" + version = "v0.1.0" + service_principal_metadata = jsonencode({ + gcp = { + service_principal = { + workload_identity_federation = { + pool_id = google_iam_workload_identity_pool.onboarding_auth_pool.workload_identity_pool_id + pool_provider_id = google_iam_workload_identity_pool_provider.onboarding_auth_pool_provider.workload_identity_pool_provider_id + project_number = data.google_project.project.number + } + email = google_service_account.onboarding_auth.email + } + } + }) + } + + depends_on = [google_service_account_iam_member.custom_auth] + + lifecycle { + ignore_changes = [ + component, + feature + ] + } } \ No newline at end of file diff --git a/modules/onboarding/organizational.tf b/modules/onboarding/organizational.tf index a83553b..4ff434a 100644 --- a/modules/onboarding/organizational.tf +++ b/modules/onboarding/organizational.tf @@ -7,29 +7,29 @@ data "google_organization" "org" { domain = var.organization_domain } -# creating custom role with organization-level permissions to access onboarding resources -resource "google_organization_iam_custom_role" "custom_onboarding_auth_role" { +################################################### +# Setup Service Account permissions +################################################### + +#--------------------------------- +# role permissions for onboarding +#--------------------------------- +resource "google_organization_iam_member" "browser" { count = var.is_organizational ? 1 : 0 - org_id = data.google_organization.org[0].org_id - role_id = var.role_name - title = "Sysdigcloud Onboarding Auth Role" - description = "A Role providing the required permissions for Sysdig Backend to read cloud resources created for onboarding" - permissions = [ - "pubsub.topics.get", - "pubsub.topics.list", - "pubsub.subscriptions.get", - "pubsub.subscriptions.list", - "logging.sinks.get", - "logging.sinks.list", - ] + org_id = data.google_organization.org[0].org_id + role = "roles/browser" + member = "serviceAccount:${google_service_account.onboarding_auth.email}" } -# adding custom role with organization-level permissions to the service account for auth -resource "google_organization_iam_member" "custom" { +#--------------------------------------------------------------------------------------------- +# Call Sysdig Backend to create organization with foundational onboarding +# (ensure it is called after all above cloud resources are created) +#--------------------------------------------------------------------------------------------- +resource "sysdig_secure_organization" "azure_organization" { count = var.is_organizational ? 1 : 0 - org_id = data.google_organization.org[0].org_id - role = google_organization_iam_custom_role.custom_onboarding_auth_role[0].id - member = "serviceAccount:${google_service_account.onboarding_auth.email}" + management_account_id = sysdig_secure_cloud_auth_account.google_account.id + organizational_unit_ids = var.management_group_ids + depends_on = [google_organization_iam_member.browser] } \ No newline at end of file diff --git a/modules/onboarding/variables.tf b/modules/onboarding/variables.tf index 3da88f8..a90da48 100644 --- a/modules/onboarding/variables.tf +++ b/modules/onboarding/variables.tf @@ -23,6 +23,12 @@ variable "organization_domain" { default = "" } +variable "management_group_ids" { + type = set(string) + description = "(Optional) Management group id to onboard. e.g. [organizations/123456789012], [folders/123456789012]" + default = [] +} + variable "external_id" { type = string description = "(Required) Random string generated unique to a customer" diff --git a/modules/onboarding/versions.tf b/modules/onboarding/versions.tf index b6453f7..0ef54f7 100644 --- a/modules/onboarding/versions.tf +++ b/modules/onboarding/versions.tf @@ -8,7 +8,7 @@ terraform { } sysdig = { source = "sysdiglabs/sysdig" - version = ">= 1.23.1" + version = ">= 1.29.2" } random = { source = "hashicorp/random" From 6795442e7b9f7133983dc75bafebb88b977c731f Mon Sep 17 00:00:00 2001 From: Haresh Suresh Date: Wed, 4 Sep 2024 22:24:18 -0700 Subject: [PATCH 09/34] adding modular onboarding example --- .../onboarding_with_posture.tf | 25 +++++++++++++++++++ .../onboarding_with_posture.tf | 24 ++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 test/examples/modular_organization/onboarding_with_posture.tf create mode 100644 test/examples/modular_single_project/onboarding_with_posture.tf diff --git a/test/examples/modular_organization/onboarding_with_posture.tf b/test/examples/modular_organization/onboarding_with_posture.tf new file mode 100644 index 0000000..63b1c09 --- /dev/null +++ b/test/examples/modular_organization/onboarding_with_posture.tf @@ -0,0 +1,25 @@ +provider "google" { + project = "org-child-project-3" + region = "us-west1" +} + +terraform { + required_providers { + sysdig = { + source = "sysdiglabs/sysdig" + version = "~> 1.29.2" + } + } +} + +provider "sysdig" { + sysdig_secure_url = "https://secure-staging.sysdig.com" + sysdig_secure_api_token = "API_TOKEN" +} + +module "onboarding" { + source = "../../../modules/onboarding" + project_id = "org-child-project-3" + external_id = "25ef0d887bc7a2b30089a025618e1c62" + is_organizational = true +} \ No newline at end of file diff --git a/test/examples/modular_single_project/onboarding_with_posture.tf b/test/examples/modular_single_project/onboarding_with_posture.tf new file mode 100644 index 0000000..6372874 --- /dev/null +++ b/test/examples/modular_single_project/onboarding_with_posture.tf @@ -0,0 +1,24 @@ +provider "google" { + project = "org-child-project-3" + region = "us-west1" +} + +terraform { + required_providers { + sysdig = { + source = "sysdiglabs/sysdig" + version = "~> 1.29.2" + } + } +} + +provider "sysdig" { + sysdig_secure_url = "https://secure-staging.sysdig.com" + sysdig_secure_api_token = "API_TOKEN" +} + +module "onboarding" { + source = "../../../modules/onboarding" + project_id = "org-child-project-3" + external_id = "25ef0d887bc7a2b30089a025618e1c62" +} \ No newline at end of file From 7a076255f5ebe332dc2249bed3cb3e471b4cd695 Mon Sep 17 00:00:00 2001 From: Haresh Suresh Date: Wed, 4 Sep 2024 23:37:57 -0700 Subject: [PATCH 10/34] adding config posture module for modular onboarding --- modules/config-posture/README.md | 0 modules/config-posture/main.tf | 109 +++++++++++++++++++++++ modules/config-posture/organizational.tf | 23 +++++ modules/config-posture/outputs.tf | 5 ++ modules/config-posture/variables.tf | 38 ++++++++ modules/config-posture/versions.tf | 18 ++++ modules/onboarding/variables.tf | 8 -- modules/onboarding/versions.tf | 2 +- 8 files changed, 194 insertions(+), 9 deletions(-) create mode 100644 modules/config-posture/README.md create mode 100644 modules/config-posture/main.tf create mode 100644 modules/config-posture/organizational.tf create mode 100644 modules/config-posture/outputs.tf create mode 100644 modules/config-posture/variables.tf create mode 100644 modules/config-posture/versions.tf diff --git a/modules/config-posture/README.md b/modules/config-posture/README.md new file mode 100644 index 0000000..e69de29 diff --git a/modules/config-posture/main.tf b/modules/config-posture/main.tf new file mode 100644 index 0000000..35e105e --- /dev/null +++ b/modules/config-posture/main.tf @@ -0,0 +1,109 @@ +#------------------------------------------------------------------# +# Fetch and compute required data for Workload Identity Federation # +#------------------------------------------------------------------# + +data "sysdig_secure_trusted_cloud_identity" "trusted_identity" { + cloud_provider = "gcp" +} + +data "google_project" "project" { + project_id = var.project_id +} + +// suffix to uniquely identify WIF pool and provider during multiple installs. If suffix value is not provided, this will generate a random value. +resource "random_id" "suffix" { + count = var.suffix == null ? 1 : 0 + byte_length = 3 +} + +locals { + suffix = var.suffix == null ? random_id.suffix[0].hex : var.suffix +} + +resource "google_service_account" "posture_auth" { + account_id = "sysdig-posture-${local.suffix}" + display_name = "Sysdig Config Posture Auth Service Account" + project = var.project_id +} + +resource "google_service_account_iam_binding" "posture_auth_binding" { + service_account_id = google_service_account.posture_auth.name + role = "roles/iam.workloadIdentityUser" + + members = [ + "serviceAccount:${google_service_account.posture_auth.email}", + ] +} + +#------------------------------------------------------------# +# Configure Workload Identity Federation for auth # +# See https://cloud.google.com/iam/docs/access-resources-aws # +#------------------------------------------------------------# + +resource "google_iam_workload_identity_pool" "posture_auth_pool" { + project = var.project_id + workload_identity_pool_id = "sysdig-posture-${local.suffix}" +} + +resource "google_iam_workload_identity_pool_provider" "posture_auth_pool_provider" { + project = var.project_id + workload_identity_pool_id = google_iam_workload_identity_pool.posture_auth_pool.workload_identity_pool_id + workload_identity_pool_provider_id = "sysdig-posture-${local.suffix}" + display_name = "Sysdigcloud config posture auth" + description = "AWS identity pool provider for Sysdig Secure Data Config Posture resources" + disabled = false + + attribute_condition = "attribute.aws_role==\"arn:aws:sts::${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id}:assumed-role/${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_role_name}/${var.external_id}\"" + + attribute_mapping = { + "google.subject" = "assertion.arn", + "attribute.aws_role" = "assertion.arn" + } + + aws { + account_id = data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id + } +} + +#--------------------------------------------------------------------------------------------- +# role permissions for CSPM (GCP Predefined Roles for Sysdig Cloud Secure Posture Management) +#--------------------------------------------------------------------------------------------- +resource "google_project_iam_member" "cspm" { + for_each = var.is_organizational ? [] : toset(["roles/cloudasset.viewer", "roles/iam.workloadIdentityUser", "roles/logging.viewer", "roles/cloudfunctions.viewer", "roles/cloudbuild.builds.viewer", "roles/orgpolicy.policyViewer"]) + + project = var.project_id + role = each.key + member = "serviceAccount:${google_service_account.posture_auth.email}" +} + +# attaching WIF as a member to the service account for auth +resource "google_service_account_iam_member" "custom_auth" { + service_account_id = google_service_account.posture_auth.name + role = "roles/iam.workloadIdentityUser" + member = "principalSet://iam.googleapis.com/projects/${data.google_project.project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.posture_auth_pool.workload_identity_pool_id}/attribute.aws_role/arn:aws:sts::${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id}:assumed-role/${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_role_name}/${var.external_id}" +} + +#-------------------------------------------------------------------------------------------------------------- +# Call Sysdig Backend to add the service-principal integration for Config Posture to the Sysdig Cloud Account +# +# Note (optional): To ensure this gets called after all cloud resources are created, add +# explicit dependency using depends_on +#-------------------------------------------------------------------------------------------------------------- +resource "sysdig_secure_cloud_auth_account_component" "google_service_principal" { + account_id = var.sysdig_secure_account_id + type = "COMPONENT_SERVICE_PRINCIPAL" + instance = "secure-posture" + verion = "v0.1.0" + service_principal_metadata = jsonencode({ + gcp = { + service_principal = { + workload_identity_federation = { + pool_id = google_iam_workload_identity_pool.posture_auth_pool.workload_identity_pool_id + pool_provider_id = google_iam_workload_identity_pool_provider.posture_auth_pool_provider.workload_identity_pool_provider_id + project_number = data.google_project.project.number + } + email = google_service_account.posture_auth.email + } + } + }) +} diff --git a/modules/config-posture/organizational.tf b/modules/config-posture/organizational.tf new file mode 100644 index 0000000..77d85b0 --- /dev/null +++ b/modules/config-posture/organizational.tf @@ -0,0 +1,23 @@ +#--------------# +# Organization # +#--------------# + +data "google_organization" "org" { + count = var.is_organizational ? 1 : 0 + domain = var.organization_domain +} + +################################################### +# Setup Service Account permissions +################################################### + +#--------------------------------------------------------------------------------------------- +# role permissions for CSPM (GCP Predefined Roles for Sysdig Cloud Secure Posture Management) +#--------------------------------------------------------------------------------------------- +resource "google_organization_iam_member" "cspm" { + for_each = var.is_organizational ? toset(["roles/cloudasset.viewer", "roles/iam.workloadIdentityUser", "roles/logging.viewer", "roles/cloudfunctions.viewer", "roles/cloudbuild.builds.viewer", "roles/orgpolicy.policyViewer"]) : [] + + org_id = data.google_organization.org[0].org_id + role = each.key + member = "serviceAccount:${google_service_account.posture_auth.email}" +} \ No newline at end of file diff --git a/modules/config-posture/outputs.tf b/modules/config-posture/outputs.tf new file mode 100644 index 0000000..20c9f5d --- /dev/null +++ b/modules/config-posture/outputs.tf @@ -0,0 +1,5 @@ +output "service_principal_component_id" { + value = "${sysdig_secure_cloud_auth_account_component.google_service_principal.type}/${sysdig_secure_cloud_auth_account_component.google_service_principal.instance}" + description = "Component identifier of Service Principal created in Sysdig Backend for Config Posture" + depends_on = [sysdig_secure_cloud_auth_account_component.google_service_principal] +} \ No newline at end of file diff --git a/modules/config-posture/variables.tf b/modules/config-posture/variables.tf new file mode 100644 index 0000000..b1d3d9e --- /dev/null +++ b/modules/config-posture/variables.tf @@ -0,0 +1,38 @@ +variable "project_id" { + type = string + description = "(Required) Target Project identifier provided by the customer" +} + +variable "is_organizational" { + description = "(Optional) Set this field to 'true' to deploy secure-for-cloud to a GCP Organization." + type = bool + default = false +} + +variable "organization_domain" { + type = string + description = "(Optional) Organization domain. e.g. sysdig.com" + default = "" +} + +variable "management_group_ids" { + type = set(string) + description = "(Optional) Management group id to onboard. e.g. [organizations/123456789012], [folders/123456789012]" + default = [] +} + +variable "external_id" { + type = string + description = "(Required) Random string generated unique to a customer" +} + +variable "suffix" { + type = string + description = "Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated" + default = null +} + +variable "sysdig_secure_account_id" { + type = string + description = "ID of the Sysdig Cloud Account to enable Config Posture for (in case of organization, ID of the Sysdig management account)" +} \ No newline at end of file diff --git a/modules/config-posture/versions.tf b/modules/config-posture/versions.tf new file mode 100644 index 0000000..7f82c5f --- /dev/null +++ b/modules/config-posture/versions.tf @@ -0,0 +1,18 @@ +terraform { + required_version = ">= 1.0.0" + + required_providers { + google = { + source = "hashicorp/google" + version = ">= 4.21.0" + } + sysdig = { + source = "sysdiglabs/sysdig" + version = ">= 1.29.2" + } + random = { + source = "hashicorp/random" + version = ">= 3.1" + } + } +} \ No newline at end of file diff --git a/modules/onboarding/variables.tf b/modules/onboarding/variables.tf index a90da48..7564fc6 100644 --- a/modules/onboarding/variables.tf +++ b/modules/onboarding/variables.tf @@ -3,14 +3,6 @@ variable "project_id" { description = "(Required) Target Project identifier provided by the customer" } -variable "labels" { - type = map(string) - description = "(Optional) Labels to be associated with Sysdig-originated resources" - default = { - originator = "sysdig" - } -} - variable "is_organizational" { description = "(Optional) Set this field to 'true' to deploy secure-for-cloud to a GCP Organization." type = bool diff --git a/modules/onboarding/versions.tf b/modules/onboarding/versions.tf index 0ef54f7..7f82c5f 100644 --- a/modules/onboarding/versions.tf +++ b/modules/onboarding/versions.tf @@ -12,7 +12,7 @@ terraform { } random = { source = "hashicorp/random" - version = ">= 3.1, < 4.0" + version = ">= 3.1" } } } \ No newline at end of file From 5581c6a39807e1833c5cdeed8d036adda1240b2a Mon Sep 17 00:00:00 2001 From: Haresh Suresh Date: Thu, 5 Sep 2024 13:35:04 -0700 Subject: [PATCH 11/34] updating README --- modules/config-posture/README.md | 87 ++++++++++++++++++++++++++++++++ modules/config-posture/main.tf | 6 +-- modules/onboarding/README.md | 15 +++--- modules/onboarding/main.tf | 6 +-- 4 files changed, 100 insertions(+), 14 deletions(-) diff --git a/modules/config-posture/README.md b/modules/config-posture/README.md index e69de29..9557b9a 100644 --- a/modules/config-posture/README.md +++ b/modules/config-posture/README.md @@ -0,0 +1,87 @@ +# GCP Config Posture Module + +This module will deploy Config Posture resources in GCP for a single project, or for a GCP Organization. +The Config Posture module serves the following functions: +- retrieving inventory for single project, or for all projects within an Organization. +- retrieving organization metadata in the case of organizational onboarding within GCP Organization. + +If instrumenting a project, the following resources will be created: +- All the necessary `Service Accounts` and `Policies` to enable the Config posture operation at the project level +- A `Workload Identity Pool`, `Provider` and added custom role permissions to the `Service Account`, to allow Sysdig to authenticate to GCP on your behalf to validate resources. +- A cloud account component in the Sysdig Backend, associated with the GCP project and with the required component to serve the config posture functions. + +If instrumenting an Organziation, the following resources will be created: +- All the necessary `Service Accounts` and `Policies` to enable the Config Posture operation at the organization level +- A `Workload Identity Pool`, `Provider` and added custom role permissions to the `Service Account`, to allow Sysdig to authenticate to GCP on your behalf to validate resources. +- A cloud account component in the Sysdig Backend, associated with the GCP project and with the required component to serve the config posture functions. + +Note: +- The outputs from the foundational module, such as `sysdig_secure_project_id` are needed as inputs to the other features/integrations modules for subsequent modular installs. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0.0 | +| [google](#requirement\_google) | >= 4.21.0 | +| [sysdig](#requirement\_sysdig) | >= 1.23.1 | + +## Providers + +| Name | Version | +|------|---------| +| [google](#provider\_google) | 5.0.0 | +| [random](#provider\_random) | >= 3.1 | + +## Modules + +No modules. + +## Resources + +| [google_service_account.posture_auth](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account) | resource | +| [google_service_account_iam_binding.posture_auth_binding](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account_iam_binding) | resource | +| [google_organization.org](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/organization) | data source | +| [sysdig_secure_trusted_cloud_identity.trusted_identity](https://registry.terraform.io/providers/sysdiglabs/sysdig/latest/docs/data-sources/secure_trusted_cloud_identity) | data source | +| [google_project.project](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/project) | data source | +| [random_id.suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource | +| [google_iam_workload_identity_pool.posture_auth_pool](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/iam_workload_identity_pool) | resource | +| [google_iam_workload_identity_pool_provider.posture_auth_pool_provider](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/iam_workload_identity_pool_provider) | resource | +| [google_project_iam_custom_role.custom_posture_auth_role](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_iam_custom_role) | resource | +| [google_project_iam_member.custom](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_iam#google_project_iam_member) | resource | +| [google_service_account_iam_member.custom_auth](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_service_account_iam#google_service_account_iam_member) | resource | +| [google_organization_iam_custom_role.custom_posture_auth_role](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_organization_iam_custom_role) | resource | +| [google_organization_iam_member.custom](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_organization_iam#google_organization_iam_member) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|---------------------------------------------------------------------------------------------------------------------------|------|-----------------------------------------------|:--------:| +| [is\_organizational](#input\_is\_organizational) | (Optional) Set this field to 'true' to deploy secure-for-cloud to a GCP Organization. | `bool` | `false` | no | +| [labels](#input\_labels) | (Optional) Labels to be associated with Sysdig-originated resources | `map(string)` |
{
"originator": "sysdig"
}
| no | +| [organization\_domain](#input\_organization\_domain) | Organization domain. e.g. sysdig.com | `string` | `""` | no | +| [project\_id](#input\_project\_id) | (Required) Target Project identifier provided by the customer | `string` | n/a | yes | +| [role\_name](#input\_role\_name) | (Optional) Role name for custom role binding to the service account, with read permissions for posture resources | `string` | `"SysdigPostureAuthRole-{random_id}"` | no | +| [external\_id](#input\_external\_id) | (Required) Random string generated unique to a customer | `string` | n/a | yes | +| [suffix](#input\_suffix) | (Optional) Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated | `string` | `null` | no | + +## Outputs + +| Name | Description | +|------|----------------------------------------------------------------------------------------------------| +| [workload\_identity\_pool\_id](#output\_workload\_identity\_pool\_id) | Id of Workload Identity Pool for authenticating to GCP to access config posture resources | +| [workload\_identity\_pool\_provider\_id](#output\_workload\_identity\_pool\_provider\_id) | Id of Workload Identity Pool Provider for authenticating to GCP to access config posture resources | +| [workload\_identity\_project\_number](#output\_workload\_identity\_project\_number) | GCP project number | +| [service\_account\_email](#output\_service\_account\_email) | email of the Service Account created | +| [sysdig\_secure\_project\_id](#output\_sysdig\_secure\_project\_id) | ID of the Sysdig Cloud Account created | +| [is\_organizational](#output\_is\_organizational) | Boolean value to indicate if secure-for-cloud is deployed to an entire GCP organization or not | + + +## Authors + +Module is maintained by [Sysdig](https://sysdig.com). + +## License + +Apache 2 Licensed. See LICENSE for full details. \ No newline at end of file diff --git a/modules/config-posture/main.tf b/modules/config-posture/main.tf index 35e105e..a14dc39 100644 --- a/modules/config-posture/main.tf +++ b/modules/config-posture/main.tf @@ -21,7 +21,7 @@ locals { } resource "google_service_account" "posture_auth" { - account_id = "sysdig-posture-${local.suffix}" + account_id = "sysdig-secure-posture-${local.suffix}" display_name = "Sysdig Config Posture Auth Service Account" project = var.project_id } @@ -42,13 +42,13 @@ resource "google_service_account_iam_binding" "posture_auth_binding" { resource "google_iam_workload_identity_pool" "posture_auth_pool" { project = var.project_id - workload_identity_pool_id = "sysdig-posture-${local.suffix}" + workload_identity_pool_id = "sysdig-secure-posture-${local.suffix}" } resource "google_iam_workload_identity_pool_provider" "posture_auth_pool_provider" { project = var.project_id workload_identity_pool_id = google_iam_workload_identity_pool.posture_auth_pool.workload_identity_pool_id - workload_identity_pool_provider_id = "sysdig-posture-${local.suffix}" + workload_identity_pool_provider_id = "sysdig-secure-posture-${local.suffix}" display_name = "Sysdigcloud config posture auth" description = "AWS identity pool provider for Sysdig Secure Data Config Posture resources" disabled = false diff --git a/modules/onboarding/README.md b/modules/onboarding/README.md index c59db6d..135f4c0 100644 --- a/modules/onboarding/README.md +++ b/modules/onboarding/README.md @@ -63,19 +63,18 @@ No modules. | [labels](#input\_labels) | (Optional) Labels to be associated with Sysdig-originated resources | `map(string)` |
{
"originator": "sysdig"
}
| no | | [organization\_domain](#input\_organization\_domain) | Organization domain. e.g. sysdig.com | `string` | `""` | no | | [project\_id](#input\_project\_id) | (Required) Target Project identifier provided by the customer | `string` | n/a | yes | -| [role\_name](#input\_role\_name) | (Optional) Role name for custom role binding to the service account, with read permissions for data onboarding resources | `string` | `"SysdigOnboardingAuthRole-{random_id}"` | no | | [external\_id](#input\_external\_id) | (Required) Random string generated unique to a customer | `string` | n/a | yes | | [suffix](#input\_suffix) | (Optional) Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated | `string` | `null` | no | ## Outputs -| Name | Description | -|------|-------------| -| [workload\_identity\_pool\_id](#output\_workload\_identity\_pool\_id) | Id of Workload Identity Pool for authenticating to GCP to access data ingestion resources | -| [workload\_identity\_pool\_provider\_id](#output\_workload\_identity\_pool\_provider\_id) | Id of Workload Identity Pool Provider for authenticating to GCP to access data ingestion resources | -| [workload\_identity\_project\_number](#output\_workload\_identity\_project\_number) | GCP project number | -| [service\_account\_email](#output\_service\_account\_email) | email of the Service Account created | -| [sysdig\_secure\_project\_id](#output\_sysdig\_secure\_project\_id) | ID of the Sysdig Cloud Account created | +| Name | Description | +|------|------------------------------------------------------------------------------------------------| +| [workload\_identity\_pool\_id](#output\_workload\_identity\_pool\_id) | Id of Workload Identity Pool for authenticating to GCP to access onboarding resources | +| [workload\_identity\_pool\_provider\_id](#output\_workload\_identity\_pool\_provider\_id) | Id of Workload Identity Pool Provider for authenticating to GCP to access onboarding resources | +| [workload\_identity\_project\_number](#output\_workload\_identity\_project\_number) | GCP project number | +| [service\_account\_email](#output\_service\_account\_email) | email of the Service Account created | +| [sysdig\_secure\_project\_id](#output\_sysdig\_secure\_project\_id) | ID of the Sysdig Cloud Account created | | [is\_organizational](#output\_is\_organizational) | Boolean value to indicate if secure-for-cloud is deployed to an entire GCP organization or not | diff --git a/modules/onboarding/main.tf b/modules/onboarding/main.tf index bc01928..f14db18 100644 --- a/modules/onboarding/main.tf +++ b/modules/onboarding/main.tf @@ -21,7 +21,7 @@ locals { } resource "google_service_account" "onboarding_auth" { - account_id = "sysdig-onboarding-${local.suffix}" + account_id = "sysdig-secure-onboarding-${local.suffix}" display_name = "Sysdig Onboarding Auth Service Account" project = var.project_id } @@ -42,13 +42,13 @@ resource "google_service_account_iam_binding" "onboarding_auth_binding" { resource "google_iam_workload_identity_pool" "onboarding_auth_pool" { project = var.project_id - workload_identity_pool_id = "sysdig-onboarding-${local.suffix}" + workload_identity_pool_id = "sysdig-secure-onboarding-${local.suffix}" } resource "google_iam_workload_identity_pool_provider" "onboarding_auth_pool_provider" { project = var.project_id workload_identity_pool_id = google_iam_workload_identity_pool.onboarding_auth_pool.workload_identity_pool_id - workload_identity_pool_provider_id = "sysdig-onboarding-${local.suffix}" + workload_identity_pool_provider_id = "sysdig-secure-onboarding-${local.suffix}" display_name = "Sysdigcloud onboarding auth" description = "AWS identity pool provider for Sysdig Secure Data Onboarding resources" disabled = false From 4abc7b2ccc3f579d9332b1681b4ad632efd0ffc9 Mon Sep 17 00:00:00 2001 From: Haresh Suresh Date: Thu, 5 Sep 2024 14:30:24 -0700 Subject: [PATCH 12/34] fix role naming & version metadata --- modules/config-posture/main.tf | 25 +++++++++++-------------- modules/onboarding/main.tf | 23 +++++++++++------------ modules/onboarding/outputs.tf | 22 +--------------------- 3 files changed, 23 insertions(+), 47 deletions(-) diff --git a/modules/config-posture/main.tf b/modules/config-posture/main.tf index a14dc39..bbb8e80 100644 --- a/modules/config-posture/main.tf +++ b/modules/config-posture/main.tf @@ -21,7 +21,8 @@ locals { } resource "google_service_account" "posture_auth" { - account_id = "sysdig-secure-posture-${local.suffix}" + # service account name cannot be longer than 30 characters + account_id = "sysdig-posture-${local.suffix}" display_name = "Sysdig Config Posture Auth Service Account" project = var.project_id } @@ -48,7 +49,7 @@ resource "google_iam_workload_identity_pool" "posture_auth_pool" { resource "google_iam_workload_identity_pool_provider" "posture_auth_pool_provider" { project = var.project_id workload_identity_pool_id = google_iam_workload_identity_pool.posture_auth_pool.workload_identity_pool_id - workload_identity_pool_provider_id = "sysdig-secure-posture-${local.suffix}" + workload_identity_pool_provider_id = "sysdig-posture-${local.suffix}" display_name = "Sysdigcloud config posture auth" description = "AWS identity pool provider for Sysdig Secure Data Config Posture resources" disabled = false @@ -77,7 +78,7 @@ resource "google_project_iam_member" "cspm" { } # attaching WIF as a member to the service account for auth -resource "google_service_account_iam_member" "custom_auth" { +resource "google_service_account_iam_member" "custom_posture_auth" { service_account_id = google_service_account.posture_auth.name role = "roles/iam.workloadIdentityUser" member = "principalSet://iam.googleapis.com/projects/${data.google_project.project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.posture_auth_pool.workload_identity_pool_id}/attribute.aws_role/arn:aws:sts::${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id}:assumed-role/${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_role_name}/${var.external_id}" @@ -85,25 +86,21 @@ resource "google_service_account_iam_member" "custom_auth" { #-------------------------------------------------------------------------------------------------------------- # Call Sysdig Backend to add the service-principal integration for Config Posture to the Sysdig Cloud Account -# -# Note (optional): To ensure this gets called after all cloud resources are created, add -# explicit dependency using depends_on #-------------------------------------------------------------------------------------------------------------- resource "sysdig_secure_cloud_auth_account_component" "google_service_principal" { account_id = var.sysdig_secure_account_id type = "COMPONENT_SERVICE_PRINCIPAL" instance = "secure-posture" - verion = "v0.1.0" + version = "v0.1.0" service_principal_metadata = jsonencode({ gcp = { - service_principal = { - workload_identity_federation = { - pool_id = google_iam_workload_identity_pool.posture_auth_pool.workload_identity_pool_id - pool_provider_id = google_iam_workload_identity_pool_provider.posture_auth_pool_provider.workload_identity_pool_provider_id - project_number = data.google_project.project.number - } - email = google_service_account.posture_auth.email + workload_identity_federation = { + pool_id = google_iam_workload_identity_pool.posture_auth_pool.workload_identity_pool_id + pool_provider_id = google_iam_workload_identity_pool_provider.posture_auth_pool_provider.workload_identity_pool_provider_id + project_number = data.google_project.project.number } + email = google_service_account.posture_auth.email } }) + depends_on = [google_service_account_iam_member.custom_posture_auth] } diff --git a/modules/onboarding/main.tf b/modules/onboarding/main.tf index f14db18..0cc8518 100644 --- a/modules/onboarding/main.tf +++ b/modules/onboarding/main.tf @@ -21,7 +21,8 @@ locals { } resource "google_service_account" "onboarding_auth" { - account_id = "sysdig-secure-onboarding-${local.suffix}" + # service account name cannot be longer than 30 characters + account_id = "sysdig-onboarding-${local.suffix}" display_name = "Sysdig Onboarding Auth Service Account" project = var.project_id } @@ -42,13 +43,13 @@ resource "google_service_account_iam_binding" "onboarding_auth_binding" { resource "google_iam_workload_identity_pool" "onboarding_auth_pool" { project = var.project_id - workload_identity_pool_id = "sysdig-secure-onboarding-${local.suffix}" + workload_identity_pool_id = "sysdig-onboarding-${local.suffix}" } resource "google_iam_workload_identity_pool_provider" "onboarding_auth_pool_provider" { project = var.project_id workload_identity_pool_id = google_iam_workload_identity_pool.onboarding_auth_pool.workload_identity_pool_id - workload_identity_pool_provider_id = "sysdig-secure-onboarding-${local.suffix}" + workload_identity_pool_provider_id = "sysdig-onboarding-${local.suffix}" display_name = "Sysdigcloud onboarding auth" description = "AWS identity pool provider for Sysdig Secure Data Onboarding resources" disabled = false @@ -77,7 +78,7 @@ resource "google_project_iam_member" "browser" { } # attaching WIF as a member to the service account for auth -resource "google_service_account_iam_member" "custom_auth" { +resource "google_service_account_iam_member" "custom_onboarding_auth" { service_account_id = google_service_account.onboarding_auth.name role = "roles/iam.workloadIdentityUser" member = "principalSet://iam.googleapis.com/projects/${data.google_project.project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.onboarding_auth_pool.workload_identity_pool_id}/attribute.aws_role/arn:aws:sts::${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id}:assumed-role/${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_role_name}/${var.external_id}" @@ -101,19 +102,17 @@ resource "sysdig_secure_cloud_auth_account" "google_account" { version = "v0.1.0" service_principal_metadata = jsonencode({ gcp = { - service_principal = { - workload_identity_federation = { - pool_id = google_iam_workload_identity_pool.onboarding_auth_pool.workload_identity_pool_id - pool_provider_id = google_iam_workload_identity_pool_provider.onboarding_auth_pool_provider.workload_identity_pool_provider_id - project_number = data.google_project.project.number - } - email = google_service_account.onboarding_auth.email + workload_identity_federation = { + pool_id = google_iam_workload_identity_pool.onboarding_auth_pool.workload_identity_pool_id + pool_provider_id = google_iam_workload_identity_pool_provider.onboarding_auth_pool_provider.workload_identity_pool_provider_id + project_number = data.google_project.project.number } + email = google_service_account.onboarding_auth.email } }) } - depends_on = [google_service_account_iam_member.custom_auth] + depends_on = [google_service_account_iam_member.custom_onboarding_auth] lifecycle { ignore_changes = [ diff --git a/modules/onboarding/outputs.tf b/modules/onboarding/outputs.tf index 75ec94c..6edda10 100644 --- a/modules/onboarding/outputs.tf +++ b/modules/onboarding/outputs.tf @@ -1,29 +1,9 @@ -output "workload_identity_pool_id" { - value = google_iam_workload_identity_pool.onboarding_auth_pool.workload_identity_pool_id - description = "Id of Workload Identity Pool for authenticating to GCP to access data onboarding resources" -} - -output "workload_identity_pool_provider_id" { - value = google_iam_workload_identity_pool_provider.onboarding_auth_pool_provider.workload_identity_pool_provider_id - description = "Id of Workload Identity Pool Provider for authenticating to GCP to access data onboarding resources" -} - -output "workload_identity_project_number" { - value = data.google_project.project.number - description = "GCP project number" -} - -output "service_account_email" { - value = google_service_account.onboarding_auth.email - description = "email of the Service Account created" -} - output "project_id" { value = var.project_id description = "Project ID in which secure-for-cloud onboarding resources are created. For organizational installs it is the Management Project ID selected during install" } -output "sysdig_secure_project_id" { +output "sysdig_secure_account_id" { value = sysdig_secure_cloud_auth_account.google_account.id description = "ID of the Sysdig Cloud Account created" } From b4d8e07e37886b6be97381eaa00d8311722e975a Mon Sep 17 00:00:00 2001 From: Haresh Suresh Date: Thu, 5 Sep 2024 15:08:44 -0700 Subject: [PATCH 13/34] updating examples for onboarding & cspm org --- modules/onboarding/organizational.tf | 2 +- modules/onboarding/outputs.tf | 5 ++++ .../onboarding_with_posture.tf | 26 ++++++++++++++++--- .../onboarding_with_posture.tf | 15 +++++++++++ 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/modules/onboarding/organizational.tf b/modules/onboarding/organizational.tf index 4ff434a..09554ea 100644 --- a/modules/onboarding/organizational.tf +++ b/modules/onboarding/organizational.tf @@ -26,7 +26,7 @@ resource "google_organization_iam_member" "browser" { # Call Sysdig Backend to create organization with foundational onboarding # (ensure it is called after all above cloud resources are created) #--------------------------------------------------------------------------------------------- -resource "sysdig_secure_organization" "azure_organization" { +resource "sysdig_secure_organization" "google_organization" { count = var.is_organizational ? 1 : 0 management_account_id = sysdig_secure_cloud_auth_account.google_account.id diff --git a/modules/onboarding/outputs.tf b/modules/onboarding/outputs.tf index 6edda10..7db7f22 100644 --- a/modules/onboarding/outputs.tf +++ b/modules/onboarding/outputs.tf @@ -12,3 +12,8 @@ output "is_organizational" { value = var.is_organizational description = "Boolean value to indicate if secure-for-cloud is deployed to an entire GCP organization or not" } + +output "organization_domain" { + value = var.organization_domain + description = "Organization domain. e.g. sysdig.com" +} diff --git a/test/examples/modular_organization/onboarding_with_posture.tf b/test/examples/modular_organization/onboarding_with_posture.tf index 63b1c09..ca933bd 100644 --- a/test/examples/modular_organization/onboarding_with_posture.tf +++ b/test/examples/modular_organization/onboarding_with_posture.tf @@ -18,8 +18,26 @@ provider "sysdig" { } module "onboarding" { - source = "../../../modules/onboarding" - project_id = "org-child-project-3" - external_id = "25ef0d887bc7a2b30089a025618e1c62" - is_organizational = true + source = "../../../modules/onboarding" + project_id = "org-child-project-3" + external_id = "25ef0d887bc7a2b30089a025618e1c62" + is_organizational = true + organization_domain = "draios.com" +} + +module "config-posture" { + source = "../../../modules/config-posture" + project_id = module.onboarding.project_id + external_id = "25ef0d887bc7a2b30089a025618e1c62" + is_organizational = module.onboarding.is_organizational + organization_domain = module.onboarding.organization_domain + sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id +} + +resource "sysdig_secure_cloud_auth_account_feature" "config_posture" { + account_id = module.onboarding.sysdig_secure_account_id + type = "FEATURE_SECURE_CONFIG_POSTURE" + enabled = true + components = [module.config-posture.service_principal_component_id] + depends_on = [module.config-posture] } \ No newline at end of file diff --git a/test/examples/modular_single_project/onboarding_with_posture.tf b/test/examples/modular_single_project/onboarding_with_posture.tf index 6372874..c2db178 100644 --- a/test/examples/modular_single_project/onboarding_with_posture.tf +++ b/test/examples/modular_single_project/onboarding_with_posture.tf @@ -21,4 +21,19 @@ module "onboarding" { source = "../../../modules/onboarding" project_id = "org-child-project-3" external_id = "25ef0d887bc7a2b30089a025618e1c62" +} + +module "config-posture" { + source = "../../../modules/config-posture" + project_id = "org-child-project-3" + external_id = "25ef0d887bc7a2b30089a025618e1c62" + sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id +} + +resource "sysdig_secure_cloud_auth_account_feature" "config_posture" { + account_id = module.onboarding.sysdig_secure_account_id + type = "FEATURE_SECURE_CONFIG_POSTURE" + enabled = true + components = [module.config-posture.service_principal_component_id] + depends_on = [module.config-posture] } \ No newline at end of file From e9a212d6409a516350cade895c1ae3a69b619188 Mon Sep 17 00:00:00 2001 From: Haresh Suresh Date: Thu, 5 Sep 2024 15:24:07 -0700 Subject: [PATCH 14/34] cleanup foundational READMEs --- modules/config-posture/README.md | 29 ++++++++++++----------------- modules/onboarding/README.md | 15 ++++++--------- 2 files changed, 18 insertions(+), 26 deletions(-) diff --git a/modules/config-posture/README.md b/modules/config-posture/README.md index 9557b9a..42ba8d6 100644 --- a/modules/config-posture/README.md +++ b/modules/config-posture/README.md @@ -56,26 +56,21 @@ No modules. ## Inputs -| Name | Description | Type | Default | Required | -|------|---------------------------------------------------------------------------------------------------------------------------|------|-----------------------------------------------|:--------:| -| [is\_organizational](#input\_is\_organizational) | (Optional) Set this field to 'true' to deploy secure-for-cloud to a GCP Organization. | `bool` | `false` | no | -| [labels](#input\_labels) | (Optional) Labels to be associated with Sysdig-originated resources | `map(string)` |
{
"originator": "sysdig"
}
| no | -| [organization\_domain](#input\_organization\_domain) | Organization domain. e.g. sysdig.com | `string` | `""` | no | -| [project\_id](#input\_project\_id) | (Required) Target Project identifier provided by the customer | `string` | n/a | yes | -| [role\_name](#input\_role\_name) | (Optional) Role name for custom role binding to the service account, with read permissions for posture resources | `string` | `"SysdigPostureAuthRole-{random_id}"` | no | -| [external\_id](#input\_external\_id) | (Required) Random string generated unique to a customer | `string` | n/a | yes | -| [suffix](#input\_suffix) | (Optional) Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated | `string` | `null` | no | +| Name | Description | Type | Default | Required | +|------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|------|-----------------------------------------------|:--------:| +| [is\_organizational](#input\_is\_organizational) | (Optional) Set this field to 'true' to deploy secure-for-cloud to a GCP Organization. | `bool` | `false` | no | +| [organization\_domain](#input\_organization\_domain) | Organization domain. e.g. sysdig.com | `string` | `""` | no | +| [project\_id](#input\_project\_id) | (Required) Target Project identifier provided by the customer | `string` | n/a | yes | +| [external\_id](#input\_external\_id) | (Required) Random string generated unique to a customer | `string` | n/a | yes | +| [suffix](#input\_suffix) | (Optional) Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated | `string` | `null` | no | +| [sysdig\_secure\_account\_id](#input\_sysdig\_secure\_account\_id) | (Required) The GUID of the management project or single project per sysdig representation | `string` | n/a | yes | +| [management\_group\_ids](#input\_management\_group\_ids) | (Optional) Management group ids to onboard sub ogs or folders like 'organizations/sysdig.com' or 'folders/test-1' | `string` | n/a | yes | ## Outputs -| Name | Description | -|------|----------------------------------------------------------------------------------------------------| -| [workload\_identity\_pool\_id](#output\_workload\_identity\_pool\_id) | Id of Workload Identity Pool for authenticating to GCP to access config posture resources | -| [workload\_identity\_pool\_provider\_id](#output\_workload\_identity\_pool\_provider\_id) | Id of Workload Identity Pool Provider for authenticating to GCP to access config posture resources | -| [workload\_identity\_project\_number](#output\_workload\_identity\_project\_number) | GCP project number | -| [service\_account\_email](#output\_service\_account\_email) | email of the Service Account created | -| [sysdig\_secure\_project\_id](#output\_sysdig\_secure\_project\_id) | ID of the Sysdig Cloud Account created | -| [is\_organizational](#output\_is\_organizational) | Boolean value to indicate if secure-for-cloud is deployed to an entire GCP organization or not | +| Name | Description | +|--------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------| +| [service\_principal\_component\_id](#output\_service\_principal\_component\_id) | The component id of the config posture service principal with its WIF metadata | ## Authors diff --git a/modules/onboarding/README.md b/modules/onboarding/README.md index 135f4c0..de459c5 100644 --- a/modules/onboarding/README.md +++ b/modules/onboarding/README.md @@ -60,7 +60,6 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [is\_organizational](#input\_is\_organizational) | (Optional) Set this field to 'true' to deploy secure-for-cloud to a GCP Organization. | `bool` | `false` | no | -| [labels](#input\_labels) | (Optional) Labels to be associated with Sysdig-originated resources | `map(string)` |
{
"originator": "sysdig"
}
| no | | [organization\_domain](#input\_organization\_domain) | Organization domain. e.g. sysdig.com | `string` | `""` | no | | [project\_id](#input\_project\_id) | (Required) Target Project identifier provided by the customer | `string` | n/a | yes | | [external\_id](#input\_external\_id) | (Required) Random string generated unique to a customer | `string` | n/a | yes | @@ -68,14 +67,12 @@ No modules. ## Outputs -| Name | Description | -|------|------------------------------------------------------------------------------------------------| -| [workload\_identity\_pool\_id](#output\_workload\_identity\_pool\_id) | Id of Workload Identity Pool for authenticating to GCP to access onboarding resources | -| [workload\_identity\_pool\_provider\_id](#output\_workload\_identity\_pool\_provider\_id) | Id of Workload Identity Pool Provider for authenticating to GCP to access onboarding resources | -| [workload\_identity\_project\_number](#output\_workload\_identity\_project\_number) | GCP project number | -| [service\_account\_email](#output\_service\_account\_email) | email of the Service Account created | -| [sysdig\_secure\_project\_id](#output\_sysdig\_secure\_project\_id) | ID of the Sysdig Cloud Account created | -| [is\_organizational](#output\_is\_organizational) | Boolean value to indicate if secure-for-cloud is deployed to an entire GCP organization or not | +| Name | Description | +|--------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------| +| [sysdig\_secure\_project\_id](#output\_sysdig\_secure\_account\_id) | ID of the Sysdig Cloud Account created | +| [is\_organizational](#output\_is\_organizational) | Boolean value to indicate if secure-for-cloud is deployed to an entire GCP organization or not | +| [organization\_domain](#output\_organization\_domain) | Organization domain of the GCP org being onboarded | +| [project\_id](#output\_project\_id) | The management project id chosen during install, where global resources are deployed | ## Authors From 2885cccf7c0c971ad8920ad612ad4d009910456f Mon Sep 17 00:00:00 2001 From: Haresh Suresh Date: Fri, 6 Sep 2024 10:01:12 -0700 Subject: [PATCH 15/34] use external_id datasource --- modules/config-posture/main.tf | 6 ++++-- modules/onboarding/main.tf | 6 ++++-- .../modular_organization/onboarding_with_posture.tf | 2 -- .../modular_single_project/onboarding_with_posture.tf | 2 -- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/config-posture/main.tf b/modules/config-posture/main.tf index bbb8e80..6b27a79 100644 --- a/modules/config-posture/main.tf +++ b/modules/config-posture/main.tf @@ -6,6 +6,8 @@ data "sysdig_secure_trusted_cloud_identity" "trusted_identity" { cloud_provider = "gcp" } +data "sysdig_secure_tenant_external_id" "external_id" {} + data "google_project" "project" { project_id = var.project_id } @@ -54,7 +56,7 @@ resource "google_iam_workload_identity_pool_provider" "posture_auth_pool_provide description = "AWS identity pool provider for Sysdig Secure Data Config Posture resources" disabled = false - attribute_condition = "attribute.aws_role==\"arn:aws:sts::${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id}:assumed-role/${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_role_name}/${var.external_id}\"" + attribute_condition = "attribute.aws_role==\"arn:aws:sts::${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id}:assumed-role/${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_role_name}/${data.sysdig_secure_tenant_external_id.external_id.external_id}\"" attribute_mapping = { "google.subject" = "assertion.arn", @@ -81,7 +83,7 @@ resource "google_project_iam_member" "cspm" { resource "google_service_account_iam_member" "custom_posture_auth" { service_account_id = google_service_account.posture_auth.name role = "roles/iam.workloadIdentityUser" - member = "principalSet://iam.googleapis.com/projects/${data.google_project.project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.posture_auth_pool.workload_identity_pool_id}/attribute.aws_role/arn:aws:sts::${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id}:assumed-role/${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_role_name}/${var.external_id}" + member = "principalSet://iam.googleapis.com/projects/${data.google_project.project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.posture_auth_pool.workload_identity_pool_id}/attribute.aws_role/arn:aws:sts::${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id}:assumed-role/${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_role_name}/${data.sysdig_secure_tenant_external_id.external_id.external_id}" } #-------------------------------------------------------------------------------------------------------------- diff --git a/modules/onboarding/main.tf b/modules/onboarding/main.tf index 0cc8518..5ed3c49 100644 --- a/modules/onboarding/main.tf +++ b/modules/onboarding/main.tf @@ -6,6 +6,8 @@ data "sysdig_secure_trusted_cloud_identity" "trusted_identity" { cloud_provider = "gcp" } +data "sysdig_secure_tenant_external_id" "external_id" {} + data "google_project" "project" { project_id = var.project_id } @@ -54,7 +56,7 @@ resource "google_iam_workload_identity_pool_provider" "onboarding_auth_pool_prov description = "AWS identity pool provider for Sysdig Secure Data Onboarding resources" disabled = false - attribute_condition = "attribute.aws_role==\"arn:aws:sts::${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id}:assumed-role/${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_role_name}/${var.external_id}\"" + attribute_condition = "attribute.aws_role==\"arn:aws:sts::${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id}:assumed-role/${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_role_name}/${data.sysdig_secure_tenant_external_id.external_id.external_id}\"" attribute_mapping = { "google.subject" = "assertion.arn", @@ -81,7 +83,7 @@ resource "google_project_iam_member" "browser" { resource "google_service_account_iam_member" "custom_onboarding_auth" { service_account_id = google_service_account.onboarding_auth.name role = "roles/iam.workloadIdentityUser" - member = "principalSet://iam.googleapis.com/projects/${data.google_project.project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.onboarding_auth_pool.workload_identity_pool_id}/attribute.aws_role/arn:aws:sts::${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id}:assumed-role/${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_role_name}/${var.external_id}" + member = "principalSet://iam.googleapis.com/projects/${data.google_project.project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.onboarding_auth_pool.workload_identity_pool_id}/attribute.aws_role/arn:aws:sts::${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id}:assumed-role/${data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_role_name}/${data.sysdig_secure_tenant_external_id.external_id.external_id}" } #--------------------------------------------------------------------------------------------- diff --git a/test/examples/modular_organization/onboarding_with_posture.tf b/test/examples/modular_organization/onboarding_with_posture.tf index ca933bd..29c2e38 100644 --- a/test/examples/modular_organization/onboarding_with_posture.tf +++ b/test/examples/modular_organization/onboarding_with_posture.tf @@ -20,7 +20,6 @@ provider "sysdig" { module "onboarding" { source = "../../../modules/onboarding" project_id = "org-child-project-3" - external_id = "25ef0d887bc7a2b30089a025618e1c62" is_organizational = true organization_domain = "draios.com" } @@ -28,7 +27,6 @@ module "onboarding" { module "config-posture" { source = "../../../modules/config-posture" project_id = module.onboarding.project_id - external_id = "25ef0d887bc7a2b30089a025618e1c62" is_organizational = module.onboarding.is_organizational organization_domain = module.onboarding.organization_domain sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id diff --git a/test/examples/modular_single_project/onboarding_with_posture.tf b/test/examples/modular_single_project/onboarding_with_posture.tf index c2db178..7325f9d 100644 --- a/test/examples/modular_single_project/onboarding_with_posture.tf +++ b/test/examples/modular_single_project/onboarding_with_posture.tf @@ -20,13 +20,11 @@ provider "sysdig" { module "onboarding" { source = "../../../modules/onboarding" project_id = "org-child-project-3" - external_id = "25ef0d887bc7a2b30089a025618e1c62" } module "config-posture" { source = "../../../modules/config-posture" project_id = "org-child-project-3" - external_id = "25ef0d887bc7a2b30089a025618e1c62" sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id } From 628a2d63f575c98cfff6e772a6f707a432574000 Mon Sep 17 00:00:00 2001 From: Haresh Suresh Date: Fri, 6 Sep 2024 10:06:19 -0700 Subject: [PATCH 16/34] update README --- modules/config-posture/README.md | 13 ++++++------- modules/config-posture/variables.tf | 5 ----- modules/onboarding/README.md | 1 - modules/onboarding/variables.tf | 5 ----- 4 files changed, 6 insertions(+), 18 deletions(-) diff --git a/modules/config-posture/README.md b/modules/config-posture/README.md index 42ba8d6..7e6c42b 100644 --- a/modules/config-posture/README.md +++ b/modules/config-posture/README.md @@ -58,13 +58,12 @@ No modules. | Name | Description | Type | Default | Required | |------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|------|-----------------------------------------------|:--------:| -| [is\_organizational](#input\_is\_organizational) | (Optional) Set this field to 'true' to deploy secure-for-cloud to a GCP Organization. | `bool` | `false` | no | -| [organization\_domain](#input\_organization\_domain) | Organization domain. e.g. sysdig.com | `string` | `""` | no | -| [project\_id](#input\_project\_id) | (Required) Target Project identifier provided by the customer | `string` | n/a | yes | -| [external\_id](#input\_external\_id) | (Required) Random string generated unique to a customer | `string` | n/a | yes | -| [suffix](#input\_suffix) | (Optional) Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated | `string` | `null` | no | -| [sysdig\_secure\_account\_id](#input\_sysdig\_secure\_account\_id) | (Required) The GUID of the management project or single project per sysdig representation | `string` | n/a | yes | -| [management\_group\_ids](#input\_management\_group\_ids) | (Optional) Management group ids to onboard sub ogs or folders like 'organizations/sysdig.com' or 'folders/test-1' | `string` | n/a | yes | +| [is\_organizational](#input\_is\_organizational) | (Optional) Set this field to 'true' to deploy secure-for-cloud to a GCP Organization. | `bool` | `false` | no | +| [organization\_domain](#input\_organization\_domain) | Organization domain. e.g. sysdig.com | `string` | `""` | no | +| [project\_id](#input\_project\_id) | (Required) Target Project identifier provided by the customer | `string` | n/a | yes | +| [suffix](#input\_suffix) | (Optional) Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated | `string` | `null` | no | +| [sysdig\_secure\_account\_id](#input\_sysdig\_secure\_account\_id) | (Required) The GUID of the management project or single project per sysdig representation | `string` | n/a | yes | +| [management\_group\_ids](#input\_management\_group\_ids) | (Optional) Management group ids to onboard sub ogs or folders like 'organizations/sysdig.com' or 'folders/test-1' | `string` | n/a | no | ## Outputs diff --git a/modules/config-posture/variables.tf b/modules/config-posture/variables.tf index b1d3d9e..c6630bd 100644 --- a/modules/config-posture/variables.tf +++ b/modules/config-posture/variables.tf @@ -21,11 +21,6 @@ variable "management_group_ids" { default = [] } -variable "external_id" { - type = string - description = "(Required) Random string generated unique to a customer" -} - variable "suffix" { type = string description = "Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated" diff --git a/modules/onboarding/README.md b/modules/onboarding/README.md index de459c5..1fbd585 100644 --- a/modules/onboarding/README.md +++ b/modules/onboarding/README.md @@ -62,7 +62,6 @@ No modules. | [is\_organizational](#input\_is\_organizational) | (Optional) Set this field to 'true' to deploy secure-for-cloud to a GCP Organization. | `bool` | `false` | no | | [organization\_domain](#input\_organization\_domain) | Organization domain. e.g. sysdig.com | `string` | `""` | no | | [project\_id](#input\_project\_id) | (Required) Target Project identifier provided by the customer | `string` | n/a | yes | -| [external\_id](#input\_external\_id) | (Required) Random string generated unique to a customer | `string` | n/a | yes | | [suffix](#input\_suffix) | (Optional) Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated | `string` | `null` | no | ## Outputs diff --git a/modules/onboarding/variables.tf b/modules/onboarding/variables.tf index 7564fc6..9571e7e 100644 --- a/modules/onboarding/variables.tf +++ b/modules/onboarding/variables.tf @@ -21,11 +21,6 @@ variable "management_group_ids" { default = [] } -variable "external_id" { - type = string - description = "(Required) Random string generated unique to a customer" -} - variable "suffix" { type = string description = "Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated" From 211a8deeb48f234df51383a6849ce3d09f23443d Mon Sep 17 00:00:00 2001 From: Haresh Suresh Date: Fri, 6 Sep 2024 10:40:38 -0700 Subject: [PATCH 17/34] remove mgmt_group_ids in cspm module --- modules/config-posture/variables.tf | 6 ------ 1 file changed, 6 deletions(-) diff --git a/modules/config-posture/variables.tf b/modules/config-posture/variables.tf index c6630bd..b975bc2 100644 --- a/modules/config-posture/variables.tf +++ b/modules/config-posture/variables.tf @@ -15,12 +15,6 @@ variable "organization_domain" { default = "" } -variable "management_group_ids" { - type = set(string) - description = "(Optional) Management group id to onboard. e.g. [organizations/123456789012], [folders/123456789012]" - default = [] -} - variable "suffix" { type = string description = "Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated" From ec938f075e84051574f839ab4aa4e7d39268c946 Mon Sep 17 00:00:00 2001 From: Haresh Suresh Date: Mon, 9 Sep 2024 20:47:46 -0700 Subject: [PATCH 18/34] bump sysdig provider version to be consistent & have latest datasources --- modules/config-posture/versions.tf | 2 +- modules/onboarding/versions.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/config-posture/versions.tf b/modules/config-posture/versions.tf index 7f82c5f..adb6e1a 100644 --- a/modules/config-posture/versions.tf +++ b/modules/config-posture/versions.tf @@ -8,7 +8,7 @@ terraform { } sysdig = { source = "sysdiglabs/sysdig" - version = ">= 1.29.2" + version = ">= 1.34.0" } random = { source = "hashicorp/random" diff --git a/modules/onboarding/versions.tf b/modules/onboarding/versions.tf index 7f82c5f..adb6e1a 100644 --- a/modules/onboarding/versions.tf +++ b/modules/onboarding/versions.tf @@ -8,7 +8,7 @@ terraform { } sysdig = { source = "sysdiglabs/sysdig" - version = ">= 1.29.2" + version = ">= 1.34.0" } random = { source = "hashicorp/random" From b37fe73cb4a32f4e3e752bfe3d22f79b1b60962c Mon Sep 17 00:00:00 2001 From: Haresh Suresh Date: Mon, 9 Sep 2024 20:49:56 -0700 Subject: [PATCH 19/34] updating examples --- test/examples/modular_organization/onboarding_with_posture.tf | 2 +- test/examples/modular_single_project/onboarding_with_posture.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/examples/modular_organization/onboarding_with_posture.tf b/test/examples/modular_organization/onboarding_with_posture.tf index 29c2e38..c902e5e 100644 --- a/test/examples/modular_organization/onboarding_with_posture.tf +++ b/test/examples/modular_organization/onboarding_with_posture.tf @@ -7,7 +7,7 @@ terraform { required_providers { sysdig = { source = "sysdiglabs/sysdig" - version = "~> 1.29.2" + version = "~> 1.34.0" } } } diff --git a/test/examples/modular_single_project/onboarding_with_posture.tf b/test/examples/modular_single_project/onboarding_with_posture.tf index 7325f9d..7222a68 100644 --- a/test/examples/modular_single_project/onboarding_with_posture.tf +++ b/test/examples/modular_single_project/onboarding_with_posture.tf @@ -7,7 +7,7 @@ terraform { required_providers { sysdig = { source = "sysdiglabs/sysdig" - version = "~> 1.29.2" + version = "~> 1.34.0" } } } From 99b4062677ae9d44549ae828a6084742d3638ec0 Mon Sep 17 00:00:00 2001 From: Haresh Suresh Date: Tue, 10 Sep 2024 13:42:10 -0700 Subject: [PATCH 20/34] update example --- test/examples/modular_single_project/onboarding_with_posture.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/examples/modular_single_project/onboarding_with_posture.tf b/test/examples/modular_single_project/onboarding_with_posture.tf index 7222a68..01c0705 100644 --- a/test/examples/modular_single_project/onboarding_with_posture.tf +++ b/test/examples/modular_single_project/onboarding_with_posture.tf @@ -24,7 +24,7 @@ module "onboarding" { module "config-posture" { source = "../../../modules/config-posture" - project_id = "org-child-project-3" + project_id = module.onboarding.project_id sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id } From af3f570db834d51b2e532b4562c2b5e1be764bdb Mon Sep 17 00:00:00 2001 From: Jose Pablo Camacho Date: Tue, 10 Sep 2024 17:51:12 -0600 Subject: [PATCH 21/34] feat(modular): address feedback for modular support for cdr/ciem, rebase and cleanup --- .../integrations/webhook-datasource/main.tf | 2 +- .../webhook-datasource/organizational.tf | 2 +- .../webhook_datasource.tf | 28 ++++++ .../onboarding_with_posture.tf | 6 +- .../webhook_datasource.tf | 26 ++++++ .../webhook_datasource.tf | 93 +------------------ .../webhook_datasource.tf | 71 +------------- 7 files changed, 62 insertions(+), 166 deletions(-) create mode 100644 test/examples/modular_organization/webhook_datasource.tf create mode 100644 test/examples/modular_single_project/webhook_datasource.tf diff --git a/modules/integrations/webhook-datasource/main.tf b/modules/integrations/webhook-datasource/main.tf index 46cd3f7..3ba941f 100644 --- a/modules/integrations/webhook-datasource/main.tf +++ b/modules/integrations/webhook-datasource/main.tf @@ -201,7 +201,7 @@ resource "google_project_iam_custom_role" "custom_ingestion_auth_role" { count = var.is_organizational ? 0 : 1 project = var.project_id - role_id = "${var.role_name}-${local.suffix}" + role_id = "${var.role_name}${local.suffix}" title = "Sysdigcloud Ingestion Auth Role" description = "A Role providing the required permissions for Sysdig Backend to read cloud resources created for data ingestion" permissions = [ diff --git a/modules/integrations/webhook-datasource/organizational.tf b/modules/integrations/webhook-datasource/organizational.tf index 098014c..664c285 100644 --- a/modules/integrations/webhook-datasource/organizational.tf +++ b/modules/integrations/webhook-datasource/organizational.tf @@ -63,7 +63,7 @@ resource "google_organization_iam_custom_role" "custom_ingestion_auth_role" { count = var.is_organizational ? 1 : 0 org_id = data.google_organization.org[0].org_id - role_id = "${var.role_name}-org-${local.suffix}" + role_id = "${var.role_name}Org${local.suffix}" title = "Sysdigcloud Ingestion Auth Role" description = "A Role providing the required permissions for Sysdig Backend to read cloud resources created for data ingestion" permissions = [ diff --git a/test/examples/modular_organization/webhook_datasource.tf b/test/examples/modular_organization/webhook_datasource.tf new file mode 100644 index 0000000..6b45215 --- /dev/null +++ b/test/examples/modular_organization/webhook_datasource.tf @@ -0,0 +1,28 @@ +#--------------------------------------------------------------------------------------------- +# Ensure installation flow for foundational onboarding has been completed before +# installing additional Sysdig features. +#--------------------------------------------------------------------------------------------- + +module "webhook-datasource" { + source = "../../../modules/integrations/webhook-datasource" + project_id = module.onboarding.project_id + is_organizational = module.onboarding.is_organizational + organization_domain = module.onboarding.organization_domain + sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id +} + +resource "sysdig_secure_cloud_auth_account_feature" "threat_detection" { + account_id = module.onboarding.sysdig_secure_account_id + type = "FEATURE_SECURE_THREAT_DETECTION" + enabled = true + components = [ module.webhook-datasource.webhook_datasource_component_id ] + depends_on = [ module.webhook-datasource ] +} + +resource "sysdig_secure_cloud_auth_account_feature" "identity_entitlement" { + account_id = module.onboarding.sysdig_secure_account_id + type = "FEATURE_SECURE_IDENTITY_ENTITLEMENT" + enabled = true + components = [module.webhook-datasource.webhook_datasource_component_id] + depends_on = [sysdig_secure_cloud_auth_account_feature.config_posture, sysdig_secure_cloud_auth_account_feature.threat_detection] +} \ No newline at end of file diff --git a/test/examples/modular_single_project/onboarding_with_posture.tf b/test/examples/modular_single_project/onboarding_with_posture.tf index 01c0705..53eda45 100644 --- a/test/examples/modular_single_project/onboarding_with_posture.tf +++ b/test/examples/modular_single_project/onboarding_with_posture.tf @@ -1,5 +1,5 @@ provider "google" { - project = "org-child-project-3" + project = "org-child-project-1" region = "us-west1" } @@ -14,12 +14,12 @@ terraform { provider "sysdig" { sysdig_secure_url = "https://secure-staging.sysdig.com" - sysdig_secure_api_token = "API_TOKEN" + sysdig_secure_api_token = "3aec5684-d355-4dd0-8e0e-4b87af8537f3" } module "onboarding" { source = "../../../modules/onboarding" - project_id = "org-child-project-3" + project_id = "org-child-project-1" } module "config-posture" { diff --git a/test/examples/modular_single_project/webhook_datasource.tf b/test/examples/modular_single_project/webhook_datasource.tf new file mode 100644 index 0000000..9effcf5 --- /dev/null +++ b/test/examples/modular_single_project/webhook_datasource.tf @@ -0,0 +1,26 @@ +#--------------------------------------------------------------------------------------------- +# Ensure installation flow for foundational onboarding has been completed before +# installing additional Sysdig features. +#--------------------------------------------------------------------------------------------- + +module "webhook-datasource" { + source = "../../../modules/integrations/webhook-datasource" + project_id = module.onboarding.project_id + sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id +} + +resource "sysdig_secure_cloud_auth_account_feature" "threat_detection" { + account_id = module.onboarding.sysdig_secure_account_id + type = "FEATURE_SECURE_THREAT_DETECTION" + enabled = true + components = [ module.webhook-datasource.webhook_datasource_component_id ] + depends_on = [ module.webhook-datasource ] +} + +resource "sysdig_secure_cloud_auth_account_feature" "identity_entitlement" { + account_id = module.onboarding.sysdig_secure_account_id + type = "FEATURE_SECURE_IDENTITY_ENTITLEMENT" + enabled = true + components = [module.webhook-datasource.webhook_datasource_component_id] + depends_on = [sysdig_secure_cloud_auth_account_feature.config_posture, sysdig_secure_cloud_auth_account_feature.threat_detection] +} \ No newline at end of file diff --git a/test/examples/organization_cdr_test/webhook_datasource.tf b/test/examples/organization_cdr_test/webhook_datasource.tf index 62c54ad..6b45215 100644 --- a/test/examples/organization_cdr_test/webhook_datasource.tf +++ b/test/examples/organization_cdr_test/webhook_datasource.tf @@ -3,48 +3,14 @@ # installing additional Sysdig features. #--------------------------------------------------------------------------------------------- -# UNCOMMENT TO TEST: FROM HERE: THIS WILL BE PART OF THE ONBOARD MODULE -# terraform { -# required_providers { -# sysdig = { -# source = "sysdiglabs/sysdig" -# version = "~> 1.34.0" -# } -# } -# } -# -# provider "sysdig" { -# sysdig_secure_url = "https://secure-staging.sysdig.com" -# sysdig_secure_api_token = -# } -# -# provider "google" { -# project = "org-child-project-1" -# region = "us-west1" -# } -# TO HERE - module "webhook-datasource" { source = "../../../modules/integrations/webhook-datasource" project_id = module.onboarding.project_id - # push_endpoint is no longer needed - # push_endpoint = "https://app-staging.sysdigcloud.com/api/cloudingestion/gcp/v2/84f934c6-eb2d-47d9-804b-bcfe9e6ef0b9" is_organizational = module.onboarding.is_organizational organization_domain = module.onboarding.organization_domain sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id } -# UNCOMMENT TO TEST: THIS IS NOT GOING TO BE LONGER NEEDED, SINCE WILL BE PART OF FOUNDATIONAL -# module "organization-posture" { -# source = "sysdiglabs/secure/google//modules/services/service-principal" -# project_id = "org-child-project-1" -# service_account_name = "sysdig-secure-2u6g" -# is_organizational = true -# organization_domain = "draios.com" -# } -# TO HERE - -# COMMENT TO TEST: THIS WILL BE PART OF THE SNIPPET resource "sysdig_secure_cloud_auth_account_feature" "threat_detection" { account_id = module.onboarding.sysdig_secure_account_id type = "FEATURE_SECURE_THREAT_DETECTION" @@ -59,61 +25,4 @@ resource "sysdig_secure_cloud_auth_account_feature" "identity_entitlement" { enabled = true components = [module.webhook-datasource.webhook_datasource_component_id] depends_on = [sysdig_secure_cloud_auth_account_feature.config_posture, sysdig_secure_cloud_auth_account_feature.threat_detection] -} -# TO HERE - -# UNCOMMENT TO TEST: THIS IS NOT GOING TO BE LONGER NEEDED, SINCE WILL BE PART OF FOUNDATIONAL -# resource "sysdig_secure_cloud_auth_account" "gcp_project_org-child-project-1" { -# enabled = true -# provider_id = "org-child-project-1" -# provider_type = "PROVIDER_GCP" -# -# feature { -# -# secure_threat_detection { -# enabled = true -# components = ["COMPONENT_WEBHOOK_DATASOURCE/secure-runtime"] -# } -# } -# component { -# type = "COMPONENT_WEBHOOK_DATASOURCE" -# instance = "secure-runtime" -# webhook_datasource_metadata = jsonencode({ -# gcp = { -# webhook_datasource = { -# pubsub_topic_name = module.webhook-datasource.ingestion_pubsub_topic_name -# sink_name = module.webhook-datasource.ingestion_sink_name -# push_subscription_name = module.webhook-datasource.ingestion_push_subscription_name -# push_endpoint = module.webhook-datasource.push_endpoint -# routing_key = "84f934c6-eb2d-47d9-804b-bcfe9e6ef0b9" -# } -# service_principal = { -# workload_identity_federation = { -# pool_id = module.webhook-datasource.workload_identity_pool_id -# pool_provider_id = module.webhook-datasource.workload_identity_pool_provider_id -# project_number = module.webhook-datasource.workload_identity_project_number -# } -# email = module.webhook-datasource.service_account_email -# } -# } -# }) -# } -# -# component { -# type = "COMPONENT_SERVICE_PRINCIPAL" -# instance = "secure-onboarding" -# service_principal_metadata = jsonencode({ -# gcp = { -# key = module.organization-posture.service_account_key -# } -# }) -# } -# depends_on = [module.organization-posture, module.webhook-datasource] -# } -# -# resource "sysdig_secure_organization" "gcp_organization_org-child-project-1" { -# organizational_unit_ids = [] -# management_account_id = sysdig_secure_cloud_auth_account.gcp_project_org-child-project-1.id -# depends_on = [module.organization-posture, module.webhook-datasource] -# } -# TO HERE \ No newline at end of file +} \ No newline at end of file diff --git a/test/examples/single_account_cdr_test/webhook_datasource.tf b/test/examples/single_account_cdr_test/webhook_datasource.tf index babebac..9effcf5 100644 --- a/test/examples/single_account_cdr_test/webhook_datasource.tf +++ b/test/examples/single_account_cdr_test/webhook_datasource.tf @@ -3,38 +3,12 @@ # installing additional Sysdig features. #--------------------------------------------------------------------------------------------- -# UNCOMMENT TO TEST: FROM HERE: THIS WILL BE PART OF THE ONBOARD MODULE -# terraform { -# required_providers { -# sysdig = { -# source = "sysdiglabs/sysdig" -# version = "~> 1.34.0" -# } -# } -# } -# -# provider "sysdig" { -# sysdig_secure_url = "https://secure-staging.sysdig.com" -# sysdig_secure_api_token = -# } -# -# provider "google" { -# project = "org-child-project-1" -# region = "us-west1" -# } -# TO HERE - module "webhook-datasource" { source = "../../../modules/integrations/webhook-datasource" - project_id = "org-child-project-1" - # push_endpoint and external_id are no longer needed - # push_endpoint = "https://app-staging.sysdigcloud.com/api/cloudingestion/gcp/v2/1f6d4677-84ec-4356-bd73-c79c8a96f96a" - # external_id = "87e82bdu28323" - # This will come from the onboarding module: module.onboarding.sysdig_secure_account_id + project_id = module.onboarding.project_id sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id } -# COMMENT TO TEST: THIS WILL BE PART OF THE SNIPPET resource "sysdig_secure_cloud_auth_account_feature" "threat_detection" { account_id = module.onboarding.sysdig_secure_account_id type = "FEATURE_SECURE_THREAT_DETECTION" @@ -49,45 +23,4 @@ resource "sysdig_secure_cloud_auth_account_feature" "identity_entitlement" { enabled = true components = [module.webhook-datasource.webhook_datasource_component_id] depends_on = [sysdig_secure_cloud_auth_account_feature.config_posture, sysdig_secure_cloud_auth_account_feature.threat_detection] -} -# TO HERE - -# UNCOMMENT TO TEST: THIS IS NOT GOING TO BE LONGER NEEDED, SINCE WILL BE PART OF FOUNDATIONAL -# resource "sysdig_secure_cloud_auth_account" "gcp_project_org-child-project-1" { -# enabled = true -# provider_id = "org-child-project-1" -# provider_type = "PROVIDER_GCP" -# -# feature { -# -# secure_threat_detection { -# enabled = true -# components = ["COMPONENT_WEBHOOK_DATASOURCE/secure-runtime"] -# } -# } -# component { -# type = "COMPONENT_WEBHOOK_DATASOURCE" -# instance = "secure-runtime" -# webhook_datasource_metadata = jsonencode({ -# gcp = { -# webhook_datasource = { -# pubsub_topic_name = module.webhook-datasource.ingestion_pubsub_topic_name -# sink_name = module.webhook-datasource.ingestion_sink_name -# push_subscription_name = module.webhook-datasource.ingestion_push_subscription_name -# push_endpoint = module.webhook-datasource.push_endpoint -# routing_key = "1f6d4677-84ec-4356-bd73-c79c8a96f96a" -# } -# service_principal = { -# workload_identity_federation = { -# pool_id = module.webhook-datasource.workload_identity_pool_id -# pool_provider_id = module.webhook-datasource.workload_identity_pool_provider_id -# project_number = module.webhook-datasource.workload_identity_project_number -# } -# email = module.webhook-datasource.service_account_email -# } -# } -# }) -# } -# depends_on = [module.webhook-datasource] -# } -# TO HERE \ No newline at end of file +} \ No newline at end of file From 70263ab28075e79fb37571295c0c872e1c82237e Mon Sep 17 00:00:00 2001 From: Jose Pablo Camacho Date: Tue, 10 Sep 2024 17:52:48 -0600 Subject: [PATCH 22/34] feat(modular): address feedback for modular support for cdr/ciem, rebase and cleanup --- test/examples/modular_single_project/onboarding_with_posture.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/examples/modular_single_project/onboarding_with_posture.tf b/test/examples/modular_single_project/onboarding_with_posture.tf index 53eda45..1281087 100644 --- a/test/examples/modular_single_project/onboarding_with_posture.tf +++ b/test/examples/modular_single_project/onboarding_with_posture.tf @@ -14,7 +14,7 @@ terraform { provider "sysdig" { sysdig_secure_url = "https://secure-staging.sysdig.com" - sysdig_secure_api_token = "3aec5684-d355-4dd0-8e0e-4b87af8537f3" + sysdig_secure_api_token = "API_TOKEN" } module "onboarding" { From dfd45daf30ec3dd6642fdc37992362f49c4779e2 Mon Sep 17 00:00:00 2001 From: Haresh Suresh Date: Tue, 10 Sep 2024 21:28:15 -0700 Subject: [PATCH 23/34] add explicit dependency --- modules/onboarding/main.tf | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/onboarding/main.tf b/modules/onboarding/main.tf index 5ed3c49..499712d 100644 --- a/modules/onboarding/main.tf +++ b/modules/onboarding/main.tf @@ -114,7 +114,14 @@ resource "sysdig_secure_cloud_auth_account" "google_account" { }) } - depends_on = [google_service_account_iam_member.custom_onboarding_auth] + depends_on = [ + google_service_account.onboarding_auth, + google_service_account_iam_binding.onboarding_auth_binding, + google_iam_workload_identity_pool.onboarding_auth_pool, + google_iam_workload_identity_pool_provider.onboarding_auth_pool_provider, + google_project_iam_member.browser, + google_service_account_iam_member.custom_onboarding_auth + ] lifecycle { ignore_changes = [ From e834d16abfafe89b6b5d95ae87edcb04a3b241e2 Mon Sep 17 00:00:00 2001 From: Jose Pablo Camacho Date: Wed, 11 Sep 2024 14:15:22 -0600 Subject: [PATCH 24/34] feat(modular): address feedback for modular support for cdr/ciem, rebase and cleanup --- modules/integrations/{webhook-datasource => pub-sub}/README.md | 2 +- modules/integrations/{webhook-datasource => pub-sub}/main.tf | 2 +- .../{webhook-datasource => pub-sub}/organizational.tf | 0 modules/integrations/{webhook-datasource => pub-sub}/outputs.tf | 0 .../integrations/{webhook-datasource => pub-sub}/variables.tf | 0 .../integrations/{webhook-datasource => pub-sub}/versions.tf | 0 modules/services/webhook-datasource/main.tf | 2 +- .../modular_organization/{webhook_datasource.tf => pub-sub.tf} | 2 +- .../{webhook_datasource.tf => pub-sub.tf} | 2 +- .../organization_cdr_test/{webhook_datasource.tf => pub-sub.tf} | 2 +- .../{webhook_datasource.tf => pub-sub.tf} | 2 +- 11 files changed, 7 insertions(+), 7 deletions(-) rename modules/integrations/{webhook-datasource => pub-sub}/README.md (99%) rename modules/integrations/{webhook-datasource => pub-sub}/main.tf (99%) rename modules/integrations/{webhook-datasource => pub-sub}/organizational.tf (100%) rename modules/integrations/{webhook-datasource => pub-sub}/outputs.tf (100%) rename modules/integrations/{webhook-datasource => pub-sub}/variables.tf (100%) rename modules/integrations/{webhook-datasource => pub-sub}/versions.tf (100%) rename test/examples/modular_organization/{webhook_datasource.tf => pub-sub.tf} (94%) rename test/examples/modular_single_project/{webhook_datasource.tf => pub-sub.tf} (94%) rename test/examples/organization_cdr_test/{webhook_datasource.tf => pub-sub.tf} (94%) rename test/examples/single_account_cdr_test/{webhook_datasource.tf => pub-sub.tf} (94%) diff --git a/modules/integrations/webhook-datasource/README.md b/modules/integrations/pub-sub/README.md similarity index 99% rename from modules/integrations/webhook-datasource/README.md rename to modules/integrations/pub-sub/README.md index e9cd058..7c9c00a 100644 --- a/modules/integrations/webhook-datasource/README.md +++ b/modules/integrations/pub-sub/README.md @@ -1,4 +1,4 @@ -# GCP Webhook Datasource Module +# GCP PubSub Module This Module creates the resources required to send AuditLogs logs to Sysdig via GCP Pub Subscription. These resources enable Threat Detection in the given GCP project or organization. Before applying the changes defined in this module, the following operations need to be performed on the target GCP environment: diff --git a/modules/integrations/webhook-datasource/main.tf b/modules/integrations/pub-sub/main.tf similarity index 99% rename from modules/integrations/webhook-datasource/main.tf rename to modules/integrations/pub-sub/main.tf index 3ba941f..66738ad 100644 --- a/modules/integrations/webhook-datasource/main.tf +++ b/modules/integrations/pub-sub/main.tf @@ -240,7 +240,7 @@ resource "google_project_iam_member" "identity_mgmt" { } #----------------------------------------------------------------------------------------------------------------------------------------- -# Call Sysdig Backend to add the webhook-datasource integration to the Sysdig Cloud Account +# Call Sysdig Backend to add the pub-sub integration to the Sysdig Cloud Account # # Note (optional): To ensure this gets called after all cloud resources are created, add # explicit dependency using depends_on diff --git a/modules/integrations/webhook-datasource/organizational.tf b/modules/integrations/pub-sub/organizational.tf similarity index 100% rename from modules/integrations/webhook-datasource/organizational.tf rename to modules/integrations/pub-sub/organizational.tf diff --git a/modules/integrations/webhook-datasource/outputs.tf b/modules/integrations/pub-sub/outputs.tf similarity index 100% rename from modules/integrations/webhook-datasource/outputs.tf rename to modules/integrations/pub-sub/outputs.tf diff --git a/modules/integrations/webhook-datasource/variables.tf b/modules/integrations/pub-sub/variables.tf similarity index 100% rename from modules/integrations/webhook-datasource/variables.tf rename to modules/integrations/pub-sub/variables.tf diff --git a/modules/integrations/webhook-datasource/versions.tf b/modules/integrations/pub-sub/versions.tf similarity index 100% rename from modules/integrations/webhook-datasource/versions.tf rename to modules/integrations/pub-sub/versions.tf diff --git a/modules/services/webhook-datasource/main.tf b/modules/services/webhook-datasource/main.tf index b86d4f7..149db43 100644 --- a/modules/services/webhook-datasource/main.tf +++ b/modules/services/webhook-datasource/main.tf @@ -1,5 +1,5 @@ ######################################################################################## -# The webhook-datasource module takes care of provisioning the necessary resources to make Sysdig's +# The pub-sub module takes care of provisioning the necessary resources to make Sysdig's # backend able to ingest data from a single GCP project. # # Before applying the changes defined in this module, the following operations need to diff --git a/test/examples/modular_organization/webhook_datasource.tf b/test/examples/modular_organization/pub-sub.tf similarity index 94% rename from test/examples/modular_organization/webhook_datasource.tf rename to test/examples/modular_organization/pub-sub.tf index 6b45215..a8f0201 100644 --- a/test/examples/modular_organization/webhook_datasource.tf +++ b/test/examples/modular_organization/pub-sub.tf @@ -4,7 +4,7 @@ #--------------------------------------------------------------------------------------------- module "webhook-datasource" { - source = "../../../modules/integrations/webhook-datasource" + source = "../../../modules/integrations/pub-sub" project_id = module.onboarding.project_id is_organizational = module.onboarding.is_organizational organization_domain = module.onboarding.organization_domain diff --git a/test/examples/modular_single_project/webhook_datasource.tf b/test/examples/modular_single_project/pub-sub.tf similarity index 94% rename from test/examples/modular_single_project/webhook_datasource.tf rename to test/examples/modular_single_project/pub-sub.tf index 9effcf5..655ce2c 100644 --- a/test/examples/modular_single_project/webhook_datasource.tf +++ b/test/examples/modular_single_project/pub-sub.tf @@ -4,7 +4,7 @@ #--------------------------------------------------------------------------------------------- module "webhook-datasource" { - source = "../../../modules/integrations/webhook-datasource" + source = "../../../modules/integrations/pub-sub" project_id = module.onboarding.project_id sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id } diff --git a/test/examples/organization_cdr_test/webhook_datasource.tf b/test/examples/organization_cdr_test/pub-sub.tf similarity index 94% rename from test/examples/organization_cdr_test/webhook_datasource.tf rename to test/examples/organization_cdr_test/pub-sub.tf index 6b45215..a8f0201 100644 --- a/test/examples/organization_cdr_test/webhook_datasource.tf +++ b/test/examples/organization_cdr_test/pub-sub.tf @@ -4,7 +4,7 @@ #--------------------------------------------------------------------------------------------- module "webhook-datasource" { - source = "../../../modules/integrations/webhook-datasource" + source = "../../../modules/integrations/pub-sub" project_id = module.onboarding.project_id is_organizational = module.onboarding.is_organizational organization_domain = module.onboarding.organization_domain diff --git a/test/examples/single_account_cdr_test/webhook_datasource.tf b/test/examples/single_account_cdr_test/pub-sub.tf similarity index 94% rename from test/examples/single_account_cdr_test/webhook_datasource.tf rename to test/examples/single_account_cdr_test/pub-sub.tf index 9effcf5..655ce2c 100644 --- a/test/examples/single_account_cdr_test/webhook_datasource.tf +++ b/test/examples/single_account_cdr_test/pub-sub.tf @@ -4,7 +4,7 @@ #--------------------------------------------------------------------------------------------- module "webhook-datasource" { - source = "../../../modules/integrations/webhook-datasource" + source = "../../../modules/integrations/pub-sub" project_id = module.onboarding.project_id sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id } From 72aafe067e256f97f160118d821241dcedc8d188 Mon Sep 17 00:00:00 2001 From: Jose Pablo Camacho Date: Wed, 11 Sep 2024 14:17:15 -0600 Subject: [PATCH 25/34] feat(modular): address feedback for modular support for cdr/ciem, rebase and cleanup --- modules/services/webhook-datasource/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/webhook-datasource/main.tf b/modules/services/webhook-datasource/main.tf index b7d3c30..a28709e 100644 --- a/modules/services/webhook-datasource/main.tf +++ b/modules/services/webhook-datasource/main.tf @@ -1,5 +1,5 @@ ######################################################################################## -# The pub-sub module takes care of provisioning the necessary resources to make Sysdig's +# The webhook-datasource module takes care of provisioning the necessary resources to make Sysdig's # backend able to ingest data from a single GCP project. # # Before applying the changes defined in this module, the following operations need to From 4d60c2d88e6d305643c9dca3aa852bd824337daf Mon Sep 17 00:00:00 2001 From: Jose Pablo Camacho Date: Wed, 11 Sep 2024 16:24:17 -0600 Subject: [PATCH 26/34] feat(modular): address feedback for modular support for cdr/ciem, rebase and cleanup --- modules/integrations/pub-sub/outputs.tf | 2 +- test/examples/modular_organization/pub-sub.tf | 8 ++++---- test/examples/modular_single_project/pub-sub.tf | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/modules/integrations/pub-sub/outputs.tf b/modules/integrations/pub-sub/outputs.tf index f55b862..6638b24 100644 --- a/modules/integrations/pub-sub/outputs.tf +++ b/modules/integrations/pub-sub/outputs.tf @@ -1,4 +1,4 @@ -output "webhook_datasource_component_id" { +output "pubsub_datasource_component_id" { value = "${sysdig_secure_cloud_auth_account_component.gcp_webhook_datasource.type}/${sysdig_secure_cloud_auth_account_component.gcp_webhook_datasource.instance}" description = "Component identifier of Webhook Datasource integration created in Sysdig Backend for Log Ingestion" depends_on = [sysdig_secure_cloud_auth_account_component.gcp_webhook_datasource] diff --git a/test/examples/modular_organization/pub-sub.tf b/test/examples/modular_organization/pub-sub.tf index a8f0201..9dc58aa 100644 --- a/test/examples/modular_organization/pub-sub.tf +++ b/test/examples/modular_organization/pub-sub.tf @@ -3,7 +3,7 @@ # installing additional Sysdig features. #--------------------------------------------------------------------------------------------- -module "webhook-datasource" { +module "pub-sub" { source = "../../../modules/integrations/pub-sub" project_id = module.onboarding.project_id is_organizational = module.onboarding.is_organizational @@ -15,14 +15,14 @@ resource "sysdig_secure_cloud_auth_account_feature" "threat_detection" { account_id = module.onboarding.sysdig_secure_account_id type = "FEATURE_SECURE_THREAT_DETECTION" enabled = true - components = [ module.webhook-datasource.webhook_datasource_component_id ] - depends_on = [ module.webhook-datasource ] + components = [ module.pub-sub.pubsub_datasource_component_id ] + depends_on = [ module.pub-sub ] } resource "sysdig_secure_cloud_auth_account_feature" "identity_entitlement" { account_id = module.onboarding.sysdig_secure_account_id type = "FEATURE_SECURE_IDENTITY_ENTITLEMENT" enabled = true - components = [module.webhook-datasource.webhook_datasource_component_id] + components = [module.pub-sub.pubsub_datasource_component_id] depends_on = [sysdig_secure_cloud_auth_account_feature.config_posture, sysdig_secure_cloud_auth_account_feature.threat_detection] } \ No newline at end of file diff --git a/test/examples/modular_single_project/pub-sub.tf b/test/examples/modular_single_project/pub-sub.tf index 655ce2c..86114b8 100644 --- a/test/examples/modular_single_project/pub-sub.tf +++ b/test/examples/modular_single_project/pub-sub.tf @@ -3,7 +3,7 @@ # installing additional Sysdig features. #--------------------------------------------------------------------------------------------- -module "webhook-datasource" { +module "pub-sub" { source = "../../../modules/integrations/pub-sub" project_id = module.onboarding.project_id sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id @@ -13,14 +13,14 @@ resource "sysdig_secure_cloud_auth_account_feature" "threat_detection" { account_id = module.onboarding.sysdig_secure_account_id type = "FEATURE_SECURE_THREAT_DETECTION" enabled = true - components = [ module.webhook-datasource.webhook_datasource_component_id ] - depends_on = [ module.webhook-datasource ] + components = [ module.pub-sub.pubsub_datasource_component_id ] + depends_on = [ module.pub-sub ] } resource "sysdig_secure_cloud_auth_account_feature" "identity_entitlement" { account_id = module.onboarding.sysdig_secure_account_id type = "FEATURE_SECURE_IDENTITY_ENTITLEMENT" enabled = true - components = [module.webhook-datasource.webhook_datasource_component_id] + components = [module.pub-sub.pubsub_datasource_component_id] depends_on = [sysdig_secure_cloud_auth_account_feature.config_posture, sysdig_secure_cloud_auth_account_feature.threat_detection] } \ No newline at end of file From 869630a41daf87c40d4ae58b578d7a0067f4f0e5 Mon Sep 17 00:00:00 2001 From: Jose Pablo Camacho Date: Fri, 13 Sep 2024 16:38:44 -0600 Subject: [PATCH 27/34] feat(vm): add vm modular support --- modules/agentless-scan/README.md | 95 ++++++++ modules/agentless-scan/main.tf | 208 ++++++++++++++++++ modules/agentless-scan/organizational.tf | 50 +++++ modules/agentless-scan/outputs.tf | 5 + modules/agentless-scan/variables.tf | 39 ++++ modules/agentless-scan/versions.tf | 18 ++ .../modular_organization/agentless-scan.tf | 20 ++ .../modular_single_project/agentless-scan.tf | 18 ++ 8 files changed, 453 insertions(+) create mode 100644 modules/agentless-scan/README.md create mode 100644 modules/agentless-scan/main.tf create mode 100644 modules/agentless-scan/organizational.tf create mode 100644 modules/agentless-scan/outputs.tf create mode 100644 modules/agentless-scan/variables.tf create mode 100644 modules/agentless-scan/versions.tf create mode 100644 test/examples/modular_organization/agentless-scan.tf create mode 100644 test/examples/modular_single_project/agentless-scan.tf diff --git a/modules/agentless-scan/README.md b/modules/agentless-scan/README.md new file mode 100644 index 0000000..1862a09 --- /dev/null +++ b/modules/agentless-scan/README.md @@ -0,0 +1,95 @@ +# GCP Agentless Scanning Module + +This Module creates the resources required to scan hosts on Google Cloud Projects. Before applying the changes defined +in this module, the following operations need to be performed on the target GCP environment: + +- The APIs needed for the CDR/CIEM feature are listed below: + - Compute Engine API + +- The following resources will be created in each instrumented project: + - For the **Resource Discovery**: Enable Sysdig to authenticate through a Workload Identity Pool (requires provider, + service account, role, and related bindings) in order to be able to discover the VPC/Instance/Volumes. + - For the **Host Data Extraction**: Enable Sysdig to create a disk copy on our SaaS platform, to be able to extract + the data required for security assessment. + +This module will also deploy a Service Principal Component in Sysdig Backend for onboarded Sysdig Cloud Account. + +## Single Project Setup + +![permission_diagram_single](./permissions_diagram_single.png) + +## Organizational Setup + +Set `is_organizatinal=true` together with the `organization_domain=`. +![permission_diagram_org](./permissions_diagram_org.png) + +## Requirements + +| Name | Version | +|---------------------------------------------------------------------------|-----------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [google](#requirement\_google) | >= 4.21.0 | +| [sysdig](#requirement\_sysdig) | >= 1.34.0 | +| [random](#requirement\_random) | >= 3.1 | + +## Providers + +| Name | Version | +|---------------------------------------------------------------------------|-----------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [google](#requirement\_google) | >= 4.21.0 | +| [sysdig](#requirement\_sysdig) | >= 1.34.0 | +| [random](#requirement\_random) | >= 3.1 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------| +| [random_id.suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource | +| [google_iam_workload_identity_pool.agentless](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/iam_workload_identity_pool) | resource | +| [google_iam_workload_identity_pool_provider.agentless](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/iam_workload_identity_pool_provider) | resource | +| [google_iam_workload_identity_pool_provider.agentless_gcp](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/iam_workload_identity_pool_provider) | resource | +| [google_organization_iam_binding.admin_account_iam](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/organization_iam_binding) | resource | +| [google_organization_iam_binding.controller_custom](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/organization_iam_binding) | resource | +| [google_organization_iam_custom_role.controller](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/organization_iam_custom_role) | resource | +| [google_organization_iam_custom_role.worker_role](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/organization_iam_custom_role) | resource | +| [google_project_iam_binding.admin_account_iam](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/project_iam_binding) | resource | +| [google_project_iam_binding.controller_custom](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/project_iam_binding) | resource | +| [google_project_iam_custom_role.controller](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/project_iam_custom_role) | resource | +| [google_project_iam_custom_role.worker_role](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/project_iam_custom_role) | resource | +| [google_service_account.controller](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account) | resource | +| [google_service_account_iam_member.controller_custom](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account_iam_member) | resource | +| [google_service_account_iam_member.controller_custom_gcp](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account_iam_member) | resource | +| [google_organization.org](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/organization) | data source | +| [google_project.project](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/project) | data source | +| [sysdig_secure_trusted_cloud_identity.trusted_identity](https://registry.terraform.io/providers/sysdiglabs/sysdig/latest/docs/data-sources/secure_trusted_cloud_identity) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|----------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------|-----------------------------|:--------:| +| [project\_id](#input\_project\_id) | GCP Project ID | `string` | n/a | yes | +| [is\_organizational](#input\_is\_organizational) | Optional. Determines whether module must scope whole organization. Otherwise single project will be scoped | `bool` | `false` | no | +| [organization\_domain](#input\_organization\_domain) | Optional. If `is_organizational=true` is set, its mandatory to specify this value, with the GCP Organization domain. e.g. sysdig.com | `string` | `null` | no | +| [role\_name](#input\_role\_name) | Optional. Name for the Worker Role on the Customer infrastructure | `string` | `"SysdigAgentlessHostRole"` | no | +| [sysdig\_account\_id](#input\_sysdig\_account\_id) | Sysdig provided GCP Account designated for the host scan.
One of `sysdig_backend` or `sysdig_account_id`must be provided | `string` | `null` | no | +| [sysdig\_secure\_account\_id](#input\_sysdig\_secure\_account\_id) | ID of the Sysdig Cloud Account to enable Agentless Scanning integration for (in case of organization, ID of the Sysdig management account) | `string` | `null` | no | +| [suffix](#input\_suffix) | Optional. Suffix word to enable multiple deployments with different naming
(Workload Identity Pool and Providers have a soft deletion on Google Platform that will disallow name re-utilization)
By default a random value will be autogenerated. | `string` | `null` | no | + +## Outputs + +| Name | Description | +|--------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------| +| [agentless\_scan\_component\_id](#agentless\_scan\_component\_id) | Component identifier of Agentless Scan integration created in Sysdig Backend for Log Ingestion | + +## Authors + +Module is maintained by [Sysdig](https://sysdig.com). + +## License + +Apache 2 Licensed. See LICENSE for full details. diff --git a/modules/agentless-scan/main.tf b/modules/agentless-scan/main.tf new file mode 100644 index 0000000..95b977c --- /dev/null +++ b/modules/agentless-scan/main.tf @@ -0,0 +1,208 @@ +#----------------------------------------------------------------------------------------- +# Fetch the data sources +#----------------------------------------------------------------------------------------- +data "sysdig_secure_agentless_scanning_assets" "assets" {} + +#----------------------------------------------------------------------------------------- +# These locals indicate the suffix to create unique name for resources and permissions +#----------------------------------------------------------------------------------------- +locals { + suffix = var.suffix == null ? random_id.suffix[0].hex : var.suffix + host_discovery_permissions = [ + # networks + "compute.networks.list", + "compute.networks.get", + # instances + "compute.instances.list", + "compute.instances.get", + # disks + "compute.disks.list", + "compute.disks.get", + # workload identity federation + "iam.serviceAccounts.getAccessToken", + ] + host_scan_permissions = [ + # general stuff + "compute.zoneOperations.get", + # disks + "compute.disks.get", + "compute.disks.useReadOnly", + ] +} + +#----------------------------------------------------------------------------------------------------------------------- +# A random resource is used to generate unique Agentless Scan name suffix for resources. +# This prevents conflicts when recreating an Agentless Scan resources with the same name. +#----------------------------------------------------------------------------------------------------------------------- +resource "random_id" "suffix" { + count = var.suffix == null ? 1 : 0 + byte_length = 3 +} + + +resource "google_service_account" "controller" { + project = var.project_id + account_id = "sysdig-ahs-${local.suffix}" + display_name = "Sysdig Agentless Host Scanning" +} + +#----------------------------------------------------------------------------------------------------------------------- +# Configure Workload Identity Federation for auth +# See https://cloud.google.com/iam/docs/access-resources-aws +#----------------------------------------------------------------------------------------------------------------------- + +resource "google_iam_workload_identity_pool" "agentless" { + workload_identity_pool_id = "sysdig-ahs-${local.suffix}" +} + +resource "google_iam_workload_identity_pool_provider" "agentless" { + count = data.sysdig_secure_agentless_scanning_assets.assets.backend.cloud_id != null ? 1 : 0 + + lifecycle { + precondition { + condition = (data.sysdig_secure_agentless_scanning_assets.assets.backend.cloud_id != null && var.sysdig_account_id == null) + error_message = "Cannot provide both sysdig_backend or sysdig_account_id" + } + } + + workload_identity_pool_id = google_iam_workload_identity_pool.agentless.workload_identity_pool_id + workload_identity_pool_provider_id = "sysdig-ahs-${local.suffix}" + display_name = "Sysdig Agentless Controller" + description = "AWS identity pool provider for Sysdig Secure Agentless Host Scanning" + disabled = false + + attribute_condition = "attribute.aws_account==\"${data.sysdig_secure_agentless_scanning_assets.assets.backend.cloud_id}\"" + + attribute_mapping = { + "google.subject" = "assertion.arn" + "attribute.aws_account" = "assertion.account" + "attribute.role" = "assertion.arn.extract(\"/assumed-role/{role}/\")" + "attribute.session" = "assertion.arn.extract(\"/assumed-role/{role_and_session}/\").extract(\"/{session}\")" + } + + aws { + account_id = data.sysdig_secure_agentless_scanning_assets.assets.backend.cloud_id + } +} + +resource "google_service_account_iam_member" "controller_custom" { + count = data.sysdig_secure_agentless_scanning_assets.assets.backend.cloud_id != null ? 1 : 0 + + lifecycle { + precondition { + condition = (data.sysdig_secure_agentless_scanning_assets.assets.backend.cloud_id != null && var.sysdig_account_id == null) + error_message = "Cannot provide both sysdig_backend or sysdig_account_id" + } + } + + service_account_id = google_service_account.controller.name + role = "roles/iam.workloadIdentityUser" + member = "principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.agentless.name}/attribute.aws_account/${data.sysdig_secure_agentless_scanning_assets.assets.backend.cloud_id}" +} + +resource "google_iam_workload_identity_pool_provider" "agentless_gcp" { + count = var.sysdig_account_id != null ? 1 : 0 + + lifecycle { + precondition { + condition = (data.sysdig_secure_agentless_scanning_assets.assets.backend.cloud_id == null && var.sysdig_account_id != null) + error_message = "Cannot provide both sysdig_backend or sysdig_account_id" + } + } + + workload_identity_pool_id = google_iam_workload_identity_pool.agentless.workload_identity_pool_id + workload_identity_pool_provider_id = "sysdig-ahs-${local.suffix}-gcp" + display_name = "Sysdig Agentless Controller" + description = "GCP identity pool provider for Sysdig Secure Agentless Host Scanning" + disabled = false + + attribute_condition = "google.subject == \"${var.sysdig_account_id}\"" + + attribute_mapping = { + "google.subject" = "assertion.sub" + "attribute.sa_id" = "assertion.sub" + } + + oidc { + issuer_uri = "https://accounts.google.com" + } +} + +resource "google_service_account_iam_member" "controller_custom_gcp" { + count = var.sysdig_account_id != null ? 1 : 0 + + lifecycle { + precondition { + condition = (data.sysdig_secure_agentless_scanning_assets.assets.backend.cloud_id == null && var.sysdig_account_id != null) + error_message = "Cannot provide both sysdig_backend or sysdig_account_id" + } + } + + service_account_id = google_service_account.controller.name + role = "roles/iam.workloadIdentityUser" + member = "principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.agentless.name}/attribute.sa_id/${var.sysdig_account_id}" +} + +#----------------------------------------------------------------------------------------- +# Custom IAM roles and bindings +#----------------------------------------------------------------------------------------- + +resource "google_project_iam_custom_role" "controller" { + count = var.is_organizational ? 0 : 1 + + project = var.project_id + role_id = "${var.role_name}Discovery${local.suffix}" + title = "${var.role_name}, for Host Discovery" + permissions = local.host_discovery_permissions +} + +resource "google_project_iam_binding" "controller_custom" { + count = var.is_organizational ? 0 : 1 + + project = var.project_id + role = google_project_iam_custom_role.controller[0].id + members = [ + "serviceAccount:${google_service_account.controller.email}", + ] +} + +resource "google_project_iam_custom_role" "worker_role" { + count = var.is_organizational ? 0 : 1 + + project = var.project_id + role_id = "${var.role_name}Scan${local.suffix}" + title = "${var.role_name}, for Host Scan" + permissions = local.host_scan_permissions +} + +resource "google_project_iam_binding" "admin_account_iam" { + count = var.is_organizational ? 0 : 1 + + project = var.project_id + role = google_project_iam_custom_role.worker_role[0].id + members = [ + "serviceAccount:${data.sysdig_secure_agentless_scanning_assets.assets.gcp.worker_identity}", + ] +} + +#----------------------------------------------------------------------------------------------------------------------------------------- +# Call Sysdig Backend to add the agentless-scan integration to the Sysdig Cloud Account +# +# Note (optional): To ensure this gets called after all cloud resources are created, add +# explicit dependency using depends_on +#----------------------------------------------------------------------------------------------------------------------------------------- + +resource "sysdig_secure_cloud_auth_account_component" "gcp_agentless_scan" { + account_id = var.sysdig_secure_account_id + type = "COMPONENT_SERVICE_PRINCIPAL" + instance = "secure-scanning" + version = "v0.1.0" + service_principal_metadata = jsonencode({ + gcp = { + workload_identity_federation = { + pool_provider_id = data.sysdig_secure_agentless_scanning_assets.assets.gcp.worker_identity != null ? google_iam_workload_identity_pool_provider.agentless[0].name : var.sysdig_account_id != null ? google_iam_workload_identity_pool_provider.agentless_gcp[0].name : null + } + email = google_service_account.controller.email + } + }) +} diff --git a/modules/agentless-scan/organizational.tf b/modules/agentless-scan/organizational.tf new file mode 100644 index 0000000..8770cb5 --- /dev/null +++ b/modules/agentless-scan/organizational.tf @@ -0,0 +1,50 @@ +#----------------------------------------------------------------------------------------- +# Fetch the data sources +#----------------------------------------------------------------------------------------- + +data "google_organization" "org" { + count = var.is_organizational ? 1 : 0 + domain = var.organization_domain +} + +#----------------------------------------------------------------------------------------- +# Custom IAM roles and bindings +#----------------------------------------------------------------------------------------- + +resource "google_organization_iam_custom_role" "controller" { + count = var.is_organizational ? 1 : 0 + + org_id = data.google_organization.org[0].org_id + role_id = "${var.role_name}Discovery${title(local.suffix)}" + title = "${var.role_name}, for Host Discovery" + permissions = local.host_discovery_permissions +} + +resource "google_organization_iam_binding" "controller_custom" { + count = var.is_organizational ? 1 : 0 + + org_id = data.google_organization.org[0].org_id + role = google_organization_iam_custom_role.controller[0].id + members = [ + "serviceAccount:${google_service_account.controller.email}", + ] +} + +resource "google_organization_iam_custom_role" "worker_role" { + count = var.is_organizational ? 1 : 0 + + org_id = data.google_organization.org[0].org_id + role_id = "${var.role_name}Scan${title(local.suffix)}" + title = "${var.role_name}, for Host Scan" + permissions = local.host_scan_permissions +} + +resource "google_organization_iam_binding" "admin_account_iam" { + count = var.is_organizational ? 1 : 0 + + org_id = data.google_organization.org[0].org_id + role = google_organization_iam_custom_role.worker_role[0].id + members = [ + "serviceAccount:${data.sysdig_secure_agentless_scanning_assets.assets.gcp.worker_identity}", + ] +} diff --git a/modules/agentless-scan/outputs.tf b/modules/agentless-scan/outputs.tf new file mode 100644 index 0000000..aa77222 --- /dev/null +++ b/modules/agentless-scan/outputs.tf @@ -0,0 +1,5 @@ +output "agentless_scan_component_id" { + value = "${sysdig_secure_cloud_auth_account_component.gcp_agentless_scan.type}/${sysdig_secure_cloud_auth_account_component.gcp_agentless_scan.instance}" + description = "Component identifier of Agentless Scan integration created in Sysdig Backend for Log Ingestion" + depends_on = [sysdig_secure_cloud_auth_account_component.gcp_agentless_scan] +} \ No newline at end of file diff --git a/modules/agentless-scan/variables.tf b/modules/agentless-scan/variables.tf new file mode 100644 index 0000000..71d0586 --- /dev/null +++ b/modules/agentless-scan/variables.tf @@ -0,0 +1,39 @@ +variable "project_id" { + type = string + description = "(Required) Target Project identifier provided by the customer" +} + +variable "is_organizational" { + description = "(Optional) Set this field to true to deploy to a GCP Organization." + type = bool + default = false +} + +variable "organization_domain" { + type = string + description = "(Optional) Organization domain. e.g. sysdig.com" + default = "" +} + +variable "role_name" { + type = string + description = "Name for Sysdig operations on discovery and scan role" + default = "SysdigCloudVM" +} + +variable "sysdig_account_id" { + type = string + description = "Sysdig provided GCP Account designated for the host scan. One of sysdig_backend or sysdig_account_id must be provided" + default = null +} + +variable "sysdig_secure_account_id" { + type = string + description = "ID of the Sysdig Cloud Account to enable Agentless Scanning integration for (in case of organization, ID of the Sysdig management account)" +} + +variable "suffix" { + type = string + description = "Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated." + default = null +} diff --git a/modules/agentless-scan/versions.tf b/modules/agentless-scan/versions.tf new file mode 100644 index 0000000..adb6e1a --- /dev/null +++ b/modules/agentless-scan/versions.tf @@ -0,0 +1,18 @@ +terraform { + required_version = ">= 1.0.0" + + required_providers { + google = { + source = "hashicorp/google" + version = ">= 4.21.0" + } + sysdig = { + source = "sysdiglabs/sysdig" + version = ">= 1.34.0" + } + random = { + source = "hashicorp/random" + version = ">= 3.1" + } + } +} \ No newline at end of file diff --git a/test/examples/modular_organization/agentless-scan.tf b/test/examples/modular_organization/agentless-scan.tf new file mode 100644 index 0000000..3f7cca8 --- /dev/null +++ b/test/examples/modular_organization/agentless-scan.tf @@ -0,0 +1,20 @@ +#--------------------------------------------------------------------------------------------- +# Ensure installation flow for foundational onboarding has been completed before +# installing additional Sysdig features. +#--------------------------------------------------------------------------------------------- + +module "agentless-scan" { + source = "../../../modules/agentless-scan" + project_id = module.onboarding.project_id + is_organizational = module.onboarding.is_organizational + organization_domain = module.onboarding.organization_domain + sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id +} + +resource "sysdig_secure_cloud_auth_account_feature" "agentless_scanning" { + account_id = module.onboarding.sysdig_secure_account_id + type = "FEATURE_SECURE_AGENTLESS_SCANNING" + enabled = true + components = [module.agentless-scan.agentless_scan_component_id] + depends_on = [module.agentless-scan] +} \ No newline at end of file diff --git a/test/examples/modular_single_project/agentless-scan.tf b/test/examples/modular_single_project/agentless-scan.tf new file mode 100644 index 0000000..1f082f8 --- /dev/null +++ b/test/examples/modular_single_project/agentless-scan.tf @@ -0,0 +1,18 @@ +#--------------------------------------------------------------------------------------------- +# Ensure installation flow for foundational onboarding has been completed before +# installing additional Sysdig features. +#--------------------------------------------------------------------------------------------- + +module "agentless-scan" { + source = "../../../modules/agentless-scan" + project_id = module.onboarding.project_id + sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id +} + +resource "sysdig_secure_cloud_auth_account_feature" "agentless_scanning" { + account_id = module.onboarding.sysdig_secure_account_id + type = "FEATURE_SECURE_AGENTLESS_SCANNING" + enabled = true + components = [module.agentless-scan.agentless_scan_component_id] + depends_on = [module.agentless-scan] +} \ No newline at end of file From 8a43fea7dfcc551ed6029e73016baa2a2be78dab Mon Sep 17 00:00:00 2001 From: Jose Pablo Camacho Date: Fri, 13 Sep 2024 16:43:29 -0600 Subject: [PATCH 28/34] feat(vm): add vm modular support --- modules/agentless-scan/outputs.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/agentless-scan/outputs.tf b/modules/agentless-scan/outputs.tf index aa77222..6bd8e41 100644 --- a/modules/agentless-scan/outputs.tf +++ b/modules/agentless-scan/outputs.tf @@ -1,5 +1,5 @@ output "agentless_scan_component_id" { value = "${sysdig_secure_cloud_auth_account_component.gcp_agentless_scan.type}/${sysdig_secure_cloud_auth_account_component.gcp_agentless_scan.instance}" description = "Component identifier of Agentless Scan integration created in Sysdig Backend for Log Ingestion" - depends_on = [sysdig_secure_cloud_auth_account_component.gcp_agentless_scan] + depends_on = [sysdig_secure_cloud_auth_account_component.gcp_agentless_scan] } \ No newline at end of file From ade528d0588eda03999ce74cbc920089cd064089 Mon Sep 17 00:00:00 2001 From: Jose Pablo Camacho Date: Mon, 16 Sep 2024 09:46:28 -0600 Subject: [PATCH 29/34] feat(modular): add vm modular support --- modules/integrations/pub-sub/README.md | 32 +++++++++++++------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/modules/integrations/pub-sub/README.md b/modules/integrations/pub-sub/README.md index 7c9c00a..4bc4916 100644 --- a/modules/integrations/pub-sub/README.md +++ b/modules/integrations/pub-sub/README.md @@ -64,22 +64,22 @@ No modules. ## Inputs -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [ack\_deadline\_seconds](#input\_ack\_deadline\_seconds) | (Optional) Maximum time in seconds after Sysdig's subscriber receives a message before the subscriber should acknowledge the message | `number` | `60` | no | -| [is\_organizational](#input\_is\_organizational) | (Optional) Set this field to 'true' to deploy secure-for-cloud to a GCP Organization. | `bool` | `false` | no | -| [labels](#input\_labels) | (Optional) Labels to be associated with Sysdig-originated resources | `map(string)` |
{
"originator": "sysdig"
}
| no | -| [max\_delivery\_attempts](#input\_max\_delivery\_attempts) | (Optional) Number of attempts redelivering missed messages from the deadletter topic to the main one | `number` | `5` | no | -| [maximum\_backoff](#input\_maximum\_backoff) | (Optional) Maximum backoff time for exponential backoff of the push subscription retry policy | `string` | `"600s"` | no | -| [message\_retention\_duration](#input\_message\_retention\_duration) | (Optional) How long unacknowledged messages are retained in Sysdig's subscription backlog, from the moment a message is published | `string` | `"604800s"` | no | -| [minimum\_backoff](#input\_minimum\_backoff) | (Optional) Minimum backoff time for exponential backoff of the push subscription retry policy | `string` | `"10s"` | no | -| [organization\_domain](#input\_organization\_domain) | Organization domain. e.g. sysdig.com | `string` | `""` | no | -| [project\_id](#input\_project\_id) | (Required) Target Project identifier provided by the customer | `string` | n/a | yes | -| [role\_name](#input\_role\_name) | (Optional) Role name for custom role binding to the service account, with read permissions for data ingestion resources | `string` | `"SysdigIngestionAuthRole"` | no | -| [suffix](#input\_suffix) | (Optional) Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated | `string` | `null` | no | -| [audit\_log\_config](#input\_audit\_log\_config) | List of services and their audit log configurations to be ingested. Default is to ingest all logs. |
list(object({
service = string,
log_config = list(object({
log_type = string,
exempted_members = optional(list(string))
}))
}))
|
[
{
"log_config": [
{
"log_type": "ADMIN_READ"
},
{
"log_type": "DATA_READ"
},
{
"log_type": "DATA_WRITE"
}
],
"service": "allServices"
}
]
| no | -| [ingestion\_sink\_filter](#input\_ingestion\_sink\_filter) | Filter the Sink is set up with. Ingests AuditLogs by default. | `string` | `protoPayload.@type = "type.googleapis.com/google.cloud.audit.AuditLog"` | no | -| [exclude\_logs\_filter](#input\_exclude\_logs\_filter) | Filter to exclude logs from ingestion. Default is to ingest all google.cloud.audit.AuditLog logs. with no exclusions. |
list(object({
name = string,
description = optional(string),
filter = string,
disabled = optional(bool)
}))
| `[]` | no | +| Name | Description | Type | Default | Required | +|----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------:| +| [ack\_deadline\_seconds](#input\_ack\_deadline\_seconds) | (Optional) Maximum time in seconds after Sysdig's subscriber receives a message before the subscriber should acknowledge the message | `number` | `60` | no | +| [is\_organizational](#input\_is\_organizational) | (Optional) Set this field to 'true' to deploy secure-for-cloud to a GCP Organization. | `bool` | `false` | no | +| [labels](#input\_labels) | (Optional) Labels to be associated with Sysdig-originated resources | `map(string)` |
{
"originator": "sysdig"
}
| no | +| [max\_delivery\_attempts](#input\_max\_delivery\_attempts) | (Optional) Number of attempts redelivering missed messages from the deadletter topic to the main one | `number` | `5` | no | +| [maximum\_backoff](#input\_maximum\_backoff) | (Optional) Maximum backoff time for exponential backoff of the push subscription retry policy | `string` | `"600s"` | no | +| [message\_retention\_duration](#input\_message\_retention\_duration) | (Optional) How long unacknowledged messages are retained in Sysdig's subscription backlog, from the moment a message is published | `string` | `"604800s"` | no | +| [minimum\_backoff](#input\_minimum\_backoff) | (Optional) Minimum backoff time for exponential backoff of the push subscription retry policy | `string` | `"10s"` | no | +| [organization\_domain](#input\_organization\_domain) | Organization domain. e.g. sysdig.com | `string` | `""` | no | +| [project\_id](#input\_project\_id) | (Required) Target Project identifier provided by the customer | `string` | n/a | yes | +| [role\_name](#input\_role\_name) | (Optional) Role name for custom role binding to the service account, with read permissions for data ingestion resources | `string` | `"SysdigIngestionAuthRole"` | no | +| [suffix](#input\_suffix) | (Optional) Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated | `string` | `null` | no | +| [audit\_log\_config](#input\_audit\_log\_config) | List of services and their audit log configurations to be ingested. Default is to ingest all logs. |
list(object({
service = string,
log_config = list(object({
log_type = string,
exempted_members = optional(list(string))
}))
}))
|
[
{
"log_config": [
{
"log_type": "ADMIN_READ"
},
{
"log_type": "DATA_READ"
},
{
"log_type": "DATA_WRITE"
}
],
"service": "allServices"
}
]
| no | +| [ingestion\_sink\_filter](#input\_ingestion\_sink\_filter) | Filter the Sink is set up with. Ingests AuditLogs by default. | `string` | `protoPayload.@type = "type.googleapis.com/google.cloud.audit.AuditLog"` | no | +| [exclude\_logs\_filter](#input\_exclude\_logs\_filter) | Filter to exclude logs from ingestion. Default is to ingest all google.cloud.audit.AuditLog logs. with no exclusions. |
list(object({
name = string,
description = optional(string),
filter = string,
disabled = optional(bool)
}))
| `[]` | no | ## Outputs From 5a148ee39c1c82af848dd3f24076c6e80b61026f Mon Sep 17 00:00:00 2001 From: Jose Pablo Camacho Date: Mon, 16 Sep 2024 12:46:46 -0600 Subject: [PATCH 30/34] feat(vm): add vm modular support --- modules/agentless-scan/README.md | 8 ++++---- modules/agentless-scan/outputs.tf | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/agentless-scan/README.md b/modules/agentless-scan/README.md index 1862a09..a844718 100644 --- a/modules/agentless-scan/README.md +++ b/modules/agentless-scan/README.md @@ -3,7 +3,7 @@ This Module creates the resources required to scan hosts on Google Cloud Projects. Before applying the changes defined in this module, the following operations need to be performed on the target GCP environment: -- The APIs needed for the CDR/CIEM feature are listed below: +- The APIs needed for the VM feature are listed below: - Compute Engine API - The following resources will be created in each instrumented project: @@ -82,9 +82,9 @@ No modules. ## Outputs -| Name | Description | -|--------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------| -| [agentless\_scan\_component\_id](#agentless\_scan\_component\_id) | Component identifier of Agentless Scan integration created in Sysdig Backend for Log Ingestion | +| Name | Description | +|--------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------| +| [agentless\_scan\_component\_id](#agentless\_scan\_component\_id) | Component identifier of Agentless Scan integration created in Sysdig Backend for VM | ## Authors diff --git a/modules/agentless-scan/outputs.tf b/modules/agentless-scan/outputs.tf index 6bd8e41..36b8b1c 100644 --- a/modules/agentless-scan/outputs.tf +++ b/modules/agentless-scan/outputs.tf @@ -1,5 +1,5 @@ output "agentless_scan_component_id" { value = "${sysdig_secure_cloud_auth_account_component.gcp_agentless_scan.type}/${sysdig_secure_cloud_auth_account_component.gcp_agentless_scan.instance}" - description = "Component identifier of Agentless Scan integration created in Sysdig Backend for Log Ingestion" + description = "Component identifier of Agentless Scan integration created in Sysdig Backend for VM" depends_on = [sysdig_secure_cloud_auth_account_component.gcp_agentless_scan] } \ No newline at end of file From 631363f1bdca5c304333eaeb6f460c5bff762a1b Mon Sep 17 00:00:00 2001 From: Jose Pablo Camacho Date: Mon, 16 Sep 2024 13:29:13 -0600 Subject: [PATCH 31/34] feat(vm): add vm modular support --- modules/agentless-scan/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/agentless-scan/README.md b/modules/agentless-scan/README.md index a844718..71074f0 100644 --- a/modules/agentless-scan/README.md +++ b/modules/agentless-scan/README.md @@ -67,6 +67,7 @@ No modules. | [google_organization.org](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/organization) | data source | | [google_project.project](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/project) | data source | | [sysdig_secure_trusted_cloud_identity.trusted_identity](https://registry.terraform.io/providers/sysdiglabs/sysdig/latest/docs/data-sources/secure_trusted_cloud_identity) | data source | +| [sysdig_secure_cloud_auth_account_component.gcp_agentless_scan](https://registry.terraform.io/providers/sysdiglabs/sysdig/latest/docs/resources/secure_cloud_auth_account_component) | resource | ## Inputs From 0dad0006025a6fc1ffb0f4eb51d4c251de9e2f45 Mon Sep 17 00:00:00 2001 From: Jose Pablo Camacho Date: Mon, 16 Sep 2024 16:42:20 -0600 Subject: [PATCH 32/34] delete some test files --- .../examples/organization_cdr_test/pub-sub.tf | 28 ------------------- .../single_account_cdr_test/pub-sub.tf | 26 ----------------- 2 files changed, 54 deletions(-) delete mode 100644 test/examples/organization_cdr_test/pub-sub.tf delete mode 100644 test/examples/single_account_cdr_test/pub-sub.tf diff --git a/test/examples/organization_cdr_test/pub-sub.tf b/test/examples/organization_cdr_test/pub-sub.tf deleted file mode 100644 index a8f0201..0000000 --- a/test/examples/organization_cdr_test/pub-sub.tf +++ /dev/null @@ -1,28 +0,0 @@ -#--------------------------------------------------------------------------------------------- -# Ensure installation flow for foundational onboarding has been completed before -# installing additional Sysdig features. -#--------------------------------------------------------------------------------------------- - -module "webhook-datasource" { - source = "../../../modules/integrations/pub-sub" - project_id = module.onboarding.project_id - is_organizational = module.onboarding.is_organizational - organization_domain = module.onboarding.organization_domain - sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id -} - -resource "sysdig_secure_cloud_auth_account_feature" "threat_detection" { - account_id = module.onboarding.sysdig_secure_account_id - type = "FEATURE_SECURE_THREAT_DETECTION" - enabled = true - components = [ module.webhook-datasource.webhook_datasource_component_id ] - depends_on = [ module.webhook-datasource ] -} - -resource "sysdig_secure_cloud_auth_account_feature" "identity_entitlement" { - account_id = module.onboarding.sysdig_secure_account_id - type = "FEATURE_SECURE_IDENTITY_ENTITLEMENT" - enabled = true - components = [module.webhook-datasource.webhook_datasource_component_id] - depends_on = [sysdig_secure_cloud_auth_account_feature.config_posture, sysdig_secure_cloud_auth_account_feature.threat_detection] -} \ No newline at end of file diff --git a/test/examples/single_account_cdr_test/pub-sub.tf b/test/examples/single_account_cdr_test/pub-sub.tf deleted file mode 100644 index 655ce2c..0000000 --- a/test/examples/single_account_cdr_test/pub-sub.tf +++ /dev/null @@ -1,26 +0,0 @@ -#--------------------------------------------------------------------------------------------- -# Ensure installation flow for foundational onboarding has been completed before -# installing additional Sysdig features. -#--------------------------------------------------------------------------------------------- - -module "webhook-datasource" { - source = "../../../modules/integrations/pub-sub" - project_id = module.onboarding.project_id - sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id -} - -resource "sysdig_secure_cloud_auth_account_feature" "threat_detection" { - account_id = module.onboarding.sysdig_secure_account_id - type = "FEATURE_SECURE_THREAT_DETECTION" - enabled = true - components = [ module.webhook-datasource.webhook_datasource_component_id ] - depends_on = [ module.webhook-datasource ] -} - -resource "sysdig_secure_cloud_auth_account_feature" "identity_entitlement" { - account_id = module.onboarding.sysdig_secure_account_id - type = "FEATURE_SECURE_IDENTITY_ENTITLEMENT" - enabled = true - components = [module.webhook-datasource.webhook_datasource_component_id] - depends_on = [sysdig_secure_cloud_auth_account_feature.config_posture, sysdig_secure_cloud_auth_account_feature.threat_detection] -} \ No newline at end of file From 332370f9120e76960b5c9848c47db79cb1c4cf6d Mon Sep 17 00:00:00 2001 From: Jose Pablo Camacho Date: Tue, 17 Sep 2024 14:16:55 -0600 Subject: [PATCH 33/34] feat(vm): modular vm feedback --- modules/agentless-scan/README.md | 1 - modules/agentless-scan/main.tf | 14 +++++++------- modules/agentless-scan/organizational.tf | 12 ++++++------ modules/agentless-scan/variables.tf | 6 ------ 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/modules/agentless-scan/README.md b/modules/agentless-scan/README.md index 71074f0..3c3cf22 100644 --- a/modules/agentless-scan/README.md +++ b/modules/agentless-scan/README.md @@ -76,7 +76,6 @@ No modules. | [project\_id](#input\_project\_id) | GCP Project ID | `string` | n/a | yes | | [is\_organizational](#input\_is\_organizational) | Optional. Determines whether module must scope whole organization. Otherwise single project will be scoped | `bool` | `false` | no | | [organization\_domain](#input\_organization\_domain) | Optional. If `is_organizational=true` is set, its mandatory to specify this value, with the GCP Organization domain. e.g. sysdig.com | `string` | `null` | no | -| [role\_name](#input\_role\_name) | Optional. Name for the Worker Role on the Customer infrastructure | `string` | `"SysdigAgentlessHostRole"` | no | | [sysdig\_account\_id](#input\_sysdig\_account\_id) | Sysdig provided GCP Account designated for the host scan.
One of `sysdig_backend` or `sysdig_account_id`must be provided | `string` | `null` | no | | [sysdig\_secure\_account\_id](#input\_sysdig\_secure\_account\_id) | ID of the Sysdig Cloud Account to enable Agentless Scanning integration for (in case of organization, ID of the Sysdig management account) | `string` | `null` | no | | [suffix](#input\_suffix) | Optional. Suffix word to enable multiple deployments with different naming
(Workload Identity Pool and Providers have a soft deletion on Google Platform that will disallow name re-utilization)
By default a random value will be autogenerated. | `string` | `null` | no | diff --git a/modules/agentless-scan/main.tf b/modules/agentless-scan/main.tf index 95b977c..b63511a 100644 --- a/modules/agentless-scan/main.tf +++ b/modules/agentless-scan/main.tf @@ -147,20 +147,20 @@ resource "google_service_account_iam_member" "controller_custom_gcp" { # Custom IAM roles and bindings #----------------------------------------------------------------------------------------- -resource "google_project_iam_custom_role" "controller" { +resource "google_project_iam_custom_role" "controller_role" { count = var.is_organizational ? 0 : 1 project = var.project_id - role_id = "${var.role_name}Discovery${local.suffix}" - title = "${var.role_name}, for Host Discovery" + role_id = "SysdigCloudVMDiscovery${local.suffix}" + title = "SysdigCloudVM, for Host Discovery" permissions = local.host_discovery_permissions } -resource "google_project_iam_binding" "controller_custom" { +resource "google_project_iam_binding" "controller_binding" { count = var.is_organizational ? 0 : 1 project = var.project_id - role = google_project_iam_custom_role.controller[0].id + role = google_project_iam_custom_role.controller_role[0].id members = [ "serviceAccount:${google_service_account.controller.email}", ] @@ -170,8 +170,8 @@ resource "google_project_iam_custom_role" "worker_role" { count = var.is_organizational ? 0 : 1 project = var.project_id - role_id = "${var.role_name}Scan${local.suffix}" - title = "${var.role_name}, for Host Scan" + role_id = "SysdigCloudVMScan${local.suffix}" + title = "SysdigCloudVM, for Host Scan" permissions = local.host_scan_permissions } diff --git a/modules/agentless-scan/organizational.tf b/modules/agentless-scan/organizational.tf index 8770cb5..60ca1a6 100644 --- a/modules/agentless-scan/organizational.tf +++ b/modules/agentless-scan/organizational.tf @@ -11,12 +11,12 @@ data "google_organization" "org" { # Custom IAM roles and bindings #----------------------------------------------------------------------------------------- -resource "google_organization_iam_custom_role" "controller" { +resource "google_organization_iam_custom_role" "controller_role" { count = var.is_organizational ? 1 : 0 org_id = data.google_organization.org[0].org_id - role_id = "${var.role_name}Discovery${title(local.suffix)}" - title = "${var.role_name}, for Host Discovery" + role_id = "SysdigCloudVMDiscovery${local.suffix}" + title = "SysdigCloudVM, for Host Discovery" permissions = local.host_discovery_permissions } @@ -24,7 +24,7 @@ resource "google_organization_iam_binding" "controller_custom" { count = var.is_organizational ? 1 : 0 org_id = data.google_organization.org[0].org_id - role = google_organization_iam_custom_role.controller[0].id + role = google_organization_iam_custom_role.controller_role[0].id members = [ "serviceAccount:${google_service_account.controller.email}", ] @@ -34,8 +34,8 @@ resource "google_organization_iam_custom_role" "worker_role" { count = var.is_organizational ? 1 : 0 org_id = data.google_organization.org[0].org_id - role_id = "${var.role_name}Scan${title(local.suffix)}" - title = "${var.role_name}, for Host Scan" + role_id = "SysdigCloudVMScan${local.suffix}" + title = "SysdigCloudVM, for Host Scan" permissions = local.host_scan_permissions } diff --git a/modules/agentless-scan/variables.tf b/modules/agentless-scan/variables.tf index 71d0586..8b2fb24 100644 --- a/modules/agentless-scan/variables.tf +++ b/modules/agentless-scan/variables.tf @@ -15,12 +15,6 @@ variable "organization_domain" { default = "" } -variable "role_name" { - type = string - description = "Name for Sysdig operations on discovery and scan role" - default = "SysdigCloudVM" -} - variable "sysdig_account_id" { type = string description = "Sysdig provided GCP Account designated for the host scan. One of sysdig_backend or sysdig_account_id must be provided" From d6e666676df3479f71655bff27027d11807c305a Mon Sep 17 00:00:00 2001 From: Jose Pablo Camacho Date: Tue, 17 Sep 2024 15:49:39 -0600 Subject: [PATCH 34/34] feat(vm): modular vm feedback --- modules/config-posture/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/config-posture/README.md b/modules/config-posture/README.md index a7ac3b5..8ad48fc 100644 --- a/modules/config-posture/README.md +++ b/modules/config-posture/README.md @@ -16,7 +16,7 @@ If instrumenting an Organziation, the following resources will be created: - A cloud account component in the Sysdig Backend, associated with the GCP project and with the required component to serve the config posture functions. Note: -- The outputs from the foundational module, such as `sysdig_secure_project_id` are needed as inputs to the other features/integrations modules for subsequent modular installs. +- The outputs from the foundational module, such as `sysdig_secure_account_id` are needed as inputs to the other features/integrations modules for subsequent modular installs. ## Requirements