first claude draft

This commit is contained in:
buenosairesam
2025-12-29 14:40:06 -03:00
commit 116d4032e2
69 changed files with 5020 additions and 0 deletions

View File

@@ -0,0 +1 @@
placeholder

Binary file not shown.

View File

@@ -0,0 +1 @@
placeholder

Binary file not shown.

148
infra/aws/terraform/ec2.tf Normal file
View File

@@ -0,0 +1,148 @@
# EC2 Instance for Docker Compose deployment
resource "aws_security_group" "sysmonstm" {
name_prefix = "${var.project_name}-"
description = "Security group for System Monitor Platform"
# HTTP/HTTPS
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
description = "HTTP"
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
description = "HTTPS"
}
# gRPC for collectors
ingress {
from_port = 50051
to_port = 50051
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
description = "gRPC Aggregator"
}
# SSH (restricted)
dynamic "ingress" {
for_each = length(var.allowed_ssh_cidrs) > 0 ? [1] : []
content {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = var.allowed_ssh_cidrs
description = "SSH"
}
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
description = "Allow all outbound"
}
tags = {
Name = "${var.project_name}-sg"
}
}
resource "aws_iam_role" "ec2" {
name_prefix = "${var.project_name}-ec2-"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "ec2.amazonaws.com"
}
}
]
})
}
resource "aws_iam_role_policy_attachment" "ec2_ssm" {
role = aws_iam_role.ec2.name
policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
resource "aws_iam_instance_profile" "ec2" {
name_prefix = "${var.project_name}-"
role = aws_iam_role.ec2.name
}
resource "aws_instance" "sysmonstm" {
ami = data.aws_ami.amazon_linux_2023.id
instance_type = var.ec2_instance_type
key_name = var.ec2_key_name != "" ? var.ec2_key_name : null
vpc_security_group_ids = [aws_security_group.sysmonstm.id]
iam_instance_profile = aws_iam_instance_profile.ec2.name
root_block_device {
volume_size = 20
volume_type = "gp3"
encrypted = true
}
user_data = <<-EOF
#!/bin/bash
set -e
# Install Docker
dnf update -y
dnf install -y docker git
systemctl enable docker
systemctl start docker
# Install Docker Compose
curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" \
-o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
# Add ec2-user to docker group
usermod -aG docker ec2-user
# Clone and start the application
cd /home/ec2-user
git clone https://github.com/yourusername/sysmonstm.git || true
cd sysmonstm
# Create .env file
cat > .env <<EOL
LOG_LEVEL=INFO
MACHINE_ID=aws-demo
EOL
# Start services
docker-compose up -d
EOF
tags = {
Name = "${var.project_name}-server"
}
lifecycle {
ignore_changes = [ami]
}
}
# Elastic IP for stable address
resource "aws_eip" "sysmonstm" {
instance = aws_instance.sysmonstm.id
domain = "vpc"
tags = {
Name = "${var.project_name}-eip"
}
}

View File

@@ -0,0 +1,203 @@
# Lambda Functions for Data Processing Pipeline
# These are optional and enabled via enable_lambda_pipeline variable
# SQS Queue for buffering metrics
resource "aws_sqs_queue" "metrics" {
count = var.enable_lambda_pipeline ? 1 : 0
name = "${var.project_name}-metrics"
visibility_timeout_seconds = var.lambda_timeout * 2
message_retention_seconds = 86400 # 24 hours
redrive_policy = jsonencode({
deadLetterTargetArn = aws_sqs_queue.metrics_dlq[0].arn
maxReceiveCount = 3
})
}
resource "aws_sqs_queue" "metrics_dlq" {
count = var.enable_lambda_pipeline ? 1 : 0
name = "${var.project_name}-metrics-dlq"
message_retention_seconds = 1209600 # 14 days
}
# S3 Bucket for metric backups
resource "aws_s3_bucket" "metrics" {
count = var.enable_s3_backup ? 1 : 0
bucket_prefix = "${var.project_name}-metrics-"
}
resource "aws_s3_bucket_lifecycle_configuration" "metrics" {
count = var.enable_s3_backup ? 1 : 0
bucket = aws_s3_bucket.metrics[0].id
rule {
id = "archive-old-metrics"
status = "Enabled"
transition {
days = 30
storage_class = "STANDARD_IA"
}
transition {
days = 90
storage_class = "GLACIER"
}
expiration {
days = 365
}
}
}
# IAM Role for Lambda
resource "aws_iam_role" "lambda" {
count = var.enable_lambda_pipeline ? 1 : 0
name_prefix = "${var.project_name}-lambda-"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "lambda.amazonaws.com"
}
}
]
})
}
resource "aws_iam_role_policy" "lambda" {
count = var.enable_lambda_pipeline ? 1 : 0
name = "lambda-policy"
role = aws_iam_role.lambda[0].id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
Resource = "arn:aws:logs:*:*:*"
},
{
Effect = "Allow"
Action = [
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:GetQueueAttributes"
]
Resource = aws_sqs_queue.metrics[0].arn
},
{
Effect = "Allow"
Action = [
"s3:PutObject",
"s3:GetObject"
]
Resource = var.enable_s3_backup ? "${aws_s3_bucket.metrics[0].arn}/*" : "*"
}
]
})
}
# Lambda function for metric aggregation
resource "aws_lambda_function" "aggregator" {
count = var.enable_lambda_pipeline ? 1 : 0
function_name = "${var.project_name}-aggregator"
role = aws_iam_role.lambda[0].arn
handler = "main.handler"
runtime = "python3.11"
timeout = var.lambda_timeout
memory_size = var.lambda_memory_size
# Placeholder - will be deployed via CI/CD
filename = "${path.module}/../lambdas/aggregator/placeholder.zip"
source_code_hash = filebase64sha256("${path.module}/../lambdas/aggregator/placeholder.zip")
environment {
variables = {
TIMESCALE_HOST = aws_instance.sysmonstm.private_ip
LOG_LEVEL = "INFO"
}
}
lifecycle {
ignore_changes = [filename, source_code_hash]
}
}
resource "aws_lambda_event_source_mapping" "sqs_trigger" {
count = var.enable_lambda_pipeline ? 1 : 0
event_source_arn = aws_sqs_queue.metrics[0].arn
function_name = aws_lambda_function.aggregator[0].arn
batch_size = 100
scaling_config {
maximum_concurrency = 5
}
}
# CloudWatch Event for scheduled compaction
resource "aws_cloudwatch_event_rule" "compactor" {
count = var.enable_lambda_pipeline ? 1 : 0
name = "${var.project_name}-compactor-schedule"
description = "Trigger metric compaction every hour"
schedule_expression = "rate(1 hour)"
}
resource "aws_lambda_function" "compactor" {
count = var.enable_lambda_pipeline ? 1 : 0
function_name = "${var.project_name}-compactor"
role = aws_iam_role.lambda[0].arn
handler = "main.handler"
runtime = "python3.11"
timeout = 300
memory_size = 512
filename = "${path.module}/../lambdas/compactor/placeholder.zip"
source_code_hash = filebase64sha256("${path.module}/../lambdas/compactor/placeholder.zip")
environment {
variables = {
TIMESCALE_HOST = aws_instance.sysmonstm.private_ip
S3_BUCKET = var.enable_s3_backup ? aws_s3_bucket.metrics[0].bucket : ""
LOG_LEVEL = "INFO"
}
}
lifecycle {
ignore_changes = [filename, source_code_hash]
}
}
resource "aws_cloudwatch_event_target" "compactor" {
count = var.enable_lambda_pipeline ? 1 : 0
rule = aws_cloudwatch_event_rule.compactor[0].name
target_id = "compactor-lambda"
arn = aws_lambda_function.compactor[0].arn
}
resource "aws_lambda_permission" "compactor_cloudwatch" {
count = var.enable_lambda_pipeline ? 1 : 0
statement_id = "AllowCloudWatchInvoke"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.compactor[0].function_name
principal = "events.amazonaws.com"
source_arn = aws_cloudwatch_event_rule.compactor[0].arn
}

View File

@@ -0,0 +1,58 @@
# System Monitor Platform - AWS Infrastructure
#
# This Terraform configuration sets up:
# - EC2 instance for running Docker Compose (demo/staging)
# - Lambda functions for data processing pipeline
# - SQS queue for buffering metrics
# - S3 bucket for metric backups
# - Security groups and IAM roles
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
# Uncomment for remote state
# backend "s3" {
# bucket = "your-terraform-state-bucket"
# key = "sysmonstm/terraform.tfstate"
# region = "us-east-1"
# }
}
provider "aws" {
region = var.aws_region
default_tags {
tags = {
Project = "sysmonstm"
Environment = var.environment
ManagedBy = "terraform"
}
}
}
# Data sources
data "aws_availability_zones" "available" {
state = "available"
}
data "aws_ami" "amazon_linux_2023" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
}

View File

@@ -0,0 +1,36 @@
# Outputs
output "ec2_public_ip" {
description = "Public IP of the EC2 instance"
value = aws_eip.sysmonstm.public_ip
}
output "ec2_instance_id" {
description = "EC2 instance ID"
value = aws_instance.sysmonstm.id
}
output "dashboard_url" {
description = "URL for the monitoring dashboard"
value = "http://${aws_eip.sysmonstm.public_ip}:8000"
}
output "grpc_endpoint" {
description = "gRPC endpoint for collectors"
value = "${aws_eip.sysmonstm.public_ip}:50051"
}
output "sqs_queue_url" {
description = "SQS queue URL for metrics"
value = var.enable_lambda_pipeline ? aws_sqs_queue.metrics[0].url : null
}
output "s3_bucket" {
description = "S3 bucket for metric backups"
value = var.enable_s3_backup ? aws_s3_bucket.metrics[0].bucket : null
}
output "ssh_command" {
description = "SSH command to connect to the instance"
value = var.ec2_key_name != "" ? "ssh -i ${var.ec2_key_name}.pem ec2-user@${aws_eip.sysmonstm.public_ip}" : "Use SSM Session Manager"
}

View File

@@ -0,0 +1,16 @@
# Example Terraform variables
# Copy to terraform.tfvars and fill in your values
aws_region = "us-east-1"
environment = "staging"
project_name = "sysmonstm"
domain_name = "sysmonstm.mcrn.ar"
# EC2
ec2_instance_type = "t2.small"
ec2_key_name = "your-key-pair-name"
allowed_ssh_cidrs = ["YOUR.IP.ADDRESS/32"]
# Feature flags
enable_lambda_pipeline = false
enable_s3_backup = false

View File

@@ -0,0 +1,70 @@
# Variables for System Monitor Platform
variable "aws_region" {
description = "AWS region to deploy to"
type = string
default = "us-east-1"
}
variable "environment" {
description = "Environment name (dev, staging, prod)"
type = string
default = "staging"
}
variable "project_name" {
description = "Project name for resource naming"
type = string
default = "sysmonstm"
}
variable "domain_name" {
description = "Domain name for the service"
type = string
default = "sysmonstm.mcrn.ar"
}
# EC2 Configuration
variable "ec2_instance_type" {
description = "EC2 instance type"
type = string
default = "t2.small"
}
variable "ec2_key_name" {
description = "SSH key pair name"
type = string
default = ""
}
variable "allowed_ssh_cidrs" {
description = "CIDR blocks allowed to SSH"
type = list(string)
default = [] # Set to your IP for security
}
# Lambda Configuration
variable "lambda_memory_size" {
description = "Lambda function memory in MB"
type = number
default = 256
}
variable "lambda_timeout" {
description = "Lambda function timeout in seconds"
type = number
default = 60
}
# Feature flags
variable "enable_lambda_pipeline" {
description = "Enable Lambda data processing pipeline"
type = bool
default = false
}
variable "enable_s3_backup" {
description = "Enable S3 backup for metrics"
type = bool
default = false
}