Terraform Configuration
The following shows how to configure Terraform.
Backend Prerequisites
The Terraform state is stored in OCI Object Storage. If the state bucket has not been created yet, it must be provisioned in the following way before running terraform init:
# Create the state bucket (one-time setup)
oci os bucket create \
--compartment-id <compartment-ocid> \
--name "your-terraform-state-bucket" \
--storage-tier Standard \
--profile <profile>Backend configuration
The backend.tf file declares an empty OCI backend
block:
backend "oci" {}
Backend parameters are supplied via .hcl files in
backend-configs/:
| File | Purpose |
|---|---|
backend-configs/primary-oci-example.hcl
| Primary workspace backend config template |
backend-configs/secondary-oci-example.hcl
| Secondary workspace backend config template |
Backend configuration fields:
| Field | Description |
|---|---|
| Bucket | Name of the OCI Object Storage bucket used to store Terraform state |
| namespace | OCI Object Storage namespace for the tenancy (retrieve with oci os ns get) |
| region | OCI region where the state bucket resides |
| key |
State file path within the bucket; the env:/ prefix
enables per-workspace state isolation
|
| auth |
Authentication method for the OCI provider (ApiKey for
API key-based auth)
|
config_file_profile
|
OCI CLI config profile to use for authentication (e.g.,
DEFAULT)
|
Example .hcl file:
bucket = "your-terraform-state-bucket"
namespace = "your-oci-namespace"
region = "<your-region>"
key = "env:/logscale-oci-oke"
auth = "ApiKey"
config_file_profile = "DEFAULT"
Separate backend configurations are required because each workspace stores
state independently. Using separate .hcl files ensures
that primary and secondary states don't collide and allows different backend
configurations per environment.
Workspace Setup
Each cluster uses a separate Terraform workspace. The workspace name must
match the workspace_name value in the corresponding
tfvars file. Workspaces must be created after
terraform init (the backend must be initialized before
workspace commands are available).
Important
terraform init is run once per backend configuration.
To switch between state files, use: terraform init -backend-config=<config> -reconfigure.
The -reconfigure flag tells Terraform to re-initialize the backend with the new config without migrating state.
Standalone deployment (single workspace):
# 1. Initialize with backend config (first time only)
terraform init -backend-config=backend-configs/primary-oci.hcl
# 2. Create the workspace (only needed once)
terraform workspace new primarySwitching between workspaces:
terraform workspace select primaryWorkspace Safety Validation
A safety mechanism prevents applying the wrong tfvars
file against the wrong workspace. Each tfvars file
includes a workspace_name variable, and a check block in
validation.tf verifies that this value matches the
current terraform.workspace at plan/apply time
Example tfvars:
workspace_name = "primary"
dr = ""
# ... other variablesSee the Terraform Variables README for a full list of configuration values.
If the current workspace does not match the workspace_name in
the tfvars file, Terraform will fail with an error:
============================================================================
ERROR: WORKSPACE MISMATCH DETECTED!
============================================================================
Current Terraform workspace: 'default'
workspace_name in tfvars: 'secondary'
To fix this, either:
1. Switch to the correct workspace:
terraform workspace select secondary
2. Or use the correct tfvars file for the 'default' workspace:
terraform plan -var-file=default-<region>.tfvars
============================================================================This prevents accidentally applying the primary configuration to the secondary cluster or vice versa.
Additional validation checks
(validation.tf also enforces):
| Check | Type | Condition | Error if violated |
|---|---|---|---|
bastion_client_allow_list_required
| check (warning) |
provision_bastion=true requires non-empty
bastion_client_allow_list
| Bastion deployed without client allow list |
control_plane_cidrs_required_for_public_endpoint
| check (warning) |
endpoint_public_access=true requires non-empty
control_plane_allowed_cidrs
| Public endpoint with no CIDR restrictions |
control_plane_cidrs_no_wildcard
| check (warning) |
control_plane_allowed_cidrs must not contain
0.0.0.0/0
| Kubernetes API exposed to the internet |
Hard validation locals (validation.tf). These fire as
blocking errors at plan time:
| Local | Condition | Error if violated |
|---|---|---|
cluster_config_validation
| Validates production readiness, storage, network, and security configuration | Aggregated error with specific failure details |
_resource_limit_check
| Validates total instances and block volumes within OCI per-AD limits | Requested resources exceed OCI limits |
security_compliant
|
0.0.0.0/0 in public_lb_cidrs
only allowed when use_external_health_check=true
| Security compliance failed |