Complete OCI Free Tier Infrastructure Guide - Part 01: Setup & Local Provider Mirror
Setting up Oracle Cloud Infrastructure (OCI) using Terraform gives you an automated, reproducible "Always Free" cloud environment. However, managing backend state safely and dealing with air-gapped or restricted provider installations can introduce friction. In Part 01 of this series, we walk through configuring local credentials, OCI API integration, an S3-compatible backend for state management, an air-gapped local Terraform provider mirror, and a modular folder structure. Prerequisites - A local Linux machine (Debian/Ubuntu preferred) or WSL environment. - An active Oracle Cloud Infrastructure (OCI) Free Tier account. - OpenSSL, SSH, and Terraform installed. Phase 1: Local Machine Setup Generate local cryptographic keys required for SSH access to your instances and secure API authentication with OCI. 1.1 Generate SSH Key Pair (ED25519) Generate a high-security ED25519 key pair without a passphrase for non-interactive infrastructure management: ssh-keygen -t ed25519 -N "" -C "oci_vm_key" -f ~/.ssh/oci_vm_key This generates two files: - Private key: ~/.ssh/oci_vm_key (keep safe) - Public key: ~/.ssh/oci_vm_key.pub 1.2 Create OCI API Key Directory Restrict permissions on the configuration directory to preserve security standards: mkdir -p ~/.oci chmod 700 ~/.oci 1.3 Generate OCI API Key Pair (RSA 4096) OCI requires an RSA 4096-bit key pair for programmatic API authentication: # Generate private key openssl genrsa -out ~/.oci/oci.pem 4096 # Generate public key openssl rsa -pubout -in ~/.oci/oci.pem -out ~/.oci/oci_public.pem # Secure permissions (OCI rejects keys with permissions broader than 600) chmod 600 ~/.oci/oci.pem 1.4 Generate Key Fingerprint Extract the MD5 fingerprint of your public key. You will need this to verify API connectivity in the OCI Console: openssl rsa -pubout -in ~/.oci/oci.pem -outform DER | openssl md5 -c ๐ก Output Example: MD5(stdin)= 57:0d:ea:8c:07:11:22:33:44:55:66:77:88:99:aa:bb Phase 2: OCI Console Configuration 2.1 Upload API Public Key - Log into your OCI Console. - Navigate to Profile (top right icon) โ My Profile. - Under Resources (bottom left), click API Keys โ Add API Key. - Select Paste a Public Key. - Output the contents of ~/.oci/oci_public.pem and paste them into the text box: cat ~/.oci/oci_public.pem - Click Add. ๐ Save Configuration Details: A Configuration File Preview popup will appear. Copy these values-they contain youruser OCID,tenancy OCID,fingerprint , and your homeregion (e.g.,ap-hyderabad-1 ). 2.2 Retrieve Object Storage Namespace Your Object Storage namespace is a unique, system-generated string tied to your tenant. Retrieve it using the OCI CLI or Cloud Shell: oci os ns get Expected JSON output: { "data": "axjetxazylvl" } 2.3 Create the Terraform Remote State Bucket Store your .tfstate files remotely in OCI Object Storage: - Open Object Storage โ Buckets in the OCI Console. - Click Create Bucket. - Fill in the parameters: - Bucket Name: terraform-states - Default Storage Tier: Standard - Visibility: Private - Region: Select your Home Region - Bucket Name: - Click Create. 2.4 Generate S3-Compatible Credentials OCI Object Storage provides an S3-compatible API endpoint, allowing you to use standard S3 backend configurations in Terraform. - Go to Profile โ My Profile โ Customer Secret Keys. - Click Generate Secret Key. - Enter a display name: terraform-backend . - Click Generate Secret Key. โ ๏ธ Important: Copy and save the generated Secret Key immediately. It will never be displayed again. - Access Key: Visible in the Customer Secret Keys table (e.g., f4068126c6fd14c08a121d17396u317e6144e6a2 )- Secret Key: Copied from the modal dialog. Phase 3: Shell Environment Setup (~/.bashrc ) To prevent hardcoding sensitive credentials inside your Terraform code, export them as environment variables. Add the following block to the bottom of your ~/.bashrc file (replace placeholders with your actual OCIDs, keys, and paths): # ============================================================================= # OCI Provider Credentials # ============================================================================= export TF_VAR_tenancy_ocid="ocid1.tenancy.oc1..aaaaaaaa..." export TF_VAR_user_ocid="ocid1.user.oc1..aaaaaaaa..." export TF_VAR_fingerprint="57:0d:ea:8c:07:..." export TF_VAR_private_key_path="$HOME/.oci/oci.pem" export TF_VAR_region="ap-hyderabad-1" export TF_VAR_compartment_id="ocid1.tenancy.oc1..aaaaaaaa..." # ============================================================================= # S3-Compatible Backend Credentials (OCI Object Storage S3 API) # ============================================================================= export AWS_ACCESS_KEY_ID="f4068126c6..." export AWS_SECRET_ACCESS_KEY="YOUR_SECRET_KEY_HERE" export AWS_REQUEST_CHECKSUM_CALCULATION=when_required # ============================================================================= # Backend Configuration Variables # ============================================================================= export TF_VAR_backend_bucket="terraform-states" export TF_VAR_backend_namespace="axjetxazylvl" export TF_VAR_backend_region="ap-hyderabad-1" # ============================================================================= # SSH Key for VM Provisioning # ============================================================================= export TF_VAR_ssh_public_key_path="$HOME/.ssh/oci_vm_key.pub" # ============================================================================= # OCI CLI Path & Autocomplete (Adjust path to your user home) # ============================================================================= export PATH="$HOME/bin:$PATH" if [[ -f "$HOME/lib/oracle-cli/lib/python3.13/site-packages/oci_cli/bin/oci_autocomplete.sh" ]]; then source "$HOME/lib/oracle-cli/lib/python3.13/site-packages/oci_cli/bin/oci_autocomplete.sh" fi Apply the environment changes: source ~/.bashrc Phase 4: Offline / Local Provider Mirror Configuration If you want fast execution or operate in an environment with limited internet access, you can mirror the official OCI provider locally. 4.1 Create Directory Structure Build the target plugin directory structure expected by Terraform for oracle/oci version 6.20.0 : mkdir -p ~/.terraform.d/plugins-local/registry.terraform.io/oracle/oci/6.20.0/linux_amd64 4.2 Download and Unpack Provider Binary Download terraform-provider-oci_6.20.0_linux_amd64.zip directly from the HashiCorp or Oracle releases registry, place it in the created path, and unpack it: cd ~/.terraform.d/plugins-local/registry.terraform.io/oracle/oci/6.20.0/linux_amd64 # Unzip binary package unzip terraform-provider-oci_6.20.0_linux_amd64.zip # Rename provider binary to append protocol version target mv terraform-provider-oci_v6.20.0 terraform-provider-oci_v6.20.0_x5 # Clean up archive rm terraform-provider-oci_6.20.0_linux_amd64.zip Verify that your local mirror directory tree matches this structure: ~/.terraform.d/ โโโ plugins-local โโโ registry.terraform.io โโโ oracle โโโ oci โโโ 6.20.0 โโโ linux_amd64 โโโ terraform-provider-oci_v6.20.0_x5 4.3 Configure Global Provider Installation (~/.terraformrc ) Create a global CLI configuration file at ~/.terraformrc to force Terraform to load the OCI provider directly from your filesystem mirror instead of downloading it during terraform init : provider_installation { filesystem_mirror { path = "/home/YOUR_USER_NAME/.terraform.d/plugins-local" include = ["registry.terraform.io/oracle/oci"] } direct { exclude = ["registry.terraform.io/oracle/oci"] } } โ ๏ธ Note: Replace /home/YOUR_USER_NAME/ with the absolute path to your home directory (Terraform does not expand~ inside.terraformrc ). Phase 5: Project Directory Architecture To manage networking and compute instances independently without creating monolithic state files, isolate components into modular subdirectories: Create the workspace structure: mkdir -p ~/oci-infra/{shared,vm-amd,vm-arm} ~/oci-infra/ โโโ shared/ # VCN, subnets, IGW, route tables, security lists, buckets โ โโโ backend.tf โ โโโ provider.tf โ โโโ variables.tf โ โโโ main.tf โ โโโ outputs.tf โโโ vm-amd/ # Always Free x86 Instance (E2.1.Micro + Oracle Linux 9) โ โโโ backend.tf โ โโโ provider.tf โ โโโ variables.tf โ โโโ data.tf โ โโโ main.tf โ โโโ outputs.tf โโโ vm-arm/ # Always Free ARM Instance (A1.Flex + Oracle Linux 9) โโโ backend.tf โโโ provider.tf โโโ variables.tf โโโ data.tf โโโ main.tf โโโ outputs.tf Next Steps With your API keys generated, environment variables configured, local provider mirrored, and project folders structured, your system is ready. In Part 02, we will write the HCL declarations for the shared/ module-building a Virtual Cloud Network (VCN), public subnets, internet gateways, and locking down security lists within OCI Always Free limits. Top comments (0)
Comments
No comments yet. Start the discussion.