All skills
aws avatar

/ingesting-into-data-lake

@b33847d

Import data into the AWS data lake from S3 files, local uploads, JDBC databases (Oracle, SQL Server, PostgreSQL, MySQL, RDS, Aurora), Amazon Redshift, Snowflake, BigQuery, DynamoDB, or existing Glue catalog tables (migration). Default target is S3 Tables; standard Iceberg on a general purpose bucket is supported where S3 Tables is not adopted. Handles one-time loads, recurring pipelines, migrations. Triggers on: import data, load data, ingest, sync database, migrate table, move data to AWS, set up pipeline, ETL, pull from Snowflake, query BigQuery into S3, export DynamoDB, CTAS, convert to Iceberg. Do NOT use for setting up or troubleshooting Glue connections (use connecting-to-data-source), creating empty tables (use creating-data-lake-table), running queries (use querying-data-lake), finding tables by fuzzy name (use finding-data-lake-assets), catalog audit (use exploring-data-catalog), or SaaS platforms like Salesforce, ServiceNow, SAP, MongoDB, Kafka.

Use this Skill: https://skilld.dev/gh/aws/agent-toolkit-for-aws/ingesting-into-data-lake

This session only. Nothing lands on disk.

referencescatalog-migration.md

≈1.8k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Catalog Migration to S3 Tables

Migrate existing Glue Data Catalog tables into Amazon S3 Tables. Source tables can be Hive-format, self-managed Iceberg, or any format Athena can read. The result is a fully managed S3 Table with automatic compaction, snapshot management, and multi-engine access.

Reference Documentation

Why Migrate?

Self-managed Iceberg and Hive tables require manual compaction, snapshot cleanup, and storage optimization. S3 Tables handles all of this automatically. Migration also enables the four-part catalog hierarchy (s3tablescatalog/<bucket>/<namespace>/<table>) for unified access from Athena, EMR, Redshift, and Spark.

Note: The target for catalog migration is always S3 Tables -- that is the purpose of this workflow.

Workflow

Phase 1: Understand the Source

  1. Identify the source table: Get the fully qualified name (database.table or catalog.database.table). If the user gives a fuzzy or business name ("our orders table", "the sales data"), delegate to the finding-data-lake-assets skill to resolve it before continuing -- the rest of this workflow assumes a concrete reference.
  2. Inspect the source:
    • With MCP: Use aws-mcp to get table metadata (format, location, schema, partitions)
    • Without MCP: aws glue get-table --database-name <db> --name <table>
  3. Classify the source format:
    • Hive (CSV, Parquet, ORC, JSON, Avro): Standard external table backed by S3 general purpose bucket
    • Self-managed Iceberg: Iceberg table in general purpose bucket with manual maintenance
    • Other: Any format Athena can query (federated sources, etc.)
  4. Assess size and complexity:
    • Small/medium (under ~100 GB, simple schema): Path A (Athena CTAS) -- single SQL statement
    • Large (over ~100 GB, complex transforms, or needs scheduling): Path B (Glue ETL)
    • Partitioned source: Note partition columns and strategy for conversion

Phase 2: Prepare the Target

  1. Ensure table bucket exists: Check with aws s3tables list-table-buckets. If none, delegate to creating-data-lake-table Phase 2.
  2. Ensure analytics integration is enabled: Verify s3tablescatalog exists. Delegate to creating-data-lake-table Phase 2, step 4 if not set up.
  3. Create or select namespace: Use existing or create new via aws s3tables create-namespace.
  4. Plan partition strategy: Iceberg supports hidden partition transforms (day(), month(), year(), hour(), bucket()). Recommend converting Hive-style explicit partition columns to Iceberg transforms where possible.

Phase 3: Migrate the Data

Path A: Athena CTAS (default for small/medium tables)

Single SQL statement that creates the S3 Table and populates it in one step. See ctas-patterns.md for full syntax and examples.

Key points:

  • Target path: "s3tablescatalog/<table_bucket_name>"."<namespace>"."<new_table_name>"
  • Default format: PARQUET. Also supports AVRO, ORC.
  • Use Iceberg partition transforms (day(), month(), bucket()) instead of Hive-style explicit partition columns.
  • No LOCATION clause -- S3 Tables manages storage.
  • Table and column names must be all lowercase.
  • Source catalog for default GDC tables is awsdatacatalog.
  • Add WHERE filters to migrate subsets or batch large migrations.
Path B: Glue ETL (for large tables or complex transforms)

Use when CTAS would time out, when transforms are complex, or when the migration needs to be scheduled/repeatable.

  1. Create PySpark script that reads from source and writes to S3 Table
  2. Create Glue 5.1 or higher job with --datalake-formats iceberg and --conf catalog config
  3. Run and monitor the job

See glue-etl-migration.md for job configuration, PySpark script template, and catalog setup.

Phase 4: Validate the Migration

Run all of these checks -- do not skip any:

  1. Row count comparison:

    SELECT 'source' AS tbl, COUNT(*) AS cnt FROM "<source_catalog>"."<source_db>"."<source_table>"
    UNION ALL
    SELECT 'target' AS tbl, COUNT(*) AS cnt FROM "s3tablescatalog/<bucket>"."<namespace>"."<new_table>"
  2. Schema comparison: Verify column names, types, and order match expectations. Minor type promotions (e.g., int to bigint) are acceptable.

  3. Spot-check data: Compare a sample of rows between source and target, focusing on:

    • Boundary values (min/max of numeric and date columns)
    • Null counts per column
    • Distinct counts on key columns
  4. Partition verification (if partitioned):

    SELECT <partition_column>, COUNT(*) FROM "s3tablescatalog/<bucket>"."<namespace>"."<new_table>"
    GROUP BY 1 ORDER BY 1

See migration-validation.md for the full checklist.

Phase 5: Post-Migration Guidance

After validation passes:

  1. Update downstream consumers: Provide the new table path for queries, dashboards, and ETL jobs.
  2. Recommend keeping the source table temporarily as a rollback option. Suggest a retention period (e.g., 30 days).
  3. Do NOT drop the source table. Warn the user and let them decide when to clean up.
  4. Evaluate table lineage: If the source table has lineage present, use it to recommend next-steps for producers and consumers.

Gotchas

  • Athena CTAS has a 100-partition limit per statement. For sources with more than 100 partitions, either migrate in batches with WHERE filters or use Glue ETL (Path B).
  • CTAS creates a new table -- it does not do an in-place conversion. The source table remains unchanged.
  • Column names with uppercase letters will cause the target table to be invisible to analytics services. Always lowercase column names in the SELECT: SELECT upper_Col AS upper_col.
  • Self-managed Iceberg tables may have schema evolution history (added/renamed columns). CTAS captures the current schema only -- historical evolution is not preserved.
  • Hive tables with complex SerDe configurations (custom delimiters, regex SerDe) should be tested with a small CTAS first to verify Athena can read them correctly. Glue will often read things Athena cannot. Try Glue if Athena fails.
  • Time travel on the source Iceberg table is lost after migration. The S3 Table starts fresh with its own snapshot history.

Troubleshooting

See migration-troubleshooting.md for common errors and fixes covering CTAS failures, validation mismatches, visibility issues, and partition problems.

Source: SKILL.md on GitHub

2 warnings16d3 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    This skill facilitates the ingestion of data from various external sources into an AWS data lake. It contains security considerations related to the processing of untrusted data and the dynamic generation of Spark scripts, which are characteristic of ETL (Extract, Transform, Load) operations. These patterns are consistent with the skill's purpose and are used within a managed cloud environment.

  • Socket16d

    1 alert: gptAnomaly

  • Snyk16d

    Risk: MEDIUM · 1 issue

Signed by skilld at b33847d. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated 2 months ago
Other metadata
metadata
{
  "version": "1",
  "argument-hint": "'[source-path|connection-name|table-name] [--target s3-tables|iceberg|parquet]'"
}

README badge

README badge for aws/agent-toolkit-for-aws/ingesting-into-data-lake