Protected Terraform States: Add database migration and model [PART 1]
What does this MR do and why?
Create the data layer for Terraform state protection rules, enabling project maintainers to define rules that restrict who can write to a Terraform state based on project role and request source (PAT, CI job, CI on protected branch).
This is the foundational MR (1 of 7) for the protected Terraform states feature. It creates the terraform_state_protection_rules database table and the Terraform::StateProtectionRule model following the packages_protection_rules pattern.
What's included:
-
Database migration creating
terraform_state_protection_ruleswith:-
project_idFK (cascade delete) -
state_name(text, max 255 chars) — exact match against Terraform state name -
minimum_access_level_for_write(smallint enum: developer, maintainer, owner, admin) -
allowed_from(smallint enum: anywhere, ci_only, ci_on_protected_branch_only) - Unique composite index on
(project_id, state_name)
-
-
Model (
Terraform::StateProtectionRule) with enums usingGitlab::Accessconstants, validations, andfor_state_namescope -
Project association:
has_many :terraform_state_protection_rules - Factory and full model spec (14 examples)
- Database dictionary YAML metadata
No behavior changes yet — rules can only be created via Rails console. Enforcement, CRUD services, API endpoints, and UI follow in subsequent MRs.
References
- Epic: &15118
- POC MR: !224329 (closed)
- Reference pattern:
packages_protection_rules
Screenshots or screen recordings
Not applicable — backend-only changes.
How to set up and validate locally
- Run the migration:
bundle exec rails db:migrate - Open Rails console and create a rule:
project = Project.first rule = project.terraform_state_protection_rules.create!( state_name: 'production', minimum_access_level_for_write: :maintainer, allowed_from: :ci_only ) - Verify uniqueness — creating a second rule with the same project and state name raises
ActiveRecord::RecordInvalid - Verify cascade delete — deleting the project also deletes associated protection rules
- Verify the association:
project.terraform_state_protection_rulesreturns the created rules - Verify the scope:
Terraform::StateProtectionRule.for_state_name('production')returns matching rules
MR acceptance checklist
Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
MR Checklist (@gerardo-navarro)
- Changelog entry added, if necessary
- Documentation created/updated via this MR
- Documentation reviewed by technical writer or follow-up review issue created
- Tests added for this feature/bug
- Tested in all supported browsers
- Conforms to the code review guidelines
- Conforms to the style guides
- Conforms to the javascript style guides
- Conforms to the database guides
- Conforms to the merge request performance guidelines
- Migration follows zero-downtime migration principles
- Database dictionary YAML metadata file included