Panoramica

Questa guida ti accompagna attraverso la distribuzione di CaseBender su AWS utilizzando immagini Docker precostruite con Amazon ECS (Elastic Container Service) e Fargate.

Prerequisiti

  1. Account AWS
  2. AWS CLI installato e configurato
  3. Docker installato

Passo 1: Configurazione Iniziale

Installa e Configura AWS CLI

# Usando Homebrew
brew install awscli

# Configura AWS CLI
aws configure

# Configura Docker per ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin $(aws sts get-caller-identity --query Account --output text).dkr.ecr.us-east-1.amazonaws.com

Passo 2: Configura l’Infrastruttura AWS

Crea Bucket S3 per lo Storage

# Crea bucket S3
aws s3 create-bucket \
  --bucket casebender-storage \
  --region us-east-1

# Abilita il versionamento (opzionale)
aws s3api put-bucket-versioning \
  --bucket casebender-storage \
  --versioning-configuration Status=Enabled

# Crea utente IAM per l'accesso S3
aws iam create-user --user-name casebender-storage-user

# Crea e allega policy
aws iam create-policy \
  --policy-name casebender-storage-policy \
  --policy-document '{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::casebender-storage",
                "arn:aws:s3:::casebender-storage/*"
            ]
        }
    ]
}'

# Allega policy all'utente
aws iam attach-user-policy \
  --user-name casebender-storage-user \
  --policy-arn arn:aws:iam::YOUR_ACCOUNT_ID:policy/casebender-storage-policy

# Crea chiavi di accesso
aws iam create-access-key --user-name casebender-storage-user

Crea una VPC

# Crea VPC
aws ec2 create-vpc \
  --cidr-block 10.0.0.0/16 \
  --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=casebender-vpc}]'

# Abilita hostname DNS
aws ec2 modify-vpc-attribute \
  --vpc-id <vpc-id> \
  --enable-dns-hostnames

Crea Subnet

# Crea subnet pubbliche
aws ec2 create-subnet \
  --vpc-id <vpc-id> \
  --cidr-block 10.0.1.0/24 \
  --availability-zone us-east-1a \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=casebender-public-1a}]'

aws ec2 create-subnet \
  --vpc-id <vpc-id> \
  --cidr-block 10.0.2.0/24 \
  --availability-zone us-east-1b \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=casebender-public-1b}]'

Configura RDS (PostgreSQL)

# Crea gruppo subnet DB
aws rds create-db-subnet-group \
  --db-subnet-group-name casebender-db-subnet \
  --db-subnet-group-description "Gruppo subnet per CaseBender RDS" \
  --subnet-ids "<subnet-1-id>" "<subnet-2-id>"

# Crea istanza RDS
aws rds create-db-instance \
  --db-instance-identifier casebender-db \
  --db-instance-class db.t3.medium \
  --engine postgres \
  --master-username superadmin \
  --master-user-password <your-secure-password> \
  --allocated-storage 20 \
  --db-subnet-group-name casebender-db-subnet

Configura ElastiCache (Redis)

# Crea gruppo subnet cache
aws elasticache create-cache-subnet-group \
  --cache-subnet-group-name casebender-cache-subnet \
  --cache-subnet-group-description "Gruppo subnet per CaseBender Redis" \
  --subnet-ids "<subnet-1-id>" "<subnet-2-id>"

# Crea cluster Redis
aws elasticache create-cache-cluster \
  --cache-cluster-id casebender-redis \
  --engine redis \
  --cache-node-type cache.t3.micro \
  --num-cache-nodes 1 \
  --cache-subnet-group-name casebender-cache-subnet

Passo 3: Crea Repository ECR

# Crea repository per ogni servizio
aws ecr create-repository --repository-name casebender/app
aws ecr create-repository --repository-name casebender/workflow-processor
aws ecr create-repository --repository-name casebender/misp-processor

# Ottieni l'ID account AWS
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)

# Scarica immagini CaseBender
docker pull casebender/casebender:latest
docker pull casebender/workflow-processor:latest
docker pull casebender/misp-processor:latest

# Tagga immagini per ECR
docker tag casebender/casebender:latest ${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/casebender/app:latest
docker tag casebender/workflow-processor:latest ${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/casebender/workflow-processor:latest
docker tag casebender/misp-processor:latest ${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/casebender/misp-processor:latest

# Carica immagini su ECR
docker push ${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/casebender/app:latest
docker push ${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/casebender/workflow-processor:latest
docker push ${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/casebender/misp-processor:latest

Passo 4: Crea Cluster ECS

# Crea cluster ECS
aws ecs create-cluster --cluster-name casebender-cluster

# Crea ruolo esecuzione task
aws iam create-role \
  --role-name ecsTaskExecutionRole \
  --assume-role-policy-document file://task-execution-assume-role.json

# Allega policy
aws iam attach-role-policy \
  --role-name ecsTaskExecutionRole \
  --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy

Passo 5: Crea Definizioni Task

Crea file JSON di definizione task per ogni servizio:

{
  "family": "casebender-app",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "1024",
  "memory": "2048",
  "executionRoleArn": "arn:aws:iam::<aws-account-id>:role/ecsTaskExecutionRole",
  "containerDefinitions": [
    {
      "name": "app",
      "image": "<aws-account-id>.dkr.ecr.us-east-1.amazonaws.com/casebender/app:latest",
      "portMappings": [
        {
          "containerPort": 3000,
          "protocol": "tcp"
        }
      ],
      "environment": [
        {
          "name": "POSTGRES_PRISMA_URL",
          "value": "postgresql://superadmin:password@casebender-db.xxxxx.region.rds.amazonaws.com:5432/casebender"
        },
        {
          "name": "REDIS_URL",
          "value": "redis://casebender-redis.xxxxx.region.cache.amazonaws.com:6379"
        },
        {
          "name": "AWS_S3_BUCKET",
          "value": "casebender-storage"
        },
        {
          "name": "AWS_S3_REGION",
          "value": "us-east-1"
        }
      ],
      "secrets": [
        {
          "name": "AUTH_SECRET",
          "valueFrom": "arn:aws:secretsmanager:region:account:secret:auth-secret"
        },
        {
          "name": "AUTH_SALT",
          "valueFrom": "arn:aws:secretsmanager:region:account:secret:auth-salt"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/casebender",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "app"
        }
      }
    }
  ]
}

Registra le definizioni task:

# Registra definizioni task
aws ecs register-task-definition --cli-input-json file://app-task-definition.json
aws ecs register-task-definition --cli-input-json file://workflow-processor-task-definition.json
aws ecs register-task-definition --cli-input-json file://misp-processor-task-definition.json

Passo 6: Crea Application Load Balancer

# Crea ALB
aws elbv2 create-load-balancer \
  --name casebender-alb \
  --subnets <subnet-1-id> <subnet-2-id> \
  --security-groups <security-group-id>

# Crea target group
aws elbv2 create-target-group \
  --name casebender-tg \
  --protocol HTTP \
  --port 3000 \
  --vpc-id <vpc-id> \
  --target-type ip

# Crea listener
aws elbv2 create-listener \
  --load-balancer-arn <alb-arn> \
  --protocol HTTPS \
  --port 443 \
  --certificates CertificateArn=<certificate-arn> \
  --default-actions Type=forward,TargetGroupArn=<target-group-arn>

Passo 7: Crea Servizi ECS

# Crea servizio per app principale
aws ecs create-service \
  --cluster casebender-cluster \
  --service-name casebender-app \
  --task-definition casebender-app \
  --desired-count 2 \
  --launch-type FARGATE \
  --network-configuration "awsvpcConfiguration={subnets=[<subnet-1-id>,<subnet-2-id>],securityGroups=[<security-group-id>],assignPublicIp=ENABLED}" \
  --load-balancers "targetGroupArn=<target-group-arn>,containerName=app,containerPort=3000"

# Crea servizi per i processori
aws ecs create-service \
  --cluster casebender-cluster \
  --service-name workflow-processor \
  --task-definition casebender-workflow-processor \
  --desired-count 1 \
  --launch-type FARGATE \
  --network-configuration "awsvpcConfiguration={subnets=[<subnet-1-id>,<subnet-2-id>],securityGroups=[<security-group-id>],assignPublicIp=ENABLED}"

aws ecs create-service \
  --cluster casebender-cluster \
  --service-name misp-processor \
  --task-definition casebender-misp-processor \
  --desired-count 1 \
  --launch-type FARGATE \
  --network-configuration "awsvpcConfiguration={subnets=[<subnet-1-id>,<subnet-2-id>],securityGroups=[<security-group-id>],assignPublicIp=ENABLED}"

Passo 8: Configura Route 53 (Opzionale)

Se stai usando un dominio personalizzato:

# Crea zona ospitata (se non esiste)
aws route53 create-hosted-zone \
  --name yourdomain.com \
  --caller-reference $(date +%s)

# Crea record A
aws route53 change-resource-record-sets \
  --hosted-zone-id <zone-id> \
  --change-batch '{
    "Changes": [{
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "yourdomain.com",
        "Type": "A",
        "AliasTarget": {
          "HostedZoneId": "<alb-hosted-zone-id>",
          "DNSName": "<alb-dns-name>",
          "EvaluateTargetHealth": true
        }
      }
    }]
  }'

Monitoraggio e Manutenzione

Configura Allarmi CloudWatch

# Crea allarme utilizzo CPU
aws cloudwatch put-metric-alarm \
  --alarm-name casebender-cpu-alarm \
  --alarm-description "Utilizzo CPU superato 80%" \
  --metric-name CPUUtilization \
  --namespace AWS/ECS \
  --statistic Average \
  --period 300 \
  --threshold 80 \
  --comparison-operator GreaterThanThreshold \
  --dimensions Name=ClusterName,Value=casebender-cluster \
  --evaluation-periods 2 \
  --alarm-actions <sns-topic-arn>

Visualizza Log

# Visualizza log del servizio
aws logs get-log-events \
  --log-group-name /ecs/casebender \
  --log-stream-name app/<container-id>

Aggiorna Servizi

# Aggiorna servizio con nuova definizione task
aws ecs update-service \
  --cluster casebender-cluster \
  --service casebender-app \
  --task-definition casebender-app:NEW_REVISION

Ottimizzazione dei Costi

  1. Usa Fargate Spot per carichi di lavoro non critici
  2. Implementa auto-scaling basato su metriche
  3. Scegli dimensioni istanze appropriate
  4. Usa Istanze Riservate per carichi di lavoro prevedibili

Migliori Pratiche di Sicurezza

  1. Usa AWS Secrets Manager per dati sensibili
  2. Implementa regole WAF
  3. Abilita VPC Flow Logs
  4. Audit regolari dei gruppi di sicurezza
  5. Abilita AWS GuardDuty

Prossimi Passi

  • Configura pipeline CI/CD con AWS CodePipeline
  • Configura strategie di backup
  • Implementa monitoraggio e alerting
  • Rivedi le migliori pratiche di sicurezza