Opentofu CI CD

Published
Length
3 min read

Luis Felipe Dias

All posts

You set up an opentofu ci cd pipeline by automating plan and apply jobs. A runner checks your code, runs a plan on pull requests, and applies changes after merge. Most teams start by giving the pipeline runner a broad cloud admin role. That setup works at first, but wide permissions create risk if a bad script runs. Anyone who can edit pipeline files can use those broad keys to change production resources. How an opentofu ci cd workflow operates A standard pipeline splits the work into two ma

CI/CD Credential Management: the complete guide

Architecture patterns, implementation strategies, and security best practices. Delivered to your inbox.

Free white paper. No spam. Unsubscribe anytime.

You set up an opentofu ci cd pipeline by automating plan and apply jobs. A runner checks your code, runs a plan on pull requests, and applies changes after merge. Most teams start by giving the pipeline runner a broad cloud admin role. That setup works at first, but wide permissions create risk if a bad script runs. Anyone who can edit pipeline files can use those broad keys to change production resources.

How an opentofu ci cd workflow operates

A standard pipeline splits the work into two main steps: planning and applying. First, a developer opens a pull request with code changes in the version control system. The pipeline starts a job that loads the OpenTofu tool on a clean runner. The runner logs in to the cloud provider and reads the shared state file. It also places a lock on that state file so two jobs cannot clash. Then, the runner builds a plan that shows what resources will change, add, or drop. The pipeline posts this plan back to the pull request for the team to check.

Second, a team member reviews the plan and merges the pull request into the main branch. This merge triggers the apply job on the runner. The runner logs in again, locks the state, and makes the real cloud changes. When the job finishes, it writes the new state and drops the lock. Teams store this state in a remote bucket so every runner sees the same truth.

Why teams move from static keys to workload identity

Early pipelines often use static cloud keys saved in the runner secret store. Static keys do not expire on their own, and people forget to rotate them. If a key leaks in a build log, an attacker can use it from anywhere. Modern pipelines fix this by using OpenID Connect to log in without static keys. The version control system signs a short token for the specific job run. The cloud provider checks that token and grants a temporary role to the runner. When the job ends, the token dies, and no long-term secrets sit in storage.

Teams also split roles between the plan step and the apply step. The plan job gets a read-only role so a pull request cannot alter live systems. Only the apply job on the main branch gets a role that can write changes. Even so, the write role still needs wide rights because OpenTofu manages many resource types.

CI/CD Credential Management: architecture patterns and best practices

Continue reading? Get the full guide.

Free. No spam. Unsubscribe anytime.

What native pipeline roles solve and what they miss

Native workload identity and branch rules solve the problem of who can start a job. They also remove static keys from your version control settings. Branch protection ensures that a human approves the code before the apply job starts. Separating read and write roles stops unmerged pull requests from breaking production.

Still, native cloud roles only check who logs in when the job begins. They do not inspect the actual commands or database calls that run during the job. Once the apply runner holds an active admin role, it can run any command allowed. If a module contains a local script or talks to a database, cloud roles cannot filter those actions. A broken script or bad dependency can read private data like emails, phone numbers, or card numbers. Standard pipeline logs also struggle to link every downstream action back to the person who approved it.

Govern statements and responses across databases and APIs

Good config and scoped roles are needed setup. They do not check single queries in flight or mask sensitive fields in returned rows. Across Postgres, MySQL, SQL Server, MongoDB, ClickHouse, Kubernetes APIs, SSH, and internal HTTP endpoints, hoop.dev sits inline in the protocol beside each supported service as an open-source proxy, a sidecar for your database or API. For every query or command an AI agent or engineer runs against production, hoop.dev decides to pass, mask, block, or hold it for human approval.

First, hoop.dev guardrails block banned queries before they run or hold risky ones for review, and hoop.dev data masking rewrites matched sensitive values in responses in memory. Furthermore, hoop.dev holds SOC 2 Type II and is open source on GitHub.

Frequently asked questions

How do you prevent two pipeline runs from changing state at once?

You use remote state storage that supports state locking. When a job starts, OpenTofu locks the state file and blocks other runs until it finishes.

Should you run the apply step on a pull request before merging?

Applying before merge can work if your tool locks the branch until the merge completes. Most teams prefer to apply after merge so the main branch always matches live systems.

How do you handle secret values inside OpenTofu state files?

OpenTofu stores raw values in the state file even if you mark variables as sensitive. You must encrypt the remote state bucket and restrict who can read that bucket directly.

Save the open-source gateway.

hoop is MIT-licensed infrastructure for controlling how AI agents reach production data. Star hoophq/hoop so you can inspect it, deploy it, or share it when your team starts governing agent access.