This tutorial is part of the Manage Bytebase with Terraform series:

๐Ÿ“š Complete tutorial terraform files on GitHub

File Structure: This tutorial series uses separate Terraform files for better organization. Files are numbered by tutorial part (e.g., 1-instances.tf for Part 1, 2-projects.tf for Part 2, etc.). Terraform automatically handles dependencies between files.

Learn how to manage users, groups, and access control policies using Terraform and the Terraform Bytebase Provider.

Bytebase Terraform Provider handles control plane configuration such as settings, policies, access controls. It does not handle data plane operations such as database creation, schema migrations, DML execution, query.

What Youโ€™ll Learn

  • Create users and service accounts for team members
  • Organize users into groups for easier management
  • Configure workspace-level IAM policies for role assignments
  • Set up project-level permissions with granular database access

Prerequisites

Before starting this tutorial, ensure you have:

Setup

From the previous tutorials, you should have:

  • Bytebase instances and projects configured
  • Workspace settings and approval flows set up
  • Service account with Workspace Admin role

Configure Access Control

Step 1 - Create Users

Create 5-user-iam.tf with user resources:

# Create users and service accounts
resource "bytebase_user" "workspace_admin" {
  email = "admin@example.com"
  title = "Workspace Admin"
  type  = "USER"
}

resource "bytebase_user" "tf_service_account" {
  email = "tf@service.bytebase.com"
  title = "Terraform Service Account"
  type  = "SERVICE_ACCOUNT"
}

resource "bytebase_user" "workspace_dba1" {
  email = "dba@example.com"
  title = "Database Administrator 1"
  type  = "USER"
}

resource "bytebase_user" "workspace_dba2" {
  email = "dba2@example.com"
  title = "Database Administrator 2"
  type  = "USER"
}

resource "bytebase_user" "dev1" {
  email = "dev1@example.com"
  title = "Developer 1"
  type  = "USER"
}

resource "bytebase_user" "dev2" {
  email = "dev2@example.com"
  title = "Developer 2"
  type  = "USER"
}

resource "bytebase_user" "dev3" {
  email = "dev3@example.com"
  title = "Developer 3"
  type  = "USER"
}

resource "bytebase_user" "qa1" {
  email = "qa1@example.com"
  title = "QA Tester 1"
  type  = "USER"
}

resource "bytebase_user" "qa2" {
  email = "qa2@example.com"
  title = "QA Tester 2"
  type  = "USER"
}

Apply and Verify Users

terraform plan
terraform apply

Verify in Bytebase:

  1. Go to IAM & Admin > Users & Groups
  2. You should see all 9 users created

Step 2 - Create Groups

Add the following groups to your 5-user-iam.tf file:

# Create groups
resource "bytebase_group" "developers" {
  email       = "developers@example.com"
  title       = "Developer Team"
  description = "Group for all developers"

  members {
    member = "users/${bytebase_user.dev1.email}"
    role   = "OWNER"
  }

  members {
    member = "users/${bytebase_user.dev2.email}"
    role   = "MEMBER"
  }

  members {
    member = "users/${bytebase_user.dev3.email}"
    role   = "MEMBER"
  }
}

resource "bytebase_group" "qa" {
  email       = "qa@example.com"
  title       = "QA Team"
  description = "Group for all QA testers"

  members {
    member = "users/${bytebase_user.qa1.email}"
    role   = "OWNER"
  }

  members {
    member = "users/${bytebase_user.qa2.email}"
    role   = "MEMBER"
  }
}

Apply and Verify Groups

terraform plan
terraform apply

Verify in Bytebase:

  1. Go to IAM & Admin > Users & Groups > Groups tab
  2. Click on Developer Team to see 3 members (dev1 as owner, dev2 and dev3 as members)
  3. Click on QA Team to see 2 members (qa1 as owner, qa2 as member)

Step 3 - Configure Workspace IAM Policy

Add the following workspace IAM policy to your 5-user-iam.tf file. Note that project roles assigned at workspace level apply to ALL projects:

resource "bytebase_iam_policy" "workspace_iam" {
  depends_on = [
    bytebase_user.workspace_admin,
    bytebase_user.tf_service_account,
    bytebase_user.workspace_dba1,
    bytebase_user.workspace_dba2,
    bytebase_group.qa
  ]

  parent = "workspaces/-"

  iam_policy {

    binding {
      role = "roles/workspaceAdmin"
      members = [
        format("user:%s", bytebase_user.workspace_admin.email),
        format("user:%s", bytebase_user.tf_service_account.email),
      ]
    }

    binding {
      role = "roles/workspaceDBA"
      members = [
        format("user:%s", bytebase_user.workspace_dba1.email),
        format("user:%s", bytebase_user.workspace_dba2.email)
      ]
    }

    binding {
      role = "roles/workspaceMember"
      members = [
        format("user:%s", bytebase_user.dev1.email),
        format("user:%s", bytebase_user.dev2.email),
        format("user:%s", bytebase_user.dev3.email),
        format("user:%s", bytebase_user.qa1.email),
        format("user:%s", bytebase_user.qa2.email)
      ]
    }

    binding {
      role = "roles/projectViewer"
      members = [
        format("group:%s", bytebase_group.qa.email),
      ]
      # Note: This grants projectViewer role to ALL projects in the workspace
    }
  }
}

Apply and Verify Workspace IAM

terraform plan
terraform apply

Verify in Bytebase:

  1. Go to IAM & Admin > Members
  2. Check user roles:
  3. Note that QA Team group has Project Viewer role for ALL projects

Step 4 - Configure Project IAM Policy

Add the following project IAM policy to your 5-user-iam.tf file. These roles only apply to Project Two, however, the project roles defined in workspace level will show in both Project One and Project Two:

resource "bytebase_iam_policy" "project_iam" {
  depends_on = [
    bytebase_group.developers,
    bytebase_user.workspace_dba1,
    bytebase_user.workspace_dba2
  ]

  parent = bytebase_project.project-two.name

  iam_policy {

    binding {
      role = "roles/projectOwner"
      members = [
        format("user:%s", bytebase_user.workspace_dba1.email),
        format("user:%s", bytebase_user.workspace_dba2.email)
      ]
    }

    binding {
      role = "roles/projectDeveloper"
      members = [
        "allUsers",
        format("group:%s", bytebase_group.developers.email)
      ]
    }

    binding {
      role = "roles/sqlEditorUser"
      members = [
        format("group:%s", bytebase_group.developers.email)
      ]
      condition {
        database         = "instances/prod-sample-instance/databases/hr_prod"
        schema           = "public"
        tables           = ["employee", "department"]
        expire_timestamp = "2027-07-10T16:17:49Z"
      }
    }

  }
}

Apply and Verify Project IAM

terraform plan
terraform apply

Verify in Bytebase:

  1. Go to Project One > Manage > Members:

    • QA Team: Project Viewer (inherited from workspace)
    • Terraform Service Account: Project Owner (as creator)

  2. Go to Project Two > Manage > Members:

    • QA Team: Project Viewer (inherited from workspace)
    • DBA users: Project Owner
    • All users + Developer Team: Project Developer
    • Developer Team: SQL Editor User (click edit to see table restrictions)

Step 5 - Test Access Control

Test the access control configuration:

  1. Set a password for Developer 1:

    • Go to IAM & Admin > Users & Groups
    • Find and click on Developer 1
    • Click Edit and set a password

  2. Log in as Developer 1 in a new browser/incognito window:

    • You should only see Project Two (not Project One)
    • Navigate to SQL Editor
  3. Test SQL Editor restrictions:

    • Connect to Prod > Prod Sample Instance > hr_prod
    • Try querying employee table - โœ… Should work
    • Try querying department table - โœ… Should work
    • Try querying salary table - โŒ Should fail with permission error

Access Control Patterns

The example demonstrates several key patterns:

  1. User Types: Regular users (USER) and service accounts (SERVICE_ACCOUNT)
  2. Group Management: Groups with owners and members for team organization
  3. Workspace Roles: Admin, DBA, and Member roles at workspace level
  4. Project Roles: Owner and Developer roles at project level
  5. Conditional Access: Time-limited, table-specific SQL Editor permissions

Key Points

  • IAM Hierarchy: Workspace policies apply globally, project policies are scoped to specific projects
  • Project Roles at Workspace Level: When assigned in workspace IAM, project roles (like projectViewer) apply to ALL projects
  • Group Benefits: Manage permissions for teams rather than individuals
  • Conditional Bindings: Fine-grained access control down to table level with expiration
  • Role Inheritance: Higher roles include permissions of lower roles

Next Steps

Continue the series: Manage Data Masking with Terraform - configure data masking policies to protect sensitive data.

Resources: