dev_arc_aws/infrastructure/cloudformation.yml
Samuel James 04d491c277
All checks were successful
CI / validate (push) Successful in 48s
System design, CloudFormation, theming assets (#3)
2026-06-24 13:55:04 +00:00

173 lines
4.4 KiB
YAML

AWSTemplateFormatVersion: '2010-09-09'
Description: >
ArchNest - Single-user self-hosted ops dashboard on AWS.
Deploys a t4g.small EC2 instance with Docker Compose.
Parameters:
KeyPairName:
Type: String
Default: kiro-ide-key
Description: SSH key pair name for EC2 access
InstanceType:
Type: String
Default: t4g.small
AllowedValues:
- t4g.micro
- t4g.small
- t4g.medium
Description: EC2 instance type (ARM/Graviton)
VolumeSize:
Type: Number
Default: 30
Description: EBS volume size in GB
Resources:
# Security Group — allows SSH, HTTP, HTTPS, and the backend port
ArchNestSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: ArchNest security group
GroupName: archnest-sg
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
Description: SSH access
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Description: HTTP (redirect to HTTPS)
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
Description: HTTPS
- IpProtocol: tcp
FromPort: 8080
ToPort: 8080
CidrIp: 0.0.0.0/0
Description: Frontend (direct, before proxy)
- IpProtocol: tcp
FromPort: 4000
ToPort: 4000
CidrIp: 0.0.0.0/0
Description: Backend API
SecurityGroupEgress:
- IpProtocol: -1
CidrIp: 0.0.0.0/0
Description: All outbound (SSH to managed hosts, Docker pulls, etc.)
Tags:
- Key: Name
Value: archnest-sg
# Elastic IP — stable public IP across stop/start
ArchNestEIP:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
Tags:
- Key: Name
Value: archnest-eip
# EC2 Instance
ArchNestInstance:
Type: AWS::EC2::Instance
Properties:
InstanceType: !Ref InstanceType
KeyName: !Ref KeyPairName
ImageId: !FindInMap [RegionAMI, !Ref 'AWS::Region', AMI]
SecurityGroupIds:
- !Ref ArchNestSecurityGroup
BlockDeviceMappings:
- DeviceName: /dev/sda1
Ebs:
VolumeSize: !Ref VolumeSize
VolumeType: gp3
Encrypted: true
UserData:
Fn::Base64: |
#!/bin/bash
set -e
# Update system
apt-get update -y
apt-get upgrade -y
# Install Docker
apt-get install -y docker.io docker-compose-v2 git curl
systemctl enable --now docker
# Create deploy directory
mkdir -p /opt/archnest
chown ubuntu:ubuntu /opt/archnest
# Signal ready
echo "ArchNest instance ready" > /opt/archnest/READY
Tags:
- Key: Name
Value: archnest
# Associate Elastic IP with instance
ArchNestEIPAssociation:
Type: AWS::EC2::EIPAssociation
Properties:
InstanceId: !Ref ArchNestInstance
EIP: !Ref ArchNestEIP
# Budget alarm — $30/month ceiling
ArchNestBudget:
Type: AWS::Budgets::Budget
Properties:
Budget:
BudgetName: archnest-monthly
BudgetType: COST
TimeUnit: MONTHLY
BudgetLimit:
Amount: 30
Unit: USD
NotificationsWithSubscribers:
- Notification:
NotificationType: ACTUAL
ComparisonOperator: GREATER_THAN
Threshold: 80
Subscribers:
- SubscriptionType: EMAIL
Address: samueljamesinc@gmail.com
- Notification:
NotificationType: ACTUAL
ComparisonOperator: GREATER_THAN
Threshold: 100
Subscribers:
- SubscriptionType: EMAIL
Address: samueljamesinc@gmail.com
Mappings:
# Ubuntu 24.04 LTS ARM64 AMIs per region
RegionAMI:
us-east-1:
AMI: ami-0a7a4e87939439934
us-east-2:
AMI: ami-0ea3405d2d2522162
us-west-2:
AMI: ami-05d38da78ce859165
Outputs:
PublicIP:
Description: ArchNest public IP address
Value: !Ref ArchNestEIP
SSHCommand:
Description: SSH into the instance
Value: !Sub 'ssh -i ~/.ssh/kiro_ide_key ubuntu@${ArchNestEIP}'
InstanceId:
Description: EC2 Instance ID
Value: !Ref ArchNestInstance
EstimatedMonthlyCost:
Description: Estimated monthly cost
Value: '~$15/month (t4g.small + 30GB gp3 + Elastic IP)'