-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(vm): add vm modular support (#39)
* feat(modular): add modular support for cdr/ciem * feat(modular): add modular support for cdr/ciem * feat(modular): add modular support for cdr/ciem * feat(modular): add modular support for cdr/ciem * feat(modular): add modular support for cdr/ciem * feat(modular): address feedback for modular support for cdr/ciem * adding modular onboarding module * fix var refns * adding modular onboarding example * adding config posture module for modular onboarding * updating README * fix role naming & version metadata * updating examples for onboarding & cspm org * cleanup foundational READMEs * use external_id datasource * update README * remove mgmt_group_ids in cspm module * bump sysdig provider version to be consistent & have latest datasources * updating examples * update example * feat(modular): address feedback for modular support for cdr/ciem, rebase and cleanup * feat(modular): address feedback for modular support for cdr/ciem, rebase and cleanup * add explicit dependency * feat(modular): address feedback for modular support for cdr/ciem, rebase and cleanup * feat(modular): address feedback for modular support for cdr/ciem, rebase and cleanup * feat(modular): address feedback for modular support for cdr/ciem, rebase and cleanup * feat(vm): add vm modular support * feat(vm): add vm modular support * feat(modular): add vm modular support * feat(vm): add vm modular support * feat(vm): add vm modular support * delete some test files * feat(vm): modular vm feedback * feat(vm): modular vm feedback --------- Co-authored-by: Haresh Suresh <[email protected]>
- Loading branch information
1 parent
e35f083
commit d8e8da8
Showing
8 changed files
with
447 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 VM 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=<domain>`. | ||
![permission_diagram_org](./permissions_diagram_org.png) | ||
|
||
## Requirements | ||
|
||
| Name | Version | | ||
|---------------------------------------------------------------------------|-----------| | ||
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 | | ||
| <a name="requirement_google"></a> [google](#requirement\_google) | >= 4.21.0 | | ||
| <a name="requirement_sysdig"></a> [sysdig](#requirement\_sysdig) | >= 1.34.0 | | ||
| <a name="requirement_random"></a> [random](#requirement\_random) | >= 3.1 | | ||
|
||
## Providers | ||
|
||
| Name | Version | | ||
|---------------------------------------------------------------------------|-----------| | ||
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 | | ||
| <a name="requirement_google"></a> [google](#requirement\_google) | >= 4.21.0 | | ||
| <a name="requirement_sysdig"></a> [sysdig](#requirement\_sysdig) | >= 1.34.0 | | ||
| <a name="requirement_random"></a> [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 | | ||
| [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 | ||
|
||
| Name | Description | Type | Default | Required | | ||
|----------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------|-----------------------------|:--------:| | ||
| <a name="input_project_id"></a> [project\_id](#input\_project\_id) | GCP Project ID | `string` | n/a | yes | | ||
| <a name="input_is_organizational"></a> [is\_organizational](#input\_is\_organizational) | Optional. Determines whether module must scope whole organization. Otherwise single project will be scoped | `bool` | `false` | no | | ||
| <a name="input_organization_domain"></a> [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 | | ||
| <a name="input_sysdig_account_id"></a> [sysdig\_account\_id](#input\_sysdig\_account\_id) | Sysdig provided GCP Account designated for the host scan.<br/>One of `sysdig_backend` or `sysdig_account_id`must be provided | `string` | `null` | no | | ||
| <a name="input_sysdig_secure_account_id"></a> [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 | | ||
| <a name="input_suffix"></a> [suffix](#input\_suffix) | Optional. Suffix word to enable multiple deployments with different naming<br/>(Workload Identity Pool and Providers have a soft deletion on Google Platform that will disallow name re-utilization)<br/>By default a random value will be autogenerated. | `string` | `null` | no | | ||
|
||
## Outputs | ||
|
||
| Name | Description | | ||
|--------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------| | ||
| <a name="agentless_scan_component_id"></a> [agentless\_scan\_component\_id](#agentless\_scan\_component\_id) | Component identifier of Agentless Scan integration created in Sysdig Backend for VM | | ||
|
||
## Authors | ||
|
||
Module is maintained by [Sysdig](https://sysdig.com). | ||
|
||
## License | ||
|
||
Apache 2 Licensed. See LICENSE for full details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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_role" { | ||
count = var.is_organizational ? 0 : 1 | ||
|
||
project = var.project_id | ||
role_id = "SysdigCloudVMDiscovery${local.suffix}" | ||
title = "SysdigCloudVM, for Host Discovery" | ||
permissions = local.host_discovery_permissions | ||
} | ||
|
||
resource "google_project_iam_binding" "controller_binding" { | ||
count = var.is_organizational ? 0 : 1 | ||
|
||
project = var.project_id | ||
role = google_project_iam_custom_role.controller_role[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 = "SysdigCloudVMScan${local.suffix}" | ||
title = "SysdigCloudVM, 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 | ||
} | ||
}) | ||
} |
Oops, something went wrong.