When you have more than a handful of microservices communicating with each other, you start adding the same things to every service: TLS for encryption, retry logic, circuit breaking, and latency metrics. These are infrastructure concerns, not application concerns. OCI Service Mesh is Oracle’s managed Envoy-based service mesh that provides mutual TLS between services without code changes, traffic management for canary deployments, and observability through metrics and distributed tracing.
Step 1: Mesh and Certificate Authority
resource "oci_identity_policy" "service_mesh_policy" {
compartment_id = var.compartment_id
name = "service-mesh-policy"
statements = [
"Allow any-user to manage service-mesh-family in compartment id ${var.compartment_id} where request.principal.type = 'cluster'",
"Allow any-user to manage certificate-authority-family in compartment id ${var.compartment_id} where request.principal.type = 'cluster'",
"Allow group ${var.platform_group} to manage service-mesh-family in compartment id ${var.compartment_id}"
]
}
resource "oci_certificates_management_certificate_authority" "mesh_ca" {
compartment_id = var.compartment_id
name = "service-mesh-ca"
kms_key_id = var.vault_key_id
certificate_authority_config {
config_type = "ROOT_CA_GENERATED_INTERNALLY"
subject {
common_name = "production-mesh-ca"
organization = "OsamaOracle"
}
signing_algorithm = "SHA512_WITH_RSA"
}
}
resource "oci_service_mesh_mesh" "production" {
compartment_id = var.compartment_id
display_name = "production-mesh"
certificate_authorities {
id = oci_certificates_management_certificate_authority.mesh_ca.id
}
mtls {
minimum = "PERMISSIVE" # Start permissive, move to STRICT after all services are enrolled
}
defined_tags = {
"Operations.Environment" = "production"
"Operations.ManagedBy" = "terraform"
}
}
output "mesh_id" { value = oci_service_mesh_mesh.production.id }
Step 2: Virtual Services and Deployments
resource "oci_service_mesh_virtual_service" "orders_api" {
compartment_id = var.compartment_id
mesh_id = oci_service_mesh_mesh.production.id
name = "orders-api"
hosts = ["orders-api"]
default_routing_policy { type = "UNIFORM" }
mtls { mode = "STRICT" }
}
# Stable version
resource "oci_service_mesh_virtual_deployment" "orders_api_v1" {
compartment_id = var.compartment_id
virtual_service_id = oci_service_mesh_virtual_service.orders_api.id
name = "orders-api-v1"
service_discovery {
type = "DNS"
hostname = "orders-api-v1.orders.svc.cluster.local"
}
listeners { protocol = "HTTP"; port = 8080 }
}
# Canary version
resource "oci_service_mesh_virtual_deployment" "orders_api_v2" {
compartment_id = var.compartment_id
virtual_service_id = oci_service_mesh_virtual_service.orders_api.id
name = "orders-api-v2"
service_discovery {
type = "DNS"
hostname = "orders-api-v2.orders.svc.cluster.local"
}
listeners { protocol = "HTTP"; port = 8080 }
}
Step 3: Canary Traffic Splitting
resource "oci_service_mesh_virtual_service_route_table" "orders_routes" {
compartment_id = var.compartment_id
virtual_service_id = oci_service_mesh_virtual_service.orders_api.id
name = "orders-api-canary-split"
priority = 1
route_rules {
type = "HTTP"
is_grpc = false
path = "/"
path_type = "PREFIX"
destinations {
virtual_deployment_id = oci_service_mesh_virtual_deployment.orders_api_v1.id
port = 8080
weight = 90 # 90% to stable
}
destinations {
virtual_deployment_id = oci_service_mesh_virtual_deployment.orders_api_v2.id
port = 8080
weight = 10 # 10% canary
}
}
}
Step 4: Ingress Gateway
resource "oci_service_mesh_ingress_gateway" "production" {
compartment_id = var.compartment_id
mesh_id = oci_service_mesh_mesh.production.id
name = "production-ingress-gateway"
hosts {
name = "api.yourdomain.com"
hostnames = ["api.yourdomain.com"]
listeners {
protocol = "HTTPS"
port = 443
tls {
mode = "TLS"
server_certificate {
type = "OCI_CERTIFICATES"
certificate_id = var.tls_certificate_id
}
}
}
}
access_logging { is_enabled = true }
}
resource "oci_service_mesh_ingress_gateway_route_table" "orders" {
compartment_id = var.compartment_id
ingress_gateway_id = oci_service_mesh_ingress_gateway.production.id
name = "orders-api-routes"
priority = 1
route_rules {
type = "HTTP"
ingress_gateway_host { name = "api.yourdomain.com"; port = 443 }
destinations {
virtual_service_id = oci_service_mesh_virtual_service.orders_api.id
port = 8080
}
}
}
Step 5: Enable Sidecar Injection on OKE
apiVersion: v1
kind: Namespace
metadata:
name: orders
labels:
oci.oraclecloud.com/injection: enabled
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: orders-api-v1
namespace: orders
spec:
template:
metadata:
annotations:
servicemesh.oci.oraclecloud.com/virtual-deployment-ocid: "ocid1.meshvirtualdeployment.oc1..your-vd-ocid"
spec:
containers:
- name: orders-api
image: me-jeddah-1.ocir.io/namespace/orders-api:1.2.3
ports:
- containerPort: 8080
Step 6: Access Policy for Service-to-Service mTLS
resource "oci_service_mesh_access_policy" "orders_to_inventory" {
compartment_id = var.compartment_id
mesh_id = oci_service_mesh_mesh.production.id
name = "orders-to-inventory"
rules {
action = "ALLOW"
source {
type = "VIRTUAL_SERVICE"
virtual_service_id = oci_service_mesh_virtual_service.orders_api.id
}
destination {
type = "VIRTUAL_SERVICE"
virtual_service_id = oci_service_mesh_virtual_service.inventory_api.id
}
}
}
# All other service-to-service communication is denied by default
# Only explicitly declared access policies are permitted
Operational Notes
Start the mesh in PERMISSIVE mTLS mode. Permissive mode accepts both mTLS and plain text traffic, letting you validate all services are correctly enrolled before enforcing encryption. Switch to STRICT only after every service-to-service call is confirmed to go through the mesh proxy. Switching to STRICT prematurely breaks any service still communicating over plain text.
Traffic weight changes take effect within seconds of a Terraform apply. For a production canary rollout, start at 5 percent, monitor error rate and latency for 30 minutes, increase to 10 then 25 then 50 then 100. If any step shows an error rate increase, set canary weight to 0 and apply. The rollback is as fast as the promotion.
Regards,
Osama
#OCI #OracleCloud #ServiceMesh #OKE #Kubernetes #mTLS #CloudNative #Terraform #TechBlog #Oracle #CanaryDeployment #TrafficManagement #Envoy #Microservices #OracleCloudInfrastructure #IaC #PlatformEngineering #DevSecOps #Observability #ZeroTrust
Leave a comment