Infrastructure Modules Reference
Mantle ships 13 OpenTofu modules. From 2.1.0 they are part of the published @j0nathan-ll0yd/cli package, so an instance sources them out of its own node_modules — the version is pinned by the instance's lockfile and moves only as a reviewed dependency bump:
module "core" { source = "../node_modules/@j0nathan-ll0yd/cli/modules/core" }mantle generate infra writes this path for you; you should not need to type it. Before 2.1.0 the only reachable copy was a sibling ../mantle checkout on disk, which meant a deploy applied whatever branch that working tree happened to be on. resolveModulesPath still falls back to a sibling checkout for instances pinned to an older CLI, and --modules-path still overrides everything.
Every module accepts name_prefix and tags from module.core.
core
Foundation module. Produces the naming prefix, common tags, and IAM assume-role policies consumed by every other module.
| Input | Type | Required | Description |
|---|---|---|---|
project_name | string | yes | Lowercase alphanumeric with hyphens |
environment | string | yes | dev, staging, or prod |
extra_tags | map(string) | no | Additional tags merged into common set |
| Output | Description |
|---|---|
name_prefix | Environment-aware prefix (e.g. staging) |
common_tags | Tag map for all resources |
account_id | AWS account ID |
region | AWS region |
lambda_assume_role_policy | IAM JSON for Lambda assume role |
lambda_gateway_assume_role_policy | IAM JSON for Lambda + API Gateway assume role |
lambda_edge_assume_role_policy | IAM JSON for Lambda@Edge assume role |
lambda_xray_policy_arn | ARN of shared X-Ray IAM policy |
Usage: aws-cloudformation-media-downloader/infra/main.tf
api-gateway
REST API Gateway with deployment, stage, optional custom authorizer, usage plan with API key, CORS error responses, and CloudWatch logging.
| Input | Type | Required | Description |
|---|---|---|---|
name_prefix | string | yes | From module.core |
tags | map(string) | yes | From module.core |
description | string | no | API description (default: "Mantle API") |
endpoint_type | string | no | REGIONAL, EDGE, or PRIVATE |
authorizer_lambda_invoke_arn | string | no | Invoke ARN for custom authorizer |
authorizer_ttl_seconds | number | no | Authorizer cache TTL (default: 300) |
create_usage_plan | bool | no | Create usage plan + API key (default: true) |
throttle_burst_limit | number | no | Max concurrent requests (default: 50) |
throttle_rate_limit | number | no | Requests/second (default: 100) |
quota_limit | number | no | Daily request quota (default: 10000) |
cors_allow_origin | string | no | CORS origin for error responses |
xray_tracing_enabled | bool | no | Enable X-Ray (default: true) |
redeployment_trigger | string | no | Hash to trigger redeployment |
| Output | Description |
|---|---|
rest_api_id | REST API ID |
rest_api_root_resource_id | Root resource ID for child resources |
rest_api_execution_arn | Execution ARN |
invoke_url | Base invoke URL |
api_key_value | API key (sensitive) |
authorizer_id | Custom authorizer ID |
stage_name | Deployed stage name |
api_name | API name (for CloudWatch dimensions) |
Usage: aws-cloudformation-media-downloader/infra/main.tf
lambda
Single Lambda function with IAM role, CloudWatch log group, and trigger configuration. One .tf file per Lambda in the instance's infra/ directory.
| Input | Type | Required | Description |
|---|---|---|---|
function_name | string | yes | Short name (prefixed with name_prefix) |
name_prefix | string | yes | From module.core |
source_dir | string | yes | Path to build output directory |
assume_role_policy | string | yes | IAM assume role JSON from module.core |
region | string | yes | AWS region |
account_id | string | yes | AWS account ID |
tags | map(string) | yes | From module.core |
environment | string | yes | dev, staging, or prod |
handler | string | no | Entrypoint (default: index.handler) |
runtime | string | no | Runtime (default: nodejs24.x) |
architecture | string | no | arm64 or x86_64 (default: arm64) |
memory_size | number | no | Memory in MB (default: 512) |
timeout | number | no | Timeout in seconds (default: 30) |
environment_variables | map(string) | no | Function-specific env vars |
layers | list(string) | no | Layer ARNs |
additional_policy_arns | list(string) | no | Extra IAM policy ARNs |
inline_policies | map(string) | no | Inline IAM policy JSON |
api_gateway_enabled | bool | no | API Gateway trigger |
sqs_trigger_arn | string | no | SQS trigger ARN |
schedule_expression | string | no | CloudWatch schedule |
eventbridge_rule_arns | list(string) | no | EventBridge rule ARNs |
is_edge_function | bool | no | Lambda@Edge mode (forces x86_64, enables publish) |
package_type | string | no | Zip or Image |
ephemeral_storage | number | no | Ephemeral storage in MB (512-10240) |
| Output | Description |
|---|---|
function_name | Full function name |
function_arn | Function ARN |
invoke_arn | Invoke ARN (for API Gateway) |
role_name | IAM role name |
role_arn | IAM role ARN |
log_group_name | CloudWatch log group name |
qualified_arn | Version-qualified ARN (for Lambda@Edge) |
Usage: aws-cloudformation-media-downloader/infra/lambda_health_sync.tf
database/aurora-dsql
Aurora DSQL cluster with IAM authentication policies for both per-Lambda roles (DbConnect) and migration admin (DbConnectAdmin).
| Input | Type | Required | Description |
|---|---|---|---|
name_prefix | string | yes | From module.core |
tags | map(string) | yes | From module.core |
deletion_protection | bool | no | Enable deletion protection (default: true) |
| Output | Description |
|---|---|
cluster_arn | DSQL cluster ARN |
cluster_identifier | Cluster identifier |
cluster_endpoint | Cluster endpoint ({id}.dsql.{region}.on.aws) |
connect_policy_arn | IAM policy ARN for DbConnect (per-Lambda) |
admin_connect_policy_arn | IAM policy ARN for DbConnectAdmin (migrations) |
Usage: mantle-LifegamesPortal/infra/main.tf
eventbridge
Custom EventBridge event bus. Rules and targets are generated per-Lambda by mantle generate infra.
| Input | Type | Required | Description |
|---|---|---|---|
bus_name | string | yes | Bus name suffix |
name_prefix | string | yes | From module.core |
tags | map(string) | yes | From module.core |
| Output | Description |
|---|---|
bus_name | Full EventBridge bus name |
bus_arn | EventBridge bus ARN |
Usage: mantle-LifegamesPortal/infra/eventbridge.tf
storage
S3 bucket with optional CloudFront distribution, CORS, transfer acceleration, intelligent tiering, and event notifications.
| Input | Type | Required | Description |
|---|---|---|---|
bucket_name | string | yes | Short bucket name |
name_prefix | string | yes | From module.core |
tags | map(string) | yes | From module.core |
project_name | string | no | For globally-unique naming |
cloudfront_enabled | bool | no | Create CloudFront distribution |
transfer_acceleration_enabled | bool | no | S3 transfer acceleration |
intelligent_tiering_enabled | bool | no | Auto storage class optimization |
cors_allowed_origins | list(string) | no | CORS origins |
versioning_enabled | bool | no | S3 versioning |
eventbridge_notifications_enabled | bool | no | S3 events to EventBridge |
lambda_notifications | list(object) | no | Direct Lambda notification targets |
| Output | Description |
|---|---|
bucket_id | S3 bucket ID |
bucket_arn | S3 bucket ARN |
bucket_regional_domain_name | Regional domain name |
cloudfront_domain_name | CloudFront domain (if enabled) |
cloudfront_distribution_id | CloudFront ID (if enabled) |
cloudfront_distribution_arn | CloudFront ARN (if enabled) |
Usage: mantle-LifegamesPortal/infra/storage.tf
queue
SQS queue with dead-letter queue, long polling, and optional DLQ alarm.
| Input | Type | Required | Description |
|---|---|---|---|
queue_name | string | yes | Short queue name |
name_prefix | string | yes | From module.core |
tags | map(string) | yes | From module.core |
visibility_timeout_seconds | number | no | Should be >= 6x consumer Lambda timeout (default: 180) |
max_receive_count | number | no | Attempts before DLQ (default: 3) |
receive_wait_time_seconds | number | no | Long polling wait (default: 20) |
retention_seconds | number | no | Message retention (default: 4 days) |
dlq_retention_seconds | number | no | DLQ retention (default: 14 days) |
enable_dlq_alarm | bool | no | DLQ CloudWatch alarm (default: true) |
alarm_sns_topic_arns | list(string) | no | SNS topics for alarm notifications |
| Output | Description |
|---|---|
queue_url | Main queue URL |
queue_arn | Main queue ARN |
queue_name | Main queue name |
dlq_url | Dead letter queue URL |
dlq_arn | Dead letter queue ARN |
dlq_name | Dead letter queue name |
Usage: aws-cloudformation-media-downloader/infra/queue.tf
sns
SNS topic with optional mobile push platform application (APNS/GCM).
| Input | Type | Required | Description |
|---|---|---|---|
topic_name | string | yes | Short topic name |
name_prefix | string | yes | From module.core |
tags | map(string) | no | From module.core |
platform | string | no | APNS, APNS_SANDBOX, GCM, or null |
platform_credential | string | no | Private key (APNS) or API key (GCM) |
platform_principal | string | no | SSL certificate (APNS only) |
| Output | Description |
|---|---|
topic_arn | SNS topic ARN |
topic_name | SNS topic name |
platform_application_arn | Platform app ARN (empty if no platform) |
Usage: aws-cloudformation-media-downloader/infra/sns.tf
dynamodb
DynamoDB table with optional GSIs, TTL, and point-in-time recovery.
| Input | Type | Required | Description |
|---|---|---|---|
table_name | string | yes | Short table name |
name_prefix | string | yes | From module.core |
hash_key | string | yes | Partition key attribute name |
attributes | list(object) | yes | Attribute definitions (name, type) |
tags | map(string) | yes | From module.core |
range_key | string | no | Sort key attribute name |
billing_mode | string | no | PAY_PER_REQUEST or PROVISIONED |
ttl_attribute | string | no | TTL attribute name |
global_secondary_indexes | list(object) | no | GSI definitions |
point_in_time_recovery | bool | no | Enable PITR |
table_name_override | string | no | Full name override (bypasses prefix) |
| Output | Description |
|---|---|
table_name | DynamoDB table name |
table_arn | DynamoDB table ARN |
table_id | DynamoDB table ID |
Usage: aws-cloudformation-media-downloader/infra/dynamodb.tf
idempotency
DynamoDB table pre-configured for Lambda Powertools idempotency (partition key id, TTL on expiration).
| Input | Type | Required | Description |
|---|---|---|---|
name_prefix | string | yes | From module.core |
tags | map(string) | yes | From module.core |
| Output | Description |
|---|---|
table_name | Idempotency table name |
table_arn | Idempotency table ARN |
observability
CloudWatch dashboard, Lambda/API/SQS/EventBridge alarms, and SNS alert topic.
| Input | Type | Required | Description |
|---|---|---|---|
name_prefix | string | yes | From module.core |
tags | map(string) | yes | From module.core |
enable_dashboard | bool | no | Create dashboard (default: false, costs $3/month) |
enable_alarms | bool | no | Create alarms (default: true) |
lambda_function_names | list(string) | no | Lambda functions to monitor |
lambda_error_threshold | number | no | Error count before alarm (default: 5) |
api_gateway_name | string | no | API name for monitoring |
api_5xx_threshold | number | no | 5xx count before alarm (default: 1) |
sqs_dlq_names | list(string) | no | DLQ names to alarm on |
eventbridge_rule_names | list(string) | no | EventBridge rules to alarm on |
custom_alarms | list(object) | no | Custom metric alarms |
| Output | Description |
|---|---|
sns_topic_arn | Alert SNS topic ARN (empty if alarms disabled) |
dashboard_url | CloudWatch dashboard URL (empty if disabled) |
websocket-api
WebSocket API Gateway with stage, route selection, and throttling.
| Input | Type | Required | Description |
|---|---|---|---|
name_prefix | string | yes | From module.core |
tags | map(string) | yes | From module.core |
route_selection_expression | string | no | Route selection (default: $request.body.action) |
stage_name | string | no | Stage name (default: live) |
throttling_burst_limit | number | no | Burst limit (default: 100) |
throttling_rate_limit | number | no | Rate limit (default: 50) |
| Output | Description |
|---|---|
api_id | WebSocket API ID |
api_endpoint | WebSocket endpoint URL |
execution_arn | Execution ARN (for Lambda permissions) |
stage_name | Stage name |
invoke_url | Full WebSocket URL (wss://.../{stage}) |
cloudfront-api
CloudFront distribution fronting an API Gateway origin, with optional Lambda@Edge associations and security headers.
| Input | Type | Required | Description |
|---|---|---|---|
origin_domain | string | yes | API Gateway domain |
name_prefix | string | yes | From module.core |
tags | map(string) | no | From module.core |
origin_path | string | no | Origin path prefix (e.g. /prod) |
forwarded_headers | list(string) | no | Headers to forward (default: Authorization, X-Api-Key) |
lambda_edge_associations | list(object) | no | Lambda@Edge associations |
enable_security_headers | bool | no | Attach security headers policy (default: true) |
price_class | string | no | Price class (default: PriceClass_100) |
geo_restriction_type | string | no | none, whitelist, or blacklist |
| Output | Description |
|---|---|
distribution_domain_name | CloudFront domain name |
distribution_id | Distribution ID |
distribution_arn | Distribution ARN |
Usage: aws-cloudformation-media-downloader/infra/cloudfront.tf