Create managed Iceberg tables using Amazon S3 Tables (s3tables API namespace) with automatic compaction and snapshot management. Sets up table bucket, namespace, table, schema, Glue catalog registration, partitioning, IAM access control. Triggers on: create table, data lake table, analytics table, structured data storage, S3 Tables, Iceberg, Athena table, partitioning strategy, access permissions. Do NOT use for: importing files (use ingesting-into-data-lake), vector storage (use storing-and-querying-vectors), querying existing tables (use querying-data-lake), or locating existing table (use finding-data-lake-assets).
76
96%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Amazon S3 Tables provides managed Iceberg tables with automatic compaction and snapshot management. Queryable via Athena and Iceberg-compatible engines.
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.
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:
ingesting-into-data-lake skill.references/table-creation-glue-etl.md first, then Steps 1-6."S3 Tables integration with Lake Formation".Constraints:
aws sts get-caller-identityingesting-into-data-lake skill.Constraints:
references/best-practices.md for Iceberg type mapping, partitions, and naming.references/athena-ddl-path.md.GENERIC_INTERNAL_ERROR. Namespace and table names MUST NOT contain hyphens.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:
aws s3tables list-table-buckets and ask user to select or create new."S3 Tables KMS key policy" for required policy.references/best-practices.md for common errors.aws s3tables create-namespace --table-bucket-arn <ARN> --namespace <NAMESPACE>Constraints:
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.
S3 Tables uses s3tables:* IAM namespace (not s3:*).
Querying principal permissions (bucket policy):
s3tables:GetTableBucket, s3tables:GetNamespace, s3tables:GetTable, s3tables:GetTableMetadataLocation, s3tables:GetTableDataQuerying principal permissions (IAM policy):
glue:GetCatalog, glue:GetDatabase, glue:GetTableYou MUST scope to correct ARN patterns. You MUST read references/access-control.md for exact resource ARNs.
Constraints:
| 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.sourceId MUST reference a valid schema field IDreferences/athena-ddl-path.mdschemaV2 for complex types (list, map, struct) with explicit field IDs. See references/best-practices.md."IcebergPartitionField S3 Tables" for supported partition transformsYou 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.
| 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. |
ingesting-into-data-lake skill222ce56
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.