AWSTemplateFormatVersion: '2010-09-09' Description: 'OpenClaw Multi-Deployment - Master Stack (All-in-One Deployment)' Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: 'Basic Configuration' Parameters: - KeyPairName - InstanceCount - InstanceNamePrefix - NotificationEmail - Label: default: 'Instance Configuration' Parameters: - InstanceType - BedrockModel - VolumeSize - Label: default: 'Scaling Configuration' Parameters: - MinSize - DesiredCapacity - MaxSize - Label: default: 'Advanced Options' Parameters: - UseSpotInstances - EnableDetailedMonitoring - DeployVPCEndpoints Parameters: KeyPairName: Description: EC2 Key Pair for SSH access Type: AWS::EC2::KeyPair::KeyName ConstraintDescription: Must be an existing EC2 key pair InstanceCount: Description: Number of OpenClaw instances to deploy Type: Number Default: 1 MinValue: 1 MaxValue: 10 ConstraintDescription: Must be between 1 and 10 InstanceNamePrefix: Description: Prefix for instance names (will add -1, -2, -3...) Type: String Default: 'openclaw' MinLength: 3 MaxLength: 24 AllowedPattern: '^[a-z0-9-]+$' ConstraintDescription: 'Only lowercase letters, numbers, and hyphens' NotificationEmail: Description: Email for CloudWatch alarms (optional) Type: String Default: '' AllowedPattern: '^$|^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$' ConstraintDescription: 'Must be a valid email address or empty' InstanceType: Description: EC2 instance type Type: String Default: 't4g.medium' AllowedValues: - t4g.small - t4g.medium - t4g.large - t4g.xlarge - c7g.large - c7g.xlarge BedrockModel: Description: Bedrock model ID Type: String Default: 'global.amazon.nova-2-lite-v1:0' AllowedValues: - 'global.amazon.nova-2-lite-v1:0' - 'us.amazon.nova-pro-v1:0' - 'global.anthropic.claude-sonnet-4-5-20250929-v1:0' MinSize: Description: Minimum number of instances Type: Number Default: 1 MinValue: 0 MaxValue: 10 DesiredCapacity: Description: Desired number of instances Type: Number Default: 1 MinValue: 0 MaxValue: 10 MaxSize: Description: Maximum number of instances Type: Number Default: 3 MinValue: 1 MaxValue: 10 VolumeSize: Description: EBS volume size in GB Type: Number Default: 30 MinValue: 20 MaxValue: 500 UseSpotInstances: Description: Use Spot Instances (70% cost savings) Type: String Default: 'false' AllowedValues: ['true', 'false'] EnableDetailedMonitoring: Description: Enable detailed CloudWatch monitoring Type: String Default: 'false' AllowedValues: ['true', 'false'] DeployVPCEndpoints: Description: Deploy VPC Endpoints (recommended for production) Type: String Default: 'true' AllowedValues: ['true', 'false'] Conditions: HasEmail: !Not [!Equals [!Ref NotificationEmail, '']] DeployEndpoints: !Equals [!Ref DeployVPCEndpoints, 'true'] Deploy1: !Not [!Equals [!Ref InstanceCount, 0]] Deploy2: !Or [!Equals [!Ref InstanceCount, 2], !Equals [!Ref InstanceCount, 3], !Equals [!Ref InstanceCount, 4], !Equals [!Ref InstanceCount, 5], !Equals [!Ref InstanceCount, 6], !Equals [!Ref InstanceCount, 7], !Equals [!Ref InstanceCount, 8], !Equals [!Ref InstanceCount, 9], !Equals [!Ref InstanceCount, 10]] Deploy3: !Or [!Equals [!Ref InstanceCount, 3], !Equals [!Ref InstanceCount, 4], !Equals [!Ref InstanceCount, 5], !Equals [!Ref InstanceCount, 6], !Equals [!Ref InstanceCount, 7], !Equals [!Ref InstanceCount, 8], !Equals [!Ref InstanceCount, 9], !Equals [!Ref InstanceCount, 10]] Deploy4: !Or [!Equals [!Ref InstanceCount, 4], !Equals [!Ref InstanceCount, 5], !Equals [!Ref InstanceCount, 6], !Equals [!Ref InstanceCount, 7], !Equals [!Ref InstanceCount, 8], !Equals [!Ref InstanceCount, 9], !Equals [!Ref InstanceCount, 10]] Deploy5: !Or [!Equals [!Ref InstanceCount, 5], !Equals [!Ref InstanceCount, 6], !Equals [!Ref InstanceCount, 7], !Equals [!Ref InstanceCount, 8], !Equals [!Ref InstanceCount, 9], !Equals [!Ref InstanceCount, 10]] Deploy6: !Or [!Equals [!Ref InstanceCount, 6], !Equals [!Ref InstanceCount, 7], !Equals [!Ref InstanceCount, 8], !Equals [!Ref InstanceCount, 9], !Equals [!Ref InstanceCount, 10]] Deploy7: !Or [!Equals [!Ref InstanceCount, 7], !Equals [!Ref InstanceCount, 8], !Equals [!Ref InstanceCount, 9], !Equals [!Ref InstanceCount, 10]] Deploy8: !Or [!Equals [!Ref InstanceCount, 8], !Equals [!Ref InstanceCount, 9], !Equals [!Ref InstanceCount, 10]] Deploy9: !Or [!Equals [!Ref InstanceCount, 9], !Equals [!Ref InstanceCount, 10]] Deploy10: !Equals [!Ref InstanceCount, 10] Resources: # ===================================================== # Foundation Stack (VPC + Network) # ===================================================== FoundationStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: https://raw.githubusercontent.com/CrypticDriver/openclaw-multi-deployment/master/cloudformation/01-vpc-foundation.yaml Parameters: AvailabilityZones: !Join - ',' - - !Select [0, !GetAZs ''] - !Select [1, !GetAZs ''] DeployNATRedundancy: 'false' EnableVPCFlowLogs: 'true' Tags: - Key: Project Value: OpenClaw-Multi - Key: Component Value: Foundation # ===================================================== # Shared Resources Stack (ALB + Endpoints) # ===================================================== SharedStack: Type: AWS::CloudFormation::Stack DependsOn: FoundationStack Properties: TemplateURL: https://raw.githubusercontent.com/CrypticDriver/openclaw-multi-deployment/master/cloudformation/02-shared-resources.yaml Parameters: FoundationStackName: !GetAtt FoundationStack.Outputs.StackName DeployVPCEndpoints: !Ref DeployVPCEndpoints NotificationEmail: !If [HasEmail, !Ref NotificationEmail, 'AWS::NoValue'] Tags: - Key: Project Value: OpenClaw-Multi - Key: Component Value: Shared # ===================================================== # Dashboard Stack (Management Console) # ===================================================== DashboardStack: Type: AWS::CloudFormation::Stack DependsOn: SharedStack Properties: TemplateURL: https://raw.githubusercontent.com/CrypticDriver/openclaw-multi-deployment/master/cloudformation/04-dashboard.yaml Parameters: SharedStackName: !GetAtt SharedStack.Outputs.StackName Tags: - Key: Project Value: OpenClaw-Multi - Key: Component Value: Dashboard # ===================================================== # OpenClaw Instance Stacks (Up to 10) # ===================================================== InstanceStack1: Type: AWS::CloudFormation::Stack Condition: Deploy1 DependsOn: SharedStack Properties: TemplateURL: https://raw.githubusercontent.com/CrypticDriver/openclaw-multi-deployment/master/cloudformation/03-openclaw-instance.yaml Parameters: FoundationStackName: !GetAtt FoundationStack.Outputs.StackName SharedStackName: !GetAtt SharedStack.Outputs.StackName InstanceName: !Sub '${InstanceNamePrefix}-1' InstanceType: !Ref InstanceType BedrockModel: !Ref BedrockModel KeyPairName: !Ref KeyPairName MinSize: !Ref MinSize DesiredCapacity: !Ref DesiredCapacity MaxSize: !Ref MaxSize VolumeSize: !Ref VolumeSize EnableDetailedMonitoring: !Ref EnableDetailedMonitoring UseSpotInstances: !Ref UseSpotInstances Tags: - Key: Project Value: OpenClaw-Multi - Key: Component Value: Instance - Key: InstanceName Value: !Sub '${InstanceNamePrefix}-1' InstanceStack2: Type: AWS::CloudFormation::Stack Condition: Deploy2 DependsOn: SharedStack Properties: TemplateURL: https://raw.githubusercontent.com/CrypticDriver/openclaw-multi-deployment/master/cloudformation/03-openclaw-instance.yaml Parameters: FoundationStackName: !GetAtt FoundationStack.Outputs.StackName SharedStackName: !GetAtt SharedStack.Outputs.StackName InstanceName: !Sub '${InstanceNamePrefix}-2' InstanceType: !Ref InstanceType BedrockModel: !Ref BedrockModel KeyPairName: !Ref KeyPairName MinSize: !Ref MinSize DesiredCapacity: !Ref DesiredCapacity MaxSize: !Ref MaxSize VolumeSize: !Ref VolumeSize EnableDetailedMonitoring: !Ref EnableDetailedMonitoring UseSpotInstances: !Ref UseSpotInstances Tags: - Key: Project Value: OpenClaw-Multi - Key: Component Value: Instance - Key: InstanceName Value: !Sub '${InstanceNamePrefix}-2' InstanceStack3: Type: AWS::CloudFormation::Stack Condition: Deploy3 DependsOn: SharedStack Properties: TemplateURL: https://raw.githubusercontent.com/CrypticDriver/openclaw-multi-deployment/master/cloudformation/03-openclaw-instance.yaml Parameters: FoundationStackName: !GetAtt FoundationStack.Outputs.StackName SharedStackName: !GetAtt SharedStack.Outputs.StackName InstanceName: !Sub '${InstanceNamePrefix}-3' InstanceType: !Ref InstanceType BedrockModel: !Ref BedrockModel KeyPairName: !Ref KeyPairName MinSize: !Ref MinSize DesiredCapacity: !Ref DesiredCapacity MaxSize: !Ref MaxSize VolumeSize: !Ref VolumeSize EnableDetailedMonitoring: !Ref EnableDetailedMonitoring UseSpotInstances: !Ref UseSpotInstances Tags: - Key: Project Value: OpenClaw-Multi - Key: Component Value: Instance - Key: InstanceName Value: !Sub '${InstanceNamePrefix}-3' InstanceStack4: Type: AWS::CloudFormation::Stack Condition: Deploy4 DependsOn: SharedStack Properties: TemplateURL: https://raw.githubusercontent.com/CrypticDriver/openclaw-multi-deployment/master/cloudformation/03-openclaw-instance.yaml Parameters: FoundationStackName: !GetAtt FoundationStack.Outputs.StackName SharedStackName: !GetAtt SharedStack.Outputs.StackName InstanceName: !Sub '${InstanceNamePrefix}-4' InstanceType: !Ref InstanceType BedrockModel: !Ref BedrockModel KeyPairName: !Ref KeyPairName MinSize: !Ref MinSize DesiredCapacity: !Ref DesiredCapacity MaxSize: !Ref MaxSize VolumeSize: !Ref VolumeSize EnableDetailedMonitoring: !Ref EnableDetailedMonitoring UseSpotInstances: !Ref UseSpotInstances Tags: - Key: Project Value: OpenClaw-Multi - Key: Component Value: Instance - Key: InstanceName Value: !Sub '${InstanceNamePrefix}-4' InstanceStack5: Type: AWS::CloudFormation::Stack Condition: Deploy5 DependsOn: SharedStack Properties: TemplateURL: https://raw.githubusercontent.com/CrypticDriver/openclaw-multi-deployment/master/cloudformation/03-openclaw-instance.yaml Parameters: FoundationStackName: !GetAtt FoundationStack.Outputs.StackName SharedStackName: !GetAtt SharedStack.Outputs.StackName InstanceName: !Sub '${InstanceNamePrefix}-5' InstanceType: !Ref InstanceType BedrockModel: !Ref BedrockModel KeyPairName: !Ref KeyPairName MinSize: !Ref MinSize DesiredCapacity: !Ref DesiredCapacity MaxSize: !Ref MaxSize VolumeSize: !Ref VolumeSize EnableDetailedMonitoring: !Ref EnableDetailedMonitoring UseSpotInstances: !Ref UseSpotInstances Tags: - Key: Project Value: OpenClaw-Multi - Key: Component Value: Instance - Key: InstanceName Value: !Sub '${InstanceNamePrefix}-5' InstanceStack6: Type: AWS::CloudFormation::Stack Condition: Deploy6 DependsOn: SharedStack Properties: TemplateURL: https://raw.githubusercontent.com/CrypticDriver/openclaw-multi-deployment/master/cloudformation/03-openclaw-instance.yaml Parameters: FoundationStackName: !GetAtt FoundationStack.Outputs.StackName SharedStackName: !GetAtt SharedStack.Outputs.StackName InstanceName: !Sub '${InstanceNamePrefix}-6' InstanceType: !Ref InstanceType BedrockModel: !Ref BedrockModel KeyPairName: !Ref KeyPairName MinSize: !Ref MinSize DesiredCapacity: !Ref DesiredCapacity MaxSize: !Ref MaxSize VolumeSize: !Ref VolumeSize EnableDetailedMonitoring: !Ref EnableDetailedMonitoring UseSpotInstances: !Ref UseSpotInstances Tags: - Key: Project Value: OpenClaw-Multi InstanceStack7: Type: AWS::CloudFormation::Stack Condition: Deploy7 DependsOn: SharedStack Properties: TemplateURL: https://raw.githubusercontent.com/CrypticDriver/openclaw-multi-deployment/master/cloudformation/03-openclaw-instance.yaml Parameters: FoundationStackName: !GetAtt FoundationStack.Outputs.StackName SharedStackName: !GetAtt SharedStack.Outputs.StackName InstanceName: !Sub '${InstanceNamePrefix}-7' InstanceType: !Ref InstanceType BedrockModel: !Ref BedrockModel KeyPairName: !Ref KeyPairName MinSize: !Ref MinSize DesiredCapacity: !Ref DesiredCapacity MaxSize: !Ref MaxSize VolumeSize: !Ref VolumeSize EnableDetailedMonitoring: !Ref EnableDetailedMonitoring UseSpotInstances: !Ref UseSpotInstances Tags: - Key: Project Value: OpenClaw-Multi InstanceStack8: Type: AWS::CloudFormation::Stack Condition: Deploy8 DependsOn: SharedStack Properties: TemplateURL: https://raw.githubusercontent.com/CrypticDriver/openclaw-multi-deployment/master/cloudformation/03-openclaw-instance.yaml Parameters: FoundationStackName: !GetAtt FoundationStack.Outputs.StackName SharedStackName: !GetAtt SharedStack.Outputs.StackName InstanceName: !Sub '${InstanceNamePrefix}-8' InstanceType: !Ref InstanceType BedrockModel: !Ref BedrockModel KeyPairName: !Ref KeyPairName MinSize: !Ref MinSize DesiredCapacity: !Ref DesiredCapacity MaxSize: !Ref MaxSize VolumeSize: !Ref VolumeSize EnableDetailedMonitoring: !Ref EnableDetailedMonitoring UseSpotInstances: !Ref UseSpotInstances Tags: - Key: Project Value: OpenClaw-Multi InstanceStack9: Type: AWS::CloudFormation::Stack Condition: Deploy9 DependsOn: SharedStack Properties: TemplateURL: https://raw.githubusercontent.com/CrypticDriver/openclaw-multi-deployment/master/cloudformation/03-openclaw-instance.yaml Parameters: FoundationStackName: !GetAtt FoundationStack.Outputs.StackName SharedStackName: !GetAtt SharedStack.Outputs.StackName InstanceName: !Sub '${InstanceNamePrefix}-9' InstanceType: !Ref InstanceType BedrockModel: !Ref BedrockModel KeyPairName: !Ref KeyPairName MinSize: !Ref MinSize DesiredCapacity: !Ref DesiredCapacity MaxSize: !Ref MaxSize VolumeSize: !Ref VolumeSize EnableDetailedMonitoring: !Ref EnableDetailedMonitoring UseSpotInstances: !Ref UseSpotInstances Tags: - Key: Project Value: OpenClaw-Multi InstanceStack10: Type: AWS::CloudFormation::Stack Condition: Deploy10 DependsOn: SharedStack Properties: TemplateURL: https://raw.githubusercontent.com/CrypticDriver/openclaw-multi-deployment/master/cloudformation/03-openclaw-instance.yaml Parameters: FoundationStackName: !GetAtt FoundationStack.Outputs.StackName SharedStackName: !GetAtt SharedStack.Outputs.StackName InstanceName: !Sub '${InstanceNamePrefix}-10' InstanceType: !Ref InstanceType BedrockModel: !Ref BedrockModel KeyPairName: !Ref KeyPairName MinSize: !Ref MinSize DesiredCapacity: !Ref DesiredCapacity MaxSize: !Ref MaxSize VolumeSize: !Ref VolumeSize EnableDetailedMonitoring: !Ref EnableDetailedMonitoring UseSpotInstances: !Ref UseSpotInstances Tags: - Key: Project Value: OpenClaw-Multi Outputs: DashboardURL: Description: Management Dashboard URL Value: !GetAtt DashboardStack.Outputs.DashboardURL Export: Name: !Sub '${AWS::StackName}-Dashboard-URL' InstanceCount: Description: Number of instances deployed Value: !Ref InstanceCount InstanceNames: Description: Instance names Value: !Sub '${InstanceNamePrefix}-1 to ${InstanceNamePrefix}-${InstanceCount}' AccessInstructions: Description: How to access instances Value: !Sub | 1. Open Dashboard: ${DashboardStack.Outputs.DashboardURL} 2. Click "打开 Web UI" for any instance 3. All instances are automatically listed! GetTokenCommand: Description: Command to retrieve gateway token for instance 1 Value: !Sub | aws ssm get-parameter --region ${AWS::Region} --name /openclaw/${InstanceNamePrefix}-1/token --with-decryption --query 'Parameter.Value' --output text MonthlyCostEstimate: Description: Estimated monthly cost Value: !Sub - 'Foundation: $70, Instances (${Count} × $33): $${InstanceCost}, Total: ~$${TotalCost}/month' - Count: !Ref InstanceCount InstanceCost: !Sub - '${Cost}' - Cost: !If [Deploy10, 330, !If [Deploy9, 297, !If [Deploy8, 264, !If [Deploy7, 231, !If [Deploy6, 198, !If [Deploy5, 165, !If [Deploy4, 132, !If [Deploy3, 99, !If [Deploy2, 66, 33]]]]]]]]] TotalCost: !Sub - '${Cost}' - Cost: !If [Deploy10, 400, !If [Deploy9, 367, !If [Deploy8, 334, !If [Deploy7, 301, !If [Deploy6, 268, !If [Deploy5, 235, !If [Deploy4, 202, !If [Deploy3, 169, !If [Deploy2, 136, 103]]]]]]]]]