

# Configuring S3 destinations for scheduled queries
<a name="scheduled-queries-s3-destination"></a>

Configure Amazon S3 as a destination to store your scheduled query results as JSON files for long-term retention and analysis.

When using Amazon S3 as a destination, query results are stored as JSON files in the specified bucket and prefix. This option is ideal for archiving results, performing batch analysis, or integrating with other Amazon services that process S3 data.

You can deliver query results to an Amazon S3 bucket in the same Amazon account as the scheduled query or to a bucket in a different Amazon account. You can also optionally encrypt query results using a customer managed Amazon KMS key (SSE-KMS).

## Delivering results to an Amazon S3 bucket in the same account
<a name="scheduled-queries-s3-same-account"></a>

When the destination Amazon S3 bucket is in the same Amazon account as the scheduled query, you can browse and select the bucket directly from the console.

**To configure a same-account Amazon S3 destination (console)**

1. In the **Post query results to S3** section, for **S3 bucket**, select **This account**.

1. For **Amazon S3 URI**, enter the Amazon S3 bucket and prefix where results will be stored (for example, `s3://my-bucket/query-results/`), or choose **Browse Amazon S3** to navigate and select an existing Amazon S3 location.

1. (Optional) To encrypt results with a customer managed Amazon KMS key, enter the ARN of the Amazon KMS key in the **KMS key ARN** field. The key must be in the same Amazon Region as the destination Amazon S3 bucket. If you don't specify a Amazon KMS key, the bucket's default encryption settings apply.

1. In the **IAM role for posting query results to Amazon S3** section, choose **Auto-create a new role with default permissions** to automatically set up the required permissions, or choose **Use an existing role** to select an existing IAM role with the required policies.

The destination delivery IAM role requires the following permissions:

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::{{my-bucket}}/{{prefix}}/*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceAccount": "{{111122223333}}"
                }
            }
        }
    ]
}
```

## Delivering results to an Amazon S3 bucket in another account
<a name="scheduled-queries-s3-cross-account"></a>

You can deliver scheduled query results to an Amazon S3 bucket in a different Amazon account. When using a cross-account bucket, you must provide the Amazon S3 URI and the account ID of the bucket-owning account.

**To configure a cross-account Amazon S3 destination (console)**

1. In the **Post query results to S3** section, for **S3 bucket**, select **Another account** and provide the account ID of the bucket-owning account as input.

1. For **Amazon S3 URI**, enter the full Amazon S3 URI of the destination bucket and prefix in the other account (for example, `s3://cross-account-bucket/query-results/`).

1. (Optional) To encrypt results with a customer managed Amazon KMS key, enter the ARN of the Amazon KMS key in the **KMS key ARN** field. The key must be in the same Amazon Region as the destination Amazon S3 bucket.

1. In the **IAM role for posting query results to Amazon S3** section, choose **Auto-create a new role with default permissions** to automatically set up the required permissions, or choose **Use an existing role** to select an existing IAM role with the required policies.

Cross-account delivery requires permissions on both sides. The destination delivery IAM role in the source account requires the following permissions:

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::{{cross-account-bucket}}/{{prefix}}/*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceAccount": "{{123456789012}}"
                }
            }
        }
    ]
}
```

The Amazon S3 bucket policy in the destination account must grant the source account's IAM role permission to write objects:

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AllowScheduledQueryRolePutObject",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::{{111122223333}}:role/{{my-s3-delivery-role}}"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::{{cross-account-bucket}}/{{prefix}}/*"
        }
    ]
}
```

## Encrypting results with a customer managed Amazon KMS key
<a name="scheduled-queries-s3-kms-encryption"></a>

You can optionally specify a customer managed Amazon KMS key to encrypt query results delivered to Amazon S3 using SSE-KMS. The Amazon KMS key can be in the same account as the scheduled query or in a different account.

When you specify a Amazon KMS key, the scheduled query uses that key to encrypt results via SSE-KMS. When you don't specify a Amazon KMS key, the bucket's default encryption settings apply. If the bucket is configured with default SSE-KMS encryption using a customer managed key, the destination delivery IAM role must still have `kms:GenerateDataKey` permission on that key.

The destination delivery IAM role requires `kms:GenerateDataKey` permission on the Amazon KMS key. The following example shows the required permissions for an Amazon S3 destination with a customer managed Amazon KMS key:

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::{{my-bucket}}/{{prefix}}/*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceAccount": "{{111122223333}}"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": "kms:GenerateDataKey",
            "Resource": "arn:aws:kms:{{us-east-1}}:{{111122223333}}:key/{{key-id}}",
            "Condition": {
                "StringEquals": {
                    "kms:ViaService": "s3.{{us-east-1}}.amazonaws.com"
                },
                "StringLike": {
                    "kms:EncryptionContext:aws:s3:arn": "arn:aws:s3:::{{my-bucket}}*"
                }
            }
        }
    ]
}
```

When the Amazon KMS key is in a different account than the destination delivery IAM role, the Amazon KMS key policy in the key-owning account must explicitly grant the role access:

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AllowScheduledQueryRoleToEncrypt",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::{{111122223333}}:role/{{my-s3-delivery-role}}"
            },
            "Action": "kms:GenerateDataKey",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "kms:ViaService": "s3.{{us-east-1}}.amazonaws.com"
                },
                "StringLike": {
                    "kms:EncryptionContext:aws:s3:arn": "arn:aws:s3:::{{my-bucket}}*"
                }
            }
        }
    ]
}
```

**Note**  
When the Amazon KMS key and the destination delivery IAM role are in the same account, the IAM identity policy alone is sufficient if the Amazon KMS key policy includes the default "Enable IAM policies" root statement. An explicit Amazon KMS key policy grant is only required if the key policy does not delegate to IAM.

The IAM role for posting query results to Amazon S3 must be configured separately from the IAM role for scheduled query execution. This separation allows for fine-grained access control, where the execution role can run queries while the Amazon S3 role specifically handles result delivery. Both roles must include a trust policy that allows the CloudWatch Logs service (`logs.amazonaws.com`) to assume the role.