Skip to content
Merged
Show file tree
Hide file tree
Changes from 62 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
94e4703
fix: first content review with claude
westonplatter Jun 19, 2025
371877a
more updates. Smooth over higher level review items:
westonplatter Jun 19, 2025
e4ebc5f
ignore cursor and claude for now
westonplatter Jun 19, 2025
90d06c9
feat: add cursor rule for review articles. Adding this as a v1. Pleas…
westonplatter Jun 19, 2025
d928f38
lint
westonplatter Jun 19, 2025
7a4c4e4
tell us to use trunk:
westonplatter Jun 19, 2025
81009ae
try the suggested fix?
westonplatter Jun 19, 2025
d79f962
change name and refine code examples
westonplatter Jun 19, 2025
33bc310
polish
westonplatter Jun 19, 2025
80f189e
small fix
westonplatter Jun 19, 2025
453536d
code formatting
westonplatter Jun 20, 2025
6e3d05e
fix: get numbering right
westonplatter Jun 24, 2025
e4f0587
update section text
westonplatter Jun 24, 2025
60528da
update design decisions
westonplatter Jun 24, 2025
a371dbe
Merge branch 'master' into feat/article-googleworkspace-module-and-ma…
westonplatter Jun 27, 2025
802c347
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jun 27, 2025
ee2655c
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jun 27, 2025
488dd8f
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jun 27, 2025
fdb79f1
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jun 27, 2025
bf2cce7
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jun 27, 2025
328fd56
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jun 27, 2025
5a42981
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jun 27, 2025
6b660c5
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jun 27, 2025
f6467f3
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jun 27, 2025
56a8c74
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jun 27, 2025
33165fd
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jun 27, 2025
7f60f7e
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jun 27, 2025
9da8239
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jun 27, 2025
74ccbaf
actually, let's keep the prompts in the prompts rpeo
westonplatter Jun 27, 2025
5cc5557
chagnes for https://github.com/masterpointio/masterpoint.io/pull/66\#…
westonplatter Jun 27, 2025
08cfdd9
update TOC entry
westonplatter Jun 27, 2025
b3b737a
update TOC entry
westonplatter Jun 27, 2025
0ec27ba
fix: rework the example section and code
westonplatter Jun 30, 2025
94f00ed
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jun 30, 2025
2a44e33
fix: add context for version pinning
westonplatter Jun 30, 2025
46f5d8e
fix: update complex test count
westonplatter Jun 30, 2025
6197706
fix: connect the docs on expecting the var.users failure
westonplatter Jun 30, 2025
c09b352
fix: use defaults, not common
westonplatter Jun 30, 2025
236bbc9
use present tense in titles
westonplatter Jun 30, 2025
4cd74e9
fix: update users.yaml file to ref SSO
westonplatter Jun 30, 2025
a9ede10
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jun 30, 2025
74a55e6
grammar
westonplatter Jun 30, 2025
5aa8898
add image
westonplatter Jun 30, 2025
4a93a08
update publish date
westonplatter Jun 30, 2025
5a7ca82
fix lint
westonplatter Jun 30, 2025
be3a937
update yaml anchor to be the same
westonplatter Jun 30, 2025
fcde0ba
update publishing date for July 14
westonplatter Jul 1, 2025
71a5d7e
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jul 1, 2025
dd6dce8
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jul 1, 2025
7880544
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jul 1, 2025
4d986d9
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jul 1, 2025
a06c790
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jul 1, 2025
309dc76
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jul 2, 2025
2f44b47
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jul 2, 2025
91ed65b
Update content/blog/managing-google-workspace-with-terraform.md
westonplatter Jul 2, 2025
5420a57
Merge branch 'master' into feat/article-googleworkspace-module-and-ma…
westonplatter Jul 2, 2025
f54aa4e
feat: update title based on using some seo title tools
westonplatter Jul 5, 2025
c548226
fix: update slug also
westonplatter Jul 5, 2025
5ecf299
fix: udpate blog title
westonplatter Jul 16, 2025
a724df6
revised language based on yang's feedback
westonplatter Jul 16, 2025
cdb56be
config: update publish date
westonplatter Jul 16, 2025
d08c2a8
close the html tag
westonplatter Jul 16, 2025
80d5fd8
spelling :)
westonplatter Jul 16, 2025
5402ab3
seo: add ref to iac in first para
westonplatter Jul 16, 2025
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
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,10 @@
/public/
/resources/
.DS_Store

# leave cursor settings and configs up to each dev with their tooling prefs
.cursor/

# leave CC settings and configs up to each dev with their tooling prefs
CLAUDE.md
.claude/
Original file line number Diff line number Diff line change
@@ -0,0 +1,384 @@
---
visible: true
draft: false
title: "The Platform Engineering Way to Manage Google Workspace Users"
author: Weston Platter
date: 2025-07-17
slug: platform-engineering-way-to-manage-google-workspace-users
description: "Migrate Google Workspace from ClickOps to Infrastructure as Code with our open source Terraform module. Includes design patterns and import examples."
tags: ["terraform", "google-workspace", "infrastructure-as-code", "automation"]
image: /img/updates/managing-googleworkspace-with-terraform/preview-3.png
callout: <p>👋 <b>If you're ready to take your infrastructure to the next level, we're here to help. We love to work together with engineering teams to help them build well-documented, scalable, automated IaC that make their jobs easier. <a href='/contact'>Get in touch!</a></p>
---
Comment on lines +1 to +12
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Front-matter will fail YAML parsing – quote the callout value.

The callout field contains : and HTML tags but isn’t wrapped in quotes or a multi-line block, which will break most static-site builders (e.g. Hugo/Jekyll).
Patch:

-callout: <p>👋 <b>If you're ready to take your infrastructure to the next level, we're here to help. We love to work together with engineering teams to help them build well-documented, scalable, automated IaC that make their jobs easier. <a href='/contact'>Get in touch!</a></p>
+callout: |
+  <p>👋 <b>If you're ready to take your infrastructure to the next level, we're here to help. We love to work together with engineering teams to help them build well-documented, scalable, automated IaC that make their jobs easier. <a href="/contact">Get in touch!</a></p>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
---
visible: true
draft: false
title: "The Platform Engineering Way to Manage Google Workspace Users"
author: Weston Platter
date: 2025-07-17
slug: platform-engineering-way-to-manage-google-workspace-users
description: "Migrate Google Workspace from ClickOps to Infrastructure as Code with our open source Terraform module. Includes design patterns and import examples."
tags: ["terraform", "google-workspace", "infrastructure-as-code", "automation"]
image: /img/updates/managing-googleworkspace-with-terraform/preview-3.png
callout: <p>👋 <b>If you're ready to take your infrastructure to the next level, we're here to help. We love to work together with engineering teams to help them build well-documented, scalable, automated IaC that make their jobs easier. <a href='/contact'>Get in touch!</a></p>
---
---
visible: true
draft: false
title: "The Platform Engineering Way to Manage Google Workspace Users"
author: Weston Platter
date: 2025-07-17
slug: platform-engineering-way-to-manage-google-workspace-users
description: "Migrate Google Workspace from ClickOps to Infrastructure as Code with our open source Terraform module. Includes design patterns and import examples."
tags: ["terraform", "google-workspace", "infrastructure-as-code", "automation"]
image: /img/updates/managing-googleworkspace-with-terraform/preview-3.png
callout: |
<p>👋 <b>If you're ready to take your infrastructure to the next level, we're here to help. We love to work together with engineering teams to help them build well-documented, scalable, automated IaC that make their jobs easier. <a href="/contact">Get in touch!</a></p>
---
🤖 Prompt for AI Agents
In content/blog/platform-engineering-way-to-manage-google-workspace-users.md
lines 1 to 12, the callout field in the front-matter contains colons and HTML
tags but is not enclosed in quotes, causing YAML parsing errors. Fix this by
wrapping the entire callout value in double quotes or using a YAML multi-line
block style to ensure proper parsing by static-site generators.


## Table of Contents

- [Growing Pains](#growing-pains)
- [Why This Matters for Scaling Teams](#why-this-matters-for-scaling-teams)
- [Managing Google Workspace with Terraform](#managing-google-workspace-with-terraform)
- [Getting Started With the Module](#getting-started-with-the-module)
- [Module Design Decisions](#module-design-decisions)
- [Implementing Integration and Validation Tests](#design-decision-1---implementing-integration-and-validation-tests)
- [Choosing Intuitive Terraform Variable Structures](#design-decision-2---choosing-intuitive-terraform-variable-structures)
- [Wrapping Up](#wrapping-up)

## Growing Pains

As Masterpoint has been around for almost 10 years now, we've experienced growing pains transitioning from a one-person consultancy to a team of core full-time engineers, with the help of additional contractors when needed.

During that time, we've focused on client projects far more than our internal systems. When I joined in December, we started to feel the friction of onboarding a new team member, including adding their [Google Workspace](https://workspace.google.com/) account. Matt (our CEO/CTO) had to:

- remember what permissions a new Google Workspace user gets by default
- how to provision SSO permissions for Masterpoint's AWS Accounts
- how to get a user set up for client-specific SSOs

Since the last onboarding was about 6 months prior, important details weren't fresh in mind, which resulted in my delayed access to the Masterpoint AWS accounts. In the end, he had to take time and focus away from other work due to these tedious administrative tasks.

## Why This Matters for Scaling Teams

In our small company and possibly in your own organization, it's not a big deal for the founder or early engineer to create a new employee's Google Workspace account or give them SSO account access via the Admin UI. But as a company scales:

- Founders and engineers are focused on product, customers, and strategy.
- Nobody remembers why or when a permission was changed.
- Group membership becomes inconsistent.
- Onboarding/offboarding gets slower and error-prone.
- The consequences for getting security permissions incorrect increase.

As a company grows past ten, dozens, or a hundred people, teams (and dare we say departments) become more distributed. It is harder to manage user accounts across many different SaaS tools. It's important to have systems in place that provide clarity and enable individuals to get the right access to get their work done in a timely manner. We believe efficient systems are part of a company evolving toward higher levels of organizational maturity.

One aspect of that is finding a better way to manager your Google Workspace accounts.

## Managing Google Workspace with Terraform

We looked at a couple of open source solutions and decided on using the [Terraform Google Workspace provider](https://github.com/hashicorp/terraform-provider-googleworkspace). We often use Terraform to provision and manage user accounts within SaaS products (for example, we created a mdoule to [provision user accounts for DataDog](https://github.com/masterpointio/terraform-datadog-users)), so using Terraform to provision and manage google users felt like an easy decision.

We heard great things about [GAM](https://github.com/GAM-team/GAM) (an imperative command line tool) from a few colleagues, but we didn't need its full range of capabilities. We prefer to use declarative systems so we know the user account and group settings we see in config files are indeed the values in production.

While there are a few Terraform modules out there for managing Google Workspaces, we decided to create our own Terraform module to use the provider. The motivation to build a module from scratch stemmed from our desire to:

1. Easily manage [user specific SSO settings](https://github.com/masterpointio/terraform-googleworkspace-users-groups-automation/blob/933242a5d69401ea097f3b9f29894091f0581f5f/examples/import-existing-org/users.yaml#L12-L18) allowing engineers to sign into multiple AWS accounts using their Google Identity.
2. Organize `group` and `group_setting` variable inputs in clear and straight forward approach (more details on this in [Design Decision #2](#design-decision-2---choosing-intuitive-terraform-variable-structures))
3. Create default values for `user`, `group`, and `group_setting` making our config files easier to work with (see [this example](https://github.com/masterpointio/terraform-googleworkspace-users-groups-automation/blob/933242a5d69401ea097f3b9f29894091f0581f5f/examples/import-existing-org/users.yaml#L2-L18)).

Here's the GitHub link for our Google Workspace module:
[https://github.com/masterpointio/terraform-googleworkspace-users-groups-automation](https://github.com/masterpointio/terraform-googleworkspace-users-groups-automation)

## Getting Started With the Module

To make the module easy to get up and running with your own Google Workspace, we included two practical examples:

1. **Import existing Google Workspace users and groups**
We expect most people will use the module with an existing Google Workspace. To make this easy, we included the Terraform and YAML configuration files we used to import our own workspace users and groups.

The key component is the `imports.tf` file, which shows how to map existing Google Workspace resources to the module's resources. We also included a [Python script](https://github.com/masterpointio/terraform-googleworkspace-users-groups-automation/blob/main/examples/import-existing-org/debugging-script.py) to help debug by printing out the JSON objects as rendered by the Google APIs.

Since importing cloud resources into Terraform modules can be tricky, we documented our complete approach in [import-existing-org](https://github.com/masterpointio/terraform-googleworkspace-users-groups-automation/tree/main/examples/import-existing-org). The example includes these key files:

- [main.tf](https://github.com/masterpointio/terraform-googleworkspace-users-groups-automation/blob/main/examples/import-existing-org/main.tf) - Module configuration
- [imports.tf](https://github.com/masterpointio/terraform-googleworkspace-users-groups-automation/blob/main/examples/import-existing-org/imports.tf) - Import mappings
- [users.yaml](https://github.com/masterpointio/terraform-googleworkspace-users-groups-automation/blob/main/examples/import-existing-org/users.yaml) - User definitions with YAML anchors
- [groups.yaml](https://github.com/masterpointio/terraform-googleworkspace-users-groups-automation/blob/main/examples/import-existing-org/groups.yaml) - Group definitions with YAML anchors

2. **Create new users and groups**
For users who don't need to import users or groups, follow [this example](https://github.com/masterpointio/terraform-googleworkspace-users-groups-automation/tree/main/examples/complete). This is a great starting point if you're setting up a new org or only creating new users and groups.

After the initial import or setup, your Google Workspace [root module](https://newsletter.masterpoint.io/p/multi-instance-vs-single-instance-root-modules) could end up being as simple as this:

```terraform
locals {
oauth_scopes = [
"https://www.googleapis.com/auth/admin.directory.group",
"https://www.googleapis.com/auth/admin.directory.user",
"https://www.googleapis.com/auth/admin.directory.userschema",
"https://www.googleapis.com/auth/apps.groups.settings",
"https://www.googleapis.com/auth/iam",
]
}

provider "googleworkspace" {
customer_id = "my_customer"
credentials = local.secrets["googleworkspace_admin_credentials_json"]
impersonated_user_email = var.impersonated_user_email
oauth_scopes = local.oauth_scopes
}

# Get users and groups from YAML files. You might choose to use other config files.
# Note: path.module refers to the directory where terraform/tofu plan/apply is run
# var.googleworkspace_configs is a variable for the directory containing config files
locals {
config_path = "${path.module}/${var.googleworkspace_configs}"
all_groups = yamldecode(file("${local.config_path}/groups.yaml"))
all_users = yamldecode(file("${local.config_path}/users.yaml"))

# Skip objects that start with "_", which we use as default or prototype objects
groups = { for k, v in local.all_groups : k => v if !startswith(k, "_") }
users = { for k, v in local.all_users : k => v if !startswith(k, "_") }
}

module "googleworkspace_users_groups" {
source = "masterpointio/users-groups-automation/googleworkspace"
# version = "X.X.X" # it's a best practive to version pin modules
groups = local.groups
users = local.users
}
```

The above code references `users.yaml` and `groups.yaml` files that contain your actual user and group configurations.

Here's an example `users.yaml` file, which uses YAML anchors to share user defaults and Google + AWS SSO configurations across team members:

```yaml
---
_default_user: &default_user
is_admin: false
groups:
company: { role: member }
engineering: { role: member }

_custom_schemas_client1: &_custom_schemas_client1
schema_name: AWS_SSO_for_Client1
schema_values:
Role: '["arn:aws:iam::111111111111:role/GoogleAppsAdmin","arn:aws:iam::111111111111:saml-provider/GoogleApps"]'

[email protected]:
<<: *default_user
primary_email: [email protected]
given_name: User1
family_name: Last
custom_schemas:
- <<: *_custom_schemas_client1

[email protected]:
<<: *default_user
primary_email: [email protected]
given_name: User2
family_name: Last
custom_schemas:
- <<: *_custom_schemas_client1
```

And here's an example `groups.yaml` file, also leveraging YAML anchors to apply sane defaults to multiple goups.

```yaml
---
_default_active_settings: &_default_active_settings
allow_external_members: false
allow_web_posting: true
archive_only: false
custom_roles_enabled_for_settings_to_be_merged: false
enable_collaborative_inbox: false
is_archived: false
primary_language: en_US
who_can_join: ALL_IN_DOMAIN_CAN_JOIN
who_can_assist_content: OWNERS_AND_MANAGERS
who_can_view_group: ALL_IN_DOMAIN_CAN_VIEW
who_can_view_membership: ALL_IN_DOMAIN_CAN_VIEW

company:
email: [email protected]
name: All Company Team
description: Includes everyone in the company
is_admin: false
settings:
<<: *_default_active_settings

engineering:
email: [email protected]
name: Engineering Team
description: Engineering Team that all technical employees are members of by default
is_admin: false
settings:
<<: *_default_active_settings
```

## Module Design Decisions

Below we point out a few Terraform module design decisions we made to reduce friction as others use the module.

### Design Decision #1 - Implementing Integration and Validation Tests

To ensure the Terraform module remains reliable after changes—whether by contributors or automated processes—we've added approximately 20 tests. Thankfully [Terraform](https://developer.hashicorp.com/terraform/tutorials/configuration-language/test#prerequisites) and [OpenTofu](https://opentofu.org/docs/cli/commands/test/) both include a built-in testing framework that allows us to write tests directly in HCL, replacing the previous Go-based approach. The tests validate that the module behaves as expected and prevent new changes from unintentionally breaking functionality that downstream consumers rely on.

We'll skip over the happy path tests ([example 1](https://github.com/masterpointio/terraform-googleworkspace-users-groups-automation/blob/9b9112a2d3ff0f3d415813a8b4de11cefcab56a9/tests/variables_users.tftest.hcl#L52-L70), [example 2](https://github.com/masterpointio/terraform-googleworkspace-users-groups-automation/blob/9b9112a2d3ff0f3d415813a8b4de11cefcab56a9/tests/variables_users.tftest.hcl#L72-L89), [example 3](https://github.com/masterpointio/terraform-googleworkspace-users-groups-automation/blob/9b9112a2d3ff0f3d415813a8b4de11cefcab56a9/tests/variables_users.tftest.hcl#L140-L157)) we added to validate things like email and password validation, since these basic unit tests can be easily generated using Cursor, GitHub Copilot, or other AI code generation tools.

Below are more complex examples validating integration between different provider resources.

1. **Validate that user and group inputs result in a user being a group member.** We view this as an integration test because we are testing if a user and a group correctly integrate and result in a user_to_group instance.

```terraform
run "groups_member_role_success" {
command = apply
providers = {
googleworkspace = googleworkspace.mock
}
variables {
users = {
"[email protected]" = {
primary_email = "[email protected]"
family_name = "Last"
given_name = "First"
groups = {
"team" = {
role = "MEMBER"
}
}
}
}
groups = {
"team" = {
name = "Team"
email = "[email protected]"
}
}
}
assert {
condition = googleworkspace_group_member.user_to_groups["[email protected]/[email protected]"].role == "MEMBER"
error_message = "Expected 'role' to be 'MEMBER'."
}
}
```

2. **Test validations in the variables.tf file.** We added variable validations to catch bad inputs early. This provides a fast feedback loop during a `terraform plan` rather than only getting this feedback from the Google Admin SDK APIs when running `terraform apply`. During Infrastructure as Code audits, we look at Terraform CI/CD workflows to ensure PRs are `terraform plan`-ed before merging to catch issues where a variable input has a bad value.

```terraform
# users variable declaration
variable "users" {
description = "List of users"
type = map(object({
# other variable fields
groups: optional(map(object({
role: optional(string, "MEMBER"),
delivery_settings: optional(string, "ALL_MAIL"),
type: optional(string, "USER"),
})), {}),
primary_email : string,
}))

# validate users.groups.[group_key].type
validation {
condition = alltrue(flatten([
for user in var.users: [
for group in values(try(user.groups, {})): (
group.type == null || contains(["USER", "GROUP", "CUSTOMER"], upper(group.type))
)
]
]))
error_message = "group type must be either 'USER', 'GROUP', or 'CUSTOMER'"
}
}

run "group_member_type_invalid" {
command = plan
providers = {
googleworkspace = googleworkspace.mock
}
variables {
users = {
"[email protected]" = {
primary_email = "[email protected]"
family_name = "Type"
given_name = "Invalid"
groups = {
"test-group" = {
type = "INVALID-TYPE"
}
}
}
}
groups = {
"test-group" = {
name = "Test Group"
email = "[email protected]"
}
}
}

# we expect the users variable to fail the "users.groups.[group_key].type" validation block
expect_failures = [var.users]
}
```

There are 4 more complex tests, helping us ensure this module won't break in the future.

### Design Decision #2 - Choosing Intuitive Terraform Variable Structures

In the Google Workspace provider, provisioning a group involves declaring two resources: `group` and `group_settings`.

```terraform
resource "googleworkspace_group" "sales" {
email = "[email protected]"
}

resource "googleworkspace_group_settings" "sales_settings" {
email = googleworkspace_group.sales.email
who_can_join = "INVITED_CAN_JOIN"
}
```

This `group` and `group_setting` resource design mirrors Google's Admin SDK REST API structure. However, we felt that group settings more intuitively belonged as a nested attribute inside a group. So in our group variable, we added `settings`. Then, later, we extracted settings in the module's `local` block to meet the provider's expectations:

```terraform
# groups variable declaration
variable "groups" {
description = "List of groups"
type = map(object({
name: string,
email: string,
settings: optional(object({
who_can_join: optional(string),
}))
}))
}

# locals block
locals {
group_settings = {
for k, v in var.groups : k => merge(v.settings, { email = v.email })
}
}

# group_settings resource
resource "googleworkspace_group_settings" "defaults" {
for_each = local.group_settings
email = each.value.email
who_can_join = "INVITED_CAN_JOIN"
}
```

Yes, it's an abstraction which can sometimes lead to issues, but we think reducing cognitive friction for the module user is worth the added business logic in the Terraform code. Here's an example of a simpler configuration for groups:

```terraform
locals {
default_group_settings = {
who_can_join = "ALL_IN_DOMAIN_CAN_JOIN"
}
}

module "googleworkspace" {
source = "masterpointio/users-groups-automation/googleworkspace"
version = "X.X.X"

groups = {
support = {
name = "Support"
email = "[email protected]"
settings = merge(local.default_group_settings, {})
}
engineers = {
name = "Engineering"
email = "[email protected]"
settings = merge(local.default_group_settings, {
who_can_join = "INVITED_CAN_JOIN"
})
}
}
}
```

## Wrapping Up

With this setup in place and a `CODEOWNERS` file, we're now transparently, consistently, and securely managing users and groups within Google Workspace. This helps our engineering leader, Matt, avoid having to keep account setup details in his head. It also enables us as a team to avoid waiting on any one person. Need an adjustment to your Google user - like enabling AWS SSO for a specific user? Open a PR, get the right approval from the `CODEOWNERS`, merge it, and automation takes care of the rest. We love this workflow and we hope it's useful to you and your team!

Want help automating your Google Workspace configuration with Terraform? Need to make sure your Workspace policies stay consistent and auditable? Want to avoid onboarding chokepoints like Matt used to be?

We do short, high-impact automation projects like this for engineering teams all the time—with long-term impact. If your onboarding still runs on sticky notes and muscle memory, reach out and we'll streamline your onboarding process.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.