Deploy OpenClaw AI on AWS EC2 with Terraform and EBS Storage
Deploy OpenClaw AI on AWS EC2 with Terraform: Ubuntu 24.04, gp3 EBS for persistent agent data, SSH key pair, security group, and user-data bootstrap.
DevOps
Provision mobile app backends with Terraform: AWS Amplify, Cognito auth, AppSync GraphQL, S3 user content, and push notifications via SNS.
Mobile apps on iOS and Android live or die by their backend: auth, sync API, file storage, push, and analytics. Terraform doesn't ship apps to the App Store, but it provisions the entire AWS backend that 90% of mobile apps rely on. This guide shows the canonical stack: Cognito + AppSync + DynamoDB + S3 + SNS + Pinpoint.
| Capability | AWS service |
|---|---|
| User auth | Cognito User Pool + Identity Pool |
| Sync API | AppSync (GraphQL) + DynamoDB |
| User content | S3 with presigned URLs |
| Push | SNS Mobile Push (APNs + FCM) |
| Analytics | Pinpoint |
resource "aws_cognito_user_pool" "users" {
name = "app-users"
password_policy {
minimum_length = 12
require_lowercase = true
require_numbers = true
require_symbols = true
require_uppercase = true
}
mfa_configuration = "OPTIONAL"
software_token_mfa_configuration {
enabled = true
}
username_attributes = ["email"]
auto_verified_attributes = ["email"]
}
resource "aws_cognito_user_pool_client" "mobile" {
name = "mobile"
user_pool_id = aws_cognito_user_pool.users.id
generate_secret = false # mobile apps can't keep secrets
refresh_token_validity = 30
access_token_validity = 60
id_token_validity = 60
token_validity_units {
refresh_token = "days"
access_token = "minutes"
id_token = "minutes"
}
explicit_auth_flows = [
"ALLOW_USER_SRP_AUTH",
"ALLOW_REFRESH_TOKEN_AUTH",
]
}resource "aws_appsync_graphql_api" "api" {
name = "app-api"
authentication_type = "AMAZON_COGNITO_USER_POOLS"
user_pool_config {
user_pool_id = aws_cognito_user_pool.users.id
aws_region = var.region
default_action = "ALLOW"
}
schema = file("${path.module}/schema.graphql")
log_config {
cloudwatch_logs_role_arn = aws_iam_role.appsync_logs.arn
field_log_level = "ERROR"
}
}
resource "aws_appsync_datasource" "todos" {
api_id = aws_appsync_graphql_api.api.id
name = "todos"
service_role_arn = aws_iam_role.appsync.arn
type = "AMAZON_DYNAMODB"
dynamodb_config {
table_name = aws_dynamodb_table.todos.name
}
}resource "aws_s3_bucket" "user_content" {
bucket = "app-user-content"
}
resource "aws_s3_bucket_cors_configuration" "user_content" {
bucket = aws_s3_bucket.user_content.id
cors_rule {
allowed_headers = ["*"]
allowed_methods = ["GET", "PUT", "POST", "HEAD"]
allowed_origins = ["*"]
expose_headers = ["ETag"]
max_age_seconds = 3000
}
}The mobile app calls a Lambda that issues short-lived presigned URLs scoped to users/<sub>/... so users only see their own files.
resource "aws_sns_platform_application" "ios" {
name = "ios-app"
platform = "APNS" # APNS_SANDBOX for dev
platform_credential = file(var.apns_p8_path)
platform_principal = var.apns_team_id
}
resource "aws_sns_platform_application" "android" {
name = "android-app"
platform = "GCM"
platform_credential = var.fcm_server_key
}generate_secret = false + SRP is the safe path.arn:aws:s3:::bucket/users/$${cognito-identity.amazonaws.com:sub}/*.Deploy OpenClaw AI on AWS EC2 with Terraform: Ubuntu 24.04, gp3 EBS for persistent agent data, SSH key pair, security group, and user-data bootstrap.
Provision multiplayer game server backends with Terraform: AWS GameLift fleets, FlexMatch matchmaking, queues, and player session APIs.
Provision macOS CI build infrastructure with Terraform: EC2 Mac instances (mac1, mac2-m2pro), dedicated hosts, and self-hosted GitHub Actions runners.
Provision Windows Server 2025 on AWS EC2 with Terraform. Includes AMI selection, password retrieval, RDP, IIS, and joining Active Directory.