Skip to content

Commit 40ba206

Browse files
committed
Gcp modular onboarding for workload scanning
1 parent 03359e9 commit 40ba206

File tree

14 files changed

+352
-0
lines changed

14 files changed

+352
-0
lines changed
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 Config Posture 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: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
data "sysdig_secure_trusted_cloud_identity" "trusted_identity" {
2+
cloud_provider = "gcp"
3+
}
4+
5+
6+
resource "google_service_account" "controller" {
7+
project = var.project_id
8+
account_id = "sysdig-ws-${local.suffix}"
9+
display_name = "Sysdig Agentless Workload Scanning"
10+
}
11+
12+
resource "google_project_iam_custom_role" "controller" {
13+
project = var.project_id
14+
role_id = "${var.role_name}WorkloadController${title(local.suffix)}"
15+
title = "Role for Sysdig Agentless Workload Controller"
16+
permissions = [
17+
# artifact registry reader permissions
18+
"artifactregistry.repositories.downloadArtifacts",
19+
"artifactregistry.repositories.get",
20+
"artifactregistry.repositories.list",
21+
"artifactregistry.dockerimages.get",
22+
"artifactregistry.dockerimages.list",
23+
"storage.objects.get",
24+
"storage.buckets.list",
25+
"storage.objects.list",
26+
27+
# workload identity federation
28+
"iam.serviceAccounts.getAccessToken",
29+
]
30+
}
31+
32+
resource "google_project_iam_binding" "controller_custom" {
33+
project = var.project_id
34+
role = google_project_iam_custom_role.controller.id
35+
36+
members = [
37+
"serviceAccount:${google_service_account.controller.email}",
38+
]
39+
}
40+
41+
resource "google_iam_workload_identity_pool" "agentless" {
42+
workload_identity_pool_id = "sysdig-wl-${local.suffix}"
43+
}
44+
45+
resource "google_iam_workload_identity_pool_provider" "agentless" {
46+
workload_identity_pool_id = google_iam_workload_identity_pool.agentless.workload_identity_pool_id
47+
workload_identity_pool_provider_id = "sysdig-wl-${local.suffix}"
48+
display_name = "Sysdig Workload Controller"
49+
description = "AWS identity pool provider for Sysdig Secure Agentless Workload Scanning"
50+
disabled = false
51+
52+
attribute_condition = "attribute.aws_account==\"${data.sysdig_secure_trusted_cloud_identity.trusted_identity}\""
53+
54+
attribute_mapping = {
55+
"google.subject" = "assertion.arn"
56+
"attribute.aws_account" = "assertion.account"
57+
"attribute.role" = "assertion.arn.extract(\"/assumed-role/{role}/\")"
58+
"attribute.session" = "assertion.arn.extract(\"/assumed-role/{role_and_session}/\").extract(\"/{session}\")"
59+
}
60+
61+
aws {
62+
account_id = data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id
63+
}
64+
}
65+
66+
resource "google_service_account_iam_member" "controller_custom" {
67+
service_account_id = google_service_account.controller.name
68+
role = "roles/iam.workloadIdentityUser"
69+
member = "principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.agentless.name}/attribute.aws_account/${data.sysdig_secure_trusted_cloud_identity.trusted_identity}"
70+
}
71+
72+
73+
#--------------------------------------------------------------------------------------------------------------
74+
# Call Sysdig Backend to add the service-principal integration for Config Posture to the Sysdig Cloud Account
75+
#--------------------------------------------------------------------------------------------------------------
76+
resource "sysdig_secure_cloud_auth_account_component" "google_service_principal" {
77+
account_id = var.sysdig_secure_account_id
78+
type = "COMPONENT_SERVICE_PRINCIPAL"
79+
instance = "secure-posture"
80+
version = "v0.1.0"
81+
service_principal_metadata = jsonencode({
82+
gcp = {
83+
workload_identity_federation = {
84+
pool_id = google_iam_workload_identity_pool.agentless.workload_identity_pool_id
85+
pool_provider_id = google_iam_workload_identity_pool_provider.agentless.workload_identity_pool_provider_id
86+
project_number = data.google_project.project.number
87+
}
88+
email = google_service_account.controller.email
89+
}
90+
})
91+
depends_on = [
92+
google_service_account.controller,
93+
google_project_iam_custom_role.controller,
94+
google_project_iam_binding.controller_custom,
95+
google_iam_workload_identity_pool.agentless,
96+
google_organization_iam_member.controller,
97+
]
98+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
data "google_project" "project" {
2+
project_id = var.project_id
3+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
locals {
2+
suffix = random_id.suffix[0].hex
3+
}
4+
5+
resource "random_id" "suffix" {
6+
byte_length = 3
7+
}
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: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
terraform {
2+
required_version = ">=1.0"
3+
4+
required_providers {
5+
google = {
6+
source = "hashicorp/google"
7+
version = ">= 4.1, < 5.0"
8+
}
9+
random = {
10+
source = "hashicorp/random"
11+
version = ">= 3.1, < 4.0"
12+
}
13+
}
14+
}
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 = ""
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: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
module "vm_workload_scanning" {
2+
source = "sysdiglabs/secure/google//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 = "sysdiglabs/secure/google//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+
}

0 commit comments

Comments
 (0)