Tried to Launch Free Compute Resources on Oracle Cloud Infrastructure with Terraform but Failed Due to Capacity Shortage

oci

Oracle Cloud Infrastructure (OCI) offers free compute resources. However, they can only be created in the home region set during account creation. Since the Tokyo region was said to be running low on capacity, I created my account with the Osaka region.

Download the private key that serves as the API Key and note the Tenant and user OCIDs.

Create the resources with Terraform. The networking concepts are similar to AWS, just with different naming. Since I plan to connect via Tailscale, no ingress rules are configured.

TerraformでVPCを管理するmoduleを作る - sambaiz-net

Connect ECS Fargate to Tailscale and SSH from Smartphone via Termius - sambaiz-net

terraform {
  required_version = "~> 1.14"

  required_providers {
    oci = {
      source  = "oracle/oci"
      version = "~> 6.0"
    }
  }

  backend "local" {
    path = "terraform.tfstate"
  }
}

provider "oci" {
  tenancy_ocid     = var.tenancy_ocid     # Identifier of the tenancy (top-level account)
  user_ocid        = var.user_ocid        # Identifier of the user calling the API
  fingerprint      = var.fingerprint      # Fingerprint of the API signing key
  private_key_path = var.private_key_path # Path to the private key file for API signing
  region           = var.region           # Region to create resources in (e.g. ap-osaka-1)
}

# --- Networking ---

resource "oci_core_vcn" "garage" {
  compartment_id = var.tenancy_ocid
  display_name   = "garage-vcn"
  cidr_blocks    = ["10.0.1.0/24"]
  dns_label      = "garagevcn"
}

resource "oci_core_internet_gateway" "garage" {
  compartment_id = var.tenancy_ocid
  vcn_id         = oci_core_vcn.garage.id
  display_name   = "garage-igw"
  enabled        = true
}

resource "oci_core_route_table" "garage" {
  compartment_id = var.tenancy_ocid
  vcn_id         = oci_core_vcn.garage.id
  display_name   = "garage-rt"

  route_rules {
    network_entity_id = oci_core_internet_gateway.garage.id
    destination       = "0.0.0.0/0"
    destination_type  = "CIDR_BLOCK"
  }
}

resource "oci_core_security_list" "garage" {
  compartment_id = var.tenancy_ocid
  vcn_id         = oci_core_vcn.garage.id
  display_name   = "garage-sl"

  egress_security_rules {
    protocol    = "all"
    destination = "0.0.0.0/0"
    stateless   = false
  }

  # No ingress rules - garage is accessed via Tailscale only
}

resource "oci_core_subnet" "garage" {
  compartment_id             = var.tenancy_ocid
  vcn_id                     = oci_core_vcn.garage.id
  display_name               = "garage-subnet"
  cidr_block                 = "10.0.1.0/24"
  dns_label                  = "garagesub"
  route_table_id             = oci_core_route_table.garage.id
  security_list_ids          = [oci_core_security_list.garage.id]
  prohibit_public_ip_on_vnic = false
}

# --- Compute ---

data "oci_identity_availability_domains" "ads" {
  compartment_id = var.tenancy_ocid
}

# Ubuntu 24.04 aarch64 (Always Free compatible, portable across clouds)
data "oci_core_images" "ubuntu" {
  compartment_id           = var.tenancy_ocid
  operating_system         = "Canonical Ubuntu"
  operating_system_version = "24.04"
  shape                    = var.instance_shape
  sort_by                  = "TIMECREATED"
  sort_order               = "DESC"

  filter {
    name   = "display_name"
    values = ["^Canonical-Ubuntu-24\\.04-aarch64-[\\d\\.\\-]+$"]
    regex  = true
  }
}

resource "oci_core_instance" "garage" {
  compartment_id      = var.tenancy_ocid
  availability_domain = data.oci_identity_availability_domains.ads.availability_domains[0].name
  display_name        = "garage"
  shape               = var.instance_shape

  shape_config {
    ocpus         = var.instance_ocpus
    memory_in_gbs = var.instance_memory_gb
  }

  source_details {
    source_type             = "image"
    source_id               = data.oci_core_images.ubuntu.images[0].id
    boot_volume_size_in_gbs = var.boot_volume_gb
  }

  create_vnic_details {
    subnet_id        = oci_core_subnet.garage.id
    assign_public_ip = true
    display_name     = "garage-vnic"
  }

  metadata = {
    user_data           = base64encode(templatefile("${path.module}/cloud-init.yaml", {
      tailscale_auth_key = var.tailscale_auth_key
    }))
  }

  lifecycle {
    ignore_changes = [source_details[0].source_id]
  }
}

However, when I applied this, it failed due to capacity shortage. I tried to upgrade to a paid account, but it didn’t take effect immediately, so I haven’t tried other regions.

Error: 500-InternalError, Out of host capacity.