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

New SecOps blueprints section and SecOps GKE Forwarder #2514

Merged
merged 16 commits into from
Nov 5, 2024
Merged
3 changes: 2 additions & 1 deletion blueprints/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Terraform end-to-end blueprints for Google Cloud

This section provides **[networking blueprints](./networking/)** that implement core patterns or features, **[data solutions blueprints](./data-solutions/)** that demonstrate how to integrate data services in complete scenarios, **[cloud operations blueprints](./cloud-operations/)** that leverage specific products to meet specific operational needs, **[GKE](./gke/)** and **[Serverless](./serverless/)** blueprints, and **[factories](./factories/)** that implement resource factories for the repetitive creation of specific resources.
This section provides **[networking blueprints](./networking/)** that implement core patterns or features, **[data solutions blueprints](./data-solutions/)** that demonstrate how to integrate data services in complete scenarios, **[cloud operations blueprints](./cloud-operations/)** that leverage specific products to meet specific operational needs, **[GKE](./gke/)**, **[SecOps](./secops/)** security blueprints, **[Serverless](./serverless/)** blueprints, and **[factories](./factories/)** that implement resource factories for the repetitive creation of specific resources.

Currently available blueprints:

Expand All @@ -10,6 +10,7 @@ Currently available blueprints:
- **factories** - [Fabric resource factories](./factories)
- **GKE** - [Binary Authorization Pipeline Blueprint](./gke/binauthz), [Storage API](./gke/binauthz/image), [Multi-cluster mesh on GKE (fleet API)](./gke/multi-cluster-mesh-gke-fleet-api), [GKE Multitenant Blueprint](./gke/multitenant-fleet), [Shared VPC with GKE support](./networking/shared-vpc-gke/), [GKE Autopilot](./gke/autopilot)
- **networking** - [Calling a private Cloud Function from On-premises](./networking/private-cloud-function-from-onprem), [HA VPN over Interconnect](./networking/ha-vpn-over-interconnect/), [GLB and multi-regional daisy-chaining through hybrid NEGs](./networking/glb-hybrid-neg-internal), [Hybrid connectivity to on-premise services through PSC](./networking/psc-hybrid), [HTTP Load Balancer with Cloud Armor](./networking/glb-and-armor), [Internal Load Balancer as Next Hop](./networking/ilb-next-hop), On-prem DNS and Google Private Access, [PSC Producer](./networking/psc-hybrid/psc-producer), [PSC Consumer](./networking/psc-hybrid/psc-consumer), [Shared VPC with optional GKE cluster](./networking/shared-vpc-gke), [VPC Connectivity Lab](./networking/vpc-connectivity-lab/)
- **SecOps** - [SecOps GKE Forwarder](./secops/secops-gke-forwarder)
- **serverless** - [Cloud Run series](./serverless/cloud-run-explore)
- **third party solutions** - [OpenShift on GCP user-provisioned infrastructure](./third-party-solutions/openshift), [Wordpress deployment on Cloud Run](./third-party-solutions/wordpress/cloudrun)

Expand Down
9 changes: 9 additions & 0 deletions blueprints/secops/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Operations blueprints

This repository provides a collection of Terraform blueprints designed to automate the implementation of custom integrations, agents and configurations for Google Cloud Security and Operations SecOps (aka Chronicle).

## SecOps GKE Forwarder

<a href="./secops-gke-forwarder/" title="SecOps GKE Forwarder"><img src="./secops-gke-forwarder/images/diagram.png" align="left" width="280px"></a> This [blueprint](./secops-gke-forwarder/) is a modular and scalable solution for setting up a SecOps forwarder on Google Kubernetes Engine (GKE). This forwarder is designed to handle multi-tenant data ingestion, ensuring secure and efficient log forwarding to your SecOps SIEM instances.

<br clear="left">
1 change: 1 addition & 0 deletions blueprints/secops/secops-gke-forwarder/OWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
simonebruzzechesse
201 changes: 201 additions & 0 deletions blueprints/secops/secops-gke-forwarder/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
# SecOps GKE Forwarder

This Terraform repository provides a modular and scalable solution for setting up a SecOps forwarder on Google Kubernetes Engine (GKE). This forwarder is designed to handle multi-tenant data ingestion, ensuring secure and efficient log forwarding to your Chronicle instance.

### High level architecture

The following diagram illustrates the high-level design of created resources, which can be adapted to specific requirements via variables:

![Chronicle Forwarder](./images/diagram.png)

### Key Features

- **Automated GKE Cluster Creation**: Streamlines the provisioning of a dedicated Kubernetes cluster for the forwarder.
- **Scalable Forwarder Deployment**: Deploys the Chronicle forwarder as a Kubernetes Deployment, allowing for easy scaling to accommodate varying log volumes.
- **Multi-tenant Support**: Enables the forwarder to ingest log data from multiple sources or tenants, maintaining clear separation within Chronicle.
- **Modular Configuration**: Provides flexible Terraform modules to customize network settings, resource allocation, and tenant-specific configurations.

### Deployment

#### Step 0: Cloning the repository

If you want to deploy from your Cloud Shell, click on the image below, sign in
if required and when the prompt appears, click on “confirm”.

[![Open Cloudshell](./images/cloud-shell-button.png)](https://shell.cloud.google.com/cloudshell/editor?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2FGoogleCloudPlatform%2Fcloud-foundation-fabric&cloudshell_workspace=blueprints%2Fthird-party-solutions%2Fwordpress%2Fcloudrun)

Otherwise, in your console of choice:

```bash
git clone https://github.com/GoogleCloudPlatform/cloud-foundation-fabric.git
```

Before you deploy the architecture, you will need at least the following
information/configurations in place (for more precise configuration see the Variables section):

* The project ID
simonebruzzechesse marked this conversation as resolved.
Show resolved Hide resolved
* The VPC host project
* VPC and subnets should already exist

#### Step 2: Prepare the variables

Once you have the required information, head back to your cloned repository.
Make sure you’re in the directory of this tutorial (where this README is in).

Configure the Terraform variables in your `terraform.tfvars` file.
See the example test at the end of this README.md as starting point - just
copy it to `terraform.tfvars` and edit the latter. See the variables
documentation below.

#### Step 3: Prepare the providers in the root module

Setup terraform providers in the root module to deal with kubernetes resources as follows:

```terraform
data "google_client_config" "identity" {
count = module.chronicle-forwarder.fleet_host != null ? 1 : 0
}

provider "kubernetes" {
host = module.chronicle-forwarder.fleet_host
token = try(data.google_client_config.identity.0.access_token, null)
}

provider "kubectl" {
host = module.chronicle-forwarder.fleet_host
token = try(data.google_client_config.identity.0.access_token, null)
}
```

#### Step 4: Deploy resources

Initialize your Terraform environment and deploy the resources:

```shell
terraform init
terraform apply
```

Get kubeconfig to connect to the cluster using the command below:

```shell
gcloud container fleet memberships get-credentials CLUSTER_NAME --project PROJECT
```

Then running the command `kubectl get pods` you should receive the following message:

```
"No resources found in default namespace."
```
<!-- BEGIN TFDOC -->
## Variables

| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [network_config](variables.tf#L28) | Shared VPC network configurations to use for GKE cluster. | <code title="object&#40;&#123;&#10; host_project &#61; optional&#40;string&#41;&#10; network_self_link &#61; string&#10; subnet_self_link &#61; string&#10; ip_range_gke_master &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [prefix](variables.tf#L38) | Prefix used for resource names. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L57) | Project id, references existing project if `project_create` is null. | <code>string</code> | ✓ | |
| [region](variables.tf#L62) | GCP region. | <code>string</code> | ✓ | |
| [chronicle_forwarder](variables.tf#L17) | Chronicle GKE forwarder configuration. | <code title="object&#40;&#123;&#10; cluster_name &#61; optional&#40;string, &#34;chronicle-log-ingestion&#34;&#41;&#10; master_authorized_ranges &#61; optional&#40;map&#40;string&#41;, &#123;&#10; rfc-1918-10-8 &#61; &#34;10.0.0.0&#47;8&#34;&#10; &#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [project_create](variables.tf#L48) | Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format. | <code title="object&#40;&#123;&#10; billing_account_id &#61; string&#10; parent &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [tenants](variables.tf#L67) | Chronicle forwarders tenants config. | <code title="map&#40;object&#40;&#123;&#10; chronicle_forwarder_image &#61; optional&#40;string, &#34;cf_production_stable&#34;&#41;&#10; chronicle_region &#61; string&#10; tenant_id &#61; string&#10; namespace &#61; string&#10; forwarder_config &#61; object&#40;&#123;&#10; config_file_content &#61; optional&#40;string&#41;&#10; customer_id &#61; optional&#40;string&#41;&#10; collector_id &#61; optional&#40;string&#41;&#10; secret_key &#61; optional&#40;string&#41;&#10; tls_config &#61; optional&#40;object&#40;&#123;&#10; required &#61; optional&#40;bool, false&#41;&#10; cert_pub &#61; optional&#40;string&#41;&#10; cert_key &#61; optional&#40;string&#41;&#10; &#125;&#41;, &#123; required &#61; false &#125;&#41;&#10; &#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |

## Outputs

| name | description | sensitive |
|---|---|:---:|
| [fleet_host](outputs.tf#L17) | GKE Fleet host. | |
<!-- END TFDOC -->
## Test

```hcl
module "test" {
source = "./fabric/blueprints/secops/secops-gke-forwarder"
project_id = "test"
project_create = {
billing_account_id = "12345-ABCDEF-12345"
parent = "folders/2345678901"
}
region = "europe-west8"
network_config = {
host_project = "prod-net-landing-0"
network_self_link = "https://www.googleapis.com/compute/v1/projects/prod-net-landing-0/global/networks/prod-landing-0"
subnet_self_link = "https://www.googleapis.com/compute/v1/projects/prod-net-landing-0/regions/europe-west1/subnetworks/gke"
ip_range_gke_master = "192.168.0.0/28"
}
prefix = "tmp"
tenants = {
tenant-1 = {
chronicle_forwarder_image = "cf_production_stable"
chronicle_region = "europe"
tenant_id = "tenant-1"
namespace = "ten-1"
forwarder_config = {
config_file_content = file("data/config.yaml")
}
}
tenant-2 = {
chronicle_forwarder_image = "cf_production_stable"
chronicle_region = "europe"
tenant_id = "tenant-2"
namespace = "tenant-2"
forwarder_config = {
secret_key = file("data/secret_key.json")
customer_id = "XXXXXXX-XXXX-XXXX-XXXX-XXXXXX"
collector_id = "XXXXXXX-XXXX-XXXX-XXXX-XXXXXX"
}
}
}
}
# tftest modules=5 resources=34 files=credentials,config
```

```
# tftest-file id=credentials path=data/secret_key.json
{
"type": "service_account",
"project_id": "xxxx",
"private_key_id": "xxxxxxxxxxxxxx",
"private_key": "-----BEGIN PRIVATE KEY-----\nsdcCDSCsLxhfQIOwdvzCn5wcwJ7xVA=\n-----END PRIVATE KEY-----\n",
"client_email": "[email protected]",
"client_id": "ASDCVSACSA",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/sample.iam.gserviceaccount.com",
"universe_domain": "googleapis.com"
}
```

```
# tftest-file id=config path=data/config.yaml
output:
url: malachiteingestion-pa.googleapis.com:443
identity:
identity:
collector_id: COLLECTOR_ID \
customer_id: CUSTOMER_ID \

collectors:
- syslog:
common:
enabled: true
data_type: "WINDOWS_DHCP"
data_hint:
batch_n_seconds: 10
batch_n_bytes: 1048576
tcp_address: 0.0.0.0:10514
udp_address: 0.0.0.0:10514
connection_timeout_sec: 60
tcp_buffer_size: 524288
- syslog:
common:
enabled: true
data_type: "WINDOWS_DNS"
data_hint:
batch_n_seconds: 10
batch_n_bytes: 1048576
tcp_address: 0.0.0.0:10515
connection_timeout_sec: 60
tcp_buffer_size: 524288
```
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
103 changes: 103 additions & 0 deletions blueprints/secops/secops-gke-forwarder/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

locals {
fleet_host = join("", [
"https://connectgateway.googleapis.com/v1/",
"projects/${module.project.number}/",
"locations/global/gkeMemberships/${var.chronicle_forwarder.cluster_name}"
])
}

module "project" {
source = "../../../modules/project"
billing_account = (var.project_create != null
? var.project_create.billing_account_id
: null
)
parent = (var.project_create != null
? var.project_create.parent
: null
)
prefix = var.prefix
project_create = var.project_create != null
name = var.project_id
services = concat([
"compute.googleapis.com",
"iap.googleapis.com",
"stackdriver.googleapis.com",
"chronicle.googleapis.com",
"container.googleapis.com",
"gkehub.googleapis.com",
"connectgateway.googleapis.com",
"gkeconnect.googleapis.com"
])
}

module "fleet" {
source = "../../../modules/gke-hub"
project_id = var.project_id
clusters = {
"chronicle-log-ingestion" = module.chronicle-forwarder.id
}
}

module "chronicle-forwarder" {
source = "../../../modules/gke-cluster-autopilot"
project_id = var.project_id
name = var.chronicle_forwarder.cluster_name
location = var.region
deletion_protection = false
vpc_config = {
network = var.network_config.network_self_link
subnetwork = var.network_config.subnet_self_link
secondary_range_names = {
pods = "pods"
services = "services"
}
master_ipv4_cidr_block = var.network_config.ip_range_gke_master
master_authorized_ranges = var.chronicle_forwarder.master_authorized_ranges
}
private_cluster_config = {
enable_private_endpoint = true
master_global_access = true
}
enable_features = {
gateway_api = true
}
logging_config = {
enable_api_server_logs = true
enable_scheduler_logs = true
enable_controller_manager_logs = true
}
monitoring_config = {
enable_daemonset_metrics = true
enable_deployment_metrics = true
enable_hpa_metrics = true
enable_pod_metrics = true
enable_statefulset_metrics = true
enable_storage_metrics = true
enable_api_server_metrics = true
enable_controller_manager_metrics = true
enable_scheduler_metrics = true
}
}

module "chronicle-forwarder-deployment" {
source = "./secops-forwarder-deployment"
depends_on = [module.chronicle-forwarder]
tenants = var.tenants
}
20 changes: 20 additions & 0 deletions blueprints/secops/secops-gke-forwarder/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

output "fleet_host" {
description = "GKE Fleet host."
value = local.fleet_host
}
Loading