Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 0 additions & 3 deletions CODEOWNERS

This file was deleted.

84 changes: 64 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,63 @@
# Terraform Module Template

**Next steps**
1. Update the top section of this file to tell people about this module.
2. Update `versions.tf` to include the required providers for the module.
3. Add resources and variables to solve the problem.
4. Add outputs for relevant details the consumer may want
5. Add example uses to the bottom of this file
6. Update the generated portion of this file using `terraform-docs .`

# gcp-terraform-drata-setup

GCP terraform module to create the Drata Read Only service account.

## Example Usage

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.

Replace `YOUR_ORGANIZATION_DOMAIN` with the organization domain. i.e. `your_org.com`.
```
module "service_account_creation" {
source = "git::https://github.com/drata/gcp-terraform-drata-setup.git?ref=main"
gcp_org_domain = "YOUR_ORGANIZATION_DOMAIN"
# gcp_project_id = "YOUR_PROJECT_ID" # if it's unset, the project by default is used
# drata_role_name = "YOUR_ROLE_NAME" # if it's unset, the default name is DrataReadOnly
}

output "drata_service_account_key" {
value = module.service_account_creation.drata_service_account_key
description = "Service Account Key"
sensitive = true
}
```

After you apply this terraform, run the following command to retrieve the key file `drata-gcp-private-key.json`
```
terraform output -raw drata_service_account_key > drata-gcp-private-key.json
```

## Setup

The following steps demonstrate how to connect GCP in Drata when using this terraform module.

1. Add the code above to your terraform project.
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`.
3. Replace `main` in `ref=main` with the latest version from the [releases page](https://github.com/drata/gcp-terraform-drata-setup/releases).
4. Replace `YOUR_ORGANIZATION_DOMAIN` with the GCP organization domain.
5. Replace `YOUR_PROJECT_ID` if the desired project is not the default project in your organization.
6. Replace the given `drata_role_name` if you don't want the role added to be the default: `DrataReadOnly`.
7. Back in your terminal, run `terraform init` to download/update the module.
8. Run `terraform apply` and **IMPORTANT** review the plan output before typing `yes`.
9. If successful, run the command to generate the json key file
- `terraform output -raw drata_service_account_key > drata-gcp-private-key.json` .
11. Verify the file has been generated.
12. Go to the GCP connection drawer and select Upload File to upload the `drata-gcp-private-key.json` file.
13. Select the `Save & Test Connection` button.

<!-- BEGIN_TF_DOCS -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.15 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.0 |
| <a name="requirement_google"></a> [google](#requirement\_google) | 5.16.0 |

## Providers

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

## Modules

Expand All @@ -30,22 +67,29 @@ No modules.

| Name | Type |
|------|------|
| [null_resource.nope](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
| [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 |
| [google_organization_iam_member.organization](https://registry.terraform.io/providers/hashicorp/google/5.16.0/docs/resources/organization_iam_member) | resource |
| [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 |
| [google_project_iam_member.drata_member_project_role](https://registry.terraform.io/providers/hashicorp/google/5.16.0/docs/resources/project_iam_member) | resource |
| [google_project_iam_member.drata_viewer_role](https://registry.terraform.io/providers/hashicorp/google/5.16.0/docs/resources/project_iam_member) | resource |
| [google_project_service.services](https://registry.terraform.io/providers/hashicorp/google/5.16.0/docs/resources/project_service) | resource |
| [google_service_account.drata](https://registry.terraform.io/providers/hashicorp/google/5.16.0/docs/resources/service_account) | resource |
| [google_service_account_key.drata_key](https://registry.terraform.io/providers/hashicorp/google/5.16.0/docs/resources/service_account_key) | resource |
| [google_organization.gcp_organization](https://registry.terraform.io/providers/hashicorp/google/5.16.0/docs/data-sources/organization) | data source |
| [google_project.gcp_project](https://registry.terraform.io/providers/hashicorp/google/5.16.0/docs/data-sources/project) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_this"></a> [this](#input\_this) | Replace me with a real variable. | `str` | `"nope"` | no |
| <a name="input_drata_role_name"></a> [drata\_role\_name](#input\_drata\_role\_name) | Role name. | `string` | `"DrataReadOnly"` | no |
| <a name="input_gcp_org_domain"></a> [gcp\_org\_domain](#input\_gcp\_org\_domain) | GCP Organization domain. | `string` | n/a | yes |
| <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 |
| <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 |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_nope"></a> [nope](#output\_nope) | TODO: Remove this and add your own outputs |
| <a name="output_true"></a> [true](#output\_true) | n/a |
| <a name="output_drata_service_account_key"></a> [drata\_service\_account\_key](#output\_drata\_service\_account\_key) | Service Account Key |
<!-- END_TF_DOCS -->

## Examples

**TODO:** Add examples here
74 changes: 72 additions & 2 deletions main.tf
Original file line number Diff line number Diff line change
@@ -1,2 +1,72 @@
# TODO: Remove this and add your own resources.
resource "null_resource" "nope" {}
# get default project
data "google_project" "gcp_project" {
count = var.gcp_project_id == null ? 1 : 0
}

# get organization data
data "google_organization" "gcp_organization" {
domain = var.gcp_org_domain
}

# set project id in local variable
locals {
PROJECT_ID = var.gcp_project_id == null ? data.google_project.gcp_project[0].project_id : var.gcp_project_id
}

# enable services
resource "google_project_service" "services" {
for_each = toset(var.gcp_services)
service = each.value
disable_on_destroy = false
project = local.PROJECT_ID
}

# create project custom role
resource "google_project_iam_custom_role" "drata_project_role" {
role_id = "${var.drata_role_name}ProjectRole"
title = "Drata Read-Only Project Role"
description = "Service Account for Drata Autopilot to get read access to all project resources"
permissions = ["storage.buckets.get", "storage.buckets.getIamPolicy"]
project = local.PROJECT_ID
}

# create organizational role
resource "google_organization_iam_custom_role" "drata_org_role" {
role_id = "${var.drata_role_name}OrganizationalRole"
title = "Drata Read-Only Organizational Role"
description = "Service Account with read-only access for Drata Autopilot to get organizational IAM data"
permissions = ["resourcemanager.organizations.getIamPolicy", "storage.buckets.get", "storage.buckets.getIamPolicy"]
org_id = data.google_organization.gcp_organization.org_id
}

# creation of the service account
resource "google_service_account" "drata" {
account_id = lower(var.drata_role_name)
display_name = "dratareadonly"
project = local.PROJECT_ID
}

# create json key file
resource "google_service_account_key" "drata_key" {
service_account_id = google_service_account.drata.id
}

# assignation of roles to the service account
# project role
resource "google_project_iam_member" "drata_member_project_role" {
project = local.PROJECT_ID
role = google_project_iam_custom_role.drata_project_role.name
member = "serviceAccount:${google_service_account.drata.email}"
}
# organization role
resource "google_organization_iam_member" "organization" {
org_id = data.google_organization.gcp_organization.org_id
role = google_organization_iam_custom_role.drata_org_role.name
member = "serviceAccount:${google_service_account.drata.email}"
}
# viewer role
resource "google_project_iam_member" "drata_viewer_role" {
project = local.PROJECT_ID
role = "roles/viewer"
member = "serviceAccount:${google_service_account.drata.email}"
}
11 changes: 4 additions & 7 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
# TODO: Remove this and add your own outputs
output "nope" {
value = null_resource.nope.id
}

output "true" {
value = true
output "drata_service_account_key" {
value = base64decode(google_service_account_key.drata_key.private_key)
description = "Service Account Key"
sensitive = true
}
26 changes: 21 additions & 5 deletions variables.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
# TODO: Add your own input variables
variable "this" {
type = str
description = "Replace me with a real variable."
default = "nope"
variable "gcp_project_id" {
type = string
description = "Project identifier of the gcp organization. If it is not provided, the provider project is used."
default = null
}

variable "gcp_org_domain" {
type = string
description = "GCP Organization domain."
}

variable "gcp_services" {
type = list(string)
default = ["cloudresourcemanager.googleapis.com", "compute.googleapis.com", "admin.googleapis.com", "sqladmin.googleapis.com", "monitoring.googleapis.com"]
description = "List of services to enable."
}

variable "drata_role_name" {
type = string
description = "Role name."
default = "DrataReadOnly"
}
7 changes: 5 additions & 2 deletions versions.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
terraform {
required_version = ">= 0.15"
required_version = ">= 0.13.0"

required_providers {
# TODO: define the providers required by this module
google = {
source = "hashicorp/google"
version = "5.16.0"
}
}
}