Creating Data Lake Table
AWSOfficialPublished by AWS
- Skill
- Workflow
- Cloud and DevOps
- Apache-2.0
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured workflow for creating and managing Iceberg tables within Amazon S3 Tables. It covers the end-to-end process, including bucket creation, namespace setup, Glue Data Catalog integration, IAM access control, and table schema definition. It ensures that users follow best practices for partitioning and storage management while avoiding common pitfalls like manual location specification or incorrect IAM policy namespaces.
What it does
- Creates and configures S3 Tables buckets and namespaces.
- Integrates S3 Tables with the AWS Glue Data Catalog.
- Defines Iceberg table schemas and partitioning strategies.
- Configures necessary IAM and bucket policies for secure access.
- Provides paths for both API-based and Athena DDL-based table creation.
- Validates table existence and configuration before execution.
When to use it
- When you need to provision a new managed Iceberg table in Amazon S3 Tables.
- When setting up structured data storage for analytics workloads.
- When you need to integrate S3 Tables with Athena or Glue ETL pipelines.
- When you need to define specific partitioning strategies for performance optimization.
Advantages
- Automates complex multi-step infrastructure setup.
- Ensures adherence to AWS best practices for S3 Tables and Iceberg.
- Reduces configuration errors by validating existing resources first.
- Provides clear guidance on IAM and Glue catalog prerequisites.
Usage examples
- “Create a new S3 Tables Iceberg table named sales_data in the analytics namespace with a monthly partition on order_date.”
- The agent will verify the bucket and namespace, define the schema and partition spec, and execute the creation command via the S3 Tables API.
- “I need to set up a new analytics table using Athena DDL for my Iceberg data.”
- The agent will guide you through the Athena DDL creation path, ensuring the correct execution context is used without specifying a manual location.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/aws/creating-data-lake-table/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip creating-data-lake-table.zip -d .agents/skills
Documentation by AWS
Create Data Lake Tables with Amazon S3 Tables
Overview
Amazon S3 Tables provides managed Iceberg tables with automatic compaction and snapshot management. Queryable via Athena and Iceberg-compatible engines.
Common Tasks
You MUST use AWS MCP server tools when connected, they provide command validation, sandboxed execution, and audit logging. Fall back to AWS CLI if MCP unavailable.
Decision Guide
Before creating, You MUST check what exists:
You MUST run aws glue get-tables --database-name <NAME> when user mentions a database.
| What you find | Action |
|---|---|
| Fuzzy database name ("our analytics db") | You MUST STOP. Delegate to finding-data-lake-assets to resolve. |
| Non-S3-Tables table with matching name | You MUST STOP. Delegate to finding-data-lake-assets. You MUST NOT create until user confirms. |
| Existing S3 Tables table with matching name | You MUST check schema match. Reuse if compatible, recreate only if user confirms. |
| No matching tables | Proceed with creation (Steps 1-8). |
| User explicitly requests new S3 Tables table | Skip checks, proceed with creation. |
Creation paths:
Existing data in S3: Create empty table (Steps 1-8), then use
ingesting-into-data-lakeskill.Glue ETL pipeline: Read
references/table-creation-glue-etl.mdfirst, then Steps 1-6.Lake Formation access control: Search AWS docs for
"S3 Tables integration with Lake Formation".
1. Verify Dependencies
Constraints:
You MUST check whether AWS MCP server tools or AWS CLI are available and inform user if missing
You MUST confirm target AWS region and verify credentials with
aws sts get-caller-identity
2. Understand the Schema
Explicit schema: Validate Iceberg types.
Loose description: Ask columns, types, grain. Propose and confirm.
Existing S3 data: Infer schema from file headers only. Create empty table first, then use
ingesting-into-data-lakeskill.
Constraints:
You MUST read
references/best-practices.mdfor Iceberg type mapping, partitions, and naming.You MUST ask for all required parameters upfront: table name, columns, types, partition strategy. For schema evolution, see
references/athena-ddl-path.md.You MUST use all lowercase names -- Glue rejects mixed case with
GENERIC_INTERNAL_ERROR. Namespace and table names MUST NOT contain hyphens.You SHOULD suggest partition columns based on access patterns.
3. Create Table Bucket
Names: 3-63 chars, lowercase, numbers, hyphens.
aws s3tables create-table-bucket --name <BUCKET_NAME> --region <REGION>Capture table-bucket-arn. Encryption (SSE-S3 default, SSE-KMS) and storage class (STANDARD, INTELLIGENT_TIERING) set at creation. See references/best-practices.md.
Constraints:
You MUST check existing buckets with
aws s3tables list-table-bucketsand ask user to select or create new.If using SSE-KMS, KMS key policy MUST allow S3 Tables maintenance service principal to read data. Search AWS docs for
"S3 Tables KMS key policy"for required policy.If bucket creation fails, see
references/best-practices.mdfor common errors.
4. Create Namespace
aws s3tables create-namespace --table-bucket-arn <ARN> --namespace <NAMESPACE>Constraints:
You MUST list existing namespaces first and suggest reusing if relevant
You MUST use lowercase names with no hyphens
5. Create Glue Data Catalog Integration
Check if s3tablescatalog exists (create once per region per account):
aws glue get-catalog --catalog-id s3tablescatalogIf not found, create (requires glue:CreateCatalog, glue:passConnection):
aws glue create-catalog --name "s3tablescatalog" --catalog-input '{
"FederatedCatalog": {
"Identifier": "arn:aws:s3tables:<REGION>:<ACCOUNT_ID>:bucket/*",
"ConnectionName": "aws:s3tables"
},
"CreateDatabaseDefaultPermissions": [{"Principal": {"DataLakePrincipalIdentifier": "IAM_ALLOWED_PRINCIPALS"}, "Permissions": ["ALL"]}],
"CreateTableDefaultPermissions": [{"Principal": {"DataLakePrincipalIdentifier": "IAM_ALLOWED_PRINCIPALS"}, "Permissions": ["ALL"]}],
"AllowFullTableExternalDataAccess": "True"
}'Verify with aws glue get-catalogs --parent-catalog-id s3tablescatalog.
6. Configure Access Control
S3 Tables uses s3tables:* IAM namespace (not s3:*).
Querying principal permissions (bucket policy):
s3tables:GetTableBucket,s3tables:GetNamespace,s3tables:GetTable,s3tables:GetTableMetadataLocation,s3tables:GetTableData
Querying principal permissions (IAM policy):
glue:GetCatalog,glue:GetDatabase,glue:GetTable
You MUST scope to correct ARN patterns. You MUST read references/access-control.md for exact resource ARNs.
Constraints:
You MUST ask user for querying principal ARN
You MUST NOT grant broader permissions than necessary
You MUST NOT create IAM roles automatically, verify existing and guide user
7. Create the Table
| Context | Path |
|---|---|
| Default (any user) | S3 Tables API (below) |
| User specifically wants SQL DDL | Athena DDL (see references/athena-ddl-path.md) |
| Glue ETL pipeline | Spark DDL via --conf job args (not spark.conf.set()). You MUST read references/table-creation-glue-etl.md for the --conf string. |
Default: S3 Tables API:
aws s3tables create-table \
--table-bucket-arn <ARN> \
--namespace <NAMESPACE> \
--name <TABLE_NAME> \
--format ICEBERG \
--metadata '<METADATA_JSON>'Metadata JSON MUST nest under "iceberg" key:
{"iceberg":{"schema":{"fields":[
{"name":"order_date","type":"date","required":true},
{"name":"customer_id","type":"string","required":true},
{"name":"amount","type":"double","required":false}
]},
"partitionSpec":{"fields":[
{"sourceId":1,"fieldId":1000,"transform":"month","name":"order_date_month"}
]}}}Constraints:
partitionSpec.sourceIdMUST reference a valid schema field IDFor schema evolution after creation, use Athena DDL. See
references/athena-ddl-path.mdYou MUST use
schemaV2for complex types (list, map, struct) with explicit field IDs. Seereferences/best-practices.md.You SHOULD search AWS docs for
"IcebergPartitionField S3 Tables"for supported partition transforms
8. Verify and Confirm
You MUST verify with aws s3tables get-table and confirm queryability with DESCRIBE <table_name> via Athena using --query-execution-context '{"Catalog":"s3tablescatalog/<BUCKET_NAME>","Database":"<NAMESPACE>"}'. Do NOT put catalog in SQL. Present summary: bucket ARN, namespace, table, schema, partitions.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
| "Table location can not be specified" | LOCATION in CREATE TABLE | Remove LOCATION clause. S3 Tables manages storage automatically. |
AccessDeniedException with s3:* policy | Using s3:* not s3tables:* | S3 Tables uses s3tables:* namespace. Update IAM policy. |
Additional Resources
access-control.md -- IAM permissions, ARN patterns, permission errors
best-practices.md -- Iceberg types, partitions, naming, common errors
athena-ddl-path.md -- Athena DDL, schema evolution
table-creation-glue-etl.md -- Spark DDL via Glue ETL
Loading data:
ingesting-into-data-lakeskill
Files
- ATTRIBUTION.mdAdded by AutoGineer928 B
- LICENSELicence file added by AutoGineer9.9 KiB
- NOTICELicence file added by AutoGineer67 B
- SKILL.md8.1 KiB
- references/access-control.md1.4 KiB
- references/athena-ddl-path.md3.5 KiB
- references/best-practices.md4.5 KiB
- references/table-creation-glue-etl.md6.1 KiB
references/athena-ddl-path.md
Creating Tables via Athena DDL
Alternative to the S3 Tables API. Use when the user specifically wants SQL DDL or needs schema evolution via ALTER TABLE after creation.
Prerequisites
Glue catalog (
s3tablescatalog) MUST be registered (see Step 5 in SKILL.md)Athena workgroup MUST use engine version 3 (required for Iceberg support)
Output S3 bucket MUST exist in the same region as the table bucket for Athena query results. If Athena has never been used in this region, the user MUST first configure a query result location in the Athena workgroup settings or via
--result-configurationon each query.
CREATE TABLE
The catalog reference goes in --query-execution-context, NOT in the SQL statement. Use <database>.<table> format in SQL:
CREATE TABLE <namespace>.<table_name> (
<column_definitions>
)
PARTITIONED BY (<partition_columns>)
TBLPROPERTIES ('table_type' = 'ICEBERG')CRITICAL: Do NOT include a LOCATION clause. S3 Tables manages storage automatically. This differs from regular Athena external tables.
CRITICAL: Do NOT put the catalog name in the SQL. Athena cannot parse s3tablescatalog/<bucket> as a catalog identifier in DDL. It goes in the execution context only.
Execute via Athena
aws athena start-query-execution \
--query-string "<DDL>" \
--query-execution-context '{"Catalog": "s3tablescatalog/<BUCKET_NAME>", "Database": "<NAMESPACE>"}' \
--work-group "<WORKGROUP>" \
--result-configuration '{"OutputLocation": "s3://<RESULTS_BUCKET>/output/"}'Check status with aws athena get-query-execution --query-execution-id <ID>.
The results bucket MUST be in the same region as the table bucket.
Querying
Use the same execution context pattern for SELECT queries:
aws athena start-query-execution \
--query-string "SELECT * FROM <namespace>.<table_name> LIMIT 10" \
--query-execution-context '{"Catalog": "s3tablescatalog/<BUCKET_NAME>", "Database": "<NAMESPACE>"}' \
--work-group "<WORKGROUP>" \
--result-configuration '{"OutputLocation": "s3://<RESULTS_BUCKET>/output/"}'Constraints
All table and column names MUST be lowercase
You MUST NOT include a LOCATION clause
You MUST NOT put catalog name in the SQL -- use execution context
Output S3 bucket MUST be in the same region
The querying principal needs
athena:StartQueryExecution,athena:GetQueryExecution,athena:GetQueryResultsplus S3 access to the results bucket. Also requires S3 Tables and Glue permissions — seeaccess-control.md.
Schema Evolution
ALTER TABLE uses the same --query-execution-context pattern:
aws athena start-query-execution \
--query-string "ALTER TABLE <namespace>.<table_name> ADD COLUMNS (<col> <type>)" \
--query-execution-context '{"Catalog": "s3tablescatalog/<BUCKET_NAME>", "Database": "<NAMESPACE>"}' \
--work-group "<WORKGROUP>" \
--result-configuration '{"OutputLocation": "s3://<RESULTS_BUCKET>/output/"}'Supported operations: ALTER TABLE ADD COLUMNS, ALTER TABLE DROP COLUMN. WARNING: schema changes affect all future queries. You MUST confirm with the user before executing.
Alternative: Schema evolution is also supported via the S3 Tables Iceberg REST API or the S3 Tables Catalog for Apache Iceberg (open-source). Search AWS docs for "S3 Tables Catalog for Apache Iceberg" for setup.
Additional Resources
For latest Athena DDL syntax, search AWS docs for "Creating Iceberg tables in Athena" and "Supported data types for Iceberg tables in Athena".
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 a command-line tool
Security
No issues found by our static scan· No issues found
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 · plugins/aws-data-analytics/skills/creating-data-lake-table · 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
- Also distributed in
- aws/agent-toolkit-for-aws
AutoGineer is not affiliated with or endorsed by AWS.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download creating-data-lake-table.zip