# Provision an AWS EKS cluster + S3 bucket for checkpoints, deploy sample app. # # Prereqs (one-time): # - AWS account with billing enabled # - aws CLI https://aws.amazon.com/cli/ # - eksctl https://eksctl.io (winget install eksctl) # - kubectl https://kubernetes.io/docs/tasks/tools/ # - helm (optional, for future addons) # # Usage: # aws configure # or: $env:AWS_ACCESS_KEY_ID=...; $env:AWS_SECRET_ACCESS_KEY=... # .\scripts\setup_eks.ps1 # # Cost: ~$4-5/day while running. Run .\scripts\teardown_eks.ps1 when done. param( [string]$ClusterName = "incident-commander", [string]$Region = "us-east-1", [string]$BucketName = "", # auto-generated if empty [switch]$SkipApp # skip deploying sample manifests ) $ErrorActionPreference = "Stop" $RepoRoot = Split-Path -Parent $PSScriptRoot $ConfigPath = Join-Path $RepoRoot "infra\eks\cluster.yaml" Write-Host "==> Checking prerequisites" -ForegroundColor Cyan foreach ($bin in @("aws", "eksctl", "kubectl")) { if (-not (Get-Command $bin -ErrorAction SilentlyContinue)) { Write-Error "'$bin' not on PATH. Install it first." } } # Verify AWS credentials resolve. $stsOut = aws sts get-caller-identity 2>&1 | Out-String if ($LASTEXITCODE -ne 0) { Write-Error "AWS credentials not configured. Run 'aws configure' or set AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY env vars." } $AccountId = ($stsOut | ConvertFrom-Json).Account Write-Host " AWS account: $AccountId region: $Region" -ForegroundColor Green # 1) Cluster ------------------------------------------------------------ $existing = (eksctl get cluster --region $Region -o json 2>$null) if ($existing -match $ClusterName) { Write-Host "==> EKS cluster '$ClusterName' already exists — reusing" -ForegroundColor Yellow } else { Write-Host "==> Creating EKS cluster '$ClusterName' (~12 min)" -ForegroundColor Cyan eksctl create cluster -f $ConfigPath if ($LASTEXITCODE -ne 0) { Write-Error "eksctl create cluster failed" } } # Wire kubeconfig (eksctl does this by default, but be explicit). aws eks update-kubeconfig --region $Region --name $ClusterName | Out-Host kubectl cluster-info | Out-Host # 2) S3 bucket for RL checkpoints -------------------------------------- if ([string]::IsNullOrEmpty($BucketName)) { $BucketName = "ic-checkpoints-$AccountId-$Region".ToLower() } Write-Host "==> Ensuring S3 bucket s3://$BucketName" -ForegroundColor Cyan aws s3api head-bucket --bucket $BucketName 2>$null if ($LASTEXITCODE -ne 0) { if ($Region -eq "us-east-1") { aws s3api create-bucket --bucket $BucketName --region $Region | Out-Host } else { aws s3api create-bucket --bucket $BucketName --region $Region ` --create-bucket-configuration LocationConstraint=$Region | Out-Host } aws s3api put-bucket-versioning --bucket $BucketName ` --versioning-configuration Status=Enabled | Out-Host aws s3api put-public-access-block --bucket $BucketName ` --public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true | Out-Host } # 3) CloudWatch log group (agent can query pod logs from here) -------- $LogGroup = "/aws/eks/$ClusterName/application" aws logs describe-log-groups --log-group-name-prefix $LogGroup --region $Region 2>$null | Out-Null aws logs create-log-group --log-group-name $LogGroup --region $Region 2>$null | Out-Null aws logs put-retention-policy --log-group-name $LogGroup --retention-in-days 7 --region $Region 2>$null | Out-Null # 4) Deploy sample app ---------------------------------------------------- if (-not $SkipApp) { Write-Host "==> Deploying sample app" -ForegroundColor Cyan $manifestDir = Join-Path $RepoRoot "rl-agent\sample_app" kubectl apply -f (Join-Path $manifestDir "namespaces.yaml") kubectl apply -R -f (Join-Path $manifestDir "base") foreach ($ns in @("ic-payments", "ic-frontend", "ic-auth")) { kubectl -n $ns wait --for=condition=available --timeout=300s deployment --all } kubectl get pods -A | findstr ic- | Out-Host } # 5) Write a .env.aws.local file you can source ---------------------------- $envFile = Join-Path $RepoRoot ".env.aws.local" @" # Generated by setup_eks.ps1 — DO NOT COMMIT. AWS_REGION=$Region EKS_CLUSTER_NAME=$ClusterName S3_CHECKPOINT_BUCKET=$BucketName CLOUDWATCH_LOG_GROUP=$LogGroup REAL_K8S=true K8S_CLOUD=aws "@ | Set-Content -Path $envFile -Encoding UTF8 Write-Host "" Write-Host "✔ AWS environment ready." -ForegroundColor Green Write-Host " cluster : $ClusterName ($Region)" Write-Host " s3 : s3://$BucketName" Write-Host " logs : $LogGroup" Write-Host " .env : $envFile" Write-Host "" Write-Host "Next: see ENV.md for env-var wiring, then start the server." -ForegroundColor Cyan Write-Host "Teardown: .\scripts\teardown_eks.ps1"