Skip to content

Commit 15672c7

Browse files
Add modular foundational support for GCP (#36)
* 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 * add explicit dependency * switch to svc principal key for onboarding * rm unnecessary binding in config posture * update READMEs and var defns * rm management group ids in config posture * set right sysdig versions
1 parent 51f00b7 commit 15672c7

File tree

14 files changed

+597
-0
lines changed

14 files changed

+597
-0
lines changed

modules/config-posture/README.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# GCP Config Posture Module
2+
3+
This module will deploy Config Posture resources in GCP for a single project, or for a GCP Organization.
4+
The Config Posture module serves the following functions:
5+
- retrieving inventory for single project, or for all projects within an Organization.
6+
- retrieving organization metadata in the case of organizational onboarding within GCP Organization.
7+
8+
If instrumenting a project, the following resources will be created:
9+
- All the necessary `Service Accounts` and `Policies` to enable the Config posture operation at the project level
10+
- 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.
11+
- A cloud account component in the Sysdig Backend, associated with the GCP project and with the required component to serve the config posture functions.
12+
13+
If instrumenting an Organziation, the following resources will be created:
14+
- All the necessary `Service Accounts` and `Policies` to enable the Config Posture operation at the organization level
15+
- 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.
16+
- A cloud account component in the Sysdig Backend, associated with the GCP project and with the required component to serve the config posture functions.
17+
18+
Note:
19+
- 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.
20+
21+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
22+
## Requirements
23+
24+
| Name | Version |
25+
|------|-----------|
26+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0.0 |
27+
| <a name="requirement_google"></a> [google](#requirement\_google) | >= 4.21.0 |
28+
| <a name="requirement_sysdig"></a> [sysdig](#requirement\_sysdig) | >= 1.34.0 |
29+
30+
## Providers
31+
32+
| Name | Version |
33+
|------|---------|
34+
| <a name="provider_google"></a> [google](#provider\_google) | 5.0.0 |
35+
| <a name="provider_random"></a> [random](#provider\_random) | >= 3.1 |
36+
37+
## Modules
38+
39+
No modules.
40+
41+
## Resources
42+
43+
| [google_service_account.posture_auth](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account) | resource |
44+
| [google_organization.org](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/organization) | data source |
45+
| [sysdig_secure_trusted_cloud_identity.trusted_identity](https://registry.terraform.io/providers/sysdiglabs/sysdig/latest/docs/data-sources/secure_trusted_cloud_identity) | data source |
46+
| [google_project.project](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/project) | data source |
47+
| [sysdig_secure_tenant_external_id](https://registry.terraform.io/providers/sysdiglabs/sysdig/latest/docs/data-sources/secure_tenant_external_id) | data source |
48+
| [random_id.suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource |
49+
| [google_iam_workload_identity_pool.posture_auth_pool](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/iam_workload_identity_pool) | resource |
50+
| [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 |
51+
| [google_project_iam_member.cspm](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_iam#google_project_iam_member) | resource |
52+
| [google_service_account_iam_member.custom_posture_auth](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_service_account_iam#google_service_account_iam_member) | resource |
53+
| [google_organization_iam_member.cspm](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_organization_iam#google_organization_iam_member) | resource |
54+
| [sysdig_secure_cloud_auth_account_component.google_service_principal](https://registry.terraform.io/providers/sysdiglabs/sysdig/latest/docs/resources/secure_cloud_auth_account_component) | resource |
55+
56+
## Inputs
57+
58+
| Name | Description | Type | Default | Required |
59+
|------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|------|-----------------------------------------------|:--------:|
60+
| <a name="input_is_organizational"></a> [is\_organizational](#input\_is\_organizational) | (Optional) Set this field to 'true' to deploy secure-for-cloud to a GCP Organization. | `bool` | `false` | no |
61+
| <a name="input_organization_domain"></a> [organization\_domain](#input\_organization\_domain) | Organization domain. e.g. sysdig.com | `string` | `""` | no |
62+
| <a name="input_project_id"></a> [project\_id](#input\_project\_id) | (Required) Target Project identifier provided by the customer | `string` | n/a | yes |
63+
| <a name="input_suffix"></a> [suffix](#input\_suffix) | (Optional) Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated | `string` | `null` | no |
64+
| <a name="input_sysdig_secure_account_id"></a> [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 |
65+
66+
## Outputs
67+
68+
| Name | Description |
69+
|--------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------|
70+
| <a name="output_service_principal_component_id"></a> [service\_principal\_component\_id](#output\_service\_principal\_component\_id) | The component id of the config posture service principal with its WIF metadata |
71+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
72+
73+
## Authors
74+
75+
Module is maintained by [Sysdig](https://sysdig.com).
76+
77+
## License
78+
79+
Apache 2 Licensed. See LICENSE for full details.

modules/config-posture/main.tf

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#------------------------------------------------------------------#
2+
# Fetch and compute required data for Workload Identity Federation #
3+
#------------------------------------------------------------------#
4+
5+
data "sysdig_secure_trusted_cloud_identity" "trusted_identity" {
6+
cloud_provider = "gcp"
7+
}
8+
9+
data "sysdig_secure_tenant_external_id" "external_id" {}
10+
11+
data "google_project" "project" {
12+
project_id = var.project_id
13+
}
14+
15+
// suffix to uniquely identify WIF pool and provider during multiple installs. If suffix value is not provided, this will generate a random value.
16+
resource "random_id" "suffix" {
17+
count = var.suffix == null ? 1 : 0
18+
byte_length = 3
19+
}
20+
21+
locals {
22+
suffix = var.suffix == null ? random_id.suffix[0].hex : var.suffix
23+
}
24+
25+
resource "google_service_account" "posture_auth" {
26+
# service account name cannot be longer than 30 characters
27+
account_id = "sysdig-posture-${local.suffix}"
28+
display_name = "Sysdig Config Posture Auth Service Account"
29+
project = var.project_id
30+
}
31+
32+
#------------------------------------------------------------#
33+
# Configure Workload Identity Federation for auth #
34+
# See https://cloud.google.com/iam/docs/access-resources-aws #
35+
#------------------------------------------------------------#
36+
37+
resource "google_iam_workload_identity_pool" "posture_auth_pool" {
38+
project = var.project_id
39+
workload_identity_pool_id = "sysdig-secure-posture-${local.suffix}"
40+
}
41+
42+
resource "google_iam_workload_identity_pool_provider" "posture_auth_pool_provider" {
43+
project = var.project_id
44+
workload_identity_pool_id = google_iam_workload_identity_pool.posture_auth_pool.workload_identity_pool_id
45+
workload_identity_pool_provider_id = "sysdig-posture-${local.suffix}"
46+
display_name = "Sysdigcloud config posture auth"
47+
description = "AWS based pool provider for Sysdig Secure Data Config Posture resources"
48+
disabled = false
49+
50+
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}\""
51+
52+
attribute_mapping = {
53+
"google.subject" = "assertion.arn",
54+
"attribute.aws_role" = "assertion.arn"
55+
}
56+
57+
aws {
58+
account_id = data.sysdig_secure_trusted_cloud_identity.trusted_identity.aws_account_id
59+
}
60+
}
61+
62+
#---------------------------------------------------------------------------------------------
63+
# role permissions for CSPM (GCP Predefined Roles for Sysdig Cloud Secure Posture Management)
64+
#---------------------------------------------------------------------------------------------
65+
resource "google_project_iam_member" "cspm" {
66+
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"])
67+
68+
project = var.project_id
69+
role = each.key
70+
member = "serviceAccount:${google_service_account.posture_auth.email}"
71+
}
72+
73+
# attaching WIF as a member to the service account for auth
74+
resource "google_service_account_iam_member" "custom_posture_auth" {
75+
service_account_id = google_service_account.posture_auth.name
76+
role = "roles/iam.workloadIdentityUser"
77+
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}"
78+
}
79+
80+
#--------------------------------------------------------------------------------------------------------------
81+
# Call Sysdig Backend to add the service-principal integration for Config Posture to the Sysdig Cloud Account
82+
#--------------------------------------------------------------------------------------------------------------
83+
resource "sysdig_secure_cloud_auth_account_component" "google_service_principal" {
84+
account_id = var.sysdig_secure_account_id
85+
type = "COMPONENT_SERVICE_PRINCIPAL"
86+
instance = "secure-posture"
87+
version = "v0.1.0"
88+
service_principal_metadata = jsonencode({
89+
gcp = {
90+
workload_identity_federation = {
91+
pool_id = google_iam_workload_identity_pool.posture_auth_pool.workload_identity_pool_id
92+
pool_provider_id = google_iam_workload_identity_pool_provider.posture_auth_pool_provider.workload_identity_pool_provider_id
93+
project_number = data.google_project.project.number
94+
}
95+
email = google_service_account.posture_auth.email
96+
}
97+
})
98+
depends_on = [
99+
google_service_account.posture_auth,
100+
google_iam_workload_identity_pool.posture_auth_pool,
101+
google_iam_workload_identity_pool_provider.posture_auth_pool_provider,
102+
google_project_iam_member.cspm,
103+
google_service_account_iam_member.custom_posture_auth
104+
]
105+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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" "cspm" {
18+
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"]) : []
19+
20+
org_id = data.google_organization.org[0].org_id
21+
role = each.key
22+
member = "serviceAccount:${google_service_account.posture_auth.email}"
23+
}

modules/config-posture/outputs.tf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
output "service_principal_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 Config Posture"
4+
depends_on = [sysdig_secure_cloud_auth_account_component.google_service_principal]
5+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
variable "project_id" {
2+
type = string
3+
description = "(Required) Target Project identifier provided by the customer"
4+
}
5+
6+
variable "is_organizational" {
7+
description = "(Optional) Set this field to 'true' to deploy secure-for-cloud to a GCP Organization."
8+
type = bool
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+
variable "suffix" {
19+
type = string
20+
description = "Suffix to uniquely identify resources during multiple installs. If not provided, random value is autogenerated"
21+
default = null
22+
}
23+
24+
variable "sysdig_secure_account_id" {
25+
type = string
26+
description = "ID of the Sysdig Cloud Account to enable Config Posture for (in case of organization, ID of the Sysdig management account)"
27+
}

modules/config-posture/versions.tf

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.0"
3+
4+
required_providers {
5+
google = {
6+
source = "hashicorp/google"
7+
version = ">= 4.21.0"
8+
}
9+
sysdig = {
10+
source = "sysdiglabs/sysdig"
11+
version = ">= 1.34.0"
12+
}
13+
random = {
14+
source = "hashicorp/random"
15+
version = ">= 3.1"
16+
}
17+
}
18+
}

0 commit comments

Comments
 (0)