Skip to content
Back to Blog
1 min read

Cloud Native Maturity: Where Organizations Stand in 2022

I wrote “Cloud Native Maturity: Where Organizations Stand in 2022” to share practical, production-minded guidance on this topic.

Cloud Native Maturity Model

Level 1: Cloud Hosted

  • Lift and shift migrations
  • VMs in the cloud
  • Traditional architectures

Level 2: Cloud Optimized

  • Using managed services
  • Basic automation
  • Some containerization

Level 3: Cloud Native

  • Microservices architecture
  • Kubernetes orchestration
  • CI/CD pipelines
  • Infrastructure as code

Level 4: Cloud Native Advanced

  • Service mesh
  • GitOps
  • Observability stack
  • Platform engineering

Level 5: Cloud Native Mastery

  • Developer self-service
  • Full automation
  • Chaos engineering
  • FinOps optimization

Assessment Framework

from enum import IntEnum
from dataclasses import dataclass
from typing import Dict, List

class MaturityLevel(IntEnum):
    CLOUD_HOSTED = 1
    CLOUD_OPTIMIZED = 2
    CLOUD_NATIVE = 3
    CLOUD_NATIVE_ADVANCED = 4
    CLOUD_NATIVE_MASTERY = 5

@dataclass
class MaturityDimension:
    name: str
    current_level: MaturityLevel
    practices: Dict[MaturityLevel, str]

def assess_cloud_native_maturity() -> Dict[str, MaturityDimension]:
    dimensions = {
        "infrastructure": MaturityDimension(
            name="Infrastructure",
            current_level=MaturityLevel.CLOUD_HOSTED,
            practices={
                MaturityLevel.CLOUD_HOSTED: "Manual provisioning, VMs",
                MaturityLevel.CLOUD_OPTIMIZED: "Some IaC, managed services",
                MaturityLevel.CLOUD_NATIVE: "Full IaC, containers, Kubernetes",
                MaturityLevel.CLOUD_NATIVE_ADVANCED: "GitOps, policy as code",
                MaturityLevel.CLOUD_NATIVE_MASTERY: "Self-healing, auto-scaling"
            }
        ),
        "application_architecture": MaturityDimension(
            name="Application Architecture",
            current_level=MaturityLevel.CLOUD_HOSTED,
            practices={
                MaturityLevel.CLOUD_HOSTED: "Monoliths",
                MaturityLevel.CLOUD_OPTIMIZED: "Modular monoliths",
                MaturityLevel.CLOUD_NATIVE: "Microservices",
                MaturityLevel.CLOUD_NATIVE_ADVANCED: "Event-driven, serverless",
                MaturityLevel.CLOUD_NATIVE_MASTERY: "Adaptive architectures"
            }
        ),
        "deployment": MaturityDimension(
            name="Deployment",
            current_level=MaturityLevel.CLOUD_HOSTED,
            practices={
                MaturityLevel.CLOUD_HOSTED: "Manual deployments",
                MaturityLevel.CLOUD_OPTIMIZED: "Basic CI/CD",
                MaturityLevel.CLOUD_NATIVE: "Automated pipelines",
                MaturityLevel.CLOUD_NATIVE_ADVANCED: "Progressive delivery",
                MaturityLevel.CLOUD_NATIVE_MASTERY: "Continuous deployment"
            }
        ),
        "observability": MaturityDimension(
            name="Observability",
            current_level=MaturityLevel.CLOUD_HOSTED,
            practices={
                MaturityLevel.CLOUD_HOSTED: "Basic monitoring",
                MaturityLevel.CLOUD_OPTIMIZED: "Centralized logging",
                MaturityLevel.CLOUD_NATIVE: "Metrics, traces, logs",
                MaturityLevel.CLOUD_NATIVE_ADVANCED: "Distributed tracing, SLOs",
                MaturityLevel.CLOUD_NATIVE_MASTERY: "AIOps, predictive"
            }
        ),
        "security": MaturityDimension(
            name="Security",
            current_level=MaturityLevel.CLOUD_HOSTED,
            practices={
                MaturityLevel.CLOUD_HOSTED: "Perimeter security",
                MaturityLevel.CLOUD_OPTIMIZED: "Basic cloud security",
                MaturityLevel.CLOUD_NATIVE: "DevSecOps, scanning",
                MaturityLevel.CLOUD_NATIVE_ADVANCED: "Zero trust, policy enforcement",
                MaturityLevel.CLOUD_NATIVE_MASTERY: "Security as code, auto-remediation"
            }
        )
    }
    return dimensions

Mature Cloud Native Practices

Infrastructure as Code

# Terraform - Mature IaC pattern
module "aks_cluster" {
  source = "./modules/aks"

  cluster_name        = var.cluster_name
  resource_group_name = azurerm_resource_group.main.name
  location            = var.location

  # GitOps configuration
  flux_enabled = true
  flux_repo    = "https://github.com/company/k8s-config"

  # Network configuration
  vnet_subnet_id = module.network.aks_subnet_id
  pod_cidr       = "10.244.0.0/16"
  service_cidr   = "10.0.0.0/16"

  # Node pools
  node_pools = [
    {
      name         = "system"
      node_count   = 3
      vm_size      = "Standard_D4s_v3"
      os_disk_size = 100
      node_labels  = { "nodepool-type" = "system" }
    },
    {
      name         = "workload"
      node_count   = 5
      vm_size      = "Standard_D8s_v3"
      auto_scaling = true
      min_count    = 3
      max_count    = 10
      node_labels  = { "nodepool-type" = "workload" }
    }
  ]

  # Security
  enable_azure_policy     = true
  enable_defender         = true
  enable_workload_identity = true

  tags = var.tags
}

GitOps Deployment

# Flux Kustomization
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: apps
  namespace: flux-system
spec:
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: flux-system
  path: ./apps/production
  prune: true
  healthChecks:
    - apiVersion: apps/v1
      kind: Deployment
      name: frontend
      namespace: production
    - apiVersion: apps/v1
      kind: Deployment
      name: api
      namespace: production
  postBuild:
    substitute:
      cluster_env: production
    substituteFrom:
      - kind: ConfigMap
        name: cluster-config

Progressive Delivery

# Flagger Canary deployment
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
  name: api
  namespace: production
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api
  progressDeadlineSeconds: 60
  service:
    port: 80
    targetPort: 8080
  analysis:
    interval: 1m
    threshold: 5
    maxWeight: 50
    stepWeight: 10
    metrics:
      - name: request-success-rate
        thresholdRange:
          min: 99
        interval: 1m
      - name: request-duration
        thresholdRange:
          max: 500
        interval: 1m
    webhooks:
      - name: load-test
        url: http://loadtester/
        timeout: 5s
        metadata:
          type: cmd
          cmd: "hey -z 1m -q 10 -c 2 http://api.production/"

Observability Stack

# OpenTelemetry Collector configuration
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

  prometheus:
    config:
      scrape_configs:
        - job_name: 'kubernetes-pods'
          kubernetes_sd_configs:
            - role: pod

processors:
  batch:
    timeout: 1s
    send_batch_size: 1024

  memory_limiter:
    check_interval: 1s
    limit_mib: 1000

  attributes:
    actions:
      - key: environment
        value: production
        action: insert

exporters:
  azuremonitor:
    connection_string: ${APPLICATIONINSIGHTS_CONNECTION_STRING}

  prometheus:
    endpoint: 0.0.0.0:8889

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, batch, attributes]
      exporters: [azuremonitor]

    metrics:
      receivers: [otlp, prometheus]
      processors: [memory_limiter, batch]
      exporters: [azuremonitor, prometheus]

Platform Engineering

The emerging discipline of building internal developer platforms:

# Backstage Software Catalog entry
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: order-service
  description: Handles order processing
  annotations:
    github.com/project-slug: company/order-service
    backstage.io/techdocs-ref: dir:.
    azure.com/application-insights: order-service-prod
spec:
  type: service
  lifecycle: production
  owner: team-commerce
  system: e-commerce
  providesApis:
    - order-api
  consumesApis:
    - inventory-api
    - payment-api
  dependsOn:
    - resource:default/orders-db
    - resource:default/orders-cache\n\n## Takeaways\n\n*Add a concise, personal takeaway and recommended next steps here.*\n
Michael John Peña

Michael John Peña

Senior Data Engineer based in Sydney. Writing about data, cloud, and technology.