Skip to content

Commit 683241d

Browse files
temblekinghayk99
andauthored
feat(scanning)!: Deploy gcr subscriptions for each project (#64)
The gcr topic is now assumed to be existing in all the projects that are going to be scanned as part of the organization. Last implementation relied on Eventarc triggers to retrieve the events from GCR / Artifact Registry into the Cloud Run deployment. That works for single-project deployments, but organizational deployments require the use of subscriptions sending the events to the HTTP endpoint of the Cloud Run deployment instead. BREAKING CHANGE: This adds a new variable called project_scan_ids which specifies the IDs of the projects where a subscription must be created for the expected gcr topic in each project, and removes the create_gcr_topic variable which may be confusing to the users, since some of the scanned projects may or may not contain this topic, and verifying if it exists is not an option. * feat(scanning): Add gcr subscription deployments for each project * chore: remove unsed datas and fix scanning push url * feat: Add project_scan_ids and remove create_gcr_topic variable * fix(ci): Add gcr topic to organizational test * fix(ci): Create gcr topic as part of single_project test * feat: Mark project_scan_ids as required * fix: Add ArtifactRegistry permissions to GCR pull Co-authored-by: Hayk Kocharyan <[email protected]>
1 parent 70c27ff commit 683241d

File tree

12 files changed

+73
-107
lines changed

12 files changed

+73
-107
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,14 @@ Notice that:
118118
$ terraform import 'module.secure-for-cloud_example_single-project.module.cloud_bench[0].module.trust_relationship["<YOUR_PROJECT_ID>"].google_iam_workload_identity_pool.pool' sysdigcloud
119119
$ terraform import 'module.secure-for-cloud_example_single-project.module.cloud_bench[0].module.trust_relationship["<YOUR_PROJECT_ID>"].google_iam_workload_identity_pool_provider.pool_provider' sysdigcloud/sysdigcloud
120120
```
121-
121+
122122
- Q2: Scanning does not seem to work<br/>
123123
A2: Verify that `gcr` topic exists. If `create_gcr_topic` is set to false and `gcr` topic is not found, the GCR scanning is ommited and won't be deployed. For more info see GCR PubSub topic.
124124

125125
- Q3: Scanning, I get an error saying:
126126
```
127-
error starting scan runner for image ****: rpc error: code = PermissionDenied desc = Cloud Build API has not been used in project *** before or it is disabled.
128-
Enable it by visiting https://console.developers.google.com/apis/api/cloudbuild.googleapis.com/overview?project=*** then retry.
127+
error starting scan runner for image ****: rpc error: code = PermissionDenied desc = Cloud Build API has not been used in project *** before or it is disabled.
128+
Enable it by visiting https://console.developers.google.com/apis/api/cloudbuild.googleapis.com/overview?project=*** then retry.
129129
If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry
130130
```
131131
A3: Do as the error says and activate CloudBuild API. Check the list of all the required APIs that need to be activated per feature module.

examples/organization/README.md

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,46 +6,49 @@ Sysdig workload will be deployed in the `project_id` defined in the required inp
66

77
![single project diagram](https://github.com/sysdiglabs/terraform-google-secure-for-cloud/blob/master/examples/organization/diagram-org.png?raw=true)
88

9-
109
## Prerequisites
1110

1211
You **must** have following **roles** in your GCP organization/project credentials
12+
1313
* _Owner_
1414
* _Organization Admin_
1515

1616
Besides, the following GCP **APIs must be enabled** to deploy resources correctly for:
1717

1818
### Cloud Connector
19+
1920
* [Cloud Pub/Sub API](https://console.cloud.google.com/marketplace/product/google/pubsub.googleapis.com)
2021
* [Cloud Run API](https://console.cloud.google.com/marketplace/product/google/run.googleapis.com)
2122
* [Eventarc API](https://console.cloud.google.com/marketplace/product/google/eventarc.googleapis.com)
2223

2324
### Cloud Scanning
25+
2426
* [Cloud Pub/Sub API](https://console.cloud.google.com/marketplace/product/google/pubsub.googleapis.com)
2527
* [Cloud Run API](https://console.cloud.google.com/marketplace/product/google/run.googleapis.com)
2628
* [Eventarc API](https://console.cloud.google.com/marketplace/product/google/eventarc.googleapis.com)
2729
* [Secret Manger API](https://console.cloud.google.com/marketplace/product/google/secretmanager.googleapis.com)
2830
* [Cloud Build API](https://console.cloud.google.com/marketplace/product/google/cloudbuild.googleapis.com)
2931
* [Identity and access management API](https://console.cloud.google.com/marketplace/product/google/iam.googleapis.com)
3032

31-
### Cloud Benchmarks
33+
### Cloud Benchmarks
34+
3235
* [Identity and access management API](https://console.cloud.google.com/marketplace/product/google/iam.googleapis.com)
3336
* [IAM Service Account Credentials API](https://console.cloud.google.com/marketplace/product/google/iamcredentials.googleapis.com)
3437
* [Cloud Resource Manager API](https://console.cloud.google.com/marketplace/product/google/cloudresourcemanager.googleapis.com)
3538
* [Security Token Service API](https://console.cloud.google.com/marketplace/product/google/sts.googleapis.com)
3639

37-
3840
## Usage
3941

4042
For quick testing, use this snippet on your terraform files
4143

42-
```
44+
```terraform
4345
module "secure-for-cloud_example_organization" {
44-
source = "sysdiglabs/secure-for-cloud/google//examples/organization"
46+
source = "sysdiglabs/secure-for-cloud/google//examples/organization"
4547
46-
sysdig_secure_api_token = "00000000-1111-2222-3333-444444444444"
47-
project_id = "your-project-id"
48-
organization_domain = "your-domain.com"
48+
project_id = "your-project-id"
49+
project_scan_ids = ["project-to-scan-1", "project-to-scan-2"]
50+
sysdig_secure_api_token = "00000000-1111-2222-3333-444444444444"
51+
organization_domain = "your-domain.com"
4952
}
5053
```
5154

@@ -93,11 +96,11 @@ module "secure-for-cloud_example_organization" {
9396
|------|-------------|------|---------|:--------:|
9497
| <a name="input_organization_domain"></a> [organization\_domain](#input\_organization\_domain) | Organization domain. e.g. sysdig.com | `string` | n/a | yes |
9598
| <a name="input_project_id"></a> [project\_id](#input\_project\_id) | Organization member project ID where the secure-for-cloud workload is going to be deployed | `string` | n/a | yes |
99+
| <a name="input_project_scan_ids"></a> [project\_scan\_ids](#input\_project\_scan\_ids) | Projects where a subscription must be created to pull events from their GCR topics. Warning, the topic called `gcr` must already exist in each provided project. | `list(string)` | n/a | yes |
96100
| <a name="input_sysdig_secure_api_token"></a> [sysdig\_secure\_api\_token](#input\_sysdig\_secure\_api\_token) | Sysdig's Secure API Token | `string` | n/a | yes |
97101
| <a name="input_benchmark_project_ids"></a> [benchmark\_project\_ids](#input\_benchmark\_project\_ids) | Google cloud project IDs to run Benchmarks on | `list(string)` | `[]` | no |
98102
| <a name="input_benchmark_regions"></a> [benchmark\_regions](#input\_benchmark\_regions) | List of regions in which to run the benchmark. If empty, the task will contain all regions by default. | `list(string)` | `[]` | no |
99103
| <a name="input_benchmark_role_name"></a> [benchmark\_role\_name](#input\_benchmark\_role\_name) | The name of the Service Account that will be created. | `string` | `"sysdigcloudbench"` | no |
100-
| <a name="input_create_gcr_topic"></a> [create\_gcr\_topic](#input\_create\_gcr\_topic) | Deploys a PubSub topic called `gcr` as part of this stack, which is needed for GCR scanning. Set to `true` only if it doesn't exist yet. If this is not deployed, and no existing `gcr` topic is found, the GCR scanning is ommited and won't be deployed. For more info see [GCR PubSub topic](https://cloud.google.com/container-registry/docs/configuring-notifications#create_a_topic). | `bool` | `true` | no |
101104
| <a name="input_deploy_bench"></a> [deploy\_bench](#input\_deploy\_bench) | whether benchmark module is to be deployed | `bool` | `true` | no |
102105
| <a name="input_location"></a> [location](#input\_location) | Zone where the stack will be deployed | `string` | `"us-central1"` | no |
103106
| <a name="input_max_instances"></a> [max\_instances](#input\_max\_instances) | Max number of instances for the workloads | `number` | `1` | no |

examples/organization/main.tf

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,11 @@ resource "google_organization_iam_custom_role" "org_gcr_image_puller" {
9292
description = "Allows pulling GCR images from all accounts in the organization"
9393
permissions = [
9494
"storage.objects.get",
95-
"storage.objects.list"
95+
"storage.objects.list",
96+
"artifactregistry.repositories.get",
97+
"artifactregistry.repositories.downloadArtifacts",
98+
"artifactregistry.tags.list",
99+
"artifactregistry.tags.get"
96100
]
97101
}
98102

@@ -129,9 +133,10 @@ module "cloud_scanning" {
129133
verify_ssl = local.verify_ssl
130134

131135
cloud_scanning_sa_email = google_service_account.scanning_sa.email
132-
create_gcr_topic = var.create_gcr_topic
133136
scanning_pubsub_topic_id = module.connector_organization_sink.pubsub_topic_id
134137
project_id = var.project_id
138+
create_gcr_topic = false # We assume all the project_scan_ids have a topic created called gcr
139+
project_scan_ids = var.project_scan_ids
135140

136141
max_instances = var.max_instances
137142
}

examples/organization/variables.tf

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ variable "project_id" {
1414
description = "Organization member project ID where the secure-for-cloud workload is going to be deployed"
1515
}
1616

17+
variable "project_scan_ids" {
18+
type = list(string)
19+
description = "Projects where a subscription must be created to pull events from their GCR topics. Warning, the topic called `gcr` must already exist in each provided project."
20+
}
21+
1722
# --------------------------
1823
# optionals, with defaults
1924
# --------------------------
@@ -46,19 +51,6 @@ variable "max_instances" {
4651
default = 1
4752
}
4853

49-
variable "create_gcr_topic" {
50-
type = bool
51-
description = "Deploys a PubSub topic called `gcr` as part of this stack, which is needed for GCR scanning. Set to `true` only if it doesn't exist yet. If this is not deployed, and no existing `gcr` topic is found, the GCR scanning is ommited and won't be deployed. For more info see [GCR PubSub topic](https://cloud.google.com/container-registry/docs/configuring-notifications#create_a_topic)."
52-
default = true
53-
}
54-
55-
variable "deploy_bench" {
56-
type = bool
57-
description = "whether benchmark module is to be deployed"
58-
default = true
59-
}
60-
61-
6254
variable "benchmark_regions" {
6355
type = list(string)
6456
description = "List of regions in which to run the benchmark. If empty, the task will contain all regions by default."
@@ -76,3 +68,9 @@ variable "benchmark_role_name" {
7668
description = "The name of the Service Account that will be created."
7769
default = "sysdigcloudbench"
7870
}
71+
72+
variable "deploy_bench" {
73+
type = bool
74+
description = "whether benchmark module is to be deployed"
75+
default = true
76+
}

examples/single-project/README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,13 @@ Besides, the following GCP **APIs must be enabled** to deploy resources correctl
3636

3737
For quick testing, use this snippet on your terraform files
3838

39-
```
39+
```terraform
4040
module "secure-for-cloud_example_single-project" {
41-
source = "sysdiglabs/secure-for-cloud/google//examples/single-project"
41+
source = "sysdiglabs/secure-for-cloud/google//examples/single-project"
42+
4243
43-
sysdig_secure_api_token = "00000000-1111-2222-3333-444444444444"
44-
project_id = "your-project-id"
44+
sysdig_secure_api_token = "00000000-1111-2222-3333-444444444444"
45+
project_id = "your-project-id"
4546
}
4647
```
4748

examples/single-project/main.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ module "cloud_scanning" {
8787
scanning_pubsub_topic_id = module.scanning_project_sink.pubsub_topic_id
8888
create_gcr_topic = var.create_gcr_topic
8989
project_id = var.project_id
90+
project_scan_ids = [var.project_id]
9091

9192
secure_api_token_secret_id = module.secure_secrets.secure_api_token_secret_name
9293
sysdig_secure_api_token = var.sysdig_secure_api_token

modules/services/cloud-scanning/README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@ deployment that trigger image scans based on changes in your infrastructure.
55

66
## Usage
77

8-
```hcl
8+
```terraform
99
module "cloud_scanning_gcp" {
1010
source = "sysdiglabs/secure-for-cloud/google/services/cloud-scanning"
1111
12-
create_gcr_topic = true
13-
# Set to "false" if there's an existing PubSub topic called "gcr"
1412
sysdig_secure_api_token = "00000000-1111-2222-3333-444444444444"
1513
sysdig_secure_endpoint = "https://secure.sysdig.com"
14+
project_scan_ids = ["project-id-to-scan"]
15+
16+
# Set to "false" if there's an existing PubSub topic called "gcr"
17+
create_gcr_topic = true
1618
}
1719
```
1820

@@ -40,15 +42,14 @@ No modules.
4042
|------|------|
4143
| [google_cloud_run_service.cloud_scanning](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloud_run_service) | resource |
4244
| [google_cloud_run_service_iam_member.run_invoker](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloud_run_service_iam_member) | resource |
43-
| [google_eventarc_trigger.gcr](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/eventarc_trigger) | resource |
4445
| [google_eventarc_trigger.trigger](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/eventarc_trigger) | resource |
4546
| [google_project_iam_member.builder](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/project_iam_member) | resource |
4647
| [google_project_iam_member.event_receiver](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/project_iam_member) | resource |
4748
| [google_project_iam_member.service_account_user_itself](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/project_iam_member) | resource |
4849
| [google_project_iam_member.token_creator](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/project_iam_member) | resource |
50+
| [google_pubsub_subscription.gcr](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/pubsub_subscription) | resource |
4951
| [google_pubsub_topic.gcr](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/pubsub_topic) | resource |
5052
| [google_project.project](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/project) | data source |
51-
| [google_pubsub_topic.gcr](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/pubsub_topic) | data source |
5253

5354
## Inputs
5455

@@ -66,6 +67,7 @@ No modules.
6667
| <a name="input_location"></a> [location](#input\_location) | Zone where the cloud scanning will be deployed | `string` | `"us-central1"` | no |
6768
| <a name="input_max_instances"></a> [max\_instances](#input\_max\_instances) | Max number of instances for the Cloud Scanning | `number` | `1` | no |
6869
| <a name="input_name"></a> [name](#input\_name) | Name to be assigned to all child resources. A suffix may be added internally when required. Use default value unless you need to install multiple instances | `string` | `"sfc-cloudscanning"` | no |
70+
| <a name="input_project_scan_ids"></a> [project\_scan\_ids](#input\_project\_scan\_ids) | Projects where a subscription must be created to pull events from their GCR topics to scan their images. Warning, a topic called `gcr` must already exist in each provided project. | `list(string)` | `[]` | no |
6971
| <a name="input_verify_ssl"></a> [verify\_ssl](#input\_verify\_ssl) | Verify the SSL certificate of the Secure endpoint | `bool` | `true` | no |
7072

7173
## Outputs
Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
locals {
2-
gcr_topic_id = var.create_gcr_topic ? google_pubsub_topic.gcr[0].id : data.google_pubsub_topic.gcr.id
3-
42
# note
53
# topic name is hardcoded by GCP and cannot be changed
64
# resource cannot honor var.name
@@ -9,12 +7,6 @@ locals {
97
gcr_topic_name = "gcr"
108
}
119

12-
data "google_pubsub_topic" "gcr" {
13-
project = var.project_id
14-
15-
name = local.gcr_topic_name
16-
# MUST exist in the infra of the customer, that's the only topic GCR will publish events to.
17-
}
1810

1911
# FIXME: is this the right place?
2012
# Required to execute cloud build runs with this same service account
@@ -33,27 +25,22 @@ resource "google_pubsub_topic" "gcr" {
3325
name = local.gcr_topic_name
3426
}
3527

36-
#new
37-
resource "google_eventarc_trigger" "gcr" {
38-
count = length(local.gcr_topic_id[*]) > 0 ? 1 : 0
39-
# We won't try to deploy this trigger if the GCR topic doesn't exist
40-
name = "${var.name}-trigger-gcr"
41-
location = var.location
42-
service_account = var.cloud_scanning_sa_email
43-
matching_criteria {
44-
attribute = "type"
45-
value = "google.cloud.pubsub.topic.v1.messagePublished"
46-
}
47-
destination {
48-
cloud_run_service {
49-
service = google_cloud_run_service.cloud_scanning.name
50-
region = var.location
51-
path = "/gcr_scanning"
28+
29+
resource "google_pubsub_subscription" "gcr" {
30+
for_each = toset(var.project_scan_ids)
31+
name = "${var.name}-gcr-${each.key}"
32+
topic = "projects/${each.key}/topics/${local.gcr_topic_name}"
33+
34+
ack_deadline_seconds = 10
35+
36+
push_config {
37+
push_endpoint = "${google_cloud_run_service.cloud_scanning.status[0].url}/gcr_scanning"
38+
oidc_token {
39+
service_account_email = var.cloud_scanning_sa_email
5240
}
5341
}
54-
transport {
55-
pubsub {
56-
topic = local.gcr_topic_id
57-
}
42+
retry_policy {
43+
minimum_backoff = "10s"
44+
maximum_backoff = "300s"
5845
}
5946
}

modules/services/cloud-scanning/variables.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,9 @@ variable "max_instances" {
7575
description = "Max number of instances for the Cloud Scanning"
7676
default = 1
7777
}
78+
79+
variable "project_scan_ids" {
80+
type = list(string)
81+
description = "Projects where a subscription must be created to pull events from their GCR topics to scan their images. Warning, a topic called `gcr` must already exist in each provided project."
82+
default = []
83+
}

test/fixtures/organization/main.tf

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@ resource "random_string" "random" {
44
upper = false
55
}
66

7+
resource "google_pubsub_topic" "gcr" {
8+
project = var.project_id
9+
name = "gcr"
10+
}
711

812
module "sfc_example_organization" {
913
source = "../../../examples/organization"
1014

1115
organization_domain = var.organization_domain
1216
sysdig_secure_api_token = var.sysdig_secure_api_token
13-
create_gcr_topic = false
1417
name = "sfc${random_string.random.result}"
1518
project_id = var.project_id
19+
project_scan_ids = [var.project_id]
1620
deploy_bench = false
1721
}

0 commit comments

Comments
 (0)