Skip to main content
Current27d ago

Redash Setup

Deploy Redash on AWS ECS (Fargate) — IaC Specification

A complete resource specification for deploying Redash on AWS ECS Fargate. Feed this to an AI and ask it to generate Terraform, CDK (TypeScript), Pulumi, or CloudFormation — all the details it needs are here.


Architecture

ECS Fargate Task (single task, two containers sharing localhost)
├── Redash container (:5000) ──► RDS PostgreSQL (:5432)
└── Redis container (:6379, sidecar)

Image source: Docker Hub (default) or Amazon ECR (recommended for production).


What Each Service Does

Amazon ECS (Elastic Container Service) — AWS's container orchestration service. It runs your Docker containers without you managing servers. Fargate is the serverless mode — you just say "run this container with X CPU and Y memory" and AWS handles the rest.

AWS Fargate — The compute engine behind ECS that removes the need to manage EC2 instances. You define your container, Fargate provisions the server, runs it, and scales it. You pay only for the CPU/memory your containers use.

Amazon RDS (Relational Database Service) — A managed PostgreSQL database. AWS handles patching, backups, and failover. Redash uses this to store its own metadata — user accounts, saved queries, dashboard definitions, and settings.

Redis — An in-memory key-value store. Redash uses it as a message broker and cache — it queues background jobs (like running queries) and caches results. We run it as a sidecar container inside the same Fargate task, so it communicates with Redash over localhost.

Amazon ECR (Elastic Container Registry) — AWS's private Docker image registry. Instead of pulling images from Docker Hub (public internet), you push them to ECR and pull from within AWS — faster, no rate limits, and you control exactly which version is deployed.

AWS Secrets Manager — A service that stores passwords, API keys, and other secrets securely. Instead of hardcoding your database password in the task definition, you store it in Secrets Manager and ECS pulls it at runtime.

Application Load Balancer (ALB) — Sits in front of your ECS containers and distributes incoming traffic. Required for HTTPS (SSL), custom domains, and running multiple Redash containers for high availability.

ACM (AWS Certificate Manager) — Provides free SSL/TLS certificates for your domain. You attach the certificate to the ALB so users access Redash over HTTPS.

IAM (Identity and Access Management) — AWS's permission system. The ECS task execution role gives your containers permission to pull images from ECR, read secrets from Secrets Manager, and write logs to CloudWatch.

CloudWatch Logs — AWS's log aggregation service. Container stdout/stderr is streamed here so you can debug issues without SSH-ing into anything.

VPC (Virtual Private Cloud) — Your isolated network in AWS. Security groups act as firewalls — you define which ports are open and who can access what. RDS lives in private subnets (no internet access), ECS lives in public subnets (or behind an ALB).


Region

ap-northeast-1 (Tokyo) All resources should be created in this region.


Resource 1 — VPC & Networking

Use the default VPC or create a new one with the following:

  • 2 Availability Zones minimum

  • Public subnets (for ECS tasks with public IP)

  • Private subnets (for RDS)

  • 1 NAT Gateway if using private subnets for ECS (set to 0 if using public subnets to save cost)

  • Internet Gateway attached


Resource 2 — Security Groups

ECS Security Group (redash-ecs-sg)

DirectionPortSourcePurpose
Inbound50000.0.0.0/0 (or restrict to your IP/CIDR)Redash Web UI
OutboundAll0.0.0.0/0Internet + DB access

RDS Security Group (redash-rds-sg)

DirectionPortSourcePurpose
Inbound5432Reference redash-ecs-sg by security group IDECS → Database
OutboundAll0.0.0.0/0Default

Resource 3 — Secrets (AWS Secrets Manager)

Secret 1: Database Credentials

  • Secret name: redash/db-credentials

  • Auto-generate password: Yes, 30 characters, exclude punctuation

  • Username: redash

Secret 2: Redash Secret Key

  • Secret name: redash/secret-key

  • Auto-generate: Yes, 64 characters, exclude punctuation


Resource 4 — RDS PostgreSQL

SettingValue
Identifierredash-analysis-db
EnginePostgreSQL 15
Instance classdb.t3.micro (see pricing guide to pick by team size)
Allocated storage20 GB
Storage typegp3
Database namepostgres
CredentialsFrom Secrets Manager (redash/db-credentials)
VPC subnetsPrivate subnets
Security groupredash-rds-sg
Multi-AZNo (single AZ for cost saving)
Public accessNo
Backup retention7 days
Deletion protectionNo for dev, Yes for production
Removal policyDestroy for dev, Retain for production

Resource 5 — ECS Cluster

SettingValue
Cluster nameredash-analysis-cluster
InfrastructureAWS Fargate (serverless, no EC2 instances)

Resource 6 — IAM Task Execution Role

SettingValue
Role nameecsTaskExecutionRole
Trusted entityAWS service → ECS Tasks
Managed policyAmazonECSTaskExecutionRolePolicy
Additional permissionssecretsmanager:GetSecretValue for both secrets above

Resource 7 — ECS Task Definition

SettingValue
Familyredash-analysis-task
Launch typeFargate
OS / ArchitectureLinux / X86_64
CPU1024 (1 vCPU) — see pricing guide to adjust
Memory2048 MB — see pricing guide to adjust
Task execution roleecsTaskExecutionRole
Network modeawsvpc (default for Fargate)

Container 1: Redash

SettingValue
Nameredash
Imageredash/redash:latest (Docker Hub) or ECR URI
EssentialYes
Port5000/tcp
Memory hard limit1536 MB
Memory soft limit1024 MB
LoggingCloudWatch Logs, stream prefix redash, retention 14 days

Environment variables:

KeyValueSource
REDASH_DATABASE_URLpostgresql://redash:\<PASSWORD>@<RDS_ENDPOINT>:5432/postgresConstructed from Secrets Manager + RDS endpoint
REDASH_REDIS_URLredis://localhost:6379/0Hardcoded (Redis is a sidecar in the same task)
PYTHONUNBUFFERED0Hardcoded
REDASH_SECRET_KEYValue from redash/secret-keySecrets Manager

Container 2: Redis

SettingValue
Nameredis
Imageredis:7-alpine (Docker Hub) or ECR URI
EssentialNo
Port6379/tcp
Memory hard limit512 MB
Memory soft limit256 MB
LoggingCloudWatch Logs, stream prefix redis, retention 14 days
Environment variablesNone

Resource 8 — ECS Service

SettingValue
Service nameredash-analysis-service
Clusterredash-analysis-cluster
Task definitionredash-analysis-task (latest revision)
Launch typeFargate
Desired count1
SubnetsPublic subnets (same VPC as RDS)
Security groupredash-ecs-sg
Auto-assign public IPYes
Min healthy percent0
Max healthy percent200
Deployment typeRolling update

Connectivity rules (applied after service creation)

  • Allow inbound on port 5000 from 0.0.0.0/0 to ECS service

  • Allow ECS service to reach RDS on port 5432


(Optional) Resource 9 — ECR Repositories

Only needed if you want to host images privately instead of pulling from Docker Hub.

RepositoryImage to pushTag
redashredash/redash:latestlatest or pin a version like 10.1.0
redisredis:7-alpine7-alpine

Enable scanOnPush: true for vulnerability scanning. When using ECR, update the container image URIs in the task definition to:
<ACCOUNT_ID>.dkr.ecr.ap-northeast-1.amazonaws.com/redash:\<TAG>


(Optional) Resource 10 — Application Load Balancer (Production)

Skip this for dev/testing. Required for production, HTTPS, and horizontal scaling.

ALB

SettingValue
Nameredash-alb
SchemeInternet-facing
TypeApplication (ALB)
VPCSame VPC as ECS and RDS
SubnetsPublic subnets (at least 2 AZs)
Security groupredash-alb-sg (see below)

ALB Security Group (redash-alb-sg)

DirectionPortSourcePurpose
Inbound800.0.0.0/0HTTP (redirect to HTTPS)
Inbound4430.0.0.0/0HTTPS
Outbound5000redash-ecs-sgALB → ECS

When using ALB, update the ECS Security Group (redash-ecs-sg)

DirectionPortSourcePurpose
Inbound5000redash-alb-sg (by security group ID, not 0.0.0.0/0)ALB → ECS only
OutboundAll0.0.0.0/0Internet + DB access

Target Group

SettingValue
Nameredash-tg
Target typeIP (required for Fargate)
ProtocolHTTP
Port5000
VPCSame VPC
Health check path/ping
Health check expected response200 OK (returns PONG)
Healthy threshold3
Unhealthy threshold3
Health check interval30 seconds
Health check timeout10 seconds
Deregistration delay60 seconds

Listener — HTTPS (port 443)

SettingValue
Port443
ProtocolHTTPS
CertificateACM certificate for your domain (e.g., redash.yourcompany.com)
Default actionForward to redash-tg

Listener — HTTP (port 80)

SettingValue
Port80
ProtocolHTTP
Default actionRedirect to HTTPS (port 443, status 301)

ACM Certificate

SettingValue
DomainYour domain (e.g., redash.yourcompany.com)
Validation methodDNS (add the CNAME record to your DNS provider)
Regionap-northeast-1 (must match ALB region)

DNS (Route 53 or external DNS)

Create an A record (alias) or CNAME pointing your domain to the ALB DNS name.

ECS Service changes when using ALB

When ALB is enabled, update Resource 8 (ECS Service) with:

SettingValue
Auto-assign public IPNo (ALB handles public access)
SubnetsPrivate subnets (with NAT Gateway for outbound)
Load balancerAttach redash-alb
Target groupredash-tg
Container nameredash
Container port5000

Post-Deploy Steps

Without ALB (dev/testing)

  1. Find the public IP in ECS Console → Cluster → Tasks → Networking

  2. Health check: http://<PUBLIC_IP>:5000/ping → returns PONG

  3. Open Redash: http://<PUBLIC_IP>:5000

  4. First boot takes 5–15 minutes (database migrations)

  5. Create admin account, set org name, add data sources

With ALB (production)

  1. Wait for ALB target group to show the target as healthy

  2. Health check: https://redash.yourcompany.com/ping → returns PONG

  3. Open Redash: https://redash.yourcompany.com

  4. First boot takes 5–15 minutes (database migrations)

  5. Create admin account, set org name, add data sources


Updating Redash

  1. If using ECR: pull new image locally, tag, push to ECR

  2. Create a new revision of the task definition with the updated image

  3. Update the ECS service to use the new revision (or force new deployment)

  4. ECS handles rolling deployment automatically


Troubleshooting

Task keeps restarting: Check CloudWatch Logs. Usually wrong DB password or RDS security group not allowing port 5432 from ECS.

Redis connection refused: Both containers must be in the same task definition. Redis URL must be redis://localhost:6379/0.

Can't reach port 5000: Confirm public IP is assigned, task is in a public subnet, and ECS security group allows inbound 5000.

Long loading on first boot: Normal — Redash runs database migrations. Wait 10–15 minutes.


Scaling

  • Horizontal: Increase desired count in the ECS service to run multiple Redash tasks (needs an ALB in front to distribute traffic)

  • Vertical: Increase CPU/memory in a new task definition revision — update the service to pick up the new revision

  • Database: Change the RDS instance class (causes a brief downtime during modification)


Backup & Recovery

  • RDS automated backups are enabled (7-day retention as configured above) — supports point-in-time recovery

  • Export important Redash dashboards and queries periodically via the Redash UI

  • Document all data source connection strings — these live inside Redash's DB, not in your IaC


Security Best Practices

  • RDS: Never expose to public internet (publicAccess: false)

  • Secrets: Always use AWS Secrets Manager for DB password and Redash secret key — never hardcode in task definitions

  • Network: Use private subnets for RDS; consider private subnets + ALB for ECS in production

  • IAM: Use least-privilege task execution roles

  • Images: Pin specific image versions instead of latest for reproducibility

  • Monitoring: Enable CloudWatch Container Insights on the ECS cluster for CPU/memory/network metrics

  • HTTPS (production): Place an Application Load Balancer with an ACM certificate in front of the ECS service; restrict the ECS security group to only accept traffic from the ALB


Pricing Guide — ap-northeast-1 (Tokyo)

Tokyo region is roughly 15–20% more expensive than us-east-1. Prices below are on-demand estimates.

RDS PostgreSQL — Pick by team size

InstancevCPURAMBest ForHourly (Tokyo)Monthly (Tokyo)
db.t3.micro21 GB1–3 users, testing~$0.022~$16
db.t3.small22 GB3–10 users~$0.044~$32
db.t3.medium24 GB10–30 users~$0.088~$64
db.t3.large28 GB30–100 users~$0.176~$128
db.r6g.large216 GB100+ users, production~$0.270~$197

Add ~$2.40/month per 20 GB gp3 storage.

ECS Fargate — Pick by team size

Fargate pricing in Tokyo: ~$0.05056/vCPU/hour + ~$0.00553/GB/hour.

ConfigBest ForMonthly (Tokyo)
0.25 vCPU / 0.5 GBPersonal use, 1–2 users~$11
0.5 vCPU / 1 GB2–5 users~$22
1 vCPU / 2 GB5–15 users~$44
2 vCPU / 4 GB15–50 users~$88
4 vCPU / 8 GB50+ users~$176

Total Estimated Monthly Cost (Tokyo)

EnvironmentRDSECSOtherTotal
Personal / testingdb.t3.micro (~¥2,400)0.5 vCPU / 1 GB (~¥3,300)~¥5,700 (~$38)
Small team (5–15)db.t3.small (~¥4,800)1 vCPU / 2 GB (~¥6,600)~¥11,400 (~$76)
Medium team (15–50)db.t3.medium (~¥9,600)2 vCPU / 4 GB (~¥13,200)ALB ~¥3,000~¥25,800 (~$172)
Large team (50+)db.t3.large (~¥19,200)4 vCPU / 8 GB (~¥26,400)ALB + HTTPS ~¥3,750~¥49,350 (~$329)

JPY estimates assume ~¥150/USD. Actual rates fluctuate. ECR storage is negligible (~$0.10/GB/month). Verify current pricing via the AWS Pricing Calculator.


How Everything Connects — Full Flow Diagram

Dev/Testing Setup (no ALB)

                         Internet


┌───────────────┐
│ Public IP │
│ :5000 │
└───────┬───────┘

┌─────────────▼──────────────┐
│ ECS Fargate Task │
│ (Public Subnet) │
│ │
│ ┌────────┐ ┌──────────┐ │
│ │ Redash │◄─►│ Redis │ │
│ │ :5000 │ │ :6379 │ │
│ └───┬────┘ └──────────┘ │
│ │ (localhost) │
└──────┼──────────────────────┘

│ Port 5432

┌──────────────┐
│ RDS │
│ PostgreSQL │
│ (Private │
│ Subnet) │
└──────────────┘

Production Setup (with ALB + HTTPS)

                         Internet

┌─────▼──────┐
│ Route 53 │ redash.yourcompany.com
└─────┬──────┘

┌───────▼────────┐
│ ALB │
│ :443 (HTTPS) │──── ACM Certificate
│ :80 → 301 │
│ (Public │
│ Subnets) │
└───────┬────────┘

│ Port 5000 (internal)

┌─────────────────────────────┐
│ ECS Fargate Task │
│ (Private Subnet) │
│ │
│ ┌────────┐ ┌──────────┐ │
│ │ Redash │◄──►│ Redis │ │
│ │ :5000 │ │ :6379 │ │
│ └───┬────┘ └──────────┘ │
│ │ (localhost) │
└──────┼───────────────────────┘

│ Port 5432

┌──────────────┐ ┌──────────────────┐
│ RDS │ │ Secrets Manager │
│ PostgreSQL │ │ - DB password │
│ (Private │ │ - Redash secret │
│ Subnet) │ └──────────────────┘
└──────────────┘
┌──────────────────┐
┌──────────────┐ │ CloudWatch Logs │
│ ECR │ │ - redash logs │
│ (optional) │ │ - redis logs │
└──────────────┘ └──────────────────┘

Request Flow (step by step)


1. User opens https://redash.yourcompany.com


2. DNS (Route 53) resolves to ALB


3. ALB terminates SSL, forwards HTTP to Target Group on port 5000


4. Target Group routes to Redash container's private IP


5. Redash container processes the request:
├── Reads/writes metadata → RDS PostgreSQL (port 5432)
├── Queues background jobs → Redis (localhost:6379)
└── Returns HTML/JSON to user via ALB


6. User sees the Redash dashboard

Security Group Flow

Internet ──► ALB SG (allow 80, 443) ──► ECS SG (allow 5000 from ALB SG only) ──► RDS SG (allow 5432 from ECS SG only)

Related Articles