Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(modular): add modular support for cdr/ciem #35

Merged
merged 35 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
5862307
feat(modular): add modular support for cdr/ciem
jose-pablo-camacho Sep 5, 2024
285d3ab
feat(modular): add modular support for cdr/ciem
jose-pablo-camacho Sep 5, 2024
86f419c
feat(modular): add modular support for cdr/ciem
jose-pablo-camacho Sep 5, 2024
5ff322f
feat(modular): add modular support for cdr/ciem
jose-pablo-camacho Sep 5, 2024
519d695
feat(modular): add modular support for cdr/ciem
jose-pablo-camacho Sep 5, 2024
72b6314
feat(modular): address feedback for modular support for cdr/ciem
jose-pablo-camacho Sep 10, 2024
f7be89a
Merge branch 'master' into feat/modular/cdr-ciem
jose-pablo-camacho Sep 10, 2024
e51c02d
adding modular onboarding module
haresh-suresh Sep 4, 2024
80b782a
fix var refns
haresh-suresh Sep 5, 2024
6795442
adding modular onboarding example
haresh-suresh Sep 5, 2024
7a07625
adding config posture module for modular onboarding
haresh-suresh Sep 5, 2024
5581c6a
updating README
haresh-suresh Sep 5, 2024
4abc7b2
fix role naming & version metadata
haresh-suresh Sep 5, 2024
b4d8e07
updating examples for onboarding & cspm org
haresh-suresh Sep 5, 2024
e9a212d
cleanup foundational READMEs
haresh-suresh Sep 5, 2024
2885ccc
use external_id datasource
haresh-suresh Sep 6, 2024
628a2d6
update README
haresh-suresh Sep 6, 2024
211a8de
remove mgmt_group_ids in cspm module
haresh-suresh Sep 6, 2024
ec938f0
bump sysdig provider version to be consistent & have latest datasources
haresh-suresh Sep 10, 2024
b37fe73
updating examples
haresh-suresh Sep 10, 2024
99b4062
update example
haresh-suresh Sep 10, 2024
af3f570
feat(modular): address feedback for modular support for cdr/ciem, re…
jose-pablo-camacho Sep 10, 2024
70263ab
feat(modular): address feedback for modular support for cdr/ciem, re…
jose-pablo-camacho Sep 10, 2024
dfd45da
add explicit dependency
haresh-suresh Sep 11, 2024
e834d16
feat(modular): address feedback for modular support for cdr/ciem, re…
jose-pablo-camacho Sep 11, 2024
9acee0d
Merge branch 'master' into feat/modular/cdr-ciem
jose-pablo-camacho Sep 11, 2024
72aafe0
feat(modular): address feedback for modular support for cdr/ciem, re…
jose-pablo-camacho Sep 11, 2024
4d60c2d
feat(modular): address feedback for modular support for cdr/ciem, re…
jose-pablo-camacho Sep 11, 2024
0af9292
feat(modular): address feedback for modular support for cdr/ciem, re…
jose-pablo-camacho Sep 13, 2024
d5c0e11
feat(modular): address feedback for modular support for cdr/ciem, re…
jose-pablo-camacho Sep 16, 2024
c0ede5f
feat(modular): address feedback for modular support for cdr/ciem, re…
jose-pablo-camacho Sep 16, 2024
30d4786
feat(modular): address feedback for modular support for cdr/ciem, re…
jose-pablo-camacho Sep 17, 2024
634ce2a
enhance(modular): use org domain instead of org ID for gcp api enable…
jose-pablo-camacho Sep 16, 2024
1a26d8f
Merge branch 'master' into feat/modular/cdr-ciem
jose-pablo-camacho Sep 17, 2024
11655a0
rebase and merge fix
jose-pablo-camacho Sep 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions modules/config-posture/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# 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.

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0.0 |
| <a name="requirement_google"></a> [google](#requirement\_google) | >= 4.21.0 |
| <a name="requirement_sysdig"></a> [sysdig](#requirement\_sysdig) | >= 1.23.1 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_google"></a> [google](#provider\_google) | 5.0.0 |
| <a name="provider_random"></a> [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 |
|------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|------|-----------------------------------------------|:--------:|
| <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 |
| <a name="input_organization_domain"></a> [organization\_domain](#input\_organization\_domain) | Organization domain. e.g. sysdig.com | `string` | `""` | no |
| <a name="input_project_id"></a> [project\_id](#input\_project\_id) | (Required) Target Project identifier provided by the customer | `string` | n/a | yes |
| <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 |
| <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 |
| <a name="input_management_group_ids"></a> [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

| Name | Description |
|--------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------|
| <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 |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

## Authors

Module is maintained by [Sysdig](https://sysdig.com).

## License

Apache 2 Licensed. See LICENSE for full details.
108 changes: 108 additions & 0 deletions modules/config-posture/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#------------------------------------------------------------------#
# Fetch and compute required data for Workload Identity Federation #
#------------------------------------------------------------------#

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
}

// 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" {
# 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
}

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-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}"
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}/${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
}
}

#---------------------------------------------------------------------------------------------
# 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_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}/${data.sysdig_secure_tenant_external_id.external_id.external_id}"
}

#--------------------------------------------------------------------------------------------------------------
# Call Sysdig Backend to add the service-principal integration for Config Posture to the Sysdig Cloud Account
#--------------------------------------------------------------------------------------------------------------
resource "sysdig_secure_cloud_auth_account_component" "google_service_principal" {
account_id = var.sysdig_secure_account_id
type = "COMPONENT_SERVICE_PRINCIPAL"
instance = "secure-posture"
version = "v0.1.0"
service_principal_metadata = jsonencode({
gcp = {
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]
}
23 changes: 23 additions & 0 deletions modules/config-posture/organizational.tf
Original file line number Diff line number Diff line change
@@ -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}"
}
5 changes: 5 additions & 0 deletions modules/config-posture/outputs.tf
Original file line number Diff line number Diff line change
@@ -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]
}
27 changes: 27 additions & 0 deletions modules/config-posture/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
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 "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)"
}
18 changes: 18 additions & 0 deletions modules/config-posture/versions.tf
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
Loading
Loading