diff --git a/docs/tutorials/manage-data-masking-with-terraform.mdx b/docs/tutorials/manage-data-masking-with-terraform.mdx index abb42db6..a8b98d12 100644 --- a/docs/tutorials/manage-data-masking-with-terraform.mdx +++ b/docs/tutorials/manage-data-masking-with-terraform.mdx @@ -31,7 +31,7 @@ This tutorial is part of the **Bytebase Terraform Provider** series: - **Configure** data classification levels and categories - **Create** global masking policies that apply workspace-wide - **Set up** database-specific column masking -- **Grant** masking exceptions for specific users +- **Grant** masking exemptions for specific users ## Prerequisites @@ -146,40 +146,42 @@ resource "bytebase_setting" "classification" { title = "Classification Example" levels { - id = "1" title = "Level 1" + level = 1 } levels { - id = "2" title = "Level 2" + level = 2 } classifications { id = "1" title = "Basic" + level = 1 } classifications { id = "1-1" title = "User basic" - level = "1" + level = 1 } classifications { id = "1-2" title = "User contact info" - level = "2" + level = 2 } classifications { id = "2" title = "Employment" + level = 1 } classifications { id = "2-1" title = "Employment info" - level = "2" + level = 2 } } } @@ -227,7 +229,7 @@ resource "bytebase_policy" "global_masking_policy" { bytebase_setting.environments ] - parent = "workspaces/-" + # parent defaults to workspace when not specified. type = "MASKING_RULE" enforce = true inherit_from_parent = false @@ -235,21 +237,21 @@ resource "bytebase_policy" "global_masking_policy" { global_masking_policy { rules { - condition = "column_name == \"birth_date\"" + condition = "resource.column_name == \"birth_date\"" id = "birth-date-mask" semantic_type = "date-year-mask" title = "Mask Birth Date Year" } rules { - condition = "column_name == \"last_name\"" + condition = "resource.column_name == \"last_name\"" id = "last-name-first-letter-only" semantic_type = "name-first-letter-only" title = "Last Name Only Show First Letter" } rules { - condition = "classification_level in [\"2\"]" + condition = "resource.classification_level == 2" id = "classification-level-2" semantic_type = "full-mask" # Maps Level 2 classification to full-mask semantic type title = "Full Mask for Classification Level 2" @@ -339,50 +341,42 @@ Verify in Bytebase: ![dev1-salary](/content/docs/tutorials/manage-data-masking-with-terraform/bb-dev1-salary.webp) -## Step 6: Grant Masking Exceptions +## Step 6: Grant Masking Exemptions | | | | --------------------- | ---------------------------------------------------------------------------------------------------------------------- | | Terraform resource | [bytebase_policy](https://registry.terraform.io/providers/bytebase/bytebase/latest/docs/resources/policy) | -| Sample file | [8-5-masking-exception.tf](https://github.com/bytebase/terraform-provider-bytebase/blob/main/tutorials/8-5-masking-exception.tf) | +| Sample file | [8-5-masking-exemption.tf](https://github.com/bytebase/terraform-provider-bytebase/blob/main/tutorials/8-5-masking-exemption.tf) | -Create `8-5-masking-exception.tf` to grant bypass permissions: +Create `8-5-masking-exemption.tf` to grant bypass permissions: -- Workspace Admin (`admin@example.com`) has Masking Exemptions for `birth_date` in table `employee` for Query -- Workspace Admin (`admin@example.com`) has Masking Exemptions for `last_name` in table `employee` for Export +- Workspace Admin (`admin@example.com`) and QA Tester (`qa1@example.com`) have masking exemptions for `birth_date` and `last_name` in table `employee` +- Developer 1 (`dev1@example.com`) has exemption for specific columns via CEL expression -```hcl 8-5-masking-exception.tf -resource "bytebase_policy" "masking_exception_policy" { +```hcl 8-5-masking-exemption.tf +resource "bytebase_policy" "masking_exemption_policy" { depends_on = [ bytebase_project.project-two, bytebase_instance.prod ] parent = bytebase_project.project-two.name - type = "MASKING_EXCEPTION" + type = "MASKING_EXEMPTION" enforce = true inherit_from_parent = false - masking_exception_policy { - exceptions { + masking_exemption_policy { + exemptions { reason = "Business requirement" database = "instances/prod-sample-instance/databases/hr_prod" table = "employee" columns = ["birth_date", "last_name"] - members = ["user:admin@example.com"] - actions = ["QUERY", "EXPORT"] - expire_timestamp = "2027-07-30T16:11:49Z" - } - exceptions { - reason = "Export data for analysis" - members = ["user:qa1@example.com"] - actions = ["EXPORT"] + members = ["user:admin@example.com", "user:qa1@example.com"] expire_timestamp = "2027-07-30T16:11:49Z" } - exceptions { + exemptions { reason = "Grant query access" - members = ["user:dev1@example.com"] - actions = ["QUERY"] + members = ["user:dev1@example.com"] raw_expression = "resource.instance_id == \"prod-sample-instance\" && resource.database_name == \"hr_prod\" && resource.table_name == \"employee\" && resource.column_name in [\"first_name\", \"last_name\", \"gender\"]" } } @@ -407,14 +401,14 @@ If you specify `raw_expression`, it defines the exemption condition directly as ## Step 7: Apply Final Configuration and Test -Apply the masking exceptions and test everything: +Apply the masking exemptions and test everything: ```bash terraform plan terraform apply ``` -Verify the masking exceptions are working: +Verify the masking exemptions are working: 1. Log in as Workspace Admin (`admin@example.com`), then go to **SQL Editor** to access `hr_prod`, double-click `employee` table on the left. You may notice the `birth_date` is not masked any longer. diff --git a/docs/tutorials/manage-database-access-control-with-terraform.mdx b/docs/tutorials/manage-database-access-control-with-terraform.mdx index a61fd3a9..54668a07 100644 --- a/docs/tutorials/manage-database-access-control-with-terraform.mdx +++ b/docs/tutorials/manage-database-access-control-with-terraform.mdx @@ -72,13 +72,14 @@ Create `7-1-workspace-iam.tf` with workspace-level permissions: resource "bytebase_iam_policy" "workspace_iam" { depends_on = [ bytebase_user.workspace_admin, - bytebase_user.tf_service_account, + bytebase_service_account.tf_service_account, + bytebase_workload_identity.github_ci, bytebase_user.workspace_dba1, bytebase_user.workspace_dba2, bytebase_group.qa ] - parent = "workspaces/-" + # parent defaults to workspace when not specified. iam_policy { @@ -86,7 +87,9 @@ resource "bytebase_iam_policy" "workspace_iam" { role = "roles/workspaceAdmin" members = [ format("user:%s", bytebase_user.workspace_admin.email), - format("user:%s", bytebase_user.tf_service_account.email), + # Keep the Terraform-running service account as Workspace Admin so + # subsequent `terraform apply` runs retain full permissions. + format("serviceAccount:%s", bytebase_service_account.tf_service_account.email), ] } @@ -94,7 +97,8 @@ resource "bytebase_iam_policy" "workspace_iam" { role = "roles/workspaceDBA" members = [ format("user:%s", bytebase_user.workspace_dba1.email), - format("user:%s", bytebase_user.workspace_dba2.email) + format("user:%s", bytebase_user.workspace_dba2.email), + format("workloadIdentity:%s", bytebase_workload_identity.github_ci.email), ] } @@ -102,7 +106,6 @@ resource "bytebase_iam_policy" "workspace_iam" { role = "roles/workspaceMember" members = [ "allUsers" - # Note: a special member representing everyone in the workspace ] } @@ -111,7 +114,6 @@ resource "bytebase_iam_policy" "workspace_iam" { members = [ format("group:%s", bytebase_group.qa.email), ] - # Note: This grants projectViewer role to ALL projects in the workspace } } } @@ -134,7 +136,7 @@ terraform apply 1. Go to **IAM & Admin > Members** 1. Check user roles: - `admin@example.com`: Workspace Admin - - `tf@service.bytebase.com`: Workspace Admin + - `tf@service.bytebase.com` (service account): Workspace Admin - `dba@example.com`, `dba2@example.com`: Workspace DBA - `allUsers`: Workspace Member 1. Note that `QA Team` group has `Project Viewer` role for ALL projects diff --git a/docs/tutorials/manage-databases-with-terraform.mdx b/docs/tutorials/manage-databases-with-terraform.mdx index c7d8334f..76493332 100644 --- a/docs/tutorials/manage-databases-with-terraform.mdx +++ b/docs/tutorials/manage-databases-with-terraform.mdx @@ -86,7 +86,7 @@ resource "bytebase_instance" "test" { # Connection settings for the built-in test database data_sources { - id = "admin-test" + id = "admin data source test-sample-instance" type = "ADMIN" host = "/tmp" # Unix socket for local connection port = "8083" @@ -105,7 +105,7 @@ resource "bytebase_instance" "prod" { activation = true data_sources { - id = "admin-prod" + id = "admin data source prod-sample-instance" type = "ADMIN" host = "/tmp" port = "8084" diff --git a/docs/tutorials/manage-environments-with-terraform.mdx b/docs/tutorials/manage-environments-with-terraform.mdx index 6bddc7dc..84761e49 100644 --- a/docs/tutorials/manage-environments-with-terraform.mdx +++ b/docs/tutorials/manage-environments-with-terraform.mdx @@ -90,7 +90,7 @@ Navigate to **Environments** in Bytebase. You'll see two default environments: ` required_providers { bytebase = { source = "registry.terraform.io/bytebase/bytebase" - version = "3.8.6" # Check for latest version + version = "3.17.1" # Check for latest version } } } @@ -206,7 +206,7 @@ When no rollout policy is found for an environment, Bytebase applies a default r You can explicitly configure these policies using Terraform. Create `1-2-env-policy-rollout.tf`: ```hcl 1-2-env-policy-rollout.tf -# Test environment - automatic deployment with default checkers +# Test environment - automatic deployment resource "bytebase_policy" "rollout_policy_test" { depends_on = [bytebase_setting.environments] parent = bytebase_setting.environments.environment_setting[0].environment[0].name @@ -216,22 +216,12 @@ resource "bytebase_policy" "rollout_policy_test" { automatic = true # Deploy changes automatically roles = [ "roles/workspaceAdmin", - "roles/projectOwner", - "roles/LAST_APPROVER", - "roles/CREATOR" + "roles/projectOwner" ] - - # Default checkers (explicitly configured) - checkers { - required_issue_approval = true - required_status_checks { - plan_check_enforcement = "ERROR_ONLY" # Block on errors only - } - } } } -# Production - manual deployment with stricter checks +# Production - manual deployment resource "bytebase_policy" "rollout_policy_prod" { depends_on = [bytebase_setting.environments] parent = bytebase_setting.environments.environment_setting[0].environment[1].name @@ -241,18 +231,8 @@ resource "bytebase_policy" "rollout_policy_prod" { automatic = false # Require manual deployment roles = [ "roles/workspaceAdmin", - "roles/projectOwner", - "roles/LAST_APPROVER", - "roles/CREATOR" + "roles/projectOwner" ] - - # Enforce all plan checks (errors and warnings) - checkers { - required_issue_approval = true - required_status_checks { - plan_check_enforcement = "STRICT" # Block on both errors and warnings - } - } } } ``` @@ -261,11 +241,6 @@ resource "bytebase_policy" "rollout_policy_prod" { - `automatic`: When `true`, changes deploy automatically after approval. When `false`, requires manual click to deploy. - `roles`: List of roles allowed to manually deploy changes. Required even with automatic rollout, as manual approval is needed when checks fail. -- `checkers.required_issue_approval`: When `true`, requires issue approval before rollout. -- `checkers.required_status_checks.plan_check_enforcement`: Controls SQL plan check enforcement: - - `PLAN_CHECK_ENFORCEMENT_UNSPECIFIED`: Allow rollout regardless of plan check results (no enforcement) - - `ERROR_ONLY`: Block rollout only when plan check finds errors (default) - - `STRICT`: Block rollout when plan check finds errors or warnings (stricter for production) ### Data Protection Policy @@ -277,38 +252,22 @@ resource "bytebase_policy" "rollout_policy_prod" { Create `1-3-env-policy-data.tf`: ```hcl 1-3-env-policy-data.tf -# Prevent copying data in SQL Editor from production -resource "bytebase_policy" "disable_copy_data_policy_prod" { - depends_on = [bytebase_setting.environments] - parent = bytebase_setting.environments.environment_setting[0].environment[1].name - type = "DISABLE_COPY_DATA" - - disable_copy_data_policy { - enable = true # Block data copy - } -} - -# Restrict SQL execution in SQL Editor from production -resource "bytebase_policy" "data_source_query_policy_prod" { +# Restrict SQL Editor data access on production +resource "bytebase_policy" "query_data_policy_prod" { depends_on = [bytebase_setting.environments] parent = bytebase_setting.environments.environment_setting[0].environment[1].name - type = "DATA_SOURCE_QUERY" + type = "DATA_QUERY" - data_source_query_policy { - restriction = "RESTRICTION_UNSPECIFIED" - disallow_ddl = true # No schema changes via SQL Editor - disallow_dml = true # No data changes via SQL Editor + query_data_policy { + maximum_result_rows = 1000 + disable_copy_data = true # Block data copy + disable_export = true # Block data export + allow_admin_data_source = false # Restrict admin data source access } } ``` -- Here data protection policy is only applied to the `Prod` environment. Which means in `Test` environment, by default, users may execute DDL and DML statements or copy data directly in SQL Editor. - -- `restriction` controls [access to the data source](/sql-editor/settings/data-source-restriction): - - - `RESTRICTION_UNSPECIFIED`: Admin data source is allowed. - - `DISALLOW`: Admin data source is completely disallowed. - - `FALLBACK`: Prefer the read-only data source; use admin only if read-only is not configured. +- The data protection policy is only applied to the `Prod` environment. In the `Test` environment, by default, users may execute queries and copy data directly in SQL Editor. ## Step 6 - Apply Configuration diff --git a/docs/tutorials/manage-general-settings-with-terraform.mdx b/docs/tutorials/manage-general-settings-with-terraform.mdx index 5614c40c..9eb09c57 100644 --- a/docs/tutorials/manage-general-settings-with-terraform.mdx +++ b/docs/tutorials/manage-general-settings-with-terraform.mdx @@ -33,7 +33,6 @@ This tutorial is part of the **Bytebase Terraform Provider** series: ## What You'll Learn - **Configure** workspace profile settings including signup controls and external URL -- **Define** risk policies to automatically assess database operations - **Create** multi-step and risk-based approval flows for database changes ## Prerequisites @@ -72,7 +71,7 @@ resource "bytebase_setting" "workspace_profile" { disallow_signup = true domains = ["example.com"] enforce_identity_domain = false - external_url = "https://your-bytebase-url.com" + external_url = "https://example.com" } } ``` @@ -83,50 +82,16 @@ This configuration: - Restricts users to specific email domains - Sets your Bytebase workspace's external URL -### Step 2 - Risk Management Policies - -| | | -| --------------------- | ---------------------------------------------------------------------------------------------------------------------- | -| Terraform resource | [bytebase_risk](https://registry.terraform.io/providers/bytebase/bytebase/latest/docs/resources/risk) | -| Sample file | [4-2-risk.tf](https://github.com/bytebase/terraform-provider-bytebase/blob/main/tutorials/4-2-risk.tf) | - -Create `4-2-risk.tf` with risk policies to assess the database operations' risk level: - -```hcl 4-2-risk.tf -# Risk management policies -resource "bytebase_risk" "dml_moderate" { - title = "DML Moderate Risk" - source = "DML" - level = 200 - active = true - condition = "environment_id == \"prod\" && affected_rows >= 100" -} - -resource "bytebase_risk" "ddl_high" { - title = "DDL High Risk" - source = "DDL" - level = 300 - active = true - condition = "environment_id == \"prod\"" -} -``` - -Risk levels: - -- **100 (LOW)**. -- **200 (MODERATE)**: DML operations in production affecting 100+ rows -- **300 (HIGH)**: All DDL operations in production - -### Step 3 - Approval Flow Settings +### Step 2 - Approval Flow Settings | | | | --------------------- | ---------------------------------------------------------------------------------------------------------------------- | | Terraform resource | [bytebase_setting](https://registry.terraform.io/providers/bytebase/bytebase/latest/docs/resources/setting) | -| Sample file | [4-3-approval-flow.tf](https://github.com/bytebase/terraform-provider-bytebase/blob/main/tutorials/4-3-approval-flow.tf) | +| Sample file | [4-2-approval-flow.tf](https://github.com/bytebase/terraform-provider-bytebase/blob/main/tutorials/4-2-approval-flow.tf) | -Create `4-3-approval-flow.tf` with approval flow configuration that requires multiple approvals for risky operations: +Create `4-2-approval-flow.tf` with approval flow configuration that requires multiple approvals for risky operations: -```hcl 4-3-approval-flow.tf +```hcl 4-2-approval-flow.tf # Approval flow settings resource "bytebase_setting" "approval_flow" { name = "settings/WORKSPACE_APPROVAL" @@ -136,37 +101,43 @@ resource "bytebase_setting" "approval_flow" { flow { title = "Project Owner → DBA → Admin" description = "Need DBA and workspace admin approval" - - steps { role = "roles/projectOwner" } - steps { role = "roles/workspaceDBA" } - steps { role = "roles/workspaceAdmin" } - } - conditions { - source = "DML" - level = "MODERATE" + roles = [ + "roles/projectOwner", + "roles/workspaceDBA", + "roles/workspaceAdmin" + ] } - conditions { - source = "DDL" - level = "HIGH" + source = "CHANGE_DATABASE" + condition = "request.risk >= 100" + } + + rules { + flow { + title = "Fallback rule" + # Approval flow following the step order. + roles = [ + "roles/workspaceDBA" + ] } + condition = "true" } } } ``` -This creates a three-step approval flow that triggers for: +Each rule defines: +- `flow.roles`: An ordered list of roles that form the approval chain +- `source` (optional): The operation type to match for that rule (e.g., `CHANGE_DATABASE`, `CREATE_DATABASE`) +- `condition`: A CEL expression that determines when the rule applies -- DML operations with MODERATE risk level -- DDL operations with HIGH risk level - -### Step 4 - Apply Configuration +### Step 3 - Apply Configuration ```bash terraform plan terraform apply ``` -### Step 5 - Verify Configuration +### Step 4 - Verify Configuration #### Workspace Profile Settings @@ -174,14 +145,6 @@ terraform apply 1. Log out and try to signup which should be disabled. 1. Visit the external URL to verify it is set. -#### Risk Policies - -1. Go to **CI/CD > Risks** to view risk policies. - - ![risks](/content/docs/tutorials/manage-general-settings-with-terraform/bb-risks.webp) - -1. You should see both "DML Moderate Risk" and "DDL High Risk" policies active. - #### Approval Flows 1. Go to **CI/CD > Custom Approval** to see the approval flow. @@ -190,23 +153,10 @@ terraform apply 1. Verify the `Project Owner → DBA → Admin` flow is configured. -#### Test the Flow - -1. Go to `Project Two`, click **Database > Databases** on the left sidebar. -1. Check `hr_prod`, click **Edit Schema**, add a new table `t0`. -1. After creating the issue, you should see: - - - Risk level: `DDL High` - - Approval flow: `Project Owner → DBA → Admin` - - ![issue-risk-high](/content/docs/tutorials/manage-general-settings-with-terraform/bb-issue-risk-high.webp) - ## Key Points - **Workspace Profile**: Controls signup, domain restrictions, and external URL for your entire Bytebase workspace -- **Risk Policies**: Automatically assess database operations based on conditions like environment and affected rows -- **Approval Flows**: Define multi-step approval processes that trigger based on risk levels -- **Integration**: Risk policies and approval flows work together to ensure proper governance for database changes +- **Approval Flows**: Define multi-step approval processes with CEL conditions for database change governance You can configure additional diff --git a/docs/tutorials/manage-projects-with-terraform.mdx b/docs/tutorials/manage-projects-with-terraform.mdx index 01cb25f8..48500290 100644 --- a/docs/tutorials/manage-projects-with-terraform.mdx +++ b/docs/tutorials/manage-projects-with-terraform.mdx @@ -63,15 +63,36 @@ Create `3-projects.tf`: ```hcl 3-projects.tf # Project One - Development/Test Environment # Uses dynamic assignment to automatically include all test databases -resource "bytebase_project" "project_one" { +resource "bytebase_project" "project-one" { depends_on = [bytebase_instance.test] resource_id = "project-one" title = "Project One" - # Project-level configurations for development workflow - allow_modify_statement = true # Allow direct SQL modifications - auto_resolve_issue = false # Manual issue resolution for review - auto_enable_backup = false # Disable automatic backups for test data + # Project-level configurations + enforce_sql_review = true + require_issue_approval = true + require_plan_check_no_error = true + allow_request_role = true + allow_just_in_time_access = true + force_issue_labels = false + + # Issue labels + issue_labels { + value = "schema-change" + color = "#0066CC" + group = "type" + } + issue_labels { + value = "data-change" + color = "#CC6600" + group = "type" + } + + # Project labels + labels = { + environment = "test" + team = "platform" + } # Dynamically include all databases from the test instance databases = bytebase_instance.test.databases @@ -82,16 +103,16 @@ resource "bytebase_project" "project_one" { type = "SLACK" url = "https://webhook.site/91fcd52a-39f1-4e7b-a43a-ddf72796d6b1" notification_types = [ - "NOTIFY_ISSUE_APPROVED", - "NOTIFY_PIPELINE_ROLLOUT", - "ISSUE_CREATE", + "ISSUE_CREATED", + "ISSUE_APPROVAL_REQUESTED", + "PIPELINE_COMPLETED", ] } } # Project Two - Production Environment # Uses explicit assignment for precise control over production databases -resource "bytebase_project" "project_two" { +resource "bytebase_project" "project-two" { depends_on = [bytebase_instance.prod] resource_id = "project-two" title = "Project Two" @@ -167,7 +188,7 @@ Congratulations! You've successfully organized your databases into logical proje - **Project Organization**: Projects serve as logical containers that group related databases for improved management and governance - **Assignment Flexibility**: Choose between dynamic assignment (automatic inclusion) for development environments or explicit assignment (manual control) for production - **Cross-Environment Projects**: Projects can span multiple environments, though it's often better to separate test and production databases into different projects -- **Project Configuration**: Customize project behavior with settings like statement modification permissions, automatic issue resolution, and backup policies +- **Project Configuration**: Customize project behavior with settings like SQL review enforcement, issue approval requirements, and access controls - **Notification Integration**: Set up webhooks to keep your team informed about project activities through Slack or other channels