TerraformPilot

DevOps

Terraform for Ultra-Fast EV Charging Backend Infrastructure

Provision EV charging backend with Terraform: charger telemetry, billing APIs, grid analytics, location services, and edge monitoring on AWS.

LLuca Berton1 min read

Ultra-fast EV charging (350 kW+ and megawatt-class for trucking) is one of 2026's most visible build-outs. Behind every charger is a CSMS (Charging Station Management System) speaking OCPP 2.0.1, plus billing, roaming, grid analytics, and predictive maintenance. Terraform makes the cloud half repeatable per region and per operator.

This guide shows how to provision an ultra-fast EV charging backend on AWS.

Architecture

#
LayerAWS service
Charger ingest (OCPP)API Gateway WebSocket → Lambda
Session storeDynamoDB
BillingEventBridge → Lambda → Stripe
Grid analyticsTimestream + Managed Grafana
Location / availabilityDynamoDB + AppSync
Predictive maintenanceSageMaker + Lookout for Equipment

OCPP WebSocket Front Door

#
resource "aws_apigatewayv2_api" "ocpp" {
  name                       = "ocpp-csms"
  protocol_type              = "WEBSOCKET"
  route_selection_expression = "$request.body.action"
}
 
resource "aws_apigatewayv2_route" "boot" {
  api_id    = aws_apigatewayv2_api.ocpp.id
  route_key = "BootNotification"
  target    = "integrations/${aws_apigatewayv2_integration.ocpp.id}"
}
 
resource "aws_apigatewayv2_route" "stop" {
  api_id    = aws_apigatewayv2_api.ocpp.id
  route_key = "StopTransaction"
  target    = "integrations/${aws_apigatewayv2_integration.ocpp.id}"
}

Session State

#
resource "aws_dynamodb_table" "sessions" {
  name         = "ev_sessions"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "session_id"
 
  attribute {
    name = "session_id"
    type = "S"
  }
  attribute {
    name = "charger_id"
    type = "S"
  }
 
  global_secondary_index {
    name            = "by-charger"
    hash_key        = "charger_id"
    projection_type = "ALL"
  }
 
  stream_enabled   = true
  stream_view_type = "NEW_AND_OLD_IMAGES"
 
  point_in_time_recovery { enabled = true }
}

Billing via EventBridge

#
resource "aws_pipes_pipe" "session_to_billing" {
  name        = "session-to-billing"
  role_arn    = aws_iam_role.pipes.arn
  source      = aws_dynamodb_table.sessions.stream_arn
  target      = aws_lambda_function.billing.arn
 
  source_parameters {
    dynamodb_stream_parameters {
      starting_position = "LATEST"
      batch_size        = 10
    }
    filter_criteria {
      filter {
        pattern = jsonencode({
          eventName = ["MODIFY"]
          dynamodb  = { NewImage = { state = { S = ["completed"] } } }
        })
      }
    }
  }
}

Grid Analytics

#
resource "aws_timestreamwrite_table" "grid" {
  database_name = aws_timestreamwrite_database.ev.database_name
  table_name    = "grid_metrics"
 
  retention_properties {
    memory_store_retention_period_in_hours  = 24
    magnetic_store_retention_period_in_days = 730
  }
}
 
resource "aws_grafana_workspace" "ev" {
  account_access_type      = "CURRENT_ACCOUNT"
  authentication_providers = ["AWS_SSO"]
  permission_type          = "SERVICE_MANAGED"
  data_sources             = ["TIMESTREAM", "CLOUDWATCH"]
  role_arn                 = aws_iam_role.grafana.arn
}

Live Availability API

#
resource "aws_appsync_graphql_api" "availability" {
  name                = "ev-availability"
  authentication_type = "API_KEY"
  schema              = file("${path.module}/schema.graphql")
}
 
resource "aws_appsync_datasource" "sessions" {
  api_id           = aws_appsync_graphql_api.availability.id
  name             = "sessions"
  service_role_arn = aws_iam_role.appsync.arn
  type             = "AMAZON_DYNAMODB"
 
  dynamodb_config {
    table_name = aws_dynamodb_table.sessions.name
  }
}

Best Practices

#
  • Use DynamoDB streams + EventBridge Pipes to decouple billing from the OCPP path — billing failures must never block charging.
  • Sign OCPP messages with mutual TLS via API Gateway custom domains and ACM private CA-issued client certs.
  • Tag every session with site_id, cpo_id, tariff_id for FinOps and roaming reconciliation.
  • Replay sessions from a versioned S3 archive to debug billing disputes.
#
#Terraform#EV#AWS#IoT#OCPP

Share this article