Generated banner for Migrating To Amazon Redshift
Generated logo for Migrating To Amazon Redshift

Migrating To Amazon Redshift

AWSOfficialPublished by AWS

  • Skill
  • Workflow
  • Cloud and DevOps
  • Apache-2.0
  • Low risk

From the author

Guides an end-to-end data-warehouse migration to Amazon Redshift — discovery, schema/SQL/stored-procedure/macro/script conversion, data migration, validation, performance comparison, and reporting. Source-routed via `references/<source>/`; Teradata (Vantage) is the supported source; additional sources are added as their own `references/<source>/` sets. Text-only knowledge (no executable code) — the AI generates all execution at runtime. Applies when a user wants to migrate Teradata to Amazon Redshift, convert Teradata DDL/SQL/stored procedures/macros/BTEQ to Redshift/RSQL, or assess Teradata-to-Redshift migration complexity. Applies only to migrations targeting Amazon Redshift; migrations to other platforms (Snowflake, BigQuery, Databricks, etc.) are out of scope regardless of source. Does not cover general Redshift administration, performance tuning, or troubleshooting of existing Redshift clusters (no migration involved), or sources not listed under references/.
— the description by AWS

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a structured, text-based framework for migrating Teradata Vantage environments to Amazon Redshift. It covers the entire migration lifecycle, including discovery, schema and SQL conversion, data migration, validation, and performance reporting. The skill acts as an expert guide, instructing the AI to generate execution scripts at runtime rather than providing pre-packaged code. It emphasizes secure, read-only discovery, best practices for Redshift architecture, and the conversion of legacy Teradata constructs like BTEQ, macros, and stored procedures into Redshift-compatible formats.

What it does

  • Inventories Teradata source systems using read-only discovery queries.
  • Converts Teradata DDL, SQL, stored procedures, and BTEQ scripts to Redshift/RSQL.
  • Maps Teradata physical architecture to Redshift distribution and sort keys.
  • Generates migration runners for data extraction, S3 staging, and COPY operations.
  • Provides validation patterns for verifying data integrity and row counts.
  • Assesses migration complexity and generates performance comparison reports.

When to use it

  • When planning or executing a migration from Teradata Vantage to Amazon Redshift.
  • When you need to convert legacy Teradata DDL or BTEQ scripts to Redshift syntax.
  • When assessing the effort and complexity of a Teradata-to-Redshift migration project.
  • When you require a structured, repeatable process for data warehouse migration.

Advantages

  • Knowledge-based approach avoids dependency drift and vendor lock-in.
  • Promotes secure, least-privilege practices for data extraction and migration.
  • Provides clear mapping rules for complex Teradata-to-Redshift architectural differences.
  • Supports both connected and disconnected migration environments.
  • Enables reproducible results through a standardized project-workspace layout.

Usage examples

“Assess the complexity of migrating my Teradata schema to Redshift.”
The agent will guide you through the discovery phase, inventorying your Teradata objects and identifying high-complexity constructs that require manual review.
“Convert this Teradata BTEQ script to RSQL for Redshift.”
The agent will apply the BTEQ-to-RSQL conversion rules, replacing .IMPORT/.EXPORT with S3-based COPY/UNLOAD commands and adapting transaction logic.
“How should I choose distribution keys for my Teradata fact tables in Redshift?”
The agent will analyze your table sizes and join patterns to recommend appropriate DISTKEY or DISTSTYLE settings based on the architecture-mapping reference.
“Generate a script to validate row counts between Teradata and Redshift.”
The agent will produce a validation runner script that executes count queries on both systems and generates a comparison report.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/aws/migrating-to-amazon-redshift/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip migrating-to-amazon-redshift.zip -d .agents/skills

Documentation by AWS

Migrating to Amazon Redshift

What this skill is

This skill is AI guidance, not an execution framework. It is entirely Markdown knowledge (rules, mappings, patterns, best practices) — no executable code. All execution — conversion, the discovery/migration/validation runners, dependencies, and infrastructure — you (the AI) generate at runtime from this knowledge, tailored to the customer's environment.

Principle: knowledge over shipped code → less drift, nothing for the customer to run or depend on, reliable first-time results. Do not look for a pyproject, a tools package, an orchestrator engine, or shipped scripts — there are none by design; you generate execution.

Runtime: this skill works with or without the AWS MCP server — step guidance uses AWS CLI syntax. Running it with the AWS MCP server is recommended for sandboxed execution and audit logging; without it, the AI runs the generated scripts on the host shell (assumes Bash, Python 3, and AWS CLI + credentials). Do not assume MCP-only tools are available.

Source routing

This skill migrates a supported source data warehouse to Amazon Redshift. First identify the source system, then load that source's knowledge under references/<source>/:

  • Teradata (Vantage) → references/teradata/ — supported (all references below).

  • Other sources (e.g. Snowflake, Oracle) — unsupported; each is added as its own references/<source>/ set when ready.

The workflow is source-agnostic (discovery → convert → migrate → validate → performance → report); only the conversion knowledge is source-specific. Everything below is the Teradata set.

When to use

  • Migrating a Teradata system (Vantage) to Amazon Redshift.

  • Converting Teradata DDL, SQL, stored procedures, macros, or BTEQ to Redshift/RSQL.

  • Assessing Teradata→Redshift migration complexity/effort.

Operating principles

  • Discovery is strictly read-only (SELECT-only) on the source. Never change production state: no DDL/DML, and never enable logging (BEGIN/REPLACE QUERY LOGGING). If DBQL is empty, mark it unavailable and fall back to always-on DBC.AMPUsageV — see references/teradata/discovery-queries.md.

  • Skill provides knowledge; you generate execution. Read the references/ to reason and convert — apply the rules in references/teradata/conversion-rules.md directly for conversion, and generate the discovery/migration/validation runners (and the read-only discovery collector from references/teradata/discovery-queries.md) tailored to the environment.

  • Generate, don't assume a framework. Assume the environment has Bash, Python 3, and AWS CLI + credentials. Any Python lib a generated script needs (teradatasql, boto3, …) is pip install-ed on demand by that script / its run-instructions — pin exact versions. Teradata TTU (BTEQ/TPT) is Linux/Windows-only — not macOS; prefer WRITE_NOS + teradatasql (cross-platform, no client) for discovery/extract unless a TTU/Linux host exists.

  • Credentials: use a read-only Teradata user; prefer IAM roles over IAM users. For production, reference credentials from AWS Secrets Manager or Systems Manager Parameter Store. For local development only, a git-ignored .env file or profile may be used — never commit it. Never hard-code or echo secrets. In a portable bundle, reference a co-located credentials file and ship a credentials.env.example template — the real file is git-ignored.

  • Persist state in files. All generated output goes under a git-ignored output/ in the user's working dir; keep output/state.md current so work is resumable.

Workflow (phases)

Run in order; each phase's result/ feeds the next (see references/teradata/orchestration.md).

  1. Discovery — inventory the source. → references/teradata/discovery-queries.md (read-only collection SQL + BTEQ driver template the AI generates) → output/discovery/result/inventory.json

  2. Conversion — schema + code. Apply the conversion rules directly, flag the manual-rewrite long tail, and fix Redshift errors from the references. → references/teradata/conversion-rules.md, references/teradata/data-type-mapping.md, references/teradata/architecture-mapping.md, references/teradata/stored-procedure-migration.md, references/teradata/bteq-to-rsql.md, references/teradata/common-errors.md

  3. Data migration — extract → S3 → COPY, restartable. → references/teradata/data-migration-patterns.md

  4. Validation — counts/aggregates/sampling. → references/teradata/validation-patterns.md

  5. Performance — baseline vs Redshift; size the target. → references/teradata/performance.md, references/teradata/sizing.md

  6. Reporting — aggregate all phases. → references/teradata/reporting.md

Conversion (how the AI applies it)

There is no converter to run — convert by applying the rules in references/teradata/conversion-rules.md directly (with the type / architecture / stored-procedure / BTEQ references): apply the deterministic rules to the well-understood bulk, flag the manual-rewrite constructs with their suggested rewrites, assign a confidence per object, and fix any Redshift errors using references/teradata/common-errors.md. The reference docs are the single source of truth; conversion-rules.md includes golden input→output examples to match.

Execution modes (connectivity)

  • Connected — your host can reach Teradata/Redshift → run the generated scripts in place.

  • Disconnected — it can't → generate a self-contained bundle under output/<phase>/ (script + co-located credentials template + relative result/ + run-instructions.md); the operator runs it on a reachable host and copies result/ back. The copied-back result/ is the durable state — read it (+ state.md) and continue.

Project-workspace layout (per migration run)

<project-workspace>/
  migration-config.yaml          # operator-authored: endpoints, scope, strategy
  .gitignore                     # ignores output/
  output/                        # everything generated (git-ignored)
    state.md                     # progress cursor
    discovery/   …  result/inventory.json
    conversion/  …  result/{ddl,sql,procedures,rsql}/  manual_review.json
    data_migration/ … result/{extract,load,templates}/  migration_manifest.json
    validation/  …  result/validation_report.json
    performance/ …  result/{perf_baseline,perf_compare}.json
    reporting/      result/migration_report.md

Security considerations

  • No shipped code or dependencies. This skill is text-only — the customer runs nothing from it. Any runner the AI generates MUST pin exact dependency versions, validate/sanitize inputs (file paths, SQL, shell args), and never print or log credentials, secrets, or PII.

  • Least privilege + ephemeral credentials. Use a read-only Teradata user for discovery. On AWS prefer IAM roles over IAM users and IAM auth over username/password. Keep secrets in AWS Secrets Manager / Parameter Store — never hard-code, echo, or commit them (credentials files are git-ignored; ship only *.example templates).

  • Data in transit / at rest. Use TLS to both engines; stage extracts in an encrypted S3 bucket (SSE) with a least-privilege bucket policy; load via COPY … IAM_ROLE (not access keys). Enable encryption on the target Redshift cluster.

  • Blast radius. Discovery is read-only by design. Migration writes to the target — validate against a throwaway / non-production Redshift first, and never point a generated write-path at production without explicit operator confirmation.

  • No secret leakage in artifacts. Generated output/… (manifests, reports, state.md) MUST NOT embed credentials or endpoints beyond what the operator supplies in migration-config.yaml.

  • COPY IAM_ROLE hardening. Scope the role's policy to the specific staging prefix (not bucket-wide s3:*), and include condition keys in its trust policy (aws:SourceAccount / aws:SourceArn, or sts:ExternalId for cross-account) to prevent confused-deputy assumption — per Redshift IAM-role authorization best practices.

  • Logging & monitoring. Enable CloudTrail (S3 data events on the staging bucket + Redshift management events), Redshift audit logging (connection/user-activity logs to S3 or CloudWatch), and CloudWatch alarms on COPY failures or unusual staging-bucket access during the migration.

The AWS MCP server (recommended runtime) additionally provides sandboxed execution and audit logging for the generated scripts.

References (specialized knowledge)

FileTopic
references/teradata/orchestration.mdphase workflow + state model
references/teradata/conversion-rules.mdthe 72 conversion rules (source of truth)
references/teradata/data-type-mapping.mdTD→RS type mapping
references/teradata/architecture-mapping.mdPI→DISTKEY, PPI→SORTKEY, Join Index→MV
references/teradata/stored-procedure-migration.mdSP → PL/pgSQL
references/teradata/bteq-to-rsql.mdBTEQ → RSQL
references/teradata/common-errors.mdcommon Redshift errors + fixes
references/teradata/discovery-queries.mdDBC system-view inventory queries
references/teradata/data-migration-patterns.mdCOPY/TPT/micro-batch/checkpoint
references/teradata/validation-patterns.mdrow-count/aggregate/sample compare
references/teradata/performance.mdrepresentative-query extraction + compare
references/teradata/sizing.mdRG node type + count from the source profile
references/teradata/reporting.mdmigration status-report generation

Files

references/teradata/sizing.md

Redshift sizing (from the source profile)

AI-facing knowledge: how to draft a Redshift target cluster from the source inventory.json (see references/teradata/discovery-queries.md) and workload signals (see references/teradata/performance.md). Facts in, a sizing recommendation out.

Philosophy

Target RG (Graviton) provisioned nodes. Node count is driven by parallelism or memory — never by raw data volume. Teradata ResUsage decides the bottleneck:

  • CPU-bound (avg CPU busy ≥ threshold) → size by parallelism: source AMPs → target slices, node_count = ceil(target_slices / slices_per_node).

  • memory-bound (below threshold) → size by RAM: target aggregate RAM ≈ source RAM, node_count = ceil(total_ram_gib / ram_per_node).

  • ResUsage unavailable → fall back to parallelism (AMP count is always known) at lower confidence; flag that CPU- vs memory-bound was not verified.

Managed storage on RG is decoupled and large, so storage is only a capacity check, never the node-count driver.

Target is RG (Graviton), not RA3.

RG node specs

Verify against the live API before sizing — node specs and limits change as AWS updates the lineup. Treat the table below as a fallback/example snapshot (per the AWS Amazon Redshift Management Guide — "Clusters and nodes in Amazon Redshift → Node type details"), and confirm current values at runtime: aws redshift describe-orderable-cluster-options --query 'OrderableClusterOptions[?starts_with(NodeType, \rg.`)].{NodeType:NodeType}' --output table` plus the Management Guide spec table for vCPU/RAM/slices/storage.

Resolve the full candidate list and per-node specs at runtime (API + Management Guide). Illustration of the shape of one fetched record (example row, retrieved 2026-07; do not reuse the values — fetch current ones):

RG node (example)vCPURAMdefault slices/nodemanaged storage / nodenode range (create)
rg.xlarge (multi-node)432 GiB232 TB2–16

Minimum cluster = 2 nodes. "Default slices per node" is the create-time value (elastic resize keeps the cluster's total slice count constant while changing node count). For RA3→RG equivalences, consult the current AWS documentation/API rather than fixed mappings — node lineups and equivalences change.

Node-count clamp bounds: clamp to the create-time node range — not the elastic-resize maximums — since the skill provisions a new cluster. The Logic below consumes max_nodes(node_type) fetched at runtime from aws redshift describe-orderable-cluster-options; the table above is illustrative only and is never read by the Logic.

Source: https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-clusters.html#rs-rg-nodes-table

Inputs (from inventory.json)

InputFieldUse
Source AMPssystem.amp_countparallelism → target slices
CPU busy %workload.resource_stats.avg_cpu_busy_pctbottleneck decision
Source RAMnode hardware spec / operator (not ResUsage — see note)memory-bound path
Storagestorage.total_current_perm_bytescapacity check only
Workload mix / peakworkload.query_stats (DBQL)Concurrency Scaling + WLM

Logic

Resolve per-node specs at runtime before sizing — slices(n), ram_gib(n), max_nodes(n) for each candidate node type — from aws redshift describe-orderable-cluster-options (node types + node ranges) and the Management Guide spec table (slices/RAM). The logic below is symbolic: it references only those fetched values, never literal numbers. Candidates are ordered smallest→largest (e.g. rg.xlarge → rg.4xlarge → rg.12xlarge).

fetch candidates C = ordered list of RG node types with slices(c), ram_gib(c), max_nodes(c)

if resource_stats.avg_cpu_busy_pct is not null:
    if avg_cpu_busy_pct >= CPU_BOUND_PCT:        # cpu-bound
        target_slices = max(slices(C[0]) * 2, ceil(amp_count * SLICE_PER_AMP))
        node_type  = smallest c in C where target_slices <= slices(c) * max_nodes(c)
        node_count = clamp(ceil(target_slices / slices(node_type)), 2, max_nodes(node_type))
    else:                                         # memory-bound
        node_type  = smallest c in C where total_ram_gib <= ram_gib(c) * max_nodes(c)
        node_count = clamp(ceil(total_ram_gib / ram_gib(node_type)), 2, max_nodes(node_type))
else:                                             # ResUsage absent → fallback
    size by parallelism (as cpu-bound), confidence = low

# The Logic targets the smallest multi-node production type (rg.xlarge today) as the floor.
# rg.large has the same slice count but half the vCPU/RAM per slice — consider it for
# cost-sensitive workloads. Storage is only a capacity check; raise node_count if the
# fetched managed-storage-per-node capacity is exceeded.

Recommendation shape

{
  "node_type": "rg.xlarge",
  "node_count": 2,
  "sizing_basis": "parallelism: AMP->slices (cpu-bound per ResUsage)",
  "bottleneck": "cpu-bound|memory-bound|unknown",
  "basis_detail": { "source_amps": 24, "slice_per_amp": 1.0, "target_slices": 24, "slices_per_node": 2 },
  "storage_check": { "source_total_current_perm_bytes": 0, "cluster_managed_capacity_bytes": 0, "sufficient": true },
  "concurrency_notes": "peak-hour arrival → Concurrency Scaling / WLM slots",
  "wlm_notes": "statement mix → ETL vs BI queues",
  "assumptions": ["DRAFT: AMP->slice ratio and CPU-bound threshold are placeholders pending calibration."],
  "confidence": "low|medium|high"
}

Confidence is high only when both ResUsage and DBQL are present; medium with ResUsage only; low on the parallelism fallback.

Calibration placeholders (not yet validated)

  • slice_per_amp = 1.0 — Graviton slices are more powerful, so a 1:1 AMP:slice mapping is likely conservative. Calibrate against a real workload.

  • cpu_bound_pct = 60 — the avg-CPU-busy threshold separating CPU- vs memory-bound.

ResUsage validation (live cluster, 2026-06-24)

Validated against DBC.ResUsageSpma (logging ON @60s; 12,272 samples, 2 nodes):

  • ✅ CPU-busy formula is correct: (CPUUExec + CPUUServ) / (CPUUExec + CPUUServ + CPUIdle) * 100. The dev cluster is near-idle (avg 0.05%, max 2.13%) — plausible, so the cpu-bound path and the bottleneck decision are sound.

  • ⚠️ ResUsageSpma.MemSize is NOT physical node RAM (observed ~126,844 per sample — not bytes, ≈124 MB-scale). The earlier MemSize × nodes / 1 GiB derivation yields ~0 and is invalid. Source aggregate RAM must come from the node hardware spec or operator input (migration-config), not from ResUsage. Until a reliable RAM source is wired in, the parallelism (CPU-bound) path is the dependable one; the memory-bound branch needs a RAM input before it can be trusted.

Placement (resolved)

This sizing logic is deterministic, but per the team's text-only decision the skill ships no scripts — it stays here as knowledge and the AI applies it at runtime (same as conversion). No scripts/ helper.

Source endpoints come from migration-config.yaml — operator-provided, never hard-coded in the skill.

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs an MCP server, Needs Python, Needs Node.js

Security

What our scanner noticed· Low risk

  • Instructions that use the network

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
AWS
Publisher
AWS (Official)
Source
aws/agent-toolkit-for-aws · skills/specialized-skills/analytics-skills/migrating-to-amazon-redshift · commit 0a218f8
Licence
Apache License 2.0 (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • NOTICE (added by AutoGineer from NOTICE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by AWS or AWS.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download migrating-to-amazon-redshift.zip