Skip to content

Large Language Model-Augmented API (Terraform)

Source: examples/llm-augmented-api.yaml

To check and price this model from a clone of the repository:

infra-cost-model validate examples/llm-augmented-api.yaml
infra-cost-model compute --time-basis monthly examples/llm-augmented-api.yaml
# Example: Large Language Model-Augmented API (Terraform)
# Demonstrates: token-based cost propagation, asymmetric prompt/completion pricing,
# a Bedrock LLM node that calls a downstream Lambda, token flow through edges.
#
# Issue: https://github.com/elecnix/infra-cost-model/issues/9

version: "1.0"

workflow:
  name: llm-augmented-api
  entry: aws_apigatewayv2_api.llm_api
  frequency:
    unit: perMinute
    value: 100

nodes:
  aws_apigatewayv2_api.llm_api:
    nodeType: routing
    resourceAddress: aws_apigatewayv2_api.llm_api
    provider: aws
    region: us-east-1
    service: AmazonAPIGatewayHTTP
    usageMetrics:
      requests: { unit: requests, value: 1 }

  # An HTTP API has no egress price of its own. AWS bills the response bytes
  # as data transfer out to the internet.
  data_transfer.llm_api_egress:
    nodeType: external
    resourceAddress: data_transfer.llm_api_egress
    provider: aws
    region: us-east-1
    service: AWSDataTransfer
    usageMetrics:
      internetOutGb: { unit: GB, value: 0.000005 }    # 5KB per request

  aws_lambda_function.orchestrator:
    nodeType: compute
    resourceAddress: aws_lambda_function.orchestrator
    provider: aws
    region: us-east-1
    service: AWSLambda
    usageMetrics:
      invocations: { unit: requests, value: 1 }
      avgDurationMs: { unit: ms, value: 500 }
      memoryMb: { unit: MB, value: 256 }

  aws_bedrock_model.claude_sonnet:
    nodeType: compute
    resourceAddress: aws_bedrock_model.claude_sonnet
    provider: aws
    service: AmazonBedrock
    region: us-east-1
    pricingModel: token_based
    # Claude 3.5 Sonnet. The Bedrock handler maps inputTokens and
    # outputTokens to the Bedrock-Input-Token and Bedrock-Output-Token
    # catalog rows (#312).
    usageMetrics:
      inputTokens: { unit: tokens, value: 500 }
      outputTokens: { unit: tokens, value: 1000 }

  aws_s3_bucket.prompt_logs:
    nodeType: storage
    resourceAddress: aws_s3_bucket.prompt_logs
    provider: aws
    region: us-east-1
    service: AmazonS3
    usageMetrics:
      putRequests: { unit: requests, value: 1 }

  aws_lambda_function.processor:
    nodeType: compute
    resourceAddress: aws_lambda_function.processor
    provider: aws
    region: us-east-1
    service: AWSLambda
    usageMetrics:
      invocations: { unit: requests, value: 1 }
      avgDurationMs: { unit: ms, value: 200 }
      memoryMb: { unit: MB, value: 512 }

  aws_dynamodb_table.results:
    nodeType: storage
    resourceAddress: aws_dynamodb_table.results
    provider: aws
    region: us-east-1
    service: AmazonDynamoDB
    usageMetrics:
      writeRequests: { unit: requests, value: 1 }

edges:
  # Every response leaves AWS as data transfer out
  - from: aws_apigatewayv2_api.llm_api
    to: data_transfer.llm_api_egress
    rate: 1

  - from: aws_apigatewayv2_api.llm_api
    to: aws_lambda_function.orchestrator
    rate: 1
  - from: aws_lambda_function.orchestrator
    to: aws_bedrock_model.claude_sonnet
    rate: 1
    tokenFlow:
      input: 500                   # 500 prompt tokens per request
  - from: aws_lambda_function.orchestrator
    to: aws_s3_bucket.prompt_logs
    rate: 1
  - from: aws_bedrock_model.claude_sonnet
    to: aws_lambda_function.processor
    rate: 1
  - from: aws_lambda_function.processor
    to: aws_dynamodb_table.results
    rate: 1
    type: write