Skip to content

Commit 1930639

Browse files
authored
feat(serviceAccount): GCP service account module [ENG-44162] (#2)
* gcp service account module [ENG-44162] * no needed file [44162] * remove for access review sentende from readme [ENG-44162] * update readme the file has been generated [ENG-44162] * update readme step 6 [ENG-44162] * update readme step 5 [ENG-44162] * delete codeowners file [ENG-44162] * Update README.md Example Usage [ENG-44162]
1 parent daa317b commit 1930639

File tree

6 files changed

+166
-39
lines changed

6 files changed

+166
-39
lines changed

CODEOWNERS

Lines changed: 0 additions & 3 deletions
This file was deleted.

README.md

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,63 @@
1-
# Terraform Module Template
2-
3-
**Next steps**
4-
1. Update the top section of this file to tell people about this module.
5-
2. Update `versions.tf` to include the required providers for the module.
6-
3. Add resources and variables to solve the problem.
7-
4. Add outputs for relevant details the consumer may want
8-
5. Add example uses to the bottom of this file
9-
6. Update the generated portion of this file using `terraform-docs .`
10-
1+
# gcp-terraform-drata-setup
2+
3+
GCP terraform module to create the Drata Read Only service account.
4+
5+
## Example Usage
6+
7+
The example below uses `ref=main` (which is appended in the URL), but it is recommended to use a specific tag version (i.e. `ref=1.0.0`) to avoid breaking changes. Go to the release page for a list of published versions. [releases page](https://github.com/drata/gcp-terraform-drata-setup/releases) for a list of published versions.
8+
9+
Replace `YOUR_ORGANIZATION_DOMAIN` with the organization domain. i.e. `your_org.com`.
10+
```
11+
module "service_account_creation" {
12+
source = "git::https://github.com/drata/gcp-terraform-drata-setup.git?ref=main"
13+
gcp_org_domain = "YOUR_ORGANIZATION_DOMAIN"
14+
# gcp_project_id = "YOUR_PROJECT_ID" # if it's unset, the project by default is used
15+
# drata_role_name = "YOUR_ROLE_NAME" # if it's unset, the default name is DrataReadOnly
16+
}
17+
18+
output "drata_service_account_key" {
19+
value = module.service_account_creation.drata_service_account_key
20+
description = "Service Account Key"
21+
sensitive = true
22+
}
23+
```
24+
25+
After you apply this terraform, run the following command to retrieve the key file `drata-gcp-private-key.json`
26+
```
27+
terraform output -raw drata_service_account_key > drata-gcp-private-key.json
28+
```
29+
30+
## Setup
31+
32+
The following steps demonstrate how to connect GCP in Drata when using this terraform module.
33+
34+
1. Add the code above to your terraform project.
35+
2. Make sure the service account to authenticate this script has the roles `Organization Administrator`, `Service Account Admin`, `Service Account Key Admin` and ` Service Usage Admin`.
36+
3. Replace `main` in `ref=main` with the latest version from the [releases page](https://github.com/drata/gcp-terraform-drata-setup/releases).
37+
4. Replace `YOUR_ORGANIZATION_DOMAIN` with the GCP organization domain.
38+
5. Replace `YOUR_PROJECT_ID` if the desired project is not the default project in your organization.
39+
6. Replace the given `drata_role_name` if you don't want the role added to be the default: `DrataReadOnly`.
40+
7. Back in your terminal, run `terraform init` to download/update the module.
41+
8. Run `terraform apply` and **IMPORTANT** review the plan output before typing `yes`.
42+
9. If successful, run the command to generate the json key file
43+
- `terraform output -raw drata_service_account_key > drata-gcp-private-key.json` .
44+
11. Verify the file has been generated.
45+
12. Go to the GCP connection drawer and select Upload File to upload the `drata-gcp-private-key.json` file.
46+
13. Select the `Save & Test Connection` button.
1147

1248
<!-- BEGIN_TF_DOCS -->
1349
## Requirements
1450

1551
| Name | Version |
1652
|------|---------|
17-
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.15 |
53+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.0 |
54+
| <a name="requirement_google"></a> [google](#requirement\_google) | 5.16.0 |
1855

1956
## Providers
2057

2158
| Name | Version |
2259
|------|---------|
23-
| <a name="provider_null"></a> [null](#provider\_null) | n/a |
60+
| <a name="provider_google"></a> [google](#provider\_google) | 5.16.0 |
2461

2562
## Modules
2663

@@ -30,22 +67,29 @@ No modules.
3067

3168
| Name | Type |
3269
|------|------|
33-
| [null_resource.nope](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
70+
| [google_organization_iam_custom_role.drata_org_role](https://registry.terraform.io/providers/hashicorp/google/5.16.0/docs/resources/organization_iam_custom_role) | resource |
71+
| [google_organization_iam_member.organization](https://registry.terraform.io/providers/hashicorp/google/5.16.0/docs/resources/organization_iam_member) | resource |
72+
| [google_project_iam_custom_role.drata_project_role](https://registry.terraform.io/providers/hashicorp/google/5.16.0/docs/resources/project_iam_custom_role) | resource |
73+
| [google_project_iam_member.drata_member_project_role](https://registry.terraform.io/providers/hashicorp/google/5.16.0/docs/resources/project_iam_member) | resource |
74+
| [google_project_iam_member.drata_viewer_role](https://registry.terraform.io/providers/hashicorp/google/5.16.0/docs/resources/project_iam_member) | resource |
75+
| [google_project_service.services](https://registry.terraform.io/providers/hashicorp/google/5.16.0/docs/resources/project_service) | resource |
76+
| [google_service_account.drata](https://registry.terraform.io/providers/hashicorp/google/5.16.0/docs/resources/service_account) | resource |
77+
| [google_service_account_key.drata_key](https://registry.terraform.io/providers/hashicorp/google/5.16.0/docs/resources/service_account_key) | resource |
78+
| [google_organization.gcp_organization](https://registry.terraform.io/providers/hashicorp/google/5.16.0/docs/data-sources/organization) | data source |
79+
| [google_project.gcp_project](https://registry.terraform.io/providers/hashicorp/google/5.16.0/docs/data-sources/project) | data source |
3480

3581
## Inputs
3682

3783
| Name | Description | Type | Default | Required |
3884
|------|-------------|------|---------|:--------:|
39-
| <a name="input_this"></a> [this](#input\_this) | Replace me with a real variable. | `str` | `"nope"` | no |
85+
| <a name="input_drata_role_name"></a> [drata\_role\_name](#input\_drata\_role\_name) | Role name. | `string` | `"DrataReadOnly"` | no |
86+
| <a name="input_gcp_org_domain"></a> [gcp\_org\_domain](#input\_gcp\_org\_domain) | GCP Organization domain. | `string` | n/a | yes |
87+
| <a name="input_gcp_project_id"></a> [gcp\_project\_id](#input\_gcp\_project\_id) | Project identifier of the gcp organization. If it is not provided, the provider project is used. | `string` | `null` | no |
88+
| <a name="input_gcp_services"></a> [gcp\_services](#input\_gcp\_services) | List of services to enable. | `list(string)` | <pre>[<br> "cloudresourcemanager.googleapis.com",<br> "compute.googleapis.com",<br> "admin.googleapis.com",<br> "sqladmin.googleapis.com",<br> "monitoring.googleapis.com"<br>]</pre> | no |
4089

4190
## Outputs
4291

4392
| Name | Description |
4493
|------|-------------|
45-
| <a name="output_nope"></a> [nope](#output\_nope) | TODO: Remove this and add your own outputs |
46-
| <a name="output_true"></a> [true](#output\_true) | n/a |
94+
| <a name="output_drata_service_account_key"></a> [drata\_service\_account\_key](#output\_drata\_service\_account\_key) | Service Account Key |
4795
<!-- END_TF_DOCS -->
48-
49-
## Examples
50-
51-
**TODO:** Add examples here

main.tf

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,72 @@
1-
# TODO: Remove this and add your own resources.
2-
resource "null_resource" "nope" {}
1+
# get default project
2+
data "google_project" "gcp_project" {
3+
count = var.gcp_project_id == null ? 1 : 0
4+
}
5+
6+
# get organization data
7+
data "google_organization" "gcp_organization" {
8+
domain = var.gcp_org_domain
9+
}
10+
11+
# set project id in local variable
12+
locals {
13+
PROJECT_ID = var.gcp_project_id == null ? data.google_project.gcp_project[0].project_id : var.gcp_project_id
14+
}
15+
16+
# enable services
17+
resource "google_project_service" "services" {
18+
for_each = toset(var.gcp_services)
19+
service = each.value
20+
disable_on_destroy = false
21+
project = local.PROJECT_ID
22+
}
23+
24+
# create project custom role
25+
resource "google_project_iam_custom_role" "drata_project_role" {
26+
role_id = "${var.drata_role_name}ProjectRole"
27+
title = "Drata Read-Only Project Role"
28+
description = "Service Account for Drata Autopilot to get read access to all project resources"
29+
permissions = ["storage.buckets.get", "storage.buckets.getIamPolicy"]
30+
project = local.PROJECT_ID
31+
}
32+
33+
# create organizational role
34+
resource "google_organization_iam_custom_role" "drata_org_role" {
35+
role_id = "${var.drata_role_name}OrganizationalRole"
36+
title = "Drata Read-Only Organizational Role"
37+
description = "Service Account with read-only access for Drata Autopilot to get organizational IAM data"
38+
permissions = ["resourcemanager.organizations.getIamPolicy", "storage.buckets.get", "storage.buckets.getIamPolicy"]
39+
org_id = data.google_organization.gcp_organization.org_id
40+
}
41+
42+
# creation of the service account
43+
resource "google_service_account" "drata" {
44+
account_id = lower(var.drata_role_name)
45+
display_name = "dratareadonly"
46+
project = local.PROJECT_ID
47+
}
48+
49+
# create json key file
50+
resource "google_service_account_key" "drata_key" {
51+
service_account_id = google_service_account.drata.id
52+
}
53+
54+
# assignation of roles to the service account
55+
# project role
56+
resource "google_project_iam_member" "drata_member_project_role" {
57+
project = local.PROJECT_ID
58+
role = google_project_iam_custom_role.drata_project_role.name
59+
member = "serviceAccount:${google_service_account.drata.email}"
60+
}
61+
# organization role
62+
resource "google_organization_iam_member" "organization" {
63+
org_id = data.google_organization.gcp_organization.org_id
64+
role = google_organization_iam_custom_role.drata_org_role.name
65+
member = "serviceAccount:${google_service_account.drata.email}"
66+
}
67+
# viewer role
68+
resource "google_project_iam_member" "drata_viewer_role" {
69+
project = local.PROJECT_ID
70+
role = "roles/viewer"
71+
member = "serviceAccount:${google_service_account.drata.email}"
72+
}

outputs.tf

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
# TODO: Remove this and add your own outputs
2-
output "nope" {
3-
value = null_resource.nope.id
4-
}
5-
6-
output "true" {
7-
value = true
1+
output "drata_service_account_key" {
2+
value = base64decode(google_service_account_key.drata_key.private_key)
3+
description = "Service Account Key"
4+
sensitive = true
85
}

variables.tf

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
1-
# TODO: Add your own input variables
2-
variable "this" {
3-
type = str
4-
description = "Replace me with a real variable."
5-
default = "nope"
1+
variable "gcp_project_id" {
2+
type = string
3+
description = "Project identifier of the gcp organization. If it is not provided, the provider project is used."
4+
default = null
5+
}
6+
7+
variable "gcp_org_domain" {
8+
type = string
9+
description = "GCP Organization domain."
10+
}
11+
12+
variable "gcp_services" {
13+
type = list(string)
14+
default = ["cloudresourcemanager.googleapis.com", "compute.googleapis.com", "admin.googleapis.com", "sqladmin.googleapis.com", "monitoring.googleapis.com"]
15+
description = "List of services to enable."
16+
}
17+
18+
variable "drata_role_name" {
19+
type = string
20+
description = "Role name."
21+
default = "DrataReadOnly"
622
}

versions.tf

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
terraform {
2-
required_version = ">= 0.15"
2+
required_version = ">= 0.13.0"
33

44
required_providers {
5-
# TODO: define the providers required by this module
5+
google = {
6+
source = "hashicorp/google"
7+
version = "5.16.0"
8+
}
69
}
710
}

0 commit comments

Comments
 (0)