> ## Documentation Index
> Fetch the complete documentation index at: https://docs.casebender.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Distribuzione su AWS

> Distribuisci CaseBender su Amazon Web Services (AWS)

## 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](https://aws.amazon.com/)
2. [AWS CLI](https://aws.amazon.com/cli/) installato e configurato
3. [Docker](https://docs.docker.com/get-docker/) installato

## Passo 1: Configurazione Iniziale

### Installa e Configura AWS CLI

<CodeGroup>
  ```bash macOS theme={null}
  # 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
  ```

  ```bash Linux theme={null}
  # Installa AWS CLI
  curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
  unzip awscliv2.zip
  sudo ./aws/install

  # 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
  ```

  ```powershell Windows theme={null}
  # Scarica ed esegui l'installer MSI di AWS CLI
  # https://awscli.amazonaws.com/AWSCLIV2.msi

  # 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
  ```
</CodeGroup>

## Passo 2: Configura l'Infrastruttura AWS

### Crea Bucket S3 per lo Storage

```bash theme={null}
# 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

```bash theme={null}
# 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

```bash theme={null}
# 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)

```bash theme={null}
# 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)

```bash theme={null}
# 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

```bash theme={null}
# 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

```bash theme={null}
# 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:

```json theme={null}
{
  "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:

```bash theme={null}
# 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

```bash theme={null}
# 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

```bash theme={null}
# 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:

```bash theme={null}
# 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

```bash theme={null}
# 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

```bash theme={null}
# Visualizza log del servizio
aws logs get-log-events \
  --log-group-name /ecs/casebender \
  --log-stream-name app/<container-id>
```

### Aggiorna Servizi

```bash theme={null}
# 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
