Exporting Rds To S3
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 procedure for exporting Amazon RDS and Aurora database snapshots to Amazon S3. It manages the end-to-end process, including snapshot identification or creation, IAM role configuration, KMS encryption setup, S3 bucket preparation, and the execution of the export task. Designed for data engineers and cloud administrators, it ensures that data is correctly formatted in Apache Parquet, making it immediately ready for consumption by analytics services like Amazon Athena, AWS Glue, and Amazon Redshift Spectrum.
What it does
- Identifies and validates RDS instances or Aurora clusters for export.
- Handles the creation of new snapshots or selection of existing ones.
- Configures necessary IAM roles and KMS encryption for secure data transfer.
- Executes the export task to S3 in Apache Parquet format.
- Monitors export progress and provides verification of the completed task.
- Offers troubleshooting guidance for common permission, engine, and configuration errors.
When to use it
- When you need to migrate database data to S3 for long-term storage or archival.
- When preparing database data for analytics using Athena, Glue, or Redshift Spectrum.
- When you require a repeatable, automated process for snapshot exports.
- When you need to ensure exported data is encrypted and stored with proper IAM controls.
Advantages
- Standardizes the export process to reduce manual configuration errors.
- Ensures compatibility with major AWS analytics services through Parquet formatting.
- Includes built-in validation for engine support and database status.
- Provides clear troubleshooting steps for common AWS infrastructure issues.
Usage examples
- “Export my production-mysql database to the rds-exports bucket.”
- The agent will prompt for the required region, verify the database status, configure the necessary IAM and KMS settings, and initiate the export task.
- “I need to move my Aurora cluster data to S3 for Athena analysis.”
- The agent will identify the cluster, confirm engine support, and guide you through the snapshot export workflow to ensure the data is in the correct Parquet format.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/aws/exporting-rds-to-s3/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip exporting-rds-to-s3.zip -d .agents/skills
Documentation by AWS
Exporting RDS/Aurora to S3
Overview
Domain expertise for exporting Amazon RDS and Aurora database snapshots to Amazon S3 in Apache Parquet format. Covers the full workflow: snapshot identification or creation, IAM role and KMS encryption setup, S3 bucket preparation, export task initiation, progress monitoring, data verification, and post-export access guidance for analytics services like Athena, Glue, and Redshift Spectrum.
Export an RDS or Aurora snapshot to S3
To export a database snapshot to S3 with proper IAM roles, encryption, and monitoring, follow the procedure exactly. See RDS to S3 export procedure.
Troubleshooting
Database not found
Verify the database identifier spelling, case, and region. For Aurora, use describe-db-clusters instead of describe-db-instances.
Export not supported
Snapshot export supports MySQL, PostgreSQL, MariaDB, Aurora MySQL, and Aurora PostgreSQL only. Oracle and SQL Server are not supported.
IAM role permission errors
Ensure the role trust policy allows export.rds.amazonaws.com with aws:SourceAccount and aws:SourceArn conditions for confused deputy protection, and has S3 PutObject and KMS permissions. Wait 10–15 seconds after role creation for propagation.
Export stuck or failed
Check the export task status for failure reasons. Common causes: S3 bucket deleted, IAM role modified, or KMS key disabled during export. See the full procedure for detailed troubleshooting.
Files
- ATTRIBUTION.mdAdded by AutoGineer926 B
- LICENSELicence file added by AutoGineer9.9 KiB
- NOTICELicence file added by AutoGineer67 B
- SKILL.md1.9 KiB
- references/export-rds-to-s3.md57.7 KiB
references/export-rds-to-s3.md
Export RDS/Aurora to S3
Overview
This SOP guides you through exporting Amazon RDS database snapshots or Aurora cluster snapshots to Amazon S3 for analytics, backup archival, long-term storage, or data migration purposes. AWS provides a native snapshot export feature that converts database snapshots to Apache Parquet format in S3, making the data accessible for analytics tools like Amazon Athena, Amazon Redshift Spectrum, and AWS Glue. The SOP handles the complete workflow including snapshot identification or creation, IAM role setup with proper permissions, KMS key configuration for encryption, S3 bucket preparation, export task initiation, progress monitoring, and verification of exported data.
Parameters
Prompt the user in a single message to provide all required parameters at once. Clearly list the required parameters and their descriptions, and include any optional parameters with their default values. Do not proceed until you have received and confirmed all required parameters. If any required parameter is missing or unclear, you MUST explicitly request the missing information before moving forward.
database_identifier (required): The RDS DB instance identifier or Aurora cluster identifier to export (e.g., "production-mysql", "analytics-aurora-cluster")
region (required): The AWS region where the database exists (e.g., "us-east-1", "eu-west-1")
s3_bucket_name (required): The S3 bucket name where exported data will be stored (e.g., "my-rds-exports")
s3_prefix (optional, default: "rds-exports/"): S3 prefix/folder for exported data (e.g., "rds-exports/", "backups/mysql/")
export_type (optional, default: "latest-snapshot"): Export source type ("latest-snapshot", "specific-snapshot", "create-new-snapshot")
snapshot_identifier (optional): Specific snapshot ID to export (required if export_type is "specific-snapshot")
export_only_tables (optional): Comma-separated list of specific tables to export (e.g., "schema1.table1,schema2.table2", exports all if not specified)
iam_role_arn (optional): Existing IAM role ARN with S3 and export permissions (will create if not provided)
kms_key_id (optional): KMS key ID for encrypting exported data in S3 (will use default S3 encryption if not provided)
export_task_identifier (optional): Custom identifier for the export task (auto-generated if not provided)
Only proceed to the steps below if you have all required information.
Steps
1. Verify Dependencies
Check for required tools and warn the user if any are missing.
Constraints:
You MUST verify the following tools are available in your context:
call_aws
You MUST ONLY check for tool existence and MUST NOT attempt to run the tools because running tools during verification could cause unintended side effects, consume resources unnecessarily, or trigger actions before the user is ready
You MUST inform the user about any missing tools with a clear message
You MUST ask if the user wants to proceed anyway despite missing tools
You MUST respect the user's decision to proceed or abort
2. Identify Database and Engine Type
Verify the database exists and determine whether it's RDS or Aurora.
Constraints:
You MUST first attempt to describe the database as an RDS instance:
aws rds describe-db-instances --db-instance-identifier ${database_identifier} --region ${region}You MUST check if the database is actually an Aurora cluster if the instance query fails:
aws rds describe-db-clusters --db-cluster-identifier ${database_identifier} --region ${region}You MUST extract critical information from the response:
Database engine type (mysql, postgres, mariadb, aurora-mysql, aurora-postgresql)
Engine version
Database status (must be "available" for snapshot operations)
Storage encrypted status
KMS key ID if encrypted
DB instance class or cluster size
Availability zone(s)
You MUST verify the database engine supports snapshot export:
Supported: MySQL, PostgreSQL, MariaDB, Aurora MySQL, Aurora PostgreSQL
NOT supported: Oracle, SQL Server
You MUST inform the user if the database engine does not support snapshot export to S3
You MUST determine if this is an Aurora cluster or standalone RDS instance:
Aurora cluster: Can export cluster snapshots
RDS instance: Can export DB snapshots
You MUST check current database status and warn if not "available"
You MUST save all database metadata for subsequent steps
3. Select or Create Snapshot for Export
Identify the snapshot to export based on user preferences.
Constraints:
You MUST handle three export type scenarios:
Scenario A: latest-snapshot (default)
You MUST list available snapshots for the database:
For RDS instance:
aws rds describe-db-snapshots --db-instance-identifier ${database_identifier} --region ${region}For Aurora cluster:
aws rds describe-db-cluster-snapshots --db-cluster-identifier ${database_identifier} --region ${region}
You MUST filter for snapshots with status "available"
You MUST sort by snapshot creation time (most recent first)
You MUST select the most recent available snapshot
You MUST display snapshot details to user:
Snapshot identifier
Creation time
Snapshot type (automated, manual)
Snapshot size
Encrypted status
Engine version
You MUST ask user to confirm using this snapshot or select a different one
Scenario B: specific-snapshot
You MUST verify the specified snapshot exists:
For RDS:
aws rds describe-db-snapshots --db-snapshot-identifier ${snapshot_identifier} --region ${region}For Aurora:
aws rds describe-db-cluster-snapshots --db-cluster-snapshot-identifier ${snapshot_identifier} --region ${region}
You MUST verify snapshot status is "available"
You MUST verify snapshot belongs to the specified database
You MUST extract snapshot metadata (creation time, size, encrypted status)
You MUST inform user if snapshot is not found or not available
Scenario C: create-new-snapshot
You MUST generate a snapshot identifier:
${database_identifier}-export-${timestamp}You MUST create a new manual snapshot:
For RDS:
aws rds create-db-snapshot --db-instance-identifier ${database_identifier} --db-snapshot-identifier ${snapshot_id} --tags Key=Purpose,Value=S3Export Key=CreatedBy,Value=export-rds-to-s3-script --region ${region}For Aurora:
aws rds create-db-cluster-snapshot --db-cluster-identifier ${database_identifier} --db-cluster-snapshot-identifier ${snapshot_id} --tags Key=Purpose,Value=S3Export Key=CreatedBy,Value=export-rds-to-s3-script --region ${region}
You MUST poll snapshot status until it becomes "available":
Check status every 30 seconds
Display progress updates to user
Timeout after 2 hours for large databases
You MUST inform user of snapshot creation progress:
Creating snapshot ${snapshot_id}... Status: creating (0:30) Status: creating (1:00) Status: creating (1:30) Status: available (2:15) ✓ Snapshot created successfully!You MUST handle snapshot creation failures by surfacing the AWS error code/message to the user and recommending actionable next steps
You MUST verify snapshot is encrypted if the source database is encrypted
You MUST save the selected snapshot identifier for the export operation
You MUST display snapshot details including:
Snapshot ID
Database identifier
Engine and version
Creation timestamp
Snapshot size (allocated storage)
Encrypted status
Percent progress (if still creating)
4. Verify and Prepare S3 Bucket
Ensure the S3 bucket exists and is properly configured for RDS export.
Constraints:
You MUST verify the S3 bucket exists:
aws s3api head-bucket --bucket ${s3_bucket_name}You MUST check bucket region and warn if different from database region:
aws s3api get-bucket-location --bucket ${s3_bucket_name}Cross-region exports are supported but may incur data transfer costs
Recommend using bucket in same region for cost efficiency
You MUST verify bucket encryption configuration:
aws s3api get-bucket-encryption --bucket ${s3_bucket_name}If encryption is not enabled, recommend enabling it for security
You MUST check if the S3 prefix exists:
aws s3 ls s3://${s3_bucket_name}/${s3_prefix}Create the prefix if it doesn't exist:
aws s3api put-object --bucket ${s3_bucket_name} --key ${s3_prefix}
You MUST verify sufficient bucket permissions:
Bucket must allow RDS service to write objects
Will be configured via bucket policy in IAM role setup step
You MUST check bucket versioning status and recommend enabling for data protection
You MUST estimate required S3 storage space:
Parquet format typically uses 30-50% less space than snapshot size
Inform user of approximate storage requirements
Warn if bucket has lifecycle policies that might delete exports
You MUST handle bucket access errors:
Bucket does not exist: Offer to create it
Access denied: Check IAM permissions
Bucket in different account: Verify cross-account access is configured
You MUST present bucket configuration summary to user:
Bucket name and region
Export path: s3://${s3_bucket_name}/${s3_prefix}
Encryption status
Versioning status
Estimated export size
5. Create or Verify IAM Role for Export
Set up IAM role with permissions for RDS to write exported data to S3.
Constraints:
You MUST skip role creation if
iam_role_arnwas provided and verify it insteadYou MUST check if provided IAM role exists:
aws iam get-role --role-name ${role_name}You MUST verify the role has correct trust policy for RDS export service with confused deputy protection:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "export.rds.amazonaws.com" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "aws:SourceAccount": "${account_id}" }, "ArnLike": { "aws:SourceArn": "arn:aws:rds:${region}:${account_id}:*" } } } ] }You MUST obtain the account ID for the trust policy condition:
aws sts get-caller-identity --query Account --output textYou MUST create IAM role if not provided:
Generate role name:
${database_identifier}-export-roleorrds-s3-export-roleCreate trust policy document (as shown above) with
${account_id}and${region}substitutedCreate role:
aws iam create-role --role-name ${role_name} --assume-role-policy-document file://trust-policy.json --description "IAM role for RDS snapshot export to S3 for ${database_identifier}"
You MUST create IAM policy with necessary S3 permissions:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject*", "s3:GetObject*", "s3:DeleteObject*" ], "Resource": "arn:aws:s3:::${s3_bucket_name}/${s3_prefix}*" }, { "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": "arn:aws:s3:::${s3_bucket_name}" } ] }You MUST add KMS permissions if KMS key is specified:
{ "Effect": "Allow", "Action": [ "kms:Decrypt", "kms:GenerateDataKey", "kms:DescribeKey" ], "Resource": "arn:aws:kms:${region}:${account_id}:key/${kms_key_id}" }You MUST create and attach the policy:
aws iam create-policy --policy-name ${policy_name} --policy-document file://export-policy.jsonaws iam attach-role-policy --role-name ${role_name} --policy-arn ${policy_arn}
You MUST add tags to the IAM role:
aws iam tag-role --role-name ${role_name} --tags Key=Purpose,Value=RDSSnapshotExport Key=Database,Value=${database_identifier} Key=ManagedBy,Value=export-rds-to-s3-script
You MUST wait for IAM role propagation (10-15 seconds):
IAM is eventually consistent
Recommend waiting before starting export task
You MUST verify role ARN format is correct:
Format:
arn:aws:iam::${account_id}:role/${role_name}Extract account ID from AWS identity:
aws sts get-caller-identity --query Account --output text
You MUST present IAM configuration summary:
Role ARN
S3 bucket access granted
KMS key access granted (if applicable)
Trust relationship confirmed
You MUST handle IAM creation errors:
Role already exists: Use existing role
Permission denied: Check user's IAM permissions
Policy limit reached: Suggest cleanup of unused policies
6. Configure KMS Encryption (Optional)
Set up KMS encryption for exported data in S3 if required.
Constraints:
You MUST skip this step if no KMS key was specified and default S3 encryption is acceptable
You MUST verify the KMS key exists:
aws kms describe-key --key-id ${kms_key_id} --region ${region}You MUST check KMS key status is "Enabled"
You MUST verify the key is in the same region as the export operation
You MUST ensure the KMS key policy allows RDS export service to use it:
{ "Sid": "Allow RDS Export Service", "Effect": "Allow", "Principal": { "Service": "export.rds.amazonaws.com" }, "Action": [ "kms:Decrypt", "kms:GenerateDataKey", "kms:DescribeKey" ], "Resource": "*", "Condition": { "StringEquals": { "kms:ViaService": "rds.${region}.amazonaws.com" } } }You MUST check if snapshot is encrypted with different KMS key:
If snapshot has KMS key A and export specifies KMS key B
Both keys must be accessible
RDS will re-encrypt data during export
You MUST add KMS key permissions to the IAM role (handled in previous step)
You MUST verify IAM role can use the KMS key:
Role must have kms:Decrypt on snapshot's KMS key (if encrypted)
Role must have kms:GenerateDataKey on export's KMS key
You MUST inform user of encryption details:
Source snapshot encryption: Yes/No and KMS key ID
Export encryption: KMS key ID or default S3 encryption
Re-encryption during export: Yes/No
You MUST warn about performance impact if re-encryption is required:
Re-encryption can increase export time by 20-30%
Recommend using same KMS key for snapshot and export when possible
You MUST handle KMS errors:
Key not found: Verify KMS key ID format
Access denied: Update KMS key policy
Key in wrong region: Use regional KMS key
7. Determine Tables to Export (Optional)
Identify specific tables for export if selective export is requested.
Constraints:
You MUST skip this step if
export_only_tablesis not specified (exports entire database)You MUST parse the comma-separated table list provided by user
You MUST validate table name format:
Format:
schema.tableor justtable(for databases without explicit schemas)Valid examples: "public.users", "inventory.products", "customers"
PostgreSQL: Include schema name (e.g., "public.users")
MySQL/MariaDB: Use database.table format (e.g., "appdb.users")
Aurora: Follow engine-specific format
You MUST warn that table-level export is not validated until export starts:
RDS does not provide API to list tables in snapshot
Invalid table names will cause export to fail
Recommend exporting entire database if unsure about table names
You MUST inform user of table-level export limitations:
Must specify exact table names as they appear in database
Case-sensitive for most database engines
Schema/database prefix required for PostgreSQL and MySQL
Cannot use wildcards or patterns
Foreign key relationships are not automatically included
Dependent tables must be explicitly listed
You MUST format table names for export task parameter:
Convert comma-separated string to proper array format
Ensure proper escaping for special characters
You MUST ask user to confirm table list before proceeding:
Display formatted list of tables to be exported
Warn about potential issues (missing dependent tables, etc.)
Offer option to export all tables instead
You MUST estimate reduced export size with selective tables:
Cannot calculate exact size without table statistics
Inform user that export will be smaller than full snapshot
Recommend CloudWatch metrics to monitor export size
8. Generate Export Task Identifier
Create a unique identifier for the export task.
Constraints:
You MUST use user-provided
export_task_identifierif specifiedYou MUST generate identifier if not provided:
Format:
${database_identifier}-export-${timestamp}Timestamp format: YYYYMMDD-HHMMSS (e.g., "20251014-153045")
Example: "production-mysql-export-20251014-153045"
Maximum length: 60 characters
Allowed characters: letters, numbers, hyphens
Must start with a letter
Must be unique across all export tasks in the account/region
You MUST validate export task identifier format:
Check length does not exceed 60 characters
Verify only allowed characters are used
Ensure starts with letter
No special characters except hyphens
You MUST check if export task identifier already exists:
aws rds describe-export-tasks --export-task-identifier ${export_task_id} --region ${region}If exists, generate a new identifier with incremental suffix
Example: "production-mysql-export-20251014-153045-2"
You MUST ensure identifier is descriptive and traceable:
Include database name for identification
Include timestamp for tracking
Consider adding environment indicator (prod, staging, dev)
You MUST save the export task identifier for monitoring and verification
9. Initiate Snapshot Export Task
Start the export process to transfer snapshot data to S3.
Constraints:
Before executing the export command, you MUST confirm with the user that Parquet output meets their needs and reiterate its key benefits (columnar storage, compression, analytics tool compatibility); offer alternative approaches if Parquet is not acceptable
You MUST construct the export task command with all required parameters:
aws rds start-export-task \ --export-task-identifier ${export_task_id} \ --source-arn ${snapshot_arn} \ --s3-bucket-name ${s3_bucket_name} \ --s3-prefix ${s3_prefix} \ --iam-role-arn ${iam_role_arn} \ --kms-key-id ${kms_key_id} \ --export-only ${export_only_tables} \ --region ${region}You MUST construct correct snapshot ARN:
For RDS snapshot:
arn:aws:rds:${region}:${account_id}:snapshot:${snapshot_id}For Aurora cluster snapshot:
arn:aws:rds:${region}:${account_id}:cluster-snapshot:${snapshot_id}Extract account ID:
aws sts get-caller-identity --query Account --output text
You MUST include optional parameters only if specified:
--kms-key-idonly if KMS encryption is configured--export-onlyonly if selective table export is requested
You MUST handle export task creation errors:
InvalidExportTaskState: Another export already in progress
InvalidS3BucketName: Verify bucket name format
InsufficientPrivileges: Check IAM role permissions
SnapshotNotFound: Verify snapshot ARN
InvalidParameterValue: Check all parameter formats
KMSKeyNotAccessible: Verify KMS key permissions
You MUST capture export task details from response:
Export task identifier
Status (should be "starting")
Source ARN (snapshot)
S3 bucket and prefix
IAM role ARN
KMS key ID (if used)
Task start time
Percent progress (initially 0)
You MUST display export task initiation confirmation:
✓ Export task started successfully! Export Task ID: production-mysql-export-20251014-153045 Snapshot: production-mysql-snapshot-2025-10-14 Destination: s3://my-rds-exports/rds-exports/ Status: starting Started: 2025-10-14 15:30:45 UTCYou MUST inform user of expected export duration:
Depends on snapshot size
Approximate rate: 10-20 GB per hour (varies by instance size)
Estimate time based on snapshot size
Example: 100 GB snapshot = approximately 5-10 hours
You MUST save export task identifier for progress monitoring
10. Monitor Export Task Progress
Track the export operation until completion.
Constraints:
You MUST poll export task status regularly:
aws rds describe-export-tasks --export-task-identifier ${export_task_id} --region ${region}Poll every 60 seconds initially
Increase interval to 5 minutes after first hour
Continue until status is "complete" or "failed"
You MUST extract and display key information from each status check:
Status (starting, in_progress, complete, failed, canceled)
Percent progress (0-100)
Total amount of data (in bytes)
Elapsed time
Estimated time remaining (if available)
Warning count (if any)
Failure message (if failed)
You MUST display progress updates to user:
Exporting snapshot to S3... Status: in_progress (5%, 2.5 GB exported, 0:15 elapsed) Status: in_progress (15%, 7.5 GB exported, 0:45 elapsed) Status: in_progress (30%, 15 GB exported, 1:30 elapsed) Status: in_progress (50%, 25 GB exported, 2:30 elapsed) Status: in_progress (75%, 37.5 GB exported, 3:45 elapsed) Status: in_progress (90%, 45 GB exported, 4:30 elapsed) Status: complete (100%, 50 GB exported, 5:00 elapsed) ✓You MUST handle different status outcomes:
starting: Task is initializing (typically 1-2 minutes)
in_progress: Export is actively running (display progress percentage)
complete: Export finished successfully (proceed to verification)
failed: Export encountered an error (display error message and troubleshooting)
canceled: Export was manually canceled (inform user)
You MUST check for warnings during export:
Extract warning messages from response
Display warnings to user even if export completes
Common warnings: Table not found, schema mismatch, permission issues
You MUST implement timeout handling:
Very large databases (>1 TB) can take 24+ hours
Recommend not blocking indefinitely
If the estimated completion time exceeds 2 hours, you MUST ask the user if they prefer continued real-time updates or to switch to scheduled/asynchronous check-ins and follow their preference
Offer option to stop monitoring and provide command to check status later
Example: "aws rds describe-export-tasks --export-task-identifier ${export_task_id}"
You MUST handle export failures gracefully:
Extract failure cause from status
Provide specific error message
Suggest troubleshooting steps based on error type
Offer to retry export with corrections
You MUST inform user they can safely close terminal:
Export task runs asynchronously in AWS
Closing session does not cancel export
Provide command to check status later
Save export task identifier for reference
You MUST calculate export metrics upon completion:
Total data exported (in GB)
Total time elapsed (in hours and minutes)
Average export speed (GB/hour)
Number of files created in S3
Final S3 path with exported data
11. Verify Exported Data in S3
Confirm the export completed successfully and data is accessible in S3.
Constraints:
You MUST list exported files in S3 bucket:
aws s3 ls s3://${s3_bucket_name}/${s3_prefix}${export_task_id}/ --recursiveExport creates folder named after export task identifier
Each table is exported to separate subfolder
Data files are in Parquet format
You MUST verify export structure:
Check for expected folders and files
Typical structure:
s3://bucket/prefix/export-task-id/ ├── schema1/ │ ├── table1/ │ │ ├── data1.parquet │ │ ├── data2.parquet │ │ └── ... │ └── table2/ │ └── data1.parquet └── schema2/ └── table3/ └── data1.parquetEach table has one or more Parquet files
Large tables are split across multiple Parquet files
You MUST count total number of files exported:
Use S3 list objects to count files
Provide summary of files per table
Calculate total size of exported data
You MUST calculate actual export size:
Sum file sizes from S3 listing
Compare to original snapshot size
Show compression ratio (Parquet vs snapshot)
Example: "50 GB snapshot → 18 GB Parquet (64% reduction)"
You MUST verify at least one Parquet file exists for expected tables:
If selective export, check specified tables are present
If full export, verify major tables exist
List all table names found in export
You MUST check file accessibility:
Attempt to read metadata of a sample Parquet file
Verify user has permissions to access exported files
Test with:
aws s3api head-object --bucket ${s3_bucket_name} --key ${sample_file_key}
You MUST verify encryption status of exported files:
Check object metadata for encryption information
Confirm KMS key ID if specified
Verify SSE-S3 or SSE-KMS is applied
You MUST provide S3 path summary:
Full S3 URI:
s3://${s3_bucket_name}/${s3_prefix}${export_task_id}/AWS Console URL to browse files
Total number of Parquet files
Total size in S3
Compression savings
You MUST handle verification failures:
No files found: Export may have failed, check task status
Missing tables: Verify table names were correct
Access denied: Check S3 bucket permissions
Incomplete data: Check for export warnings or errors
12. Provide Data Access Instructions
Guide user on how to query and use the exported data.
Constraints:
You MUST provide multiple options for accessing exported data:
Option 1: Amazon Athena
Create external table in Athena to query Parquet data
Provide sample CREATE EXTERNAL TABLE DDL:
CREATE EXTERNAL TABLE IF NOT EXISTS database_name.table_name ( column1 data_type, column2 data_type, column3 data_type ) STORED AS PARQUET LOCATION 's3://${s3_bucket_name}/${s3_prefix}${export_task_id}/schema/table/';Provide sample SELECT query:
SELECT * FROM database_name.table_name LIMIT 10;Explain need to create Athena database first
Mention Athena query costs ($5 per TB scanned)
Option 2: AWS Glue
Create Glue crawler to automatically discover schema
Provide crawler creation command:
aws glue create-crawler \ --name ${database_identifier}-export-crawler \ --role ${glue_service_role} \ --database ${glue_database} \ --targets "S3Targets=[{Path=s3://${s3_bucket_name}/${s3_prefix}${export_task_id}/}]" \ --region ${region}Explain how to run crawler and view Data Catalog
Mention Glue crawling costs
Option 3: Amazon Redshift Spectrum
Create external schema in Redshift pointing to S3 data
Provide sample DDL:
CREATE EXTERNAL SCHEMA spectrum_schema FROM DATA CATALOG DATABASE 'glue_database' IAM_ROLE 'arn:aws:iam::account-id:role/redshift-spectrum-role' REGION '${region}'; SELECT * FROM spectrum_schema.table_name LIMIT 10;Explain querying from Redshift cluster
Option 4: Direct Parquet File Access
Download Parquet files locally:
aws s3 cp s3://${s3_bucket_name}/${s3_prefix}${export_task_id}/ ./local-folder/ --recursiveUse Python with pandas/pyarrow to read:
import pandas as pd import pyarrow.parquet as pq # Read Parquet file table = pq.read_table('data.parquet') df = table.to_pandas() print(df.head())Use Apache Spark:
val df = spark.read.parquet("s3a://${s3_bucket_name}/${s3_prefix}${export_task_id}/schema/table/") df.show()
You MUST explain Parquet format benefits when confirming the export approach and again here if the user needs a refresher:
Columnar storage for efficient analytics queries
Built-in compression (snappy by default)
Self-describing schema
Compatible with most analytics tools
Optimized for AWS analytics services
You MUST provide schema discovery guidance:
Parquet files contain embedded schema
Use AWS Glue crawler for automatic schema discovery
Or infer schema using pyarrow:
pq.read_schema('file.parquet')Explain data types may differ from original database types
You MUST warn about data consistency:
Export is point-in-time snapshot
Data represents database state at snapshot time
No ongoing replication or synchronization
Changes after snapshot are not reflected
You MUST provide cost estimates for common access patterns:
Athena: $5 per TB of data scanned
S3 storage: ~$0.023 per GB per month (Standard)
S3 GET requests: $0.0004 per 1,000 requests
Data transfer: Free within same region, varies cross-region
13. Generate Export Summary Report
Create comprehensive documentation of the export operation.
Constraints:
You MUST create a detailed export report containing:
Export Overview:
Export task identifier
Database identifier and engine
Snapshot identifier used
Export status (completed, failed, warnings)
Start and end timestamps
Total duration
Source Configuration:
RDS instance or Aurora cluster details
Database engine and version
Snapshot size (allocated storage)
Snapshot creation timestamp
Encrypted status and KMS key
Destination Configuration:
S3 bucket name and region
S3 prefix/path
Full S3 URI to exported data
Exported data size
Compression ratio
Number of Parquet files
Encryption configuration
IAM and Security:
IAM role ARN used
IAM policies attached
KMS key ID (if used)
S3 bucket encryption status
Export Metrics:
Total data exported (GB)
Export duration (hours:minutes)
Average export speed (GB/hour)
Number of tables exported
Selective tables (if applicable)
Warning count
Access Instructions:
How to query with Athena
How to catalog with Glue
How to access with Redshift Spectrum
How to download and process locally
Cost Summary:
S3 storage cost estimate
Export operation cost (if any)
Ongoing storage costs
Query cost estimates (Athena, Redshift Spectrum)
Cleanup Instructions:
How to delete exported data from S3
How to delete the snapshot (if created for export)
How to remove IAM role (if no longer needed)
Next Steps and Recommendations:
Set up S3 lifecycle policies for automatic archival
Configure S3 Intelligent-Tiering for cost optimization
Set up CloudWatch alarms for export failures
Document export schedule for recurring exports
Consider automating exports with Lambda or Step Functions
You MUST format the report in clear, readable markdown format
You MUST include specific commands for all recommendations
You MUST provide AWS Console URLs for easy access:
S3 bucket URL
Export task details URL
IAM role URL
CloudWatch logs URL (if available)
You MUST save report to file:
rds-export-report-${export_task_id}.mdYou MUST present the complete report to the user
You MUST offer to save the report to a local file for reference
14. Provide Cleanup and Cost Optimization Guidance
Advise on managing exported data and optimizing costs.
Constraints:
You MUST provide instructions for deleting exported data when no longer needed:
# Delete exported data from S3 aws s3 rm s3://${s3_bucket_name}/${s3_prefix}${export_task_id}/ --recursive # Delete the snapshot if it was created for export only aws rds delete-db-snapshot --db-snapshot-identifier ${snapshot_id} --region ${region} # Or for Aurora cluster snapshot: aws rds delete-db-cluster-snapshot --db-cluster-snapshot-identifier ${snapshot_id} --region ${region}You MUST recommend S3 lifecycle policies for cost optimization:
Transition to S3 Intelligent-Tiering after 30 days
Or transition to S3 Glacier after 90 days for archival
Delete after retention period expires
Example lifecycle policy:
{ "Rules": [ { "Id": "Archive RDS Exports", "Status": "Enabled", "Filter": { "Prefix": "${s3_prefix}" }, "Transitions": [ { "Days": 30, "StorageClass": "INTELLIGENT_TIERING" }, { "Days": 90, "StorageClass": "GLACIER" } ], "Expiration": { "Days": 365 } } ] }Apply policy:
aws s3api put-bucket-lifecycle-configuration --bucket ${s3_bucket_name} --lifecycle-configuration file://lifecycle.json
You MUST recommend monitoring and alerting:
CloudWatch alarm for failed exports
S3 storage metrics to track growth
Cost alerts for unexpected charges
Example alarm creation:
aws cloudwatch put-metric-alarm \ --alarm-name rds-export-failures \ --alarm-description "Alert on RDS export task failures" \ --metric-name ExportTaskFailures \ --namespace AWS/RDS \ --statistic Sum \ --period 300 \ --threshold 1 \ --comparison-operator GreaterThanThreshold
You MUST suggest automation for recurring exports:
AWS Lambda function triggered by EventBridge (CloudWatch Events) schedule
Step Functions workflow for complex export logic
Example Lambda trigger setup:
# Create EventBridge rule to run daily aws events put-rule \ --name daily-rds-export \ --schedule-expression "cron(0 2 * * ? *)" \ --state ENABLED # Add Lambda function as target aws events put-targets \ --rule daily-rds-export \ --targets "Id=1,Arn=${lambda_function_arn}"
You MUST provide cost optimization tips:
Use S3 Intelligent-Tiering for automatic cost optimization
Export during off-peak hours to minimize database impact
Use selective table export to reduce data volume
Compress older exports with S3 lifecycle policies
Delete unnecessary snapshots after export
Use S3 Storage Lens to analyze storage patterns
Consider S3 Batch Operations for bulk actions
You MUST recommend data retention policies:
Determine retention requirements based on compliance
Document retention policy in S3 object tags
Use S3 Object Lock for compliance requirements
Implement MFA Delete for critical exports
Examples
Example Input
database_identifier: production-mysql
region: us-east-1
s3_bucket_name: analytics-data-lake
s3_prefix: rds-exports/mysql/
export_type: latest-snapshotExample Output
# RDS Snapshot Export to S3 - Summary Report
**Export Task ID:** production-mysql-export-20251014-153045
**Status:** ✓ Completed Successfully
**Generated:** 2025-10-14 20:45:30 UTC
---
## Export Overview
Successfully exported RDS MySQL snapshot to S3 for analytics and backup purposes.
- **Database:** production-mysql (MySQL 8.0.35)
- **Snapshot:** production-mysql-automated-2025-10-14-12-30
- **Export Status:** Complete
- **Duration:** 5 hours 15 minutes
- **Data Exported:** 245 GB → 92 GB Parquet (62% compression)
---
## Source Configuration
### Database Details
- **DB Instance:** production-mysql
- **Engine:** MySQL 8.0.35
- **Instance Class:** db.r5.2xlarge
- **Region:** us-east-1
- **Multi-AZ:** Yes
- **Storage:** 500 GB (gp3)
- **Encrypted:** Yes (KMS key: arn:aws:kms:us-east-1:123456789012:key/abcd1234-...)
### Snapshot Details
- **Snapshot ID:** production-mysql-automated-2025-10-14-12-30
- **Type:** Automated backup
- **Created:** 2025-10-14 12:30:00 UTC
- **Size:** 245 GB
- **Status:** Available
- **Encrypted:** Yes (same KMS key as instance)
---
## Destination Configuration
### S3 Export Location
- **Bucket:** analytics-data-lake
- **Region:** us-east-1 (same as database)
- **Prefix:** rds-exports/mysql/
- **Full Path:** s3://analytics-data-lake/rds-exports/mysql/production-mysql-export-20251014-153045/
- **Console URL:** https://s3.console.aws.amazon.com/s3/buckets/analytics-data-lake?prefix=rds-exports/mysql/production-mysql-export-20251014-153045/
### Exported Data
- **Format:** Apache Parquet
- **Compression:** Snappy (default)
- **Total Size:** 92 GB
- **Files:** 1,247 Parquet files
- **Tables:** 87 tables exported
- **Encryption:** SSE-KMS (KMS key: arn:aws:kms:us-east-1:123456789012:key/abcd1234-...)
### Data Structures3://analytics-data-lake/rds-exports/mysql/production-mysql-export-20251014-153045/ ├── appdb/ │ ├── users/ │ │ ├── 1.parquet │ │ ├── 2.parquet │ │ └── ... (15 files, 8.2 GB) │ ├── orders/ │ │ ├── 1.parquet │ │ └── ... (42 files, 18.5 GB) │ ├── products/ │ │ └── 1.parquet (2.1 GB) │ └── ... (87 tables total) └── ...
---
## IAM and Security Configuration
### IAM Role
- **Role ARN:** arn:aws:iam::123456789012:role/production-mysql-export-role
- **Trust Policy:** Allows export.rds.amazonaws.com
- **Created:** 2025-10-14 15:25:00 UTC
### IAM Permissions
- **S3 Access:** PutObject, GetObject, DeleteObject on s3://analytics-data-lake/rds-exports/mysql/*
- **S3 List:** ListBucket on analytics-data-lake
- **KMS Access:** Decrypt (snapshot key), GenerateDataKey (export key)
### Encryption
- **Snapshot Encryption:** Yes (KMS key: abcd1234-5678-90ab-cdef-1234567890ab)
- **Export Encryption:** Yes (same KMS key)
- **Re-encryption:** No (same key used)
- **S3 Bucket Encryption:** SSE-KMS enabled
---
## Export Metrics
### Performance
- **Total Data Exported:** 92 GB (Parquet format)
- **Original Snapshot Size:** 245 GB
- **Compression Ratio:** 62% reduction
- **Export Duration:** 5 hours 15 minutes (315 minutes)
- **Average Speed:** 17.5 GB/hour
- **Start Time:** 2025-10-14 15:30:00 UTC
- **End Time:** 2025-10-14 20:45:00 UTC
### Data Details
- **Tables Exported:** 87 (all tables)
- **Parquet Files Created:** 1,247 files
- **Largest Table:** orders (18.5 GB, 42 Parquet files)
- **Smallest Table:** config (12 MB, 1 Parquet file)
- **Warnings:** None
---
## Accessing Exported Data
### Option 1: Query with Amazon Athena
1. **Create Athena Database:**
```sql
CREATE DATABASE IF NOT EXISTS production_mysql_export;Create External Table (Example for 'users' table):
CREATE EXTERNAL TABLE IF NOT EXISTS production_mysql_export.users ( id INT, username STRING, email STRING, created_at TIMESTAMP, updated_at TIMESTAMP ) STORED AS PARQUET LOCATION 's3://analytics-data-lake/rds-exports/mysql/production-mysql-export-20251014-153045/appdb/users/';Query Data:
SELECT COUNT(*) as total_users FROM production_mysql_export.users; SELECT * FROM production_mysql_export.users WHERE created_at > '2025-01-01' LIMIT 100;
Cost: ~$5 per TB scanned (92 GB = $0.46 per full scan)
Option 2: Catalog with AWS Glue
Create Glue Database:
aws glue create-database \ --database-input "Name=production_mysql_export,Description=Exported from RDS" \ --region us-east-1Create Glue Crawler:
aws glue create-crawler \ --name production-mysql-export-crawler \ --role arn:aws:iam::123456789012:role/AWSGlueServiceRole \ --database-targets DatabaseTargets=[{DatabaseName=production_mysql_export,Path=s3://analytics-data-lake/rds-exports/mysql/production-mysql-export-20251014-153045/}] \ --region us-east-1Run Crawler:
aws glue start-crawler --name production-mysql-export-crawler --region us-east-1Query via Athena:
Crawler automatically discovers schemas
Query tables through Athena using discovered schemas
View Data Catalog in AWS Glue Console
Option 3: Query with Amazon Redshift Spectrum
Create External Schema in Redshift:
CREATE EXTERNAL SCHEMA mysql_export FROM DATA CATALOG DATABASE 'production_mysql_export' IAM_ROLE 'arn:aws:iam::123456789012:role/RedshiftSpectrumRole' REGION 'us-east-1';Query from Redshift:
SELECT * FROM mysql_export.users LIMIT 100; -- Join with Redshift tables SELECT u.username, o.order_total FROM mysql_export.users u JOIN local_schema.orders o ON u.id = o.user_id;
Option 4: Download and Process Locally
Download with AWS CLI:
# Download all data
aws s3 cp s3://analytics-data-lake/rds-exports/mysql/production-mysql-export-20251014-153045/ ./rds-export/ --recursive
# Download specific table
aws s3 cp s3://analytics-data-lake/rds-exports/mysql/production-mysql-export-20251014-153045/appdb/users/ ./users-data/ --recursiveProcess with Python:
import pandas as pd
import pyarrow.parquet as pq
import boto3
# Option A: Read from local file
df = pd.read_parquet('users-data/1.parquet')
print(df.head())
# Option B: Read directly from S3
s3 = boto3.client('s3')
obj = s3.get_object(Bucket='analytics-data-lake',
Key='rds-exports/mysql/production-mysql-export-20251014-153045/appdb/users/1.parquet')
table = pq.read_table(obj['Body'])
df = table.to_pandas()
# Option C: Read all Parquet files in a directory
df = pd.read_parquet('s3://analytics-data-lake/rds-exports/mysql/production-mysql-export-20251014-153045/appdb/users/')Process with Apache Spark:
val df = spark.read.parquet("s3a://analytics-data-lake/rds-exports/mysql/production-mysql-export-20251014-153045/appdb/users/")
df.show()
df.printSchema()
df.count()Cost Summary
One-Time Export Costs
RDS Export Operation: Free (no charge for export task)
Snapshot Storage (if new): $0.095/GB-month for snapshot retention
Data Transfer: Free (same region)
Monthly Storage Costs (S3 Standard)
92 GB × $0.023/GB-month = $2.12/month
Ongoing Query Costs
Athena: $5 per TB scanned ($0.46 per full 92 GB scan)
S3 GET Requests: $0.0004 per 1,000 requests (~$0.50 for typical usage)
Redshift Spectrum: Included with Redshift cluster costs
Cost Optimization Recommendations
Transition to S3 Intelligent-Tiering after 30 days: Save 40-68% on storage
Transition to S3 Glacier after 90 days: Save 85% on storage ($0.004/GB-month)
Use selective queries in Athena: Partition data by date to scan less data
Delete exports after retention period: Set lifecycle policy for auto-deletion
Estimated Monthly Cost with Optimization: $0.37/month (Glacier after 90 days)
Cleanup Instructions
Delete Exported Data (When No Longer Needed)
# Delete all exported data from S3
aws s3 rm s3://analytics-data-lake/rds-exports/mysql/production-mysql-export-20251014-153045/ --recursive
# Verify deletion
aws s3 ls s3://analytics-data-lake/rds-exports/mysql/production-mysql-export-20251014-153045/Delete Snapshot (If Created for Export Only)
# For automated snapshots (not recommended - managed by RDS)
# For manual snapshots created for export:
aws rds delete-db-snapshot \
--db-snapshot-identifier production-mysql-manual-export-snapshot \
--region us-east-1Remove IAM Role (If No Longer Needed)
# Detach policies first
aws iam detach-role-policy \
--role-name production-mysql-export-role \
--policy-arn arn:aws:iam::123456789012:policy/ProductionMySQLExportPolicy
# Delete policy
aws iam delete-policy \
--policy-arn arn:aws:iam::123456789012:policy/ProductionMySQLExportPolicy
# Delete role
aws iam delete-role --role-name production-mysql-export-roleRecommendations and Next Steps
Immediate Actions
✓ Verify exported data is accessible via Athena or Glue
✓ Test queries on sample tables to confirm data integrity
✓ Set up Athena workgroup with query result location
✓ Document table schemas and relationships for team reference
Short-Term Actions
Configure S3 Lifecycle Policy (Save 40-85% on storage costs)
# Apply lifecycle policy to automatically transition to cheaper storage aws s3api put-bucket-lifecycle-configuration \ --bucket analytics-data-lake \ --lifecycle-configuration file://lifecycle-policy.jsonSet Up CloudWatch Alarms (Monitor export failures)
aws cloudwatch put-metric-alarm \ --alarm-name rds-export-failures \ --alarm-description "Alert on RDS export task failures" \ --metric-name ExportTaskFailures \ --namespace AWS/RDS \ --statistic Sum \ --period 300 \ --threshold 1 \ --comparison-operator GreaterThanThreshold \ --alarm-actions arn:aws:sns:us-east-1:123456789012:alertsEnable S3 Versioning (Protect against accidental deletion)
aws s3api put-bucket-versioning \ --bucket analytics-data-lake \ --versioning-configuration Status=EnabledTag S3 Objects (Organize and track exports)
aws s3api put-object-tagging \ --bucket analytics-data-lake \ --key rds-exports/mysql/production-mysql-export-20251014-153045/ \ --tagging 'TagSet=[{Key=Database,Value=production-mysql},{Key=ExportDate,Value=2025-10-14},{Key=RetentionDays,Value=90}]'
Long-Term Actions
Automate Recurring Exports (Daily/Weekly snapshots)
Create Lambda function to trigger exports on schedule
Use EventBridge (CloudWatch Events) for scheduling
Implement error handling and notifications
Example: Export every Sunday at 2 AM UTC
Implement Data Retention Policy
Define retention requirements (e.g., 90 days, 1 year, 7 years)
Configure S3 Object Lock for compliance if required
Set up MFA Delete for critical exports
Document retention policy in corporate wiki
Set Up Data Catalog and Governance
Use AWS Glue Data Catalog for centralized metadata
Implement Lake Formation for access control
Enable AWS Config for compliance auditing
Create data dictionary for business users
Optimize for Analytics Workloads
Partition exported data by date for better query performance
Use AWS Glue ETL to transform and optimize data
Create materialized views in Athena for common queries
Consider Amazon Redshift for complex analytics queries
Monitor and Optimize Costs
Review S3 Storage Lens for usage patterns
Set up Cost Anomaly Detection for unexpected charges
Use AWS Cost Explorer to track export-related costs
Implement chargeback/showback for department budgets
Troubleshooting Reference
Export Task Failed
Check IAM role permissions (S3 and KMS access)
Verify S3 bucket exists and is accessible
Check KMS key policy allows RDS export service
Review CloudWatch Logs for detailed error messages
Missing Tables in Export
Verify table names were correct (case-sensitive)
Check that tables existed in snapshot
Ensure schema prefix was included (PostgreSQL)
Review export task warnings for table issues
Cannot Query with Athena
Verify S3 path is correct in CREATE TABLE statement
Check Athena query result location is configured
Ensure IAM user has Athena and S3 permissions
Verify Parquet files are not corrupted
High Query Costs in Athena
Use partition pruning (add partition columns)
Select specific columns instead of SELECT *
Use columnar formats (Parquet compression helps)
Consider caching frequent queries in Redshift
Additional Resources
AWS Documentation
Related AWS Services
Amazon Athena: https://aws.amazon.com/athena/
AWS Glue: https://aws.amazon.com/glue/
Amazon Redshift Spectrum: https://aws.amazon.com/redshift/spectrum/
S3 Intelligent-Tiering: https://aws.amazon.com/s3/storage-classes/intelligent-tiering/
Support
AWS Support: https://console.aws.amazon.com/support/
RDS Forums: https://forums.aws.amazon.com/forum.jspa?forumID=60
Stack Overflow: Tag
amazon-rdsoramazon-athena
Summary
Successfully exported 245 GB MySQL database snapshot to S3 in Parquet format (92 GB compressed). Data is now available for analytics via Amazon Athena, AWS Glue, Amazon Redshift Spectrum, or direct file access. Export completed in 5 hours 15 minutes with no errors or warnings, and status updates were delivered on the agreed asynchronous schedule.
Next Steps:
Verify data accessibility via Athena
Set up S3 lifecycle policy for cost optimization
Configure CloudWatch alarms for future exports
Document export process for team
Export Details:
S3 Path: s3://analytics-data-lake/rds-exports/mysql/production-mysql-export-20251014-153045/
Export Task ID: production-mysql-export-20251014-153045
Monthly Storage Cost: $2.12 (can be reduced to $0.37 with Glacier)
Report generated by export-rds-to-s3-script on 2025-10-14 20:45:30 UTC
## Troubleshooting
### Database Not Found
**Symptoms:** DB instance or cluster identifier not found
**Solutions:**
- Verify database identifier spelling and case (case-sensitive)
- Check you're in the correct AWS region
- Use `aws rds describe-db-instances --region ${region}` to list all instances
- For Aurora, use `aws rds describe-db-clusters --region ${region}`
- Verify you have permissions to describe RDS resources
### Export Not Supported for Database Engine
**Symptoms:** Error indicating database engine doesn't support export
**Solutions:**
- Snapshot export is supported for: MySQL, PostgreSQL, MariaDB, Aurora MySQL, Aurora PostgreSQL
- NOT supported for: Oracle, SQL Server
- For unsupported engines, consider alternative backup methods:
- Native database backup tools (mysqldump, pg_dump)
- AWS Database Migration Service (DMS) for data replication
- Third-party backup solutions
- Check engine version meets minimum requirements
### Snapshot Not Available
**Symptoms:** Snapshot status is not "available" or snapshot doesn't exist
**Solutions:**
- Wait for automated snapshots to complete (taken during backup window)
- Check snapshot creation is not disabled on DB instance
- Verify snapshot retention period is not set to 0
- For Aurora, cluster snapshots may be in different namespace than instance snapshots
- List all snapshots: `aws rds describe-db-snapshots --db-instance-identifier ${db_id}`
- Create manual snapshot and wait for "available" status
### IAM Role Permission Errors
**Symptoms:** Export fails with access denied or insufficient permissions
**Solutions:**
- Verify IAM role has trust policy allowing export.rds.amazonaws.com
- Check S3 bucket policy allows RDS export service principal
- Ensure IAM role has PutObject permissions on S3 bucket and prefix
- Verify KMS key policy allows export service to use key
- Wait 10-15 seconds after creating IAM role (eventual consistency)
- Test IAM role with `aws sts assume-role` to verify trust policy
- Check for typos in ARNs (role ARN, bucket ARN, KMS key ARN)
### S3 Bucket Access Denied
**Symptoms:** Export fails with S3 access denied errors
**Solutions:**
- Verify S3 bucket exists and is accessible
- Check bucket is not in different AWS account (cross-account requires additional configuration)
- Ensure bucket policy allows RDS export service:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "export.rds.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::bucket-name/prefix/*"
}
]
}Verify S3 bucket is not encrypted with SSE-C (use SSE-S3 or SSE-KMS instead)
Check S3 bucket doesn't have Block Public Access settings preventing writes
Test bucket write access:
aws s3 cp testfile.txt s3://bucket-name/prefix/
KMS Key Access Errors
Symptoms: Export fails with KMS key not accessible or decrypt errors
Solutions:
Verify KMS key exists and is in "Enabled" state
Check KMS key is in same region as export operation
Ensure KMS key policy grants permissions to export service:
kms:Decrypt on snapshot's KMS key
kms:GenerateDataKey on export's KMS key
For cross-account KMS keys, ensure trust relationships are configured
Verify IAM role has KMS permissions in attached policy
Use
aws kms describe-key --key-id ${key_id}to check key statusConsider using default S3 encryption if KMS permissions are complex
Export Task Stuck in "starting" Status
Symptoms: Export task remains in "starting" status for extended time
Solutions:
Wait at least 5-10 minutes (initialization can take time)
Check IAM role was created successfully and permissions propagated
Verify S3 bucket is accessible from RDS service
Cancel stuck export and retry:
aws rds cancel-export-task --export-task-identifier ${task_id}Check CloudWatch Logs for detailed error messages (if available)
Verify no account limits preventing export task execution
Try exporting to different S3 bucket to isolate issue
Export Task Failed During Progress
Symptoms: Export fails after starting successfully
Solutions:
Check export task details for failure reason:
aws rds describe-export-tasks --export-task-identifier ${task_id}Common failure reasons:
S3 bucket was deleted during export
IAM role was modified during export
KMS key was disabled during export
Insufficient S3 storage quota
Invalid table names in selective export
Review CloudWatch Logs for detailed errors
Retry export after fixing identified issue
Consider creating new snapshot and exporting from that
Missing Tables in Export
Symptoms: Expected tables are not present in S3 export
Solutions:
Verify table names were spelled correctly (case-sensitive)
Check table names include schema/database prefix where required:
PostgreSQL: "schema.table"
MySQL: "database.table"
Ensure tables existed in snapshot at snapshot time
Review export task warnings for table-specific issues
Try exporting entire database instead of selective tables
Verify table was not empty (empty tables may not create files)
Parquet Files Corrupted or Unreadable
Symptoms: Cannot open or query Parquet files
Solutions:
Verify files were fully written (check file size > 0)
Check S3 storage class allows immediate access (not Glacier Deep Archive)
Ensure client tools support Parquet format (use pyarrow or pandas)
Try different Parquet file from same table
Verify no S3 lifecycle policies moved/archived files during export
Re-export if corruption is confirmed
Use AWS Glue crawler to validate Parquet schema
High Export Costs
Symptoms: Unexpected charges for export operation or storage
Solutions:
Export task itself is free, but related costs include:
S3 storage for exported data
Cross-region data transfer (if bucket in different region)
KMS key usage (if encrypting with custom key)
Snapshot storage (if new snapshot was created)
Implement S3 lifecycle policies to reduce storage costs
Use S3 Intelligent-Tiering for automatic cost optimization
Delete old exports after retention period
Export to S3 bucket in same region to avoid transfer fees
Monitor costs with AWS Cost Explorer
Athena Query Fails on Exported Data
Symptoms: Cannot query exported Parquet files with Athena
Solutions:
Verify S3 path in CREATE EXTERNAL TABLE matches actual export location
Check Athena has permissions to S3 bucket
Ensure Parquet files are not encrypted with inaccessible KMS key
Verify column names and data types in table definition
Use AWS Glue crawler to automatically generate correct schema
Check for nested or complex data types requiring special handling
Try querying with simpler SELECT statement first
Review Athena query logs for specific error messages
Slow Export Performance
Symptoms: Export taking much longer than expected
Solutions:
Export speed depends on:
Snapshot size (larger = longer)
Database instance class (affects I/O)
Network bandwidth
Number of tables and indexes
KMS re-encryption (if different keys)
Typical speed: 10-20 GB per hour
Export during off-peak hours for better performance
Consider selective table export to reduce data volume
Avoid re-encryption by using same KMS key for snapshot and export
Check for no other heavy operations on same database
Contact AWS Support if performance is significantly degraded
Cannot Delete Export Task
Symptoms: Export task remains visible even after completion
Solutions:
Export tasks are permanent records and cannot be deleted
They remain visible in AWS console and API responses
Use descriptive naming to identify old exports
Filter by date when listing export tasks
Export task metadata is free (no storage cost)
Focus on deleting exported S3 data instead:
aws s3 rm s3://bucket/prefix/export-task-id/ --recursive
Cross-Region Export Issues
Symptoms: Export fails or incurs unexpected costs with cross-region setup
Solutions:
Verify S3 bucket region vs database region
Cross-region exports are supported but have additional costs:
Data transfer charges apply (typically $0.02/GB)
Higher latency and slower speeds
Recommend using S3 bucket in same region when possible
For cross-region requirements:
Ensure IAM role permissions include cross-region access
Verify KMS key (if used) is accessible from both regions
Consider S3 Cross-Region Replication as alternative
Export to same-region bucket first, then replicate if needed
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.
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 · skills/specialized-skills/database-skills/exporting-rds-to-s3 · 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.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download exporting-rds-to-s3.zip