OCI Instance Pools let you maintain a group of identically configured compute instances and scale them in and out based on demand. An Instance Configuration is the launch template: it captures the shape, image, network configuration, user data, and tags. The Instance Pool uses that configuration to add or remove instances when autoscaling policies trigger. This post covers creating an Instance Configuration, Instance Pool, load balancer integration, and CPU-based autoscaling with Terraform.
Step 1: Instance Configuration
resource "oci_core_instance_configuration" "api_server_config" {
compartment_id = var.compartment_id
display_name = "orders-api-server-config-v2"
instance_details {
instance_type = "compute"
launch_details {
compartment_id = var.compartment_id
shape = "VM.Standard.E4.Flex"
display_name = "orders-api-server"
shape_config {
ocpus = 4
memory_in_gbs = 32
}
source_details {
source_type = "image"
image_id = var.orders_api_image_id
}
create_vnic_details {
subnet_id = var.app_subnet_id
nsg_ids = [var.app_server_nsg_id]
assign_public_ip = false
}
metadata = {
ssh_authorized_keys = var.ssh_public_key
user_data = base64encode(var.api_server_cloud_init)
}
defined_tags = {
"Operations.Environment" = "production"
"Operations.Application" = "orders"
"Operations.ManagedBy" = "terraform"
}
}
}
}
output "instance_config_id" { value = oci_core_instance_configuration.api_server_config.id }
Step 2: Instance Pool with Load Balancer
resource "oci_core_instance_pool" "api_server_pool" {
compartment_id = var.compartment_id
instance_configuration_id = oci_core_instance_configuration.api_server_config.id
display_name = "orders-api-server-pool"
size = 3 # Baseline: 3 instances
placement_configurations {
availability_domain = data.oci_identity_availability_domains.ads.availability_domains[0].name
primary_subnet_id = var.app_subnet_id
fault_domains = ["FAULT-DOMAIN-1", "FAULT-DOMAIN-2", "FAULT-DOMAIN-3"]
}
# Automatically register instances with the load balancer backend set
load_balancers {
load_balancer_id = var.production_lb_id
backend_set_name = "orders-api-backend-set"
port = 8080
vnic_selection = "PrimaryVnic"
}
defined_tags = { "Operations.Environment" = "production", "Operations.ManagedBy" = "terraform" }
}
output "pool_id" { value = oci_core_instance_pool.api_server_pool.id }
Step 3: Autoscaling Configuration
resource "oci_autoscaling_auto_scaling_configuration" "api_cpu_autoscaler" {
compartment_id = var.compartment_id
display_name = "orders-api-cpu-autoscaler"
is_enabled = true
auto_scaling_resources {
id = oci_core_instance_pool.api_server_pool.id
type = "instancePool"
}
policies {
policy_type = "threshold"
display_name = "cpu-based-scaling"
capacity {
initial = 3
min = 2
max = 12
}
rules {
display_name = "scale-out-high-cpu"
action {
type = "CHANGE_COUNT_BY"
value = 2 # Add 2 instances when scaling out
}
metric {
metric_type = "CPU_UTILIZATION"
threshold {
operator = "GT"
value = 75
}
}
}
rules {
display_name = "scale-in-low-cpu"
action {
type = "CHANGE_COUNT_BY"
value = -1 # Remove 1 instance when scaling in
}
metric {
metric_type = "CPU_UTILIZATION"
threshold {
operator = "LT"
value = 30
}
}
}
}
}
# Scheduled scaling: pre-scale before known peak hours
resource "oci_autoscaling_auto_scaling_configuration" "api_scheduled_scaling" {
compartment_id = var.compartment_id
display_name = "orders-api-scheduled-scale"
is_enabled = true
auto_scaling_resources {
id = oci_core_instance_pool.api_server_pool.id
type = "instancePool"
}
policies {
policy_type = "scheduled"
display_name = "peak-hours-scale-up"
execution_schedule {
type = "cron"
expression = "0 7 * * MON-FRI"
timezone = "Asia/Riyadh"
}
resource_action {
action_type = "power"
action = "START"
}
capacity {
initial = 8
min = 6
max = 12
}
}
}
Operational Notes
Instance Pools register new instances with the load balancer backend set automatically when the pool scales out and deregister them when scaling in. The load balancer health check must pass before the pool counts the instance as healthy. If your health check is slow, new instances may receive traffic before the application is fully initialized. Use a dedicated startup health endpoint that returns 200 only after all application dependencies (database connections, cache warmup) are ready.
Scale in conservatively and scale out aggressively. Set the scale-in action to remove one instance at a time and require the CPU threshold to be sustained for 10 minutes before scale-in triggers. Scale out by 2 instances immediately when CPU exceeds the threshold. This asymmetry prevents removing capacity too quickly during brief idle periods while still adding capacity fast when demand spikes.
Regards,
Osama
#OCI #OracleCloud #Autoscaling #InstancePool #Terraform #IaC #TechBlog #Oracle #PlatformEngineering #CloudCompute #FinOps #OracleCloudInfrastructure #LoadBalancer #InstanceConfiguration #ScaleOut #ScheduledScaling #HighAvailability #CloudNative #DevOps #ComputeOptimization
Leave a Reply