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:

shell
# 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:

terraform
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:

HCL
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):

shell
# 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 primary

Switching between workspaces:

shell
terraform workspace select primary

Workspace 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:

terraform
workspace_name = "primary"
dr = ""
# ... other variables

See 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:

shell
============================================================================
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 ConditionError 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_cidrsPublic 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