Skip to content

Commit a7ab5bb

Browse files
authored
[SSPROD-48725] GCP modular onboarding for workload scanning (#48)
* Gcp modular onboarding for workload scanning * Fmt-fix * Adding constraint for sysdig * Corrections * Adding required version * comments from jose's code review * Fixes found during testing * Correcting service principal instance name * Last fix
1 parent bb8b7c5 commit a7ab5bb

File tree

13 files changed

+362
-0
lines changed

13 files changed

+362
-0
lines changed

modules/services/workload-scan/provider.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,9 @@ terraform {
1010
source = "hashicorp/random"
1111
version = ">= 3.1, < 4.0"
1212
}
13+
sysdig = {
14+
source = "sysdiglabs/sysdig"
15+
version = "~> 1.37"
16+
}
1317
}
1418
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# GCP VM Workload Scanning Module
2+
3+
This Module creates the resources required to perform agentless workload scanning operations in Google Cloud Platform (GCP). It sets up the necessary roles, service accounts, and workload identity providers to enable Sysdig to scan workloads running in GCP projects.
4+
5+
By default, it will create a service account with permissions necessary to access and access GAR and GCR repositories and pull their images.
6+
7+
The following resources will be created in each instrumented project:
8+
- A Service Account and associated roles that allow Sysdig to perform tasks necessary for VM agentless workload scanning, i.e., access GAR/GCR repositories and pull its images.
9+
- A Workload Identity Provider to facilitate secure authentication between GCP and Sysdig.
10+
11+
### Requirements
12+
13+
| Name | Version |
14+
|------|---------|
15+
| terraform | ~> 1.7 |
16+
| google | >= 4.50.0 |
17+
| sysdig | ~> 1.37 |
18+
19+
### Providers
20+
21+
| Name | Version |
22+
|------|---------|
23+
| google | >= 4.50.0 |
24+
| sysdig | ~> 1.37 |
25+
26+
### Modules
27+
28+
No modules.
29+
30+
### Resources
31+
32+
| Name | Type |
33+
|------|------|
34+
| google_service_account.controller | resource |
35+
| google_project_iam_member.controller | resource |
36+
| google_iam_workload_identity_pool.agentless | resource |
37+
| google_iam_workload_identity_pool_provider.agentless | resource |
38+
| google_iam_workload_identity_pool.agentless_gcp | resource |
39+
| google_iam_workload_identity_pool_provider.agentless_gcp | resource |
40+
| google_project.project | data source |
41+
42+
### Inputs
43+
44+
| Name | Description | Type | Default | Required |
45+
|------|----------------------------------------------------------------------------------------------------------------------------------|------|---------|:--------:|
46+
| project_id | GCP Project ID | string | n/a | yes |
47+
| is_organizational | Set this field to 'true' to deploy workload scanning to a GCP Organization. | bool | false | no |
48+
| organization_domain | (Optional) Organization domain. e.g. sysdig.com | string | "" | no |
49+
| role_name | Name for the Worker Role on the Customer infrastructure | string | "SysdigAgentlessWorkloadRole" | no |
50+
| sysdig_secure_account_id | ID of the Sysdig Cloud Account to enable VM Workload Scanning for (in case of organization, ID of the Sysdig management account) | string | n/a | yes |
51+
52+
### Outputs
53+
54+
| Name | Description |
55+
|------|-------------|
56+
| vm_workload_scanning_component_id | Component identifier of service principal created in Sysdig Backend for VM Workload Scanning |
57+
58+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
59+
60+
## Authors
61+
62+
Module is maintained by [Sysdig](https://sysdig.com).
63+
64+
## License
65+
66+
Apache 2 Licensed. See LICENSE for full details.
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
locals {
2+
suffix = random_id.suffix.hex
3+
}
4+
5+
resource "random_id" "suffix" {
6+
byte_length = 3
7+
}
8+
9+
data "google_project" "project" {
10+
project_id = var.project_id
11+
}
12+
13+
data "sysdig_secure_trusted_cloud_identity" "trusted_identity" {
14+
cloud_provider = "gcp"
15+
}
16+
17+
data "sysdig_secure_tenant_external_id" "external_id" {}
18+
19+
resource "google_service_account" "controller" {
20+
project = var.project_id
21+
account_id = "sysdig-ws-${local.suffix}"
22+
display_name = "Sysdig Agentless Workload Scanning"
23+
}
24+
25+
resource "google_project_iam_custom_role" "controller" {
26+
project = var.project_id
27+
role_id = "${var.role_name}WorkloadController${title(local.suffix)}"
28+
title = "Role for Sysdig Agentless Workload Controller"
29+
permissions = [
30+
# artifact registry reader permissions
31+
"artifactregistry.repositories.downloadArtifacts",
32+
"artifactregistry.repositories.get",
33+
"artifactregistry.repositories.list",
34+
"artifactregistry.dockerimages.get",
35+
"artifactregistry.dockerimages.list",
36+
"storage.objects.get",
37+
"storage.buckets.list",
38+
"storage.objects.list",
39+
40+
# workload identity federation
41+
"iam.serviceAccounts.getAccessToken",
42+
]
43+
}
44+
45+
resource "google_project_iam_binding" "controller_binding" {
46+
project = var.project_id
47+
role = google_project_iam_custom_role.controller.id
48+
49+
members = [
50+
"serviceAccount:${google_service_account.controller.email}",
51+
]
52+
}
53+
54+
resource "google_iam_workload_identity_pool" "agentless" {
55+
workload_identity_pool_id = "sysdig-wl-${local.suffix}"
56+
}
57+
58+
resource "google_iam_workload_identity_pool_provider" "agentless" {
59+
project = var.project_id
60+
workload_identity_pool_id = google_iam_workload_identity_pool.agentless.workload_identity_pool_id
61+
workload_identity_pool_provider_id = "sysdig-wl-${local.suffix}"
62+
display_name = "Sysdig Workload Controller"
63+
description = "AWS identity pool provider for Sysdig Secure Agentless Workload Scanning"
64+
disabled = false
65+
66+
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}\""
67+
68+
attribute_mapping = {
69+
"google.subject" = "assertion.arn",
70+
"attribute.aws_role" = "assertion.arn"
71+
}
72+
73+
aws {
74+
account_id = data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id
75+
}
76+
}
77+
78+
resource "google_service_account_iam_member" "controller_binding" {
79+
service_account_id = google_service_account.controller.name
80+
role = "roles/iam.workloadIdentityUser"
81+
member = "principalSet://iam.googleapis.com/projects/${data.google_project.project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.agentless.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}"
82+
}
83+
84+
85+
#--------------------------------------------------------------------------------------------------------------
86+
# Call Sysdig Backend to add the service-principal integration for VM Workload Scanning to the Sysdig Cloud Account
87+
#--------------------------------------------------------------------------------------------------------------
88+
resource "sysdig_secure_cloud_auth_account_component" "google_service_principal" {
89+
account_id = var.sysdig_secure_account_id
90+
type = "COMPONENT_SERVICE_PRINCIPAL"
91+
instance = "secure-vm-workload-scanning"
92+
version = "v0.1.0"
93+
service_principal_metadata = jsonencode({
94+
gcp = {
95+
workload_identity_federation = {
96+
pool_id = google_iam_workload_identity_pool.agentless.workload_identity_pool_id
97+
pool_provider_id = google_iam_workload_identity_pool_provider.agentless.workload_identity_pool_provider_id
98+
project_number = data.google_project.project.number
99+
}
100+
email = google_service_account.controller.email
101+
}
102+
})
103+
depends_on = [
104+
google_service_account.controller,
105+
google_project_iam_custom_role.controller,
106+
google_project_iam_binding.controller_binding,
107+
google_iam_workload_identity_pool.agentless,
108+
google_organization_iam_member.controller,
109+
]
110+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#--------------#
2+
# Organization #
3+
#--------------#
4+
5+
data "google_organization" "org" {
6+
count = var.is_organizational ? 1 : 0
7+
domain = var.organization_domain
8+
}
9+
10+
###################################################
11+
# Setup Service Account permissions
12+
###################################################
13+
14+
#---------------------------------------------------------------------------------------------
15+
# role permissions for CSPM (GCP Predefined Roles for Sysdig Cloud Secure Posture Management)
16+
#---------------------------------------------------------------------------------------------
17+
resource "google_organization_iam_member" "controller" {
18+
# adding ciem role with permissions to the service account alongside cspm roles
19+
for_each = var.is_organizational ? toset([
20+
"artifactregistry.repositories.downloadArtifacts",
21+
"artifactregistry.repositories.get",
22+
"artifactregistry.repositories.list",
23+
"artifactregistry.dockerimages.get",
24+
"artifactregistry.dockerimages.list",
25+
"storage.objects.get",
26+
"storage.buckets.list",
27+
"storage.objects.list",
28+
29+
# workload identity federation
30+
"iam.serviceAccounts.getAccessToken"]) : []
31+
32+
org_id = data.google_organization.org[0].org_id
33+
role = each.key
34+
member = "serviceAccount:${google_service_account.controller.email}"
35+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
output "vm_workload_scanning_component_id" {
2+
value = "${sysdig_secure_cloud_auth_account_component.google_service_principal.type}/${sysdig_secure_cloud_auth_account_component.google_service_principal.instance}"
3+
description = "Component identifier of service principal created in Sysdig Backend for VM Workload Scanning"
4+
depends_on = [sysdig_secure_cloud_auth_account_component.google_service_principal]
5+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
variable "project_id" {
2+
type = string
3+
description = "GCP Project ID"
4+
}
5+
6+
variable "is_organizational" {
7+
type = bool
8+
description = "Set this field to 'true' to deploy workload scanning to a GCP Organization."
9+
default = false
10+
}
11+
12+
variable "organization_domain" {
13+
type = string
14+
description = "(Optional) Organization domain. e.g. sysdig.com"
15+
default = false
16+
}
17+
18+
# optionals
19+
variable "role_name" {
20+
type = string
21+
description = "Name for the Worker Role on the Customer infrastructure"
22+
default = "SysdigAgentlessWorkloadRole"
23+
}
24+
25+
variable "sysdig_secure_account_id" {
26+
type = string
27+
description = "ID of the Sysdig Cloud Account to enable Config Posture for (in case of organization, ID of the Sysdig management account)"
28+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
terraform {
2+
required_version = ">=1.0"
3+
4+
required_providers {
5+
google = {
6+
source = "hashicorp/google"
7+
version = ">= 4.21.0"
8+
}
9+
random = {
10+
source = "hashicorp/random"
11+
version = ">= 3.1, < 4.0"
12+
}
13+
sysdig = {
14+
source = "sysdiglabs/sysdig"
15+
version = "~> 1.37"
16+
}
17+
}
18+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
module "vm_workload_scanning" {
2+
source = "../../../modules/vm-workload-scanning"
3+
4+
project_id = module.onboarding.project_id
5+
is_organizational = module.onboarding.is_organizational
6+
organization_domain = module.onboarding.organization_domain
7+
sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id
8+
}
9+
10+
11+
resource "sysdig_secure_cloud_auth_account_feature" "config_cloud_run" {
12+
account_id = module.onboarding.sysdig_secure_account_id
13+
type = "FEATURE_SECURE_WORKLOAD_SCANNING_CONTAINERS"
14+
enabled = true
15+
components = [module.vm_workload_scanning.vm_workload_scanning_component_id]
16+
depends_on = [module.vm_workload_scanning]
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
module "vm_workload_scanning" {
2+
source = "../../../modules/vm-workload-scanning"
3+
4+
project_id = module.onboarding.project_id
5+
is_organizational = module.onboarding.is_organizational
6+
organization_domain = module.onboarding.organization_domain
7+
sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id
8+
}
9+
10+
11+
resource "sysdig_secure_cloud_auth_account_feature" "config_functions" {
12+
account_id = module.onboarding.sysdig_secure_account_id
13+
type = "FEATURE_SECURE_WORKLOAD_SCANNING_FUNCTIONS"
14+
enabled = true
15+
components = [module.vm_workload_scanning.vm_workload_scanning_component_id]
16+
depends_on = [module.vm_workload_scanning]
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
module "vm_workload_scanning" {
2+
source = "../../../modules/vm-workload-scanning"
3+
4+
project_id = module.onboarding.project_id
5+
is_organizational = module.onboarding.is_organizational
6+
organization_domain = module.onboarding.organization_domain
7+
sysdig_secure_account_id = module.onboarding.sysdig_secure_account_id
8+
}
9+
10+
11+
resource "sysdig_secure_cloud_auth_account_feature" "config_gke" {
12+
account_id = module.onboarding.sysdig_secure_account_id
13+
type = "FEATURE_SECURE_WORKLOAD_SCANNING_KUBERNETES"
14+
enabled = true
15+
components = [module.vm_workload_scanning.vm_workload_scanning_component_id]
16+
depends_on = [module.vm_workload_scanning]
17+
}

0 commit comments

Comments
 (0)